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

Skip to content

Commit b87c8e2

Browse files
tamasvajkigfoo
authored andcommitted
Extract generated <obinit> method, and calls to it
1 parent e31c573 commit b87c8e2

5 files changed

Lines changed: 58 additions & 17 deletions

File tree

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

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class KotlinExtractorExtension(private val invocationTrapFile: String, private v
4343
moduleFragment.files.mapIndexed { index: Int, file: IrFile ->
4444
val fileTrapWriter = FileTrapWriter(lm, invocationTrapFileBW, file)
4545
fileTrapWriter.writeCompilation_compiling_files(compilation, index, fileTrapWriter.fileId)
46-
doFile(invocationTrapFile, fileTrapWriter, checkTrapIdentical, logCounter, trapDir, srcDir, file)
46+
doFile(invocationTrapFile, fileTrapWriter, checkTrapIdentical, logCounter, trapDir, srcDir, file, pluginContext)
4747
}
4848
logger.printLimitedWarningCounts()
4949
// We don't want the compiler to continue and generate class
@@ -94,7 +94,14 @@ private fun equivalentTrap(f1: File, f2: File): Boolean {
9494
}
9595
}
9696

97-
fun doFile(invocationTrapFile: String, fileTrapWriter: FileTrapWriter, checkTrapIdentical: Boolean, logCounter: LogCounter, trapDir: File, srcDir: File, file: IrFile) {
97+
fun doFile(invocationTrapFile: String,
98+
fileTrapWriter: FileTrapWriter,
99+
checkTrapIdentical: Boolean,
100+
logCounter: LogCounter,
101+
trapDir: File,
102+
srcDir: File,
103+
file: IrFile,
104+
pluginContext: IrPluginContext) {
98105
val filePath = file.path
99106
val logger = FileLogger(logCounter, fileTrapWriter)
100107
logger.info("Extracting file $filePath")
@@ -116,7 +123,7 @@ fun doFile(invocationTrapFile: String, fileTrapWriter: FileTrapWriter, checkTrap
116123
trapTmpFile.bufferedWriter().use { trapFileBW ->
117124
trapFileBW.write("// Generated by invocation ${invocationTrapFile.replace("\n", "\n// ")}\n")
118125
val tw = FileTrapWriter(TrapLabelManager(), trapFileBW, file)
119-
val fileExtractor = KotlinFileExtractor(logger, tw, file)
126+
val fileExtractor = KotlinFileExtractor(logger, tw, file, pluginContext)
120127
fileExtractor.extractFileContents(tw.fileId)
121128
}
122129
if (checkTrapIdentical && trapFile.exists()) {
@@ -151,7 +158,7 @@ fun <T> fakeLabel(): Label<T> {
151158
return IntLabel(0)
152159
}
153160

154-
class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val file: IrFile) {
161+
class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val file: IrFile, val pluginContext: IrPluginContext) {
155162
val fileClass by lazy {
156163
extractFileClass(file)
157164
}
@@ -213,11 +220,7 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
213220
is IrClass -> extractClass(declaration)
214221
is IrFunction -> extractFunction(declaration, if (optParentid.isPresent()) optParentid.get() else fileClass)
215222
is IrAnonymousInitializer -> {
216-
// todo: how do we want to represent this?
217-
// there could be multiple 'init' blocks inside a declaration.
218-
// We could add a generated 'init' method, with all the statements inside the blocks.
219-
// In Kotlin/JVM, the statements inside 'init' blocks get copied to the default constructor, or if there's no default then to all of them.
220-
logger.warnElement(Severity.ErrorSevere, "Todo: handle IrAnonymousInitializer", declaration)
223+
// Leaving this intentionally empty. init blocks are extracted during class extraction.
221224
}
222225
is IrProperty -> extractProperty(declaration, if (optParentid.isPresent()) optParentid.get() else fileClass)
223226
else -> logger.warnElement(Severity.ErrorSevere, "Unrecognised IrDeclaration: " + declaration.javaClass, declaration)
@@ -363,6 +366,9 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
363366
}
364367
}
365368
c.declarations.map { extractDeclaration(it, Optional.of(id)) }
369+
370+
extractObjectInitializerFunction(c, id)
371+
366372
return id
367373
}
368374

@@ -399,10 +405,14 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
399405
}
400406

401407
private fun getFunctionLabel(f: IrFunction) : String {
402-
val paramTypeIds = f.valueParameters.joinToString() { "{${useType(erase(it.type)).toString()}}" }
403-
val returnTypeId = useType(erase(f.returnType))
404-
val parentId = useDeclarationParent(f.parent)
405-
val label = "@\"callable;{$parentId}.${f.name.asString()}($paramTypeIds){$returnTypeId}\""
408+
return getFunctionLabel(f.parent, f.name.asString(), f.valueParameters, f.returnType)
409+
}
410+
411+
private fun getFunctionLabel(parent: IrDeclarationParent, name: String, parameters: List<IrValueParameter>, returnType: IrType) : String {
412+
val paramTypeIds = parameters.joinToString() { "{${useType(erase(it.type)).toString()}}" }
413+
val returnTypeId = useType(erase(returnType))
414+
val parentId = useDeclarationParent(parent)
415+
val label = "@\"callable;{$parentId}.$name($paramTypeIds){$returnTypeId}\""
406416
return label
407417
}
408418

@@ -459,6 +469,19 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
459469
tw.writeParamName(id, vp.name.asString())
460470
}
461471

472+
private fun extractObjectInitializerFunction(c: IrClass, parentid: Label<out DbReftype>) {
473+
var methodLabel = getFunctionLabel(c, "<obinit>", listOf(), pluginContext.irBuiltIns.unitType)
474+
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
475+
val signature = "TODO"
476+
val returnTypeId = useType(pluginContext.irBuiltIns.unitType)
477+
tw.writeMethods(methodId, "<obinit>", signature, returnTypeId, parentid, methodId)
478+
479+
val locId = tw.getLocation(c)
480+
tw.writeHasLocation(methodId, locId)
481+
482+
// todo add body with non-static field initializers, and init blocks
483+
}
484+
462485
fun extractFunction(f: IrFunction, parentid: Label<out DbReftype>) {
463486
val id = useFunction(f)
464487
val locId = tw.getLocation(f)
@@ -702,11 +725,19 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
702725
val callableLabel = useFunction(irCallable)
703726
when(e) {
704727
is IrInstanceInitializerCall -> {
705-
// todo: how do we want to handle this?
706-
// In Kotlin/JVM, this seems like a no-op.
707-
if (e.classSymbol.owner.declarations.any { it is IrAnonymousInitializer }) {
708-
// we could add a call to a generated 'init' function.
728+
if (irCallable is IrConstructor && irCallable.isPrimary) {
729+
// Todo add parameter to field assignments
709730
}
731+
732+
// Add call to <obinit>:
733+
val id = tw.getFreshIdLabel<DbMethodaccess>()
734+
val typeId = useType(e.type)
735+
val locId = tw.getLocation(e)
736+
var methodLabel = getFunctionLabel(irCallable.parent, "<obinit>", listOf(), e.type)
737+
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
738+
tw.writeExprs_methodaccess(id, typeId, parent, idx)
739+
tw.writeHasLocation(id, locId)
740+
tw.writeCallableBinding(id, methodId)
710741
}
711742
is IrDelegatingConstructorCall -> {
712743
val delegatingClass = e.symbol.owner.parent as IrClass

java/ql/test/kotlin/library-tests/exprs/exprs.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
| exprs.kt:46:18:46:20 | 456 | IntegerLiteral |
4444
| exprs.kt:50:13:50:16 | true | BooleanLiteral |
4545
| exprs.kt:50:13:50:23 | ::class | ClassExpr |
46+
| exprs.kt:53:1:55:1 | <obinit>(...) | MethodAccess |
4647
| exprs.kt:54:27:54:31 | (no string representation) | ClassInstanceExpr |
4748
| exprs.kt:54:29:54:30 | 42 | IntegerLiteral |
4849
| file://:0:0:0:0 | b1 | LocalVariableDeclExpr |

java/ql/test/kotlin/library-tests/methods/exprs.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
| methods2.kt:7:1:10:1 | <obinit>(...) | MethodAccess |
2+
| methods3.kt:5:1:7:1 | <obinit>(...) | MethodAccess |
3+
| methods.kt:5:1:13:1 | <obinit>(...) | MethodAccess |
14
| methods.kt:10:9:10:25 | classMethod(...) | MethodAccess |
25
| methods.kt:10:9:10:25 | this | ThisAccess |
36
| methods.kt:10:21:10:21 | a | VarAccess |

java/ql/test/kotlin/library-tests/methods/methods.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
methods
22
| file://:0:0:0:0 | <init> |
3+
| file://:0:0:0:0 | <obinit> |
4+
| file://:0:0:0:0 | <obinit> |
35
| file://:0:0:0:0 | equals |
46
| file://:0:0:0:0 | equals |
57
| file://:0:0:0:0 | hashCode |
@@ -8,18 +10,21 @@ methods
810
| file://:0:0:0:0 | toString |
911
| methods2.kt:4:1:5:1 | fooBarTopLevelMethod |
1012
| methods2.kt:7:1:10:1 | <init> |
13+
| methods2.kt:7:1:10:1 | <obinit> |
1114
| methods2.kt:7:1:10:1 | equals |
1215
| methods2.kt:7:1:10:1 | hashCode |
1316
| methods2.kt:7:1:10:1 | toString |
1417
| methods2.kt:8:5:9:5 | fooBarClassMethod |
1518
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod |
1619
| methods3.kt:5:1:7:1 | <init> |
20+
| methods3.kt:5:1:7:1 | <obinit> |
1721
| methods3.kt:5:1:7:1 | equals |
1822
| methods3.kt:5:1:7:1 | hashCode |
1923
| methods3.kt:5:1:7:1 | toString |
2024
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod |
2125
| methods.kt:2:1:3:1 | topLevelMethod |
2226
| methods.kt:5:1:13:1 | <init> |
27+
| methods.kt:5:1:13:1 | <obinit> |
2328
| methods.kt:5:1:13:1 | equals |
2429
| methods.kt:5:1:13:1 | hashCode |
2530
| methods.kt:5:1:13:1 | toString |

java/ql/test/kotlin/library-tests/types/types.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
| file://:0:0:0:0 | <nulltype> | NullType |
22
| file://:0:0:0:0 | Any | Class |
3+
| file://:0:0:0:0 | Unit | Class |
34
| file://:0:0:0:0 | boolean | PrimitiveType |
45
| file://:0:0:0:0 | byte | PrimitiveType |
56
| file://:0:0:0:0 | char | PrimitiveType |

0 commit comments

Comments
 (0)