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