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

Skip to content

Commit cb6941d

Browse files
committed
Account for JVM type equivalency when recognising unspecialised types
(As before, these are not really unspecialised, they are instantiated by their own type parameters, but this replicates the behaviour of the Java extractor)
1 parent 39551fd commit cb6941d

3 files changed

Lines changed: 22 additions & 6 deletions

File tree

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,7 @@ open class KotlinUsesExtractor(
122122
}
123123

124124
fun getJavaEquivalentClass(c: IrClass) =
125-
c.fqNameWhenAvailable?.toUnsafe()
126-
?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
127-
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
128-
?.owner
125+
getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner
129126

130127
/**
131128
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.

java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
77
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
88

99
import com.intellij.openapi.vfs.VirtualFile
10+
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
1011
import org.jetbrains.kotlin.ir.declarations.*
12+
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
1113
import org.jetbrains.kotlin.ir.util.parentClassOrNull
1214
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
1315

@@ -84,4 +86,7 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? {
8486
is IrClass -> decl
8587
else -> decl.parentClassOrNull
8688
}
87-
}
89+
}
90+
91+
fun getJavaEquivalentClassId(c: IrClass) =
92+
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }

java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.codeql.utils
22

33
import com.github.codeql.KotlinUsesExtractor
4+
import com.github.codeql.getJavaEquivalentClassId
45
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
56
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
67
import org.jetbrains.kotlin.descriptors.ClassKind
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.*
1920
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
2021
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
2122
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
23+
import org.jetbrains.kotlin.ir.util.classId
2224
import org.jetbrains.kotlin.ir.util.constructedClassType
2325
import org.jetbrains.kotlin.ir.util.constructors
2426
import org.jetbrains.kotlin.ir.util.parentAsClass
@@ -195,13 +197,25 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument =
195197

196198
typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType
197199

200+
fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
201+
if (l === r)
202+
return true
203+
if (l == null)
204+
return false
205+
// Special case: match List's E and MutableList's E, for example, because in the JVM lowering they will map to the same thing.
206+
val lParent = l.parent as? IrClass ?: return false
207+
val rParent = r.parent as? IrClass ?: return false
208+
val lJavaId = getJavaEquivalentClassId(lParent) ?: lParent.classId
209+
return (getJavaEquivalentClassId(rParent) ?: rParent.classId) == lJavaId && l.name == r.name
210+
}
211+
198212
// Returns true if type is C<T1, T2, ...> where C is declared `class C<T1, T2, ...> { ... }`
199213
fun isUnspecialised(paramsContainer: IrTypeParametersContainer, args: List<IrTypeArgument>): Boolean {
200214
val unspecialisedHere = paramsContainer.typeParameters.zip(args).all { paramAndArg ->
201215
(paramAndArg.second as? IrTypeProjection)?.let {
202216
// Type arg refers to the class' own type parameter?
203217
it.variance == Variance.INVARIANT &&
204-
it.type.classifierOrNull?.owner === paramAndArg.first
218+
matchingTypeParameters(it.type.classifierOrNull?.owner as? IrTypeParameter, paramAndArg.first)
205219
} ?: false
206220
}
207221
val remainingArgs = args.drop(paramsContainer.typeParameters.size)

0 commit comments

Comments
 (0)