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

Skip to content

Commit 12ce2d5

Browse files
smowtonigfoo
authored andcommitted
Substitute Kotlin classes for Java equivalents
1 parent 6de5a36 commit 12ce2d5

1 file changed

Lines changed: 33 additions & 10 deletions

File tree

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

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.github.codeql
33
import com.github.codeql.comments.CommentExtractor
44
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
55
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
6+
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
67
import org.jetbrains.kotlin.descriptors.ClassKind
78
import org.jetbrains.kotlin.ir.IrElement
89
import org.jetbrains.kotlin.ir.IrStatement
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
1516
import org.jetbrains.kotlin.ir.types.*
1617
import org.jetbrains.kotlin.ir.util.packageFqName
1718
import org.jetbrains.kotlin.ir.util.render
19+
import org.jetbrains.kotlin.name.FqName
1820
import java.io.File
1921
import java.io.FileOutputStream
2022
import java.io.PrintWriter
@@ -27,6 +29,8 @@ import com.intellij.openapi.vfs.StandardFileSystems
2729
import com.semmle.extractor.java.OdasaOutput
2830
import com.semmle.extractor.java.OdasaOutput.TrapFileManager
2931
import com.semmle.util.files.FileUtil
32+
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
33+
import org.jetbrains.kotlin.ir.util.kotlinFqName
3034
import kotlin.system.exitProcess
3135

3236
class KotlinExtractorExtension(private val invocationTrapFile: String, private val checkTrapIdentical: Boolean) : IrGenerationExtension {
@@ -370,6 +374,7 @@ XXX delete?
370374
s.isChar() -> return primitiveType("char", "java.lang", "Character", "kotlin", "Char")
371375
s.isString() -> return primitiveType(null, "java.lang", "String", "kotlin", "String")
372376

377+
s.isUnit() -> return primitiveType("void", "java.lang", "Void", "kotlin", "Nothing") // TODO: Is this right?
373378
s.isNothing() -> return primitiveType(null, "java.lang", "Void", "kotlin", "Nothing") // TODO: Is this right?
374379

375380
/*
@@ -605,20 +610,39 @@ class X {
605610
return tw.getLabelFor(classId)
606611
}
607612

613+
fun extractClassLaterIfExternal(c: IrClass) {
614+
// we don't have an "external dependencies" extractor yet,
615+
// so for now we extract the source class for those too
616+
if (c.origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB ||
617+
c.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) {
618+
extractExternalClassLater(c)
619+
}
620+
}
621+
608622
fun useClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>): Label<out DbClassorinterface> {
609-
val classId = getClassLabel(c, typeArgs)
623+
// TODO: only substitute in class and function signatures
624+
// because within function bodies we can get things like Unit.INSTANCE
625+
// and List.asIterable (an extension, i.e. static, method)
626+
// Map Kotlin class to its equivalent Java class:
627+
val substituteClass = c.fqNameWhenAvailable?.toUnsafe()
628+
?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
629+
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
630+
?.owner
631+
632+
val extractClass = substituteClass ?: c
633+
634+
val classId = getClassLabel(extractClass, typeArgs)
610635
return tw.getLabelFor(classId, {
611636
// If this is a generic type instantiation then it has no
612637
// source entity, so we need to extract it here
613638
if (typeArgs.isNotEmpty()) {
614-
extractClassInstance(c, typeArgs)
615-
}
616-
// we don't have an "external dependencies" extractor yet,
617-
// so for now we extract the source class for those too
618-
if (c.origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB ||
619-
c.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) {
620-
extractExternalClassLater(c)
639+
extractClassInstance(extractClass, typeArgs)
621640
}
641+
642+
// Extract both the Kotlin and equivalent Java classes, so that we have database entries
643+
// for both even if all internal references to the Kotlin type are substituted.
644+
extractClassLaterIfExternal(c)
645+
substituteClass?.let { extractClassLaterIfExternal(it) }
622646
})
623647
}
624648

@@ -1465,5 +1489,4 @@ class X {
14651489

14661490
tw.writeKtBreakContinueTargets(id, loopId)
14671491
}
1468-
1469-
}
1492+
}

0 commit comments

Comments
 (0)