mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Fix wildcard introduction vs. constructor parameters
Previously we handled the case of *methods* with potentially-wildcarded types that Java nontheless constrains to be invariant, but missed out the constructor case.
This commit is contained in:
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.ir.types.*
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaMethod
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
@@ -514,7 +516,7 @@ open class KotlinFileExtractor(
|
|||||||
else
|
else
|
||||||
null
|
null
|
||||||
} ?: vp.type
|
} ?: vp.type
|
||||||
val javaType = ((vp.parent as? IrFunction)?.let { getJavaMethod(it) })?.valueParameters?.getOrNull(idx)?.type
|
val javaType = (vp.parent as? IrFunction)?.let { getJavaCallable(it)?.let { jCallable -> getJavaValueParameterType(jCallable, idx) } }
|
||||||
val typeWithWildcards = addJavaLoweringWildcards(maybeErasedType, !hasWildcardSuppressionAnnotation(vp), javaType)
|
val typeWithWildcards = addJavaLoweringWildcards(maybeErasedType, !hasWildcardSuppressionAnnotation(vp), javaType)
|
||||||
val substitutedType = typeSubstitution?.let { it(typeWithWildcards, TypeContext.OTHER, pluginContext) } ?: typeWithWildcards
|
val substitutedType = typeSubstitution?.let { it(typeWithWildcards, TypeContext.OTHER, pluginContext) } ?: typeWithWildcards
|
||||||
val id = useValueParameter(vp, parent)
|
val id = useValueParameter(vp, parent)
|
||||||
@@ -691,8 +693,8 @@ open class KotlinFileExtractor(
|
|||||||
with("function", f) {
|
with("function", f) {
|
||||||
DeclarationStackAdjuster(f).use {
|
DeclarationStackAdjuster(f).use {
|
||||||
|
|
||||||
val javaMethod = getJavaMethod(f)
|
val javaCallable = getJavaCallable(f)
|
||||||
getFunctionTypeParameters(f).mapIndexed { idx, tp -> extractTypeParameter(tp, idx, javaMethod?.typeParameters?.getOrNull(idx)) }
|
getFunctionTypeParameters(f).mapIndexed { idx, tp -> extractTypeParameter(tp, idx, (javaCallable as? JavaTypeParameterListOwner)?.typeParameters?.getOrNull(idx)) }
|
||||||
|
|
||||||
val id =
|
val id =
|
||||||
idOverride
|
idOverride
|
||||||
@@ -726,7 +728,7 @@ open class KotlinFileExtractor(
|
|||||||
|
|
||||||
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
|
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
|
||||||
|
|
||||||
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, javaMethod?.returnType)
|
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, (javaCallable as? JavaMethod)?.returnType)
|
||||||
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
|
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
|
||||||
|
|
||||||
val locId = locOverride ?: getLocation(f, classTypeArgsIncludingOuterClasses)
|
val locId = locOverride ?: getLocation(f, classTypeArgsIncludingOuterClasses)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.ir.allOverridden
|
|||||||
import org.jetbrains.kotlin.backend.common.ir.isFinalClass
|
import org.jetbrains.kotlin.backend.common.ir.isFinalClass
|
||||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||||
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.getJvmNameFromAnnotation
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -996,7 +995,7 @@ open class KotlinUsesExtractor(
|
|||||||
getFunctionTypeParameters(f),
|
getFunctionTypeParameters(f),
|
||||||
classTypeArgsIncludingOuterClasses,
|
classTypeArgsIncludingOuterClasses,
|
||||||
overridesCollectionsMethodWithAlteredParameterTypes(f),
|
overridesCollectionsMethodWithAlteredParameterTypes(f),
|
||||||
getJavaMethod(f),
|
getJavaCallable(f),
|
||||||
!hasWildcardSuppressionAnnotation(f)
|
!hasWildcardSuppressionAnnotation(f)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1028,7 +1027,7 @@ open class KotlinUsesExtractor(
|
|||||||
// parameter erasure to match the way this class will appear to an external consumer of the .class file.
|
// parameter erasure to match the way this class will appear to an external consumer of the .class file.
|
||||||
overridesCollectionsMethod: Boolean,
|
overridesCollectionsMethod: Boolean,
|
||||||
// The Java signature of this callable, if known.
|
// The Java signature of this callable, if known.
|
||||||
javaSignature: JavaMethod?,
|
javaSignature: JavaMember?,
|
||||||
// If true, Java wildcards implied by Kotlin type parameter variance should be added by default to this function's value parameters' types.
|
// If true, Java wildcards implied by Kotlin type parameter variance should be added by default to this function's value parameters' types.
|
||||||
// (Return-type wildcard addition is always off by default)
|
// (Return-type wildcard addition is always off by default)
|
||||||
addParameterWildcardsByDefault: Boolean,
|
addParameterWildcardsByDefault: Boolean,
|
||||||
@@ -1056,7 +1055,7 @@ open class KotlinUsesExtractor(
|
|||||||
// If this has happened, erase the type again to get the correct Java signature.
|
// If this has happened, erase the type again to get the correct Java signature.
|
||||||
val maybeAmendedForCollections = if (overridesCollectionsMethod) eraseCollectionsMethodParameterType(it.value.type, name, it.index) else it.value.type
|
val maybeAmendedForCollections = if (overridesCollectionsMethod) eraseCollectionsMethodParameterType(it.value.type, name, it.index) else it.value.type
|
||||||
// Add any wildcard types that the Kotlin compiler would add in the Java lowering of this function:
|
// Add any wildcard types that the Kotlin compiler would add in the Java lowering of this function:
|
||||||
val withAddedWildcards = addJavaLoweringWildcards(maybeAmendedForCollections, addParameterWildcardsByDefault, javaSignature?.let { sig -> sig.valueParameters[it.index].type })
|
val withAddedWildcards = addJavaLoweringWildcards(maybeAmendedForCollections, addParameterWildcardsByDefault, javaSignature?.let { sig -> getJavaValueParameterType(sig, it.index) })
|
||||||
// Now substitute any class type parameters in:
|
// Now substitute any class type parameters in:
|
||||||
val maybeSubbed = withAddedWildcards.substituteTypeAndArguments(substitutionMap, TypeContext.OTHER, pluginContext)
|
val maybeSubbed = withAddedWildcards.substituteTypeAndArguments(substitutionMap, TypeContext.OTHER, pluginContext)
|
||||||
// Finally, mimic the Java extractor's behaviour by naming functions with type parameters for their erased types;
|
// Finally, mimic the Java extractor's behaviour by naming functions with type parameters for their erased types;
|
||||||
@@ -1103,7 +1102,13 @@ open class KotlinUsesExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
fun getJavaMethod(f: IrFunction) = (f.descriptor.source as? JavaSourceElement)?.javaElement as? JavaMethod
|
fun getJavaCallable(f: IrFunction) = (f.descriptor.source as? JavaSourceElement)?.javaElement as? JavaMember
|
||||||
|
|
||||||
|
fun getJavaValueParameterType(m: JavaMember, idx: Int) = when(m) {
|
||||||
|
is JavaMethod -> m.valueParameters[idx].type
|
||||||
|
is JavaConstructor -> m.valueParameters[idx].type
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
fun hasWildcardSuppressionAnnotation(d: IrDeclaration) =
|
fun hasWildcardSuppressionAnnotation(d: IrDeclaration) =
|
||||||
d.hasAnnotation(jvmWildcardSuppressionAnnotaton) ||
|
d.hasAnnotation(jvmWildcardSuppressionAnnotaton) ||
|
||||||
|
|||||||
Reference in New Issue
Block a user