@@ -73,6 +73,7 @@ open class KotlinFileExtractor(
7373 }
7474
7575 file.declarations.map { extractDeclaration(it) }
76+ extractStaticInitializer(file)
7677 CommentExtractor (this , file, tw.fileId).extract()
7778 }
7879 }
@@ -467,72 +468,110 @@ open class KotlinFileExtractor(
467468 return type
468469 }
469470
471+ private fun extractStaticInitializer (file : IrFile ) {
472+ with (" static initializer extraction" , file) {
473+ extractDeclInitializers(file.declarations, true ) {
474+ val parentId = extractFileClass(file)
475+ val clinitLabel = getFunctionLabel(
476+ file,
477+ parentId,
478+ " <clinit>" ,
479+ listOf (),
480+ pluginContext.irBuiltIns.unitType,
481+ extensionReceiverParameter = null ,
482+ functionTypeParameters = listOf (),
483+ classTypeArgsIncludingOuterClasses = listOf ()
484+ )
485+ val clinitId = tw.getLabelFor<DbMethod >(clinitLabel)
486+ val returnType = useType(pluginContext.irBuiltIns.unitType)
487+ tw.writeMethods(clinitId, " <clinit>" , " <clinit>()" , returnType.javaResult.id, parentId, clinitId)
488+ tw.writeMethodsKotlinType(clinitId, returnType.kotlinResult.id)
489+
490+ val locId = tw.getWholeFileLocation()
491+ tw.writeHasLocation(clinitId, locId)
492+
493+ // add and return body block:
494+ Pair (tw.getFreshIdLabel<DbBlock >().also ({
495+ tw.writeStmts_block(it, clinitId, 0 , clinitId)
496+ tw.writeHasLocation(it, locId)
497+ }), clinitId)
498+ }
499+ }
500+ }
501+
470502 private fun extractInstanceInitializerBlock (parent : StmtParent , enclosingConstructor : IrConstructor ) {
471503 with (" object initializer block" , enclosingConstructor) {
472504 val constructorId = useFunction<DbConstructor >(enclosingConstructor)
473- val blockId by lazy {
474- tw.getFreshIdLabel<DbBlock >().also {
475- tw.writeStmts_block(it, parent.parent, parent.idx, constructorId)
476- val locId = tw.getLocation(enclosingConstructor)
477- tw.writeHasLocation(it, locId)
478- }
479- }
480505 val enclosingClass = enclosingConstructor.parentClassOrNull
481506 if (enclosingClass == null ) {
482507 logger.warnElement(" Constructor's parent is not a class" , enclosingConstructor)
483508 return
484509 }
485510
486- // body content with field initializers and init blocks
487- var idx = 0
488- for (decl in enclosingClass.declarations) {
489- when (decl) {
490- is IrProperty -> {
491- val backingField = decl.backingField
492- val initializer = backingField?.initializer
511+ extractDeclInitializers(enclosingClass.declarations, false ) {
512+ Pair (tw.getFreshIdLabel<DbBlock >().also ({
513+ tw.writeStmts_block(it, parent.parent, parent.idx, constructorId)
514+ val locId = tw.getLocation(enclosingConstructor)
515+ tw.writeHasLocation(it, locId)
516+ }), constructorId)
517+ }
518+ }
519+ }
520+
521+ private fun extractDeclInitializers (declarations : List <IrDeclaration >, extractStaticInitializers : Boolean , makeEnclosingBlock : () -> Pair <Label <DbBlock >, Label <out DbCallable >>) {
522+ val blockAndFunctionId by lazy {
523+ makeEnclosingBlock()
524+ }
493525
494- if (backingField == null || backingField.isStatic || initializer == null ) {
495- continue
496- }
526+ // Extract field initializers and init blocks (the latter can only occur in object initializers)
527+ var idx = 0
528+ for (decl in declarations) {
529+ when (decl) {
530+ is IrProperty -> {
531+ val backingField = decl.backingField
532+ val initializer = backingField?.initializer
497533
498- val expr = initializer.expression
499-
500- val declLocId = tw.getLocation(decl)
501- val stmtId = tw.getFreshIdLabel<DbExprstmt >()
502- tw.writeStmts_exprstmt(stmtId, blockId, idx++ , constructorId)
503- tw.writeHasLocation(stmtId, declLocId)
504- val assignmentId = tw.getFreshIdLabel<DbAssignexpr >()
505- val type = useType(expr.type)
506- tw.writeExprs_assignexpr(assignmentId, type.javaResult.id, stmtId, 0 )
507- tw.writeExprsKotlinType(assignmentId, type.kotlinResult.id)
508- tw.writeHasLocation(assignmentId, declLocId)
509- tw.writeCallableEnclosingExpr(assignmentId, constructorId)
510- tw.writeStatementEnclosingExpr(assignmentId, stmtId)
511- tw.writeKtInitializerAssignment(assignmentId)
512-
513- val lhsId = tw.getFreshIdLabel<DbVaraccess >()
514- val lhsType = useType(backingField.type)
515- tw.writeExprs_varaccess(lhsId, lhsType.javaResult.id, assignmentId, 0 )
516- tw.writeExprsKotlinType(lhsId, lhsType.kotlinResult.id)
517- tw.writeHasLocation(lhsId, declLocId)
518- tw.writeCallableEnclosingExpr(lhsId, constructorId)
519- tw.writeStatementEnclosingExpr(lhsId, stmtId)
520- val vId = useField(backingField)
521- tw.writeVariableBinding(lhsId, vId)
522-
523- extractExpressionExpr(expr, constructorId, assignmentId, 1 , stmtId)
524- }
525- is IrAnonymousInitializer -> {
526- if (decl.isStatic) {
527- continue
528- }
534+ if (backingField == null || backingField.isStatic != extractStaticInitializers || initializer == null ) {
535+ continue
536+ }
529537
530- for (stmt in decl.body.statements) {
531- extractStatement(stmt, constructorId, blockId, idx++ )
532- }
538+ val expr = initializer.expression
539+
540+ val declLocId = tw.getLocation(decl)
541+ val stmtId = tw.getFreshIdLabel<DbExprstmt >()
542+ tw.writeStmts_exprstmt(stmtId, blockAndFunctionId.first, idx++ , blockAndFunctionId.second)
543+ tw.writeHasLocation(stmtId, declLocId)
544+ val assignmentId = tw.getFreshIdLabel<DbAssignexpr >()
545+ val type = useType(expr.type)
546+ tw.writeExprs_assignexpr(assignmentId, type.javaResult.id, stmtId, 0 )
547+ tw.writeExprsKotlinType(assignmentId, type.kotlinResult.id)
548+ tw.writeHasLocation(assignmentId, declLocId)
549+ tw.writeCallableEnclosingExpr(assignmentId, blockAndFunctionId.second)
550+ tw.writeStatementEnclosingExpr(assignmentId, stmtId)
551+ tw.writeKtInitializerAssignment(assignmentId)
552+
553+ val lhsId = tw.getFreshIdLabel<DbVaraccess >()
554+ val lhsType = useType(backingField.type)
555+ tw.writeExprs_varaccess(lhsId, lhsType.javaResult.id, assignmentId, 0 )
556+ tw.writeExprsKotlinType(lhsId, lhsType.kotlinResult.id)
557+ tw.writeHasLocation(lhsId, declLocId)
558+ tw.writeCallableEnclosingExpr(lhsId, blockAndFunctionId.second)
559+ tw.writeStatementEnclosingExpr(lhsId, stmtId)
560+ val vId = useField(backingField)
561+ tw.writeVariableBinding(lhsId, vId)
562+
563+ extractExpressionExpr(expr, blockAndFunctionId.second, assignmentId, 1 , stmtId)
564+ }
565+ is IrAnonymousInitializer -> {
566+ if (decl.isStatic) {
567+ continue
568+ }
569+
570+ for (stmt in decl.body.statements) {
571+ extractStatement(stmt, blockAndFunctionId.second, blockAndFunctionId.first, idx++ )
533572 }
534- else -> continue
535573 }
574+ else -> continue
536575 }
537576 }
538577 }
0 commit comments