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

Skip to content

Commit de13741

Browse files
committed
Kotlin: Use an IrClass for the Java class in the priomitive type handling
This means we can add a label for it, and indicate that we use it, properly.
1 parent 7fa4da8 commit de13741

6 files changed

Lines changed: 85 additions & 31 deletions

File tree

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package com.github.codeql
33
import com.semmle.extractor.java.OdasaOutput
44
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
55
import org.jetbrains.kotlin.ir.declarations.IrClass
6+
import org.jetbrains.kotlin.ir.util.IdSignature
67
import java.io.File
78
import java.util.ArrayList
89
import java.util.HashSet
910
import java.util.zip.GZIPOutputStream
1011

11-
class ExternalClassExtractor(val logger: FileLogger, val sourceFilePath: String, val pluginContext: IrPluginContext) {
12+
class ExternalClassExtractor(val logger: FileLogger, val sourceFilePath: String, val primitiveTypeMapping: Map<IdSignature.PublicSignature, PrimitiveTypeInfo>, val pluginContext: IrPluginContext) {
1213

1314
val externalClassesDone = HashSet<IrClass>()
1415
val externalClassWorkList = ArrayList<IrClass>()
@@ -34,7 +35,7 @@ class ExternalClassExtractor(val logger: FileLogger, val sourceFilePath: String,
3435
GZIPOutputStream(manager.getFile().outputStream()).bufferedWriter().use { trapFileBW ->
3536
val tw =
3637
FileTrapWriter(TrapLabelManager(), trapFileBW, getIrClassBinaryPath(irClass), true)
37-
val fileExtractor = KotlinFileExtractor(logger, tw, manager, this, pluginContext)
38+
val fileExtractor = KotlinFileExtractor(logger, tw, manager, this, primitiveTypeMapping, pluginContext)
3839
fileExtractor.extractClassSource(irClass)
3940
}
4041
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.github.codeql
33
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
44
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
55
import org.jetbrains.kotlin.ir.declarations.*
6+
import org.jetbrains.kotlin.ir.util.*
67
import java.io.File
78
import java.io.FileOutputStream
89
import java.nio.file.Files
@@ -35,6 +36,7 @@ class KotlinExtractorExtension(
3536
val logger = Logger(logCounter, tw)
3637
logger.info("Extraction started")
3738
logger.flush()
39+
val primitiveTypeMapping = makePrimitiveTypeMapping(logger, pluginContext)
3840
// FIXME: FileUtil expects a static global logger
3941
// which should be provided by SLF4J's factory facility. For now we set it here.
4042
FileUtil.logger = logger
@@ -43,7 +45,7 @@ class KotlinExtractorExtension(
4345
moduleFragment.files.mapIndexed { index: Int, file: IrFile ->
4446
val fileTrapWriter = tw.makeSourceFileTrapWriter(file, true)
4547
fileTrapWriter.writeCompilation_compiling_files(compilation, index, fileTrapWriter.fileId)
46-
doFile(invocationTrapFile, fileTrapWriter, checkTrapIdentical, logCounter, trapDir, srcDir, file, pluginContext)
48+
doFile(invocationTrapFile, fileTrapWriter, checkTrapIdentical, logCounter, trapDir, srcDir, file, primitiveTypeMapping, pluginContext)
4749
}
4850
logger.printLimitedWarningCounts()
4951
// We don't want the compiler to continue and generate class
@@ -89,6 +91,7 @@ fun doFile(invocationTrapFile: String,
8991
trapDir: File,
9092
srcDir: File,
9193
file: IrFile,
94+
primitiveTypeMapping: Map<IdSignature.PublicSignature, PrimitiveTypeInfo>,
9295
pluginContext: IrPluginContext) {
9396
val filePath = file.path
9497
val logger = FileLogger(logCounter, fileTrapWriter)
@@ -111,8 +114,8 @@ fun doFile(invocationTrapFile: String,
111114
trapTmpFile.bufferedWriter().use { trapFileBW ->
112115
val tw = SourceFileTrapWriter(TrapLabelManager(), trapFileBW, file, true)
113116
tw.writeComment("Generated by invocation $invocationTrapFile")
114-
val externalClassExtractor = ExternalClassExtractor(logger, file.path, pluginContext)
115-
val fileExtractor = KotlinSourceFileExtractor(logger, tw, file, externalClassExtractor, pluginContext)
117+
val externalClassExtractor = ExternalClassExtractor(logger, file.path, primitiveTypeMapping, pluginContext)
118+
val fileExtractor = KotlinSourceFileExtractor(logger, tw, file, externalClassExtractor, primitiveTypeMapping, pluginContext)
116119
fileExtractor.extractFileContents(tw.fileId)
117120
externalClassExtractor.extractExternalClasses()
118121
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ open class KotlinFileExtractor(
1717
override val tw: FileTrapWriter,
1818
dependencyCollector: OdasaOutput.TrapFileManager?,
1919
externalClassExtractor: ExternalClassExtractor,
20+
primitiveTypeMapping: Map<IdSignature.PublicSignature, PrimitiveTypeInfo>,
2021
pluginContext: IrPluginContext
21-
): KotlinUsesExtractor(logger, tw, dependencyCollector, externalClassExtractor, pluginContext) {
22+
): KotlinUsesExtractor(logger, tw, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext) {
2223

2324
fun extractDeclaration(declaration: IrDeclaration, parentId: Label<out DbReftype>) {
2425
when (declaration) {

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ import org.jetbrains.kotlin.ir.expressions.IrConst
88
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
99
import org.jetbrains.kotlin.ir.types.IrSimpleType
1010
import org.jetbrains.kotlin.ir.util.packageFqName
11+
import org.jetbrains.kotlin.ir.util.IdSignature
1112

1213
class KotlinSourceFileExtractor(
1314
logger: FileLogger,
1415
tw: FileTrapWriter,
1516
val file: IrFile,
1617
externalClassExtractor: ExternalClassExtractor,
18+
primitiveTypeMapping: Map<IdSignature.PublicSignature, PrimitiveTypeInfo>,
1719
pluginContext: IrPluginContext
1820
) :
19-
KotlinFileExtractor(logger, tw, null, externalClassExtractor, pluginContext) {
21+
KotlinFileExtractor(logger, tw, null, externalClassExtractor, primitiveTypeMapping, pluginContext) {
2022

2123
val fileClass by lazy {
2224
extractFileClass(file)
@@ -65,4 +67,4 @@ class KotlinSourceFileExtractor(
6567
return id
6668
}
6769

68-
}
70+
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ open class KotlinUsesExtractor(
1919
open val tw: TrapWriter,
2020
val dependencyCollector: OdasaOutput.TrapFileManager?,
2121
val externalClassExtractor: ExternalClassExtractor,
22+
val primitiveTypeMapping: Map<IdSignature.PublicSignature, PrimitiveTypeInfo>,
2223
val pluginContext: IrPluginContext
2324
) {
2425
fun usePackage(pkg: String): Label<out DbPackage> {
@@ -78,7 +79,7 @@ open class KotlinUsesExtractor(
7879

7980
val newLogger = FileLogger(logger.logCounter, newTrapWriter)
8081

81-
return KotlinFileExtractor(newLogger, newTrapWriter, dependencyCollector, externalClassExtractor, pluginContext)
82+
return KotlinFileExtractor(newLogger, newTrapWriter, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext)
8283
}
8384

8485
fun useClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>): UseClassInstanceResult {
@@ -284,17 +285,16 @@ open class KotlinUsesExtractor(
284285
}
285286
fun primitiveType(kotlinClass: IrClass, primitiveName: String?,
286287
otherIsPrimitive: Boolean,
287-
javaPackageName: String, javaClassName: String,
288+
javaClass: IrClass,
288289
kotlinPackageName: String, kotlinClassName: String): TypeResults {
289290
val javaResult = if ((context == TypeContext.RETURN || (context == TypeContext.OTHER && otherIsPrimitive)) && !s.hasQuestionMark && primitiveName != null) {
290291
val label: Label<DbPrimitive> = tw.getLabelFor("@\"type;$primitiveName\"", {
291292
tw.writePrimitives(it, primitiveName)
292293
})
293294
TypeResult(label, primitiveName, primitiveName)
294295
} else {
295-
val label = makeClass(javaPackageName, javaClassName)
296-
val signature = "$javaPackageName.$javaClassName"
297-
TypeResult(label, signature, javaClassName)
296+
extractClassLaterIfExternal(javaClass)
297+
addClassLabel(javaClass, listOf())
298298
}
299299
val kotlinClassId = useClassInstance(kotlinClass, listOf()).typeResult.id
300300
val kotlinResult = if (s.hasQuestionMark) {
@@ -332,7 +332,7 @@ XXX delete?
332332
primitiveInfo != null -> return primitiveType(
333333
s.classifier.owner as IrClass,
334334
primitiveInfo.primitiveName, primitiveInfo.otherIsPrimitive,
335-
primitiveInfo.javaPackageName, primitiveInfo.javaClassName,
335+
primitiveInfo.javaClass,
336336
primitiveInfo.kotlinPackageName, primitiveInfo.kotlinClassName
337337
)
338338
/*
Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,79 @@
11
package com.github.codeql
22

3+
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
4+
import org.jetbrains.kotlin.ir.declarations.IrClass
35
import org.jetbrains.kotlin.ir.types.IdSignatureValues
6+
import org.jetbrains.kotlin.ir.util.IdSignature
7+
import org.jetbrains.kotlin.name.FqName
48

59
data class PrimitiveTypeInfo(
610
val primitiveName: String?,
711
val otherIsPrimitive: Boolean,
8-
val javaPackageName: String, val javaClassName: String,
12+
val javaClass: IrClass,
913
val kotlinPackageName: String, val kotlinClassName: String
1014
)
1115

12-
val primitiveTypeMapping = mapOf(
13-
IdSignatureValues._byte to PrimitiveTypeInfo("byte", true, "java.lang", "Byte", "kotlin", "Byte"),
14-
IdSignatureValues._short to PrimitiveTypeInfo("short", true, "java.lang", "Short", "kotlin", "Short"),
15-
IdSignatureValues._int to PrimitiveTypeInfo("int", true, "java.lang", "Integer", "kotlin", "Int"),
16-
IdSignatureValues._long to PrimitiveTypeInfo("long", true, "java.lang", "Long", "kotlin", "Long"),
16+
private fun findClass(fqName: String, fallback: IrClass, logger: Logger, pluginContext: IrPluginContext): IrClass {
17+
val symbol = pluginContext.referenceClass(FqName(fqName))
18+
if(symbol == null) {
19+
logger.warn("Can't find $fqName")
20+
// Do the best we can
21+
return fallback
22+
} else {
23+
return symbol.owner
24+
}
25+
}
1726

18-
IdSignatureValues.uByte to PrimitiveTypeInfo("byte", true, "kotlin", "UByte", "kotlin", "UByte"),
19-
IdSignatureValues.uShort to PrimitiveTypeInfo("short", true, "kotlin", "UShort", "kotlin", "UShort"),
20-
IdSignatureValues.uInt to PrimitiveTypeInfo("int", true, "kotlin", "UInt", "kotlin", "UInt"),
21-
IdSignatureValues.uLong to PrimitiveTypeInfo("long", true, "kotlin", "ULong", "kotlin", "ULong"),
27+
fun makePrimitiveTypeMapping(logger: Logger, pluginContext: IrPluginContext): Map<IdSignature.PublicSignature, PrimitiveTypeInfo> {
28+
val kotlinByte = pluginContext.irBuiltIns.byteClass.owner
29+
val javaLangByte = findClass("java.lang.Byte", kotlinByte, logger, pluginContext)
30+
val kotlinShort = pluginContext.irBuiltIns.shortClass.owner
31+
val javaLangShort = findClass("java.lang.Short", kotlinShort, logger, pluginContext)
32+
val kotlinInt = pluginContext.irBuiltIns.intClass.owner
33+
val javaLangInteger = findClass("java.lang.Integer", kotlinInt, logger, pluginContext)
34+
val kotlinLong = pluginContext.irBuiltIns.longClass.owner
35+
val javaLangLong = findClass("java.lang.Long", kotlinLong, logger, pluginContext)
2236

23-
IdSignatureValues._double to PrimitiveTypeInfo("double", true, "java.lang", "Double", "kotlin", "Double"),
24-
IdSignatureValues._float to PrimitiveTypeInfo("float", true, "java.lang", "Float", "kotlin", "Float"),
37+
val kotlinUByte = findClass("kotlin.UByte", kotlinByte, logger, pluginContext)
38+
val kotlinUShort = findClass("kotlin.UShort", kotlinShort, logger, pluginContext)
39+
val kotlinUInt = findClass("kotlin.UInt", kotlinInt, logger, pluginContext)
40+
val kotlinULong = findClass("kotlin.ULong", kotlinLong, logger, pluginContext)
2541

26-
IdSignatureValues._boolean to PrimitiveTypeInfo("boolean", true, "java.lang", "Boolean", "kotlin", "Boolean"),
42+
val kotlinDouble = pluginContext.irBuiltIns.doubleClass.owner
43+
val javaLangDouble = findClass("java.lang.Double", kotlinDouble, logger, pluginContext)
44+
val kotlinFloat = pluginContext.irBuiltIns.floatClass.owner
45+
val javaLangFloat = findClass("java.lang.Float", kotlinFloat, logger, pluginContext)
2746

28-
IdSignatureValues._char to PrimitiveTypeInfo("char", true, "java.lang", "Character", "kotlin", "Char"),
47+
val kotlinBoolean = pluginContext.irBuiltIns.booleanClass.owner
48+
val javaLangBoolean = findClass("java.lang.Boolean", kotlinBoolean, logger, pluginContext)
2949

30-
IdSignatureValues.unit to PrimitiveTypeInfo("void", false, "kotlin", "Unit", "kotlin", "Unit"),
31-
IdSignatureValues.nothing to PrimitiveTypeInfo(null, true, "java.lang", "Void", "kotlin", "Nothing"),
32-
)
50+
val kotlinChar = pluginContext.irBuiltIns.charClass.owner
51+
val javaLangCharacter = findClass("java.lang.Character", kotlinChar, logger, pluginContext)
52+
53+
val kotlinUnit = pluginContext.irBuiltIns.unitClass.owner
54+
55+
val kotlinNothing = pluginContext.irBuiltIns.nothingClass.owner
56+
val javaLangVoid = findClass("java.lang.Void", kotlinNothing, logger, pluginContext)
57+
58+
return mapOf(
59+
IdSignatureValues._byte to PrimitiveTypeInfo("byte", true, javaLangByte, "kotlin", "Byte"),
60+
IdSignatureValues._short to PrimitiveTypeInfo("short", true, javaLangShort, "kotlin", "Short"),
61+
IdSignatureValues._int to PrimitiveTypeInfo("int", true, javaLangInteger, "kotlin", "Int"),
62+
IdSignatureValues._long to PrimitiveTypeInfo("long", true, javaLangLong, "kotlin", "Long"),
63+
64+
IdSignatureValues.uByte to PrimitiveTypeInfo("byte", true, kotlinUByte, "kotlin", "UByte"),
65+
IdSignatureValues.uShort to PrimitiveTypeInfo("short", true, kotlinUShort, "kotlin", "UShort"),
66+
IdSignatureValues.uInt to PrimitiveTypeInfo("int", true, kotlinUInt, "kotlin", "UInt"),
67+
IdSignatureValues.uLong to PrimitiveTypeInfo("long", true, kotlinULong, "kotlin", "ULong"),
68+
69+
IdSignatureValues._double to PrimitiveTypeInfo("double", true, javaLangDouble, "kotlin", "Double"),
70+
IdSignatureValues._float to PrimitiveTypeInfo("float", true, javaLangFloat, "kotlin", "Float"),
71+
72+
IdSignatureValues._boolean to PrimitiveTypeInfo("boolean", true, javaLangBoolean, "kotlin", "Boolean"),
73+
74+
IdSignatureValues._char to PrimitiveTypeInfo("char", true, javaLangCharacter, "kotlin", "Char"),
75+
76+
IdSignatureValues.unit to PrimitiveTypeInfo("void", false, kotlinUnit, "kotlin", "Unit"),
77+
IdSignatureValues.nothing to PrimitiveTypeInfo(null, true, javaLangVoid, "kotlin", "Nothing"),
78+
)
79+
}

0 commit comments

Comments
 (0)