mirror of
https://github.com/github/codeql.git
synced 2025-12-22 19:56:32 +01:00
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)
This commit is contained in:
@@ -122,10 +122,7 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
|
||||
fun getJavaEquivalentClass(c: IrClass) =
|
||||
c.fqNameWhenAvailable?.toUnsafe()
|
||||
?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
|
||||
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
|
||||
?.owner
|
||||
getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner
|
||||
|
||||
/**
|
||||
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.
|
||||
|
||||
@@ -7,7 +7,9 @@ import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
|
||||
@@ -84,4 +86,7 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? {
|
||||
is IrClass -> decl
|
||||
else -> decl.parentClassOrNull
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getJavaEquivalentClassId(c: IrClass) =
|
||||
c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) }
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.codeql.utils
|
||||
|
||||
import com.github.codeql.KotlinUsesExtractor
|
||||
import com.github.codeql.getJavaEquivalentClassId
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.classId
|
||||
import org.jetbrains.kotlin.ir.util.constructedClassType
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
@@ -195,13 +197,25 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument =
|
||||
|
||||
typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType
|
||||
|
||||
fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean {
|
||||
if (l === r)
|
||||
return true
|
||||
if (l == null)
|
||||
return false
|
||||
// Special case: match List's E and MutableList's E, for example, because in the JVM lowering they will map to the same thing.
|
||||
val lParent = l.parent as? IrClass ?: return false
|
||||
val rParent = r.parent as? IrClass ?: return false
|
||||
val lJavaId = getJavaEquivalentClassId(lParent) ?: lParent.classId
|
||||
return (getJavaEquivalentClassId(rParent) ?: rParent.classId) == lJavaId && l.name == r.name
|
||||
}
|
||||
|
||||
// Returns true if type is C<T1, T2, ...> where C is declared `class C<T1, T2, ...> { ... }`
|
||||
fun isUnspecialised(paramsContainer: IrTypeParametersContainer, args: List<IrTypeArgument>): Boolean {
|
||||
val unspecialisedHere = paramsContainer.typeParameters.zip(args).all { paramAndArg ->
|
||||
(paramAndArg.second as? IrTypeProjection)?.let {
|
||||
// Type arg refers to the class' own type parameter?
|
||||
it.variance == Variance.INVARIANT &&
|
||||
it.type.classifierOrNull?.owner === paramAndArg.first
|
||||
matchingTypeParameters(it.type.classifierOrNull?.owner as? IrTypeParameter, paramAndArg.first)
|
||||
} ?: false
|
||||
}
|
||||
val remainingArgs = args.drop(paramsContainer.typeParameters.size)
|
||||
|
||||
Reference in New Issue
Block a user