Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6abb252

Browse files
smowtonigfoo
authored andcommitted
Extract a clinit method for Kotlin files
1 parent 2d0bb43 commit 6abb252

3 files changed

Lines changed: 93 additions & 53 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 91 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

java/ql/test/kotlin/library-tests/variables/variableAccesses.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ varAcc
22
| variables.kt:3:5:3:21 | prop |
33
| variables.kt:3:5:3:21 | this.prop |
44
| variables.kt:10:1:10:21 | topLevel |
5+
| variables.kt:10:1:10:21 | topLevel |
56
| variables.kt:16:11:16:18 | o |
67
| variables.kt:16:11:16:18 | o |
78
| variables.kt:16:11:16:18 | this.o |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
| variables.kt:3:5:3:21 | prop | int | variables.kt:3:21:3:21 | 1 |
22
| variables.kt:5:20:5:29 | param | int | file://:0:0:0:0 | <none> |
33
| variables.kt:6:9:6:25 | int local | int | variables.kt:6:21:6:25 | ... + ... |
4-
| variables.kt:10:1:10:21 | topLevel | int | file://:0:0:0:0 | <none> |
4+
| variables.kt:10:1:10:21 | topLevel | int | variables.kt:10:21:10:21 | 1 |
55
| variables.kt:16:11:16:18 | o | C1 | file://:0:0:0:0 | <none> |
66
| variables.kt:16:11:16:18 | o | C1 | variables.kt:16:11:16:18 | o |
77
| variables.kt:23:9:23:10 | <this> | C1 | file://:0:0:0:0 | <none> |

0 commit comments

Comments
 (0)