mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +01:00
Revert "Merge pull request #160 from github/smowton/feature/type-substitution-prototypes"
This reverts commit 1dd83a3f0fab407fe94a09fc517c516ed24b1d0c, reversing changes made to 22aebf8128bfe20bb89e5ecc11e0e8cdd65bf317.
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
package com.github.codeql
|
||||
|
||||
import com.github.codeql.utils.lowerBound
|
||||
import com.github.codeql.utils.substituteTypeAndArguments
|
||||
import com.github.codeql.utils.upperBound
|
||||
import com.semmle.extractor.java.OdasaOutput
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
@@ -12,10 +9,8 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
open class KotlinFileExtractor(
|
||||
override val logger: FileLogger,
|
||||
@@ -48,7 +43,7 @@ open class KotlinFileExtractor(
|
||||
is IrClass -> return getClassLabel(element, listOf()).classLabel
|
||||
is IrTypeParameter -> return getTypeParameterLabel(element)
|
||||
is IrFunction -> return getFunctionLabel(element)
|
||||
is IrValueParameter -> return getValueParameterLabel(element, null)
|
||||
is IrValueParameter -> return getValueParameterLabel(element)
|
||||
is IrProperty -> return getPropertyLabel(element)
|
||||
is IrField -> return getFieldLabel(element)
|
||||
is IrEnumEntry -> return getEnumEntryLabel(element)
|
||||
@@ -86,7 +81,7 @@ open class KotlinFileExtractor(
|
||||
return id
|
||||
}
|
||||
|
||||
fun extractClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>, extractFunctionPrototypes: Boolean): Label<out DbClassorinterface> {
|
||||
fun extractClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>): Label<out DbClassorinterface> {
|
||||
if (typeArgs.isEmpty()) {
|
||||
logger.warn(Severity.ErrorSevere, "Instance without type arguments: " + c.name.asString())
|
||||
}
|
||||
@@ -127,18 +122,6 @@ open class KotlinFileExtractor(
|
||||
val locId = tw.getLocation(c)
|
||||
tw.writeHasLocation(id, locId)
|
||||
|
||||
if (extractFunctionPrototypes) {
|
||||
val typeParamSubstitution = c.typeParameters.map({ it.symbol }).zip(typeArgs).toMap()
|
||||
|
||||
c.declarations.map {
|
||||
when(it) {
|
||||
is IrFunction -> extractFunction(it, id, false, typeParamSubstitution)
|
||||
is IrProperty -> extractProperty(it, id, false, typeParamSubstitution)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
@@ -271,12 +254,9 @@ open class KotlinFileExtractor(
|
||||
return FieldResult(instanceId, instanceName)
|
||||
}
|
||||
|
||||
fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>, idx: Int, typeSubstitutionMap: Map<IrTypeParameterSymbol, IrTypeArgument>?): TypeResults {
|
||||
val id = useValueParameter(vp, parent)
|
||||
val substitutedType = vp.type.substituteTypeAndArguments(typeSubstitutionMap) {
|
||||
it.lowerBound(pluginContext)
|
||||
}
|
||||
val type = useType(substitutedType)
|
||||
fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>, idx: Int): TypeResults {
|
||||
val id = useValueParameter(vp)
|
||||
val type = useType(vp.type)
|
||||
val locId = tw.getLocation(vp)
|
||||
tw.writeParams(id, type.javaResult.id, type.kotlinResult.id, idx, parent, id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
@@ -351,7 +331,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean = true, typeSubstitutionMap: Map<IrTypeParameterSymbol, IrTypeArgument>? = null): Label<out DbCallable> {
|
||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>): Label<out DbCallable> {
|
||||
currentFunction = f
|
||||
|
||||
f.typeParameters.map { extractTypeParameter(it) }
|
||||
@@ -362,21 +342,19 @@ open class KotlinFileExtractor(
|
||||
if (f.isLocalFunction())
|
||||
getLocalFunctionLabels(f).function
|
||||
else
|
||||
// TODO: figure out whether to standardise on naming top-level functions for the file-class
|
||||
// or (as temporarily done here) for their containing package.
|
||||
useFunction<DbCallable>(f, if (f.parent is IrFile) useDeclarationParent(f.parent) else parentId)
|
||||
useFunction<DbCallable>(f)
|
||||
|
||||
val extReceiver = f.extensionReceiverParameter
|
||||
val idxOffset = if (extReceiver != null) 1 else 0
|
||||
val paramTypes = f.valueParameters.mapIndexed { i, vp ->
|
||||
extractValueParameter(vp, id, i + idxOffset, typeSubstitutionMap)
|
||||
extractValueParameter(vp, id, i + idxOffset)
|
||||
}
|
||||
val allParamTypes = if (extReceiver != null) {
|
||||
val extendedType = useType(extReceiver.type)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
tw.writeKtExtensionFunctions(id as Label<DbMethod>, extendedType.javaResult.id, extendedType.kotlinResult.id)
|
||||
|
||||
val t = extractValueParameter(extReceiver, id, 0, null)
|
||||
val t = extractValueParameter(extReceiver, id, 0)
|
||||
val l = mutableListOf(t)
|
||||
l.addAll(paramTypes)
|
||||
l
|
||||
@@ -386,21 +364,13 @@ open class KotlinFileExtractor(
|
||||
|
||||
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
|
||||
|
||||
val substReturnType = f.returnType.substituteTypeAndArguments(typeSubstitutionMap) {
|
||||
it.upperBound(pluginContext)
|
||||
}
|
||||
|
||||
if (f.symbol is IrConstructorSymbol) {
|
||||
val unitType = useType(pluginContext.irBuiltIns.unitType, TypeContext.RETURN)
|
||||
val shortName = when {
|
||||
f.returnType.isAnonymous -> ""
|
||||
typeSubstitutionMap != null -> useType(substReturnType).javaResult.shortName
|
||||
else -> f.returnType.classFqName?.shortName()?.asString() ?: f.name.asString()
|
||||
}
|
||||
val returnType = useType(erase(f.returnType), TypeContext.RETURN)
|
||||
val shortName = if (f.returnType.isAnonymous) "" else f.returnType.classFqName?.shortName()?.asString() ?: f.name.asString()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
tw.writeConstrs(id as Label<DbConstructor>, shortName, "$shortName$paramsSignature", unitType.javaResult.id, unitType.kotlinResult.id, parentId, id)
|
||||
tw.writeConstrs(id as Label<DbConstructor>, shortName, "$shortName$paramsSignature", returnType.javaResult.id, returnType.kotlinResult.id, parentId, id)
|
||||
} else {
|
||||
val returnType = useType(substReturnType, TypeContext.RETURN)
|
||||
val returnType = useType(f.returnType, TypeContext.RETURN)
|
||||
val shortName = f.name.asString()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
tw.writeMethods(id as Label<DbMethod>, shortName, "$shortName$paramsSignature", returnType.javaResult.id, returnType.kotlinResult.id, parentId, id)
|
||||
@@ -408,9 +378,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
tw.writeHasLocation(id, locId)
|
||||
val body = f.body
|
||||
if(body != null && extractBody) {
|
||||
if(typeSubstitutionMap != null)
|
||||
logger.warnElement(Severity.ErrorSevere, "Type substitution should only be used to extract a function prototype, not the body", f)
|
||||
if(body != null) {
|
||||
extractBody(body, id)
|
||||
}
|
||||
|
||||
@@ -427,8 +395,8 @@ open class KotlinFileExtractor(
|
||||
return id
|
||||
}
|
||||
|
||||
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean = true, typeSubstitutionMap: Map<IrTypeParameterSymbol, IrTypeArgument>? = null) {
|
||||
val id = useProperty(p, parentId)
|
||||
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>) {
|
||||
val id = useProperty(p)
|
||||
val locId = tw.getLocation(p)
|
||||
tw.writeKtProperties(id, p.name.asString())
|
||||
tw.writeHasLocation(id, locId)
|
||||
@@ -439,7 +407,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
if(getter != null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val getterId = extractFunction(getter, parentId, extractBackingField, typeSubstitutionMap) as Label<out DbMethod>
|
||||
val getterId = extractFunction(getter, parentId) as Label<out DbMethod>
|
||||
tw.writeKtPropertyGetters(id, getterId)
|
||||
} else {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
@@ -452,7 +420,7 @@ open class KotlinFileExtractor(
|
||||
logger.warnElement(Severity.ErrorSevere, "!isVar property with a setter", p)
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val setterId = extractFunction(setter, parentId, extractBackingField, typeSubstitutionMap) as Label<out DbMethod>
|
||||
val setterId = extractFunction(setter, parentId) as Label<out DbMethod>
|
||||
tw.writeKtPropertySetters(id, setterId)
|
||||
} else {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
@@ -460,7 +428,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
if(bf != null && extractBackingField) {
|
||||
if(bf != null) {
|
||||
val fieldId = extractField(bf, parentId)
|
||||
tw.writeKtPropertyBackingFields(id, fieldId)
|
||||
}
|
||||
@@ -716,16 +684,17 @@ open class KotlinFileExtractor(
|
||||
isFunction("kotlin", "Double", fName)
|
||||
}
|
||||
|
||||
fun extractMethodAccess(callTarget: IrFunction, extractMethodTypeArguments: Boolean = true, extractClassTypeArguments: Boolean = false) {
|
||||
fun extractMethodAccess(callTarget: IrFunction, extractTypeArguments: Boolean = true){
|
||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val type = useType(c.type)
|
||||
val locId = tw.getLocation(c)
|
||||
|
||||
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, enclosingStmt)
|
||||
|
||||
if (extractMethodTypeArguments) {
|
||||
if (extractTypeArguments) {
|
||||
// type arguments at index -2, -3, ...
|
||||
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
|
||||
}
|
||||
@@ -744,28 +713,10 @@ open class KotlinFileExtractor(
|
||||
tw.writeCallableBinding(idNewexpr, ids.constructor)
|
||||
|
||||
} else {
|
||||
val dr = c.dispatchReceiver
|
||||
|
||||
// Returns true if type is C<T1, T2, ...> where C is declared `class <T1, T2, ...> C { ... }`
|
||||
fun isUnspecialised(type: IrSimpleType) =
|
||||
type.classifier.owner is IrClass &&
|
||||
(type.classifier.owner as IrClass).typeParameters.zip(type.arguments).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
|
||||
} ?: false
|
||||
}
|
||||
|
||||
val drType = dr?.type
|
||||
val methodId =
|
||||
if (drType != null && extractClassTypeArguments && drType is IrSimpleType && !isUnspecialised(drType))
|
||||
useFunction<DbCallable>(callTarget, drType.arguments)
|
||||
else
|
||||
useFunction<DbCallable>(callTarget)
|
||||
|
||||
val methodId = useFunction<DbMethod>(callTarget)
|
||||
tw.writeCallableBinding(id, methodId)
|
||||
|
||||
val dr = c.dispatchReceiver
|
||||
if (dr != null) {
|
||||
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
|
||||
}
|
||||
@@ -1087,7 +1038,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
extractMethodAccess(c.symbol.owner, true, true)
|
||||
extractMethodAccess(c.symbol.owner)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1136,7 +1087,7 @@ open class KotlinFileExtractor(
|
||||
type = useType(e.type)
|
||||
}
|
||||
val locId = tw.getLocation(e)
|
||||
val methodId = useFunction<DbConstructor>(e.symbol.owner, (e.type as? IrSimpleType)?.arguments)
|
||||
val methodId = useFunction<DbConstructor>(e.symbol.owner)
|
||||
tw.writeExprs_newexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
|
||||
Reference in New Issue
Block a user