mirror of
https://github.com/github/codeql.git
synced 2025-12-18 09:43:15 +01:00
Merge pull request #10853 from smowton/smowton/fix/specialised-anon-classes
Kotlin: extract called private methods of specialised types, and specialised instances of anonymous types
This commit is contained in:
@@ -120,11 +120,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
private fun shouldExtractDecl(declaration: IrDeclaration, extractPrivateMembers: Boolean) =
|
||||
extractPrivateMembers ||
|
||||
when(declaration) {
|
||||
is IrDeclarationWithVisibility -> declaration.visibility.let { it != DescriptorVisibilities.PRIVATE && it != DescriptorVisibilities.PRIVATE_TO_THIS }
|
||||
else -> true
|
||||
}
|
||||
extractPrivateMembers || !isPrivate(declaration)
|
||||
|
||||
fun extractDeclaration(declaration: IrDeclaration, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
|
||||
with("declaration", declaration) {
|
||||
@@ -367,23 +363,37 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeTypeParamSubstitution(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?) =
|
||||
when (argsIncludingOuterClasses) {
|
||||
null -> { x: IrType, _: TypeContext, _: IrPluginContext -> x.toRawType() }
|
||||
else -> makeGenericSubstitutionFunction(c, argsIncludingOuterClasses)
|
||||
}
|
||||
|
||||
fun extractDeclarationPrototype(d: IrDeclaration, parentId: Label<out DbReftype>, argsIncludingOuterClasses: List<IrTypeArgument>?, typeParamSubstitutionQ: TypeSubstitution? = null) {
|
||||
val typeParamSubstitution = typeParamSubstitutionQ ?:
|
||||
when(val parent = d.parent) {
|
||||
is IrClass -> makeTypeParamSubstitution(parent, argsIncludingOuterClasses)
|
||||
else -> {
|
||||
logger.warnElement("Unable to extract prototype of local declaration", d)
|
||||
return
|
||||
}
|
||||
}
|
||||
when (d) {
|
||||
is IrFunction -> extractFunction(d, parentId, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(d, parentId, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
// `argsIncludingOuterClasses` can be null to describe a raw generic type.
|
||||
// For non-generic types it will be zero-length list.
|
||||
private fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?, id: Label<out DbClassorinterface>) {
|
||||
with("member prototypes", c) {
|
||||
val typeParamSubstitution =
|
||||
when (argsIncludingOuterClasses) {
|
||||
null -> { x: IrType, _: TypeContext, _: IrPluginContext -> x.toRawType() }
|
||||
else -> makeGenericSubstitutionFunction(c, argsIncludingOuterClasses)
|
||||
}
|
||||
val typeParamSubstitution = makeTypeParamSubstitution(c, argsIncludingOuterClasses)
|
||||
|
||||
c.declarations.map {
|
||||
if (shouldExtractDecl(it, false)) {
|
||||
when(it) {
|
||||
is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
else -> {}
|
||||
}
|
||||
extractDeclarationPrototype(it, id, argsIncludingOuterClasses, typeParamSubstitution)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,12 +593,7 @@ open class KotlinFileExtractor(
|
||||
var parent: IrDeclarationParent? = declarationParent
|
||||
while (parent != null) {
|
||||
if (parent is IrClass) {
|
||||
val parentId =
|
||||
if (parent.isAnonymousObject) {
|
||||
useAnonymousClass(parent).javaResult.id.cast<DbClass>()
|
||||
} else {
|
||||
useClassInstance(parent, parentClassTypeArguments).typeResult.id
|
||||
}
|
||||
val parentId = useClassInstance(parent, parentClassTypeArguments).typeResult.id
|
||||
tw.writeEnclInReftype(innerId, parentId)
|
||||
if (innerClass != null && innerClass.isCompanion) {
|
||||
// If we are a companion then our parent has a
|
||||
@@ -868,7 +873,7 @@ open class KotlinFileExtractor(
|
||||
extractTypeAccess(useType(paramType), locId, paramId, -1)
|
||||
}
|
||||
}
|
||||
val paramsSignature = allParamTypeResults.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature }
|
||||
val paramsSignature = allParamTypeResults.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
|
||||
val shortName = getDefaultsMethodName(f)
|
||||
|
||||
if (f.symbol is IrConstructorSymbol) {
|
||||
@@ -1078,6 +1083,14 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun signatureOrWarn(t: TypeResult<*>, associatedElement: IrElement?) =
|
||||
t.signature ?: "<signature unavailable>".also {
|
||||
if (associatedElement != null)
|
||||
logger.warnElement("Needed a signature for a type that doesn't have one", associatedElement)
|
||||
else
|
||||
logger.warn("Needed a signature for a type that doesn't have one")
|
||||
}
|
||||
|
||||
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, extractOrigin: Boolean = true, overriddenAttributes: OverriddenFunctionAttributes? = null): Label<out DbCallable> {
|
||||
with("function", f) {
|
||||
DeclarationStackAdjuster(f, overriddenAttributes).use {
|
||||
@@ -1114,7 +1127,7 @@ open class KotlinFileExtractor(
|
||||
paramTypes
|
||||
}
|
||||
|
||||
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature }
|
||||
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
|
||||
|
||||
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, (javaCallable as? JavaMethod)?.returnType)
|
||||
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
|
||||
@@ -2952,20 +2965,8 @@ open class KotlinFileExtractor(
|
||||
logger.errorElement("Constructor call has non-simple type ${eType.javaClass}", e)
|
||||
return
|
||||
}
|
||||
val type = useType(eType)
|
||||
val isAnonymous = eType.isAnonymous
|
||||
val type: TypeResults = if (isAnonymous) {
|
||||
if (e.typeArgumentsCount > 0) {
|
||||
logger.warnElement("Unexpected type arguments (${e.typeArgumentsCount}) for anonymous class constructor call", e)
|
||||
}
|
||||
val c = eType.classifier.owner
|
||||
if (c !is IrClass) {
|
||||
logger.errorElement("Anonymous constructor call type not a class (${c.javaClass})", e)
|
||||
return
|
||||
}
|
||||
useAnonymousClass(c)
|
||||
} else {
|
||||
useType(eType)
|
||||
}
|
||||
val locId = tw.getLocation(e)
|
||||
val valueArgs = (0 until e.valueArgumentsCount).map { e.getValueArgument(it) }
|
||||
// For now, don't try to use default methods for enum constructor calls,
|
||||
@@ -2982,7 +2983,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
if (isAnonymous) {
|
||||
tw.writeIsAnonymClass(type.javaResult.id.cast<DbClass>(), id)
|
||||
tw.writeIsAnonymClass(type.javaResult.id.cast(), id)
|
||||
}
|
||||
|
||||
val dr = e.dispatchReceiver
|
||||
@@ -4640,7 +4641,7 @@ open class KotlinFileExtractor(
|
||||
Pair(paramId, paramType)
|
||||
}
|
||||
|
||||
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { it.second.javaResult.signature }
|
||||
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.second.javaResult, declarationStack.tryPeek()?.first) }
|
||||
|
||||
val rt = useType(returnType, TypeContext.RETURN)
|
||||
tw.writeMethods(methodId, name, "$name$paramsSignature", rt.javaResult.id, parentId, methodId)
|
||||
@@ -5359,6 +5360,8 @@ open class KotlinFileExtractor(
|
||||
|
||||
fun peek() = stack.peek()
|
||||
|
||||
fun tryPeek() = if (stack.isEmpty()) null else stack.peek()
|
||||
|
||||
fun findOverriddenAttributes(f: IrFunction) =
|
||||
stack.lastOrNull { it.first == f } ?.second
|
||||
|
||||
|
||||
Reference in New Issue
Block a user