mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
Extract local functions
This commit is contained in:
@@ -35,8 +35,6 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun getLabel(element: IrElement) : String? {
|
fun getLabel(element: IrElement) : String? {
|
||||||
when (element) {
|
when (element) {
|
||||||
is IrFile -> return "@\"${element.path};sourcefile\"" // todo: remove copy-pasted code
|
is IrFile -> return "@\"${element.path};sourcefile\"" // todo: remove copy-pasted code
|
||||||
@@ -125,35 +123,10 @@ open class KotlinFileExtractor(
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
private val anonymousTypeMap: MutableMap<IrClass, TypeResults> = mutableMapOf()
|
|
||||||
|
|
||||||
override fun useAnonymousClass(c: IrClass): TypeResults {
|
|
||||||
var res = anonymousTypeMap[c]
|
|
||||||
if (res == null) {
|
|
||||||
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
|
|
||||||
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
|
|
||||||
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
|
|
||||||
res = TypeResults(javaResult, kotlinResult)
|
|
||||||
anonymousTypeMap[c] = res
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractAnonymousClassStmt(c: IrClass, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
val id = extractClassSource(c) as Label<out DbClass>
|
|
||||||
val stmtId = tw.getFreshIdLabel<DbAnonymousclassdeclstmt>()
|
|
||||||
tw.writeStmts_anonymousclassdeclstmt(stmtId, parent, idx, callable)
|
|
||||||
tw.writeKtAnonymousClassDeclarationStmts(stmtId, id)
|
|
||||||
val locId = tw.getLocation(c)
|
|
||||||
tw.writeHasLocation(stmtId, locId)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun extractClassSource(c: IrClass): Label<out DbClassorinterface> {
|
fun extractClassSource(c: IrClass): Label<out DbClassorinterface> {
|
||||||
val id = if (c.isAnonymousObject) {
|
val id = if (c.isAnonymousObject) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
useAnonymousClass(c).javaResult.id as Label<out DbClass>
|
withSourceFile(c.fileOrNull!!).useAnonymousClass(c).javaResult.id as Label<out DbClass>
|
||||||
} else {
|
} else {
|
||||||
useClassSource(c)
|
useClassSource(c)
|
||||||
}
|
}
|
||||||
@@ -183,7 +156,7 @@ open class KotlinFileExtractor(
|
|||||||
val parentId =
|
val parentId =
|
||||||
if (parent.isAnonymousObject) {
|
if (parent.isAnonymousObject) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
useAnonymousClass(c).javaResult.id as Label<out DbClass>
|
withSourceFile(c.fileOrNull!!).useAnonymousClass(c).javaResult.id as Label<out DbClass>
|
||||||
} else {
|
} else {
|
||||||
useClassInstance(parent, listOf()).typeResult.id
|
useClassInstance(parent, listOf()).typeResult.id
|
||||||
}
|
}
|
||||||
@@ -280,7 +253,7 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add method:
|
// add method:
|
||||||
val obinitLabel = getFunctionLabel(c, "<obinit>", listOf(), pluginContext.irBuiltIns.unitType)
|
val obinitLabel = getFunctionLabel(c, "<obinit>", listOf(), pluginContext.irBuiltIns.unitType, extensionReceiverParameter = null)
|
||||||
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
|
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
|
||||||
val returnType = useType(pluginContext.irBuiltIns.unitType)
|
val returnType = useType(pluginContext.irBuiltIns.unitType)
|
||||||
tw.writeMethods(obinitId, "<obinit>", "<obinit>()", returnType.javaResult.id, returnType.kotlinResult.id, parentId, obinitId)
|
tw.writeMethods(obinitId, "<obinit>", "<obinit>()", returnType.javaResult.id, returnType.kotlinResult.id, parentId, obinitId)
|
||||||
@@ -341,22 +314,34 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>): Label<out DbCallable> {
|
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, label: Label<DbMethod>? = null): Label<out DbCallable> {
|
||||||
currentFunction = f
|
currentFunction = f
|
||||||
|
|
||||||
f.typeParameters.map { extractTypeParameter(it) }
|
f.typeParameters.map { extractTypeParameter(it) }
|
||||||
|
|
||||||
val locId = tw.getLocation(f)
|
val locId = tw.getLocation(f)
|
||||||
|
|
||||||
val id = useFunction<DbCallable>(f)
|
val id = label ?: useFunction<DbCallable>(f)
|
||||||
|
|
||||||
val extReceiver = f.extensionReceiverParameter
|
val extReceiver = f.extensionReceiverParameter
|
||||||
val isExtension = extReceiver != null
|
val idxOffset = if (extReceiver != null) 1 else 0
|
||||||
val idxOffset = if (isExtension) 1 else 0
|
|
||||||
val paramTypes = f.valueParameters.mapIndexed { i, vp ->
|
val paramTypes = f.valueParameters.mapIndexed { i, vp ->
|
||||||
extractValueParameter(vp, id, i + idxOffset)
|
extractValueParameter(vp, id, i + idxOffset)
|
||||||
}
|
}
|
||||||
val paramsSignature = paramTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
|
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)
|
||||||
|
val l = mutableListOf(t)
|
||||||
|
l.addAll(paramTypes)
|
||||||
|
l
|
||||||
|
} else {
|
||||||
|
paramTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
|
||||||
|
|
||||||
if (f.symbol is IrConstructorSymbol) {
|
if (f.symbol is IrConstructorSymbol) {
|
||||||
val returnType = useType(erase(f.returnType), TypeContext.RETURN)
|
val returnType = useType(erase(f.returnType), TypeContext.RETURN)
|
||||||
@@ -368,12 +353,6 @@ open class KotlinFileExtractor(
|
|||||||
val shortName = f.name.asString()
|
val shortName = f.name.asString()
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
tw.writeMethods(id as Label<DbMethod>, shortName, "$shortName$paramsSignature", returnType.javaResult.id, returnType.kotlinResult.id, parentId, id)
|
tw.writeMethods(id as Label<DbMethod>, shortName, "$shortName$paramsSignature", returnType.javaResult.id, returnType.kotlinResult.id, parentId, id)
|
||||||
|
|
||||||
if (extReceiver != null) {
|
|
||||||
val extendedType = useType(extReceiver.type)
|
|
||||||
tw.writeKtExtensionFunctions(id, extendedType.javaResult.id, extendedType.kotlinResult.id)
|
|
||||||
extractValueParameter(extReceiver, id, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
@@ -524,11 +503,20 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
is IrClass -> {
|
is IrClass -> {
|
||||||
if (s.isAnonymousObject) {
|
if (s.isAnonymousObject) {
|
||||||
extractAnonymousClassStmt(s, callable, parent, idx)
|
withSourceFile(s.fileOrNull!!).extractAnonymousClassStmt(s, callable, parent, idx)
|
||||||
} else {
|
} else {
|
||||||
logger.warnElement(Severity.ErrorSevere, "Found non anonymous IrClass as IrStatement: " + s.javaClass, s)
|
logger.warnElement(Severity.ErrorSevere, "Found non anonymous IrClass as IrStatement: " + s.javaClass, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is IrFunction -> {
|
||||||
|
if (s.isLocalFunction()) {
|
||||||
|
val extractor = withSourceFile(s.fileOrNull!!)
|
||||||
|
val classId = extractor.extractGeneratedClass(s, listOf(pluginContext.irBuiltIns.anyType))
|
||||||
|
extractor.extractAnonymousClassStmt(classId, s, callable, parent, idx)
|
||||||
|
} else {
|
||||||
|
logger.warnElement(Severity.ErrorSevere, "Expected to find local function", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logger.warnElement(Severity.ErrorSevere, "Unrecognised IrStatement: " + s.javaClass, s)
|
logger.warnElement(Severity.ErrorSevere, "Unrecognised IrStatement: " + s.javaClass, s)
|
||||||
}
|
}
|
||||||
@@ -680,11 +668,10 @@ open class KotlinFileExtractor(
|
|||||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||||
val type = useType(c.type)
|
val type = useType(c.type)
|
||||||
val locId = tw.getLocation(c)
|
val locId = tw.getLocation(c)
|
||||||
val methodId = useFunction<DbMethod>(callTarget)
|
|
||||||
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
tw.writeCallableEnclosingExpr(id, callable)
|
tw.writeCallableEnclosingExpr(id, callable)
|
||||||
tw.writeCallableBinding(id, methodId)
|
|
||||||
tw.writeStatementEnclosingExpr(id, enclosingStmt)
|
tw.writeStatementEnclosingExpr(id, enclosingStmt)
|
||||||
|
|
||||||
if (extractTypeArguments) {
|
if (extractTypeArguments) {
|
||||||
@@ -692,9 +679,27 @@ open class KotlinFileExtractor(
|
|||||||
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
|
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val dr = c.dispatchReceiver
|
if (callTarget.isLocalFunction()) {
|
||||||
if (dr != null) {
|
val ids = withSourceFile(callTarget.fileOrNull!!).useGeneratedLocalFunctionClass(callTarget)
|
||||||
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
|
|
||||||
|
val methodId = ids.function
|
||||||
|
tw.writeCallableBinding(id, methodId)
|
||||||
|
|
||||||
|
val idNewexpr = tw.getFreshIdLabel<DbNewexpr>()
|
||||||
|
tw.writeExprs_newexpr(idNewexpr, ids.type.javaResult.id, ids.type.kotlinResult.id, id, -1)
|
||||||
|
tw.writeHasLocation(idNewexpr, locId)
|
||||||
|
tw.writeCallableEnclosingExpr(idNewexpr, callable)
|
||||||
|
tw.writeStatementEnclosingExpr(idNewexpr, enclosingStmt)
|
||||||
|
tw.writeCallableBinding(idNewexpr, ids.constructor)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
val methodId = useFunction<DbMethod>(callTarget)
|
||||||
|
tw.writeCallableBinding(id, methodId)
|
||||||
|
|
||||||
|
val dr = c.dispatchReceiver
|
||||||
|
if (dr != null) {
|
||||||
|
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val er = c.extensionReceiver
|
val er = c.extensionReceiver
|
||||||
@@ -1054,7 +1059,7 @@ open class KotlinFileExtractor(
|
|||||||
|
|
||||||
val c = (e.type as IrSimpleType).classifier.owner as IrClass
|
val c = (e.type as IrSimpleType).classifier.owner as IrClass
|
||||||
|
|
||||||
type = useAnonymousClass(c)
|
type = withSourceFile(c.fileOrNull!!).useAnonymousClass(c)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
tw.writeIsAnonymClass(type.javaResult.id as Label<DbClass>, id)
|
tw.writeIsAnonymClass(type.javaResult.id as Label<DbClass>, id)
|
||||||
@@ -1290,7 +1295,7 @@ open class KotlinFileExtractor(
|
|||||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||||
val type = useType(e.type)
|
val type = useType(e.type)
|
||||||
val locId = tw.getLocation(e)
|
val locId = tw.getLocation(e)
|
||||||
val methodLabel = getFunctionLabel(irCallable.parent, "<obinit>", listOf(), e.type)
|
val methodLabel = getFunctionLabel(irCallable.parent, "<obinit>", listOf(), e.type, null)
|
||||||
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
|
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
|
||||||
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, exprParent.parent, exprParent.idx)
|
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, exprParent.parent, exprParent.idx)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
|
|||||||
@@ -2,11 +2,17 @@ package com.github.codeql
|
|||||||
|
|
||||||
import com.github.codeql.comments.CommentExtractor
|
import com.github.codeql.comments.CommentExtractor
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
|
import org.jetbrains.kotlin.ir.util.fileOrNull
|
||||||
import org.jetbrains.kotlin.ir.util.packageFqName
|
import org.jetbrains.kotlin.ir.util.packageFqName
|
||||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||||
|
|
||||||
@@ -21,7 +27,24 @@ class KotlinSourceFileExtractor(
|
|||||||
) :
|
) :
|
||||||
KotlinFileExtractor(logger, tw, null, externalClassExtractor, primitiveTypeMapping, pluginContext) {
|
KotlinFileExtractor(logger, tw, null, externalClassExtractor, primitiveTypeMapping, pluginContext) {
|
||||||
|
|
||||||
val fileClass by lazy {
|
init {
|
||||||
|
if (!stateCache.containsKey(file)){
|
||||||
|
stateCache[file] = SourceFileExtractionState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class SourceFileExtractionState(val anonymousTypeMap: MutableMap<IrClass, TypeResults> = mutableMapOf(),
|
||||||
|
val generatedLocalFunctionTypeMap: MutableMap<IrFunction, LocalFunctionLabels> = mutableMapOf())
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val stateCache: MutableMap<IrFile, SourceFileExtractionState> = mutableMapOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fileExtractionState by lazy {
|
||||||
|
stateCache[file]!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fileClass by lazy {
|
||||||
extractFileClass(file)
|
extractFileClass(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,4 +93,94 @@ class KotlinSourceFileExtractor(
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun useAnonymousClass(c: IrClass): TypeResults {
|
||||||
|
var res = fileExtractionState.anonymousTypeMap[c]
|
||||||
|
if (res == null) {
|
||||||
|
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
|
||||||
|
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
|
||||||
|
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
|
||||||
|
res = TypeResults(javaResult, kotlinResult)
|
||||||
|
fileExtractionState.anonymousTypeMap[c] = res
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
data class LocalFunctionLabels(val type: TypeResults, val constructor: Label<DbConstructor>, val function: Label<DbMethod>)
|
||||||
|
|
||||||
|
fun useGeneratedLocalFunctionClass(f: IrFunction): LocalFunctionLabels {
|
||||||
|
if (!f.isLocalFunction()){
|
||||||
|
logger.warnElement(Severity.ErrorSevere, "Extracting a non-local function as a local one", f)
|
||||||
|
}
|
||||||
|
|
||||||
|
var res = fileExtractionState.generatedLocalFunctionTypeMap[f]
|
||||||
|
if (res == null) {
|
||||||
|
val javaResult = TypeResult(tw.getFreshIdLabel<DbClass>(), "", "")
|
||||||
|
val kotlinResult = TypeResult(tw.getFreshIdLabel<DbKt_notnull_type>(), "", "")
|
||||||
|
tw.writeKt_notnull_types(kotlinResult.id, javaResult.id)
|
||||||
|
res = LocalFunctionLabels(
|
||||||
|
TypeResults(javaResult, kotlinResult),
|
||||||
|
tw.getFreshIdLabel(),
|
||||||
|
tw.getFreshIdLabel())
|
||||||
|
fileExtractionState.generatedLocalFunctionTypeMap[f] = res
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extractGeneratedClass(localFunction: IrFunction, superTypes: List<IrType>) : Label<out DbClass> {
|
||||||
|
val ids = withSourceFile(localFunction.fileOrNull!!).useGeneratedLocalFunctionClass(localFunction)
|
||||||
|
|
||||||
|
// Write class
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val id = ids.type.javaResult.id as Label<out DbClass>
|
||||||
|
val pkgId = extractPackage("")
|
||||||
|
tw.writeClasses(id, "", pkgId, id)
|
||||||
|
val locId = tw.getLocation(localFunction)
|
||||||
|
tw.writeHasLocation(id, locId)
|
||||||
|
|
||||||
|
// Extract local function as a member
|
||||||
|
extractFunction(localFunction, id, ids.function)
|
||||||
|
|
||||||
|
// Extract constructor
|
||||||
|
tw.writeConstrs(ids.constructor, "", "", ids.type.javaResult.id, ids.type.kotlinResult.id, id, ids.constructor)
|
||||||
|
tw.writeHasLocation(ids.constructor, locId)
|
||||||
|
|
||||||
|
// Constructor body
|
||||||
|
val constructorBlockId = tw.getFreshIdLabel<DbBlock>()
|
||||||
|
tw.writeStmts_block(constructorBlockId, ids.constructor, 0, ids.constructor)
|
||||||
|
tw.writeHasLocation(constructorBlockId, locId)
|
||||||
|
|
||||||
|
// Super call
|
||||||
|
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
|
||||||
|
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.function)
|
||||||
|
|
||||||
|
val baseConstructor = superTypes.first().classOrNull!!.owner.declarations.find { it is IrFunction && it.symbol is IrConstructorSymbol }
|
||||||
|
val baseConstructorId = useFunction<DbConstructor>(baseConstructor as IrFunction)
|
||||||
|
|
||||||
|
tw.writeHasLocation(superCallId, locId)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
tw.writeCallableBinding(superCallId as Label<DbCaller>, baseConstructorId)
|
||||||
|
|
||||||
|
// TODO: We might need to add an `<obinit>` function, and a call to it to match other classes
|
||||||
|
|
||||||
|
addModifiers(id, "public", "static", "final")
|
||||||
|
extractClassSupertypes(superTypes, listOf(), id)
|
||||||
|
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extractAnonymousClassStmt(c: IrClass, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val id = extractClassSource(c) as Label<out DbClass>
|
||||||
|
extractAnonymousClassStmt(id, c, callable, parent, idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extractAnonymousClassStmt(id: Label<out DbClass>, locElement: IrElement, callable: Label<out DbCallable>, parent: Label<out DbStmtparent>, idx: Int) {
|
||||||
|
val stmtId = tw.getFreshIdLabel<DbAnonymousclassdeclstmt>()
|
||||||
|
tw.writeStmts_anonymousclassdeclstmt(stmtId, parent, idx, callable)
|
||||||
|
tw.writeKtAnonymousClassDeclarationStmts(stmtId, id)
|
||||||
|
val locId = tw.getLocation(locElement)
|
||||||
|
tw.writeHasLocation(stmtId, locId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.github.codeql.utils.substituteTypeArguments
|
|||||||
import com.semmle.extractor.java.OdasaOutput
|
import com.semmle.extractor.java.OdasaOutput
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
@@ -65,22 +66,25 @@ open class KotlinUsesExtractor(
|
|||||||
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
|
?.let { pluginContext.referenceClass(it.asSingleFqName()) }
|
||||||
?.owner
|
?.owner
|
||||||
|
|
||||||
|
fun withSourceFile(clsFile: IrFile): KotlinSourceFileExtractor {
|
||||||
|
val newTrapWriter = tw.makeSourceFileTrapWriter(clsFile, false)
|
||||||
|
val newLogger = FileLogger(logger.logCounter, newTrapWriter)
|
||||||
|
return KotlinSourceFileExtractor(newLogger, newTrapWriter, clsFile, externalClassExtractor, primitiveTypeMapping, pluginContext)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.
|
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.
|
||||||
*/
|
*/
|
||||||
fun withSourceFileOfClass(cls: IrClass): KotlinFileExtractor {
|
fun withSourceFileOfClass(cls: IrClass): KotlinFileExtractor {
|
||||||
val clsFile = cls.fileOrNull
|
val clsFile = cls.fileOrNull
|
||||||
|
|
||||||
val newTrapWriter =
|
if (isExternalDeclaration(cls) || clsFile == null) {
|
||||||
if (isExternalDeclaration(cls) || clsFile == null)
|
val newTrapWriter = tw.makeFileTrapWriter(getIrClassBinaryPath(cls))
|
||||||
tw.makeFileTrapWriter(getIrClassBinaryPath(cls))
|
val newLogger = FileLogger(logger.logCounter, newTrapWriter)
|
||||||
else
|
return KotlinFileExtractor(newLogger, newTrapWriter, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext)
|
||||||
tw.makeSourceFileTrapWriter(clsFile, false)
|
} else {
|
||||||
|
return withSourceFile(clsFile)
|
||||||
val newLogger = FileLogger(logger.logCounter, newTrapWriter)
|
}
|
||||||
|
|
||||||
// TODO: Conditionally KotlinSourceFileExtractor?
|
|
||||||
return KotlinFileExtractor(newLogger, newTrapWriter, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun useClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>): UseClassInstanceResult {
|
fun useClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>): UseClassInstanceResult {
|
||||||
@@ -150,10 +154,6 @@ open class KotlinUsesExtractor(
|
|||||||
classLabelResult.shortName)
|
classLabelResult.shortName)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun useAnonymousClass(c: IrClass): TypeResults {
|
|
||||||
throw Exception("Anonymous classes can only be accessed through source file extraction")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun useSimpleTypeClass(c: IrClass, args: List<IrTypeArgument>, hasQuestionMark: Boolean): TypeResults {
|
fun useSimpleTypeClass(c: IrClass, args: List<IrTypeArgument>, hasQuestionMark: Boolean): TypeResults {
|
||||||
if (c.isAnonymousObject) {
|
if (c.isAnonymousObject) {
|
||||||
if (args.isNotEmpty()) {
|
if (args.isNotEmpty()) {
|
||||||
@@ -163,7 +163,7 @@ open class KotlinUsesExtractor(
|
|||||||
logger.warn(Severity.ErrorHigh, "Unexpected nullable anonymous class")
|
logger.warn(Severity.ErrorHigh, "Unexpected nullable anonymous class")
|
||||||
}
|
}
|
||||||
|
|
||||||
return useAnonymousClass(c)
|
return withSourceFile(c.fileOrNull!!).useAnonymousClass(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
val classInstanceResult = useClassInstance(c, args)
|
val classInstanceResult = useClassInstance(c, args)
|
||||||
@@ -421,22 +421,40 @@ class X {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getFunctionLabel(f: IrFunction) : String {
|
fun getFunctionLabel(f: IrFunction) : String {
|
||||||
return getFunctionLabel(f.parent, f.name.asString(), f.valueParameters, f.returnType)
|
return getFunctionLabel(f.parent, f.name.asString(), f.valueParameters, f.returnType, f.extensionReceiverParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFunctionLabel(
|
fun getFunctionLabel(
|
||||||
parent: IrDeclarationParent,
|
parent: IrDeclarationParent,
|
||||||
name: String,
|
name: String,
|
||||||
parameters: List<IrValueParameter>,
|
parameters: List<IrValueParameter>,
|
||||||
returnType: IrType
|
returnType: IrType,
|
||||||
|
extensionReceiverParameter: IrValueParameter?
|
||||||
): String {
|
): String {
|
||||||
val paramTypeIds = parameters.joinToString { "{${useType(erase(it.type)).javaResult.id}}" }
|
val allParams = if (extensionReceiverParameter == null) {
|
||||||
|
parameters
|
||||||
|
} else {
|
||||||
|
val params = mutableListOf(extensionReceiverParameter)
|
||||||
|
params.addAll(parameters)
|
||||||
|
params
|
||||||
|
}
|
||||||
|
val paramTypeIds = allParams.joinToString { "{${useType(erase(it.type)).javaResult.id}}" }
|
||||||
val returnTypeId = useType(erase(returnType)).javaResult.id
|
val returnTypeId = useType(erase(returnType)).javaResult.id
|
||||||
val parentId = useDeclarationParent(parent)
|
val parentId = useDeclarationParent(parent)
|
||||||
return "@\"callable;{$parentId}.$name($paramTypeIds){$returnTypeId}\""
|
return "@\"callable;{$parentId}.$name($paramTypeIds){$returnTypeId}\""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected fun IrFunction.isLocalFunction(): Boolean {
|
||||||
|
return this.visibility == DescriptorVisibilities.LOCAL
|
||||||
|
}
|
||||||
|
|
||||||
fun <T: DbCallable> useFunction(f: IrFunction): Label<out T> {
|
fun <T: DbCallable> useFunction(f: IrFunction): Label<out T> {
|
||||||
|
if (f.isLocalFunction()) {
|
||||||
|
val ids = withSourceFile(f.fileOrNull!!).useGeneratedLocalFunctionClass(f)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return ids.function as Label<out T>
|
||||||
|
}
|
||||||
|
|
||||||
val label = getFunctionLabel(f)
|
val label = getFunctionLabel(f)
|
||||||
val id: Label<T> = tw.getLabelFor(label)
|
val id: Label<T> = tw.getLabelFor(label)
|
||||||
if(isExternalDeclaration(f)) {
|
if(isExternalDeclaration(f)) {
|
||||||
@@ -536,7 +554,7 @@ class X {
|
|||||||
fun useClassSource(c: IrClass): Label<out DbClassorinterface> {
|
fun useClassSource(c: IrClass): Label<out DbClassorinterface> {
|
||||||
if (c.isAnonymousObject) {
|
if (c.isAnonymousObject) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return useAnonymousClass(c).javaResult.id as Label<DbClass>
|
return withSourceFile(c.fileOrNull!!).useAnonymousClass(c).javaResult.id as Label<DbClass>
|
||||||
}
|
}
|
||||||
|
|
||||||
// For source classes, the label doesn't include and type arguments
|
// For source classes, the label doesn't include and type arguments
|
||||||
@@ -586,13 +604,18 @@ class X {
|
|||||||
* where `E` is the type variable declared as `List<E>`.
|
* where `E` is the type variable declared as `List<E>`.
|
||||||
*/
|
*/
|
||||||
fun extractClassSupertypes(c: IrClass, id: Label<out DbReftype>, typeArgsQ: List<IrTypeArgument>? = null) {
|
fun extractClassSupertypes(c: IrClass, id: Label<out DbReftype>, typeArgsQ: List<IrTypeArgument>? = null) {
|
||||||
|
extractClassSupertypes(c.superTypes, c.typeParameters, id, typeArgsQ)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun extractClassSupertypes(superTypes: List<IrType>, typeParameters: List<IrTypeParameter>, id: Label<out DbReftype>, typeArgsQ: List<IrTypeArgument>? = null) {
|
||||||
// Note we only need to substitute type args here because it is illegal to directly extend a type variable.
|
// Note we only need to substitute type args here because it is illegal to directly extend a type variable.
|
||||||
// (For example, we can't have `class A<E> : E`, but can have `class A<E> : Comparable<E>`)
|
// (For example, we can't have `class A<E> : E`, but can have `class A<E> : Comparable<E>`)
|
||||||
val subbedSupertypes = typeArgsQ?.let { typeArgs ->
|
val subbedSupertypes = typeArgsQ?.let { typeArgs ->
|
||||||
c.superTypes.map {
|
superTypes.map {
|
||||||
it.substituteTypeArguments(c.typeParameters, typeArgs)
|
it.substituteTypeArguments(typeParameters, typeArgs)
|
||||||
}
|
}
|
||||||
} ?: c.superTypes
|
} ?: superTypes
|
||||||
|
|
||||||
for(t in subbedSupertypes) {
|
for(t in subbedSupertypes) {
|
||||||
when(t) {
|
when(t) {
|
||||||
|
|||||||
@@ -77,3 +77,4 @@
|
|||||||
| exprs.kt:161:8:161:16 | ... != ... | exprs.kt:161:8:161:8 | r | exprs.kt:161:13:161:16 | null |
|
| exprs.kt:161:8:161:16 | ... != ... | exprs.kt:161:8:161:8 | r | exprs.kt:161:13:161:16 | null |
|
||||||
| exprs.kt:190:31:190:37 | ... + ... | exprs.kt:190:31:190:32 | <get-a1>(...) | exprs.kt:190:36:190:37 | a2 |
|
| exprs.kt:190:31:190:37 | ... + ... | exprs.kt:190:31:190:32 | <get-a1>(...) | exprs.kt:190:36:190:37 | a2 |
|
||||||
| exprs.kt:206:19:206:25 | ... + ... | exprs.kt:206:20:206:21 | ...!! | exprs.kt:206:25:206:25 | 5 |
|
| exprs.kt:206:19:206:25 | ... + ... | exprs.kt:206:20:206:21 | ...!! | exprs.kt:206:25:206:25 | 5 |
|
||||||
|
| localFunctionCalls.kt:5:25:5:29 | ... + ... | localFunctionCalls.kt:5:25:5:25 | i | localFunctionCalls.kt:5:29:5:29 | x |
|
||||||
|
|||||||
@@ -599,9 +599,37 @@
|
|||||||
| exprs.kt:210:33:210:37 | GREEN | exprs.kt:200:5:211:5 | x | StringLiteral |
|
| exprs.kt:210:33:210:37 | GREEN | exprs.kt:200:5:211:5 | x | StringLiteral |
|
||||||
| exprs.kt:215:5:215:10 | TODO(...) | exprs.kt:214:1:216:1 | todo | MethodAccess |
|
| exprs.kt:215:5:215:10 | TODO(...) | exprs.kt:214:1:216:1 | todo | MethodAccess |
|
||||||
| file://:0:0:0:0 | C | exprs.kt:143:5:143:33 | foo | TypeAccess |
|
| file://:0:0:0:0 | C | exprs.kt:143:5:143:33 | foo | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | C1<Integer> | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
| file://:0:0:0:0 | Color | exprs.kt:172:6:176:1 | Color | TypeAccess |
|
| file://:0:0:0:0 | Color | exprs.kt:172:6:176:1 | Color | TypeAccess |
|
||||||
| file://:0:0:0:0 | Direction | exprs.kt:168:6:170:1 | Direction | TypeAccess |
|
| file://:0:0:0:0 | Direction | exprs.kt:168:6:170:1 | Direction | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | Integer | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | Integer | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
| file://:0:0:0:0 | Interface1 | exprs.kt:187:13:192:5 | getObject | TypeAccess |
|
| file://:0:0:0:0 | Interface1 | exprs.kt:187:13:192:5 | getObject | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | String | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
| file://:0:0:0:0 | Unit | exprs.kt:168:6:170:1 | Direction | TypeAccess |
|
| file://:0:0:0:0 | Unit | exprs.kt:168:6:170:1 | Direction | TypeAccess |
|
||||||
| file://:0:0:0:0 | Unit | exprs.kt:172:6:176:1 | Color | TypeAccess |
|
| file://:0:0:0:0 | Unit | exprs.kt:172:6:176:1 | Color | TypeAccess |
|
||||||
| file://:0:0:0:0 | tmp0 | exprs.kt:4:1:136:1 | topLevelMethod | LocalVariableDeclExpr |
|
| file://:0:0:0:0 | tmp0 | exprs.kt:4:1:136:1 | topLevelMethod | LocalVariableDeclExpr |
|
||||||
|
| localFunctionCalls.kt:4:5:4:13 | x | localFunctionCalls.kt:3:1:11:1 | x | LocalVariableDeclExpr |
|
||||||
|
| localFunctionCalls.kt:4:13:4:13 | 5 | localFunctionCalls.kt:3:1:11:1 | x | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:5:25:5:25 | i | localFunctionCalls.kt:5:5:5:29 | a | VarAccess |
|
||||||
|
| localFunctionCalls.kt:5:25:5:29 | ... + ... | localFunctionCalls.kt:5:5:5:29 | a | AddExpr |
|
||||||
|
| localFunctionCalls.kt:5:29:5:29 | x | localFunctionCalls.kt:5:5:5:29 | a | VarAccess |
|
||||||
|
| localFunctionCalls.kt:6:5:6:5 | ...=... | localFunctionCalls.kt:3:1:11:1 | x | AssignExpr |
|
||||||
|
| localFunctionCalls.kt:6:5:6:5 | x | localFunctionCalls.kt:3:1:11:1 | x | VarAccess |
|
||||||
|
| localFunctionCalls.kt:6:9:6:9 | 6 | localFunctionCalls.kt:3:1:11:1 | x | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:7:5:7:17 | (...)... | localFunctionCalls.kt:3:1:11:1 | x | CastExpr |
|
||||||
|
| localFunctionCalls.kt:7:5:7:17 | Unit | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
|
| localFunctionCalls.kt:7:5:7:17 | a(...) | localFunctionCalls.kt:3:1:11:1 | x | MethodAccess |
|
||||||
|
| localFunctionCalls.kt:7:5:7:17 | new (...) | localFunctionCalls.kt:3:1:11:1 | x | ClassInstanceExpr |
|
||||||
|
| localFunctionCalls.kt:7:15:7:16 | 42 | localFunctionCalls.kt:3:1:11:1 | x | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:8:5:8:5 | ...=... | localFunctionCalls.kt:3:1:11:1 | x | AssignExpr |
|
||||||
|
| localFunctionCalls.kt:8:5:8:5 | x | localFunctionCalls.kt:3:1:11:1 | x | VarAccess |
|
||||||
|
| localFunctionCalls.kt:8:9:8:9 | 7 | localFunctionCalls.kt:3:1:11:1 | x | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:9:34:9:34 | 5 | localFunctionCalls.kt:9:5:9:34 | f1 | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:10:5:10:13 | new C1(...) | localFunctionCalls.kt:3:1:11:1 | x | ClassInstanceExpr |
|
||||||
|
| localFunctionCalls.kt:10:15:10:20 | (...)... | localFunctionCalls.kt:3:1:11:1 | x | CastExpr |
|
||||||
|
| localFunctionCalls.kt:10:15:10:20 | Unit | localFunctionCalls.kt:3:1:11:1 | x | TypeAccess |
|
||||||
|
| localFunctionCalls.kt:10:15:10:20 | f1(...) | localFunctionCalls.kt:3:1:11:1 | x | MethodAccess |
|
||||||
|
| localFunctionCalls.kt:10:15:10:20 | new (...) | localFunctionCalls.kt:3:1:11:1 | x | ClassInstanceExpr |
|
||||||
|
| localFunctionCalls.kt:10:18:10:19 | 42 | localFunctionCalls.kt:3:1:11:1 | x | IntegerLiteral |
|
||||||
|
| localFunctionCalls.kt:13:1:13:14 | <obinit>(...) | localFunctionCalls.kt:13:1:13:14 | C1 | MethodAccess |
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
fun x() {
|
||||||
|
var x = 5
|
||||||
|
fun <T> a(i: Int) = i + x
|
||||||
|
x = 6
|
||||||
|
a<String>(42)
|
||||||
|
x = 7
|
||||||
|
fun <T1> C1<T1>.f1(i: Int) = 5
|
||||||
|
C1<Int>().f1(42)
|
||||||
|
}
|
||||||
|
|
||||||
|
class C1<T> {}
|
||||||
@@ -25,8 +25,8 @@ parameterizedType
|
|||||||
| generics.kt:36:1:40:1 | BoundedTest | generics.kt:36:1:40:1 | BoundedTest | 0 | T |
|
| generics.kt:36:1:40:1 | BoundedTest | generics.kt:36:1:40:1 | BoundedTest | 0 | T |
|
||||||
| generics.kt:36:1:40:1 | BoundedTest | generics.kt:36:1:40:1 | BoundedTest | 1 | S |
|
| generics.kt:36:1:40:1 | BoundedTest | generics.kt:36:1:40:1 | BoundedTest | 1 | S |
|
||||||
function
|
function
|
||||||
| generics.kt:3:1:5:1 | f0 | f0(java.lang.Object) |
|
| generics.kt:3:1:5:1 | f0 | f0(int,java.lang.Object) |
|
||||||
| generics.kt:7:1:9:1 | f1 | f1(java.lang.Object) |
|
| generics.kt:7:1:9:1 | f1 | f1(int,java.lang.Object) |
|
||||||
| generics.kt:11:1:11:19 | <obinit> | <obinit>() |
|
| generics.kt:11:1:11:19 | <obinit> | <obinit>() |
|
||||||
| generics.kt:11:6:11:19 | C0 | C0() |
|
| generics.kt:11:6:11:19 | C0 | C0() |
|
||||||
| generics.kt:11:6:11:19 | equals | equals(java.lang.Object) |
|
| generics.kt:11:6:11:19 | equals | equals(java.lang.Object) |
|
||||||
|
|||||||
@@ -1,7 +1,35 @@
|
|||||||
|
| file://:0:0:0:0 | C1<Integer> | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | Integer | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | Integer | TypeAccess |
|
||||||
|
| file://:0:0:0:0 | String | TypeAccess |
|
||||||
| methods2.kt:7:1:10:1 | <obinit>(...) | MethodAccess |
|
| methods2.kt:7:1:10:1 | <obinit>(...) | MethodAccess |
|
||||||
| methods3.kt:5:1:7:1 | <obinit>(...) | MethodAccess |
|
| methods3.kt:5:1:7:1 | <obinit>(...) | MethodAccess |
|
||||||
| methods4.kt:3:1:11:1 | <obinit>(...) | MethodAccess |
|
| methods4.kt:3:1:11:1 | <obinit>(...) | MethodAccess |
|
||||||
| methods4.kt:5:3:9:3 | <obinit>(...) | MethodAccess |
|
| methods4.kt:5:3:9:3 | <obinit>(...) | MethodAccess |
|
||||||
|
| methods5.kt:4:3:4:11 | x | LocalVariableDeclExpr |
|
||||||
|
| methods5.kt:4:11:4:11 | 5 | IntegerLiteral |
|
||||||
|
| methods5.kt:5:23:5:23 | i | VarAccess |
|
||||||
|
| methods5.kt:5:23:5:27 | ... + ... | AddExpr |
|
||||||
|
| methods5.kt:5:27:5:27 | x | VarAccess |
|
||||||
|
| methods5.kt:6:3:6:3 | ...=... | AssignExpr |
|
||||||
|
| methods5.kt:6:3:6:3 | x | VarAccess |
|
||||||
|
| methods5.kt:6:7:6:7 | 6 | IntegerLiteral |
|
||||||
|
| methods5.kt:7:3:7:15 | (...)... | CastExpr |
|
||||||
|
| methods5.kt:7:3:7:15 | Unit | TypeAccess |
|
||||||
|
| methods5.kt:7:3:7:15 | a(...) | MethodAccess |
|
||||||
|
| methods5.kt:7:3:7:15 | new (...) | ClassInstanceExpr |
|
||||||
|
| methods5.kt:7:13:7:14 | 42 | IntegerLiteral |
|
||||||
|
| methods5.kt:8:3:8:3 | ...=... | AssignExpr |
|
||||||
|
| methods5.kt:8:3:8:3 | x | VarAccess |
|
||||||
|
| methods5.kt:8:7:8:7 | 7 | IntegerLiteral |
|
||||||
|
| methods5.kt:9:32:9:32 | 5 | IntegerLiteral |
|
||||||
|
| methods5.kt:10:3:10:11 | new C1(...) | ClassInstanceExpr |
|
||||||
|
| methods5.kt:10:13:10:18 | (...)... | CastExpr |
|
||||||
|
| methods5.kt:10:13:10:18 | Unit | TypeAccess |
|
||||||
|
| methods5.kt:10:13:10:18 | f1(...) | MethodAccess |
|
||||||
|
| methods5.kt:10:13:10:18 | new (...) | ClassInstanceExpr |
|
||||||
|
| methods5.kt:10:16:10:17 | 42 | IntegerLiteral |
|
||||||
|
| methods5.kt:13:1:13:14 | <obinit>(...) | MethodAccess |
|
||||||
| methods.kt:5:1:13:1 | <obinit>(...) | MethodAccess |
|
| methods.kt:5:1:13:1 | <obinit>(...) | MethodAccess |
|
||||||
| methods.kt:10:9:10:25 | classMethod(...) | MethodAccess |
|
| methods.kt:10:9:10:25 | classMethod(...) | MethodAccess |
|
||||||
| methods.kt:10:9:10:25 | this | ThisAccess |
|
| methods.kt:10:9:10:25 | this | ThisAccess |
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ methods
|
|||||||
| methods2.kt:7:1:10:1 | hashCode | hashCode() |
|
| methods2.kt:7:1:10:1 | hashCode | hashCode() |
|
||||||
| methods2.kt:7:1:10:1 | toString | toString() |
|
| methods2.kt:7:1:10:1 | toString | toString() |
|
||||||
| methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) |
|
| methods2.kt:8:5:9:5 | fooBarClassMethod | fooBarClassMethod(int,int) |
|
||||||
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod | fooBarTopLevelMethod(int) |
|
| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) |
|
||||||
| methods3.kt:5:1:7:1 | <obinit> | <obinit>() |
|
| methods3.kt:5:1:7:1 | <obinit> | <obinit>() |
|
||||||
| methods3.kt:5:1:7:1 | equals | equals(java.lang.Object) |
|
| methods3.kt:5:1:7:1 | equals | equals(java.lang.Object) |
|
||||||
| methods3.kt:5:1:7:1 | hashCode | hashCode() |
|
| methods3.kt:5:1:7:1 | hashCode | hashCode() |
|
||||||
| methods3.kt:5:1:7:1 | toString | toString() |
|
| methods3.kt:5:1:7:1 | toString | toString() |
|
||||||
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod | fooBarTopLevelMethod(int) |
|
| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | fooBarTopLevelMethodExt(int,int) |
|
||||||
| methods4.kt:3:1:11:1 | <obinit> | <obinit>() |
|
| methods4.kt:3:1:11:1 | <obinit> | <obinit>() |
|
||||||
| methods4.kt:3:1:11:1 | equals | equals(java.lang.Object) |
|
| methods4.kt:3:1:11:1 | equals | equals(java.lang.Object) |
|
||||||
| methods4.kt:3:1:11:1 | hashCode | hashCode() |
|
| methods4.kt:3:1:11:1 | hashCode | hashCode() |
|
||||||
@@ -20,6 +20,13 @@ methods
|
|||||||
| methods4.kt:5:3:9:3 | hashCode | hashCode() |
|
| methods4.kt:5:3:9:3 | hashCode | hashCode() |
|
||||||
| methods4.kt:5:3:9:3 | toString | toString() |
|
| methods4.kt:5:3:9:3 | toString | toString() |
|
||||||
| methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) |
|
| methods4.kt:7:5:7:34 | m | m(foo.bar.NestedTest.InsideNestedTest) |
|
||||||
|
| methods5.kt:3:1:11:1 | x | x() |
|
||||||
|
| methods5.kt:5:3:5:27 | a | a(int) |
|
||||||
|
| methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) |
|
||||||
|
| methods5.kt:13:1:13:14 | <obinit> | <obinit>() |
|
||||||
|
| methods5.kt:13:1:13:14 | equals | equals(java.lang.Object) |
|
||||||
|
| methods5.kt:13:1:13:14 | hashCode | hashCode() |
|
||||||
|
| methods5.kt:13:1:13:14 | toString | toString() |
|
||||||
| methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) |
|
| methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) |
|
||||||
| methods.kt:5:1:13:1 | <obinit> | <obinit>() |
|
| methods.kt:5:1:13:1 | <obinit> | <obinit>() |
|
||||||
| methods.kt:5:1:13:1 | equals | equals(java.lang.Object) |
|
| methods.kt:5:1:13:1 | equals | equals(java.lang.Object) |
|
||||||
@@ -32,7 +39,11 @@ constructors
|
|||||||
| methods3.kt:5:1:7:1 | Class3 | Class3() |
|
| methods3.kt:5:1:7:1 | Class3 | Class3() |
|
||||||
| methods4.kt:3:1:11:1 | NestedTest | NestedTest() |
|
| methods4.kt:3:1:11:1 | NestedTest | NestedTest() |
|
||||||
| methods4.kt:5:3:9:3 | InsideNestedTest | InsideNestedTest() |
|
| methods4.kt:5:3:9:3 | InsideNestedTest | InsideNestedTest() |
|
||||||
|
| methods5.kt:5:3:5:27 | | |
|
||||||
|
| methods5.kt:9:3:9:32 | | |
|
||||||
|
| methods5.kt:13:1:13:14 | C1 | C1() |
|
||||||
| methods.kt:5:1:13:1 | Class | Class() |
|
| methods.kt:5:1:13:1 | Class | Class() |
|
||||||
extensions
|
extensions
|
||||||
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod | file://:0:0:0:0 | int |
|
| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int |
|
||||||
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod | file://:0:0:0:0 | int |
|
| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int |
|
||||||
|
| methods5.kt:9:3:9:32 | f1 | methods5.kt:13:1:13:14 | C1<T1> |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package foo.bar
|
package foo.bar
|
||||||
|
|
||||||
fun Int.fooBarTopLevelMethod(x: Int) {}
|
fun Int.fooBarTopLevelMethodExt(x: Int) {}
|
||||||
|
|
||||||
class Class3 {
|
class Class3 {
|
||||||
fun Int.fooBarTopLevelMethod(x: Int) {}
|
fun Int.fooBarTopLevelMethodExt(x: Int) {}
|
||||||
}
|
}
|
||||||
|
|||||||
13
java/ql/test/kotlin/library-tests/methods/methods5.kt
Normal file
13
java/ql/test/kotlin/library-tests/methods/methods5.kt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package foo.bar
|
||||||
|
|
||||||
|
fun x() {
|
||||||
|
var x = 5
|
||||||
|
fun <T> a(i: Int) = i + x
|
||||||
|
x = 6
|
||||||
|
a<String>(42)
|
||||||
|
x = 7
|
||||||
|
fun <T1> C1<T1>.f1(i: Int) = 5
|
||||||
|
C1<Int>().f1(42)
|
||||||
|
}
|
||||||
|
|
||||||
|
class C1<T> {}
|
||||||
@@ -3,14 +3,18 @@
|
|||||||
| methods2.kt:7:1:10:1 | equals | methods2.kt:7:1:10:1 | other | 0 |
|
| methods2.kt:7:1:10:1 | equals | methods2.kt:7:1:10:1 | other | 0 |
|
||||||
| methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:27:8:32 | x | 0 |
|
| methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:27:8:32 | x | 0 |
|
||||||
| methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:35:8:40 | y | 1 |
|
| methods2.kt:8:5:9:5 | fooBarClassMethod | methods2.kt:8:35:8:40 | y | 1 |
|
||||||
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod | methods3.kt:3:5:3:7 | <this> | 0 |
|
| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | methods3.kt:3:5:3:7 | <this> | 0 |
|
||||||
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod | methods3.kt:3:30:3:35 | x | 1 |
|
| methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | methods3.kt:3:33:3:38 | x | 1 |
|
||||||
| methods3.kt:5:1:7:1 | equals | methods3.kt:5:1:7:1 | other | 0 |
|
| methods3.kt:5:1:7:1 | equals | methods3.kt:5:1:7:1 | other | 0 |
|
||||||
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod | methods3.kt:6:9:6:11 | <this> | 0 |
|
| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | methods3.kt:6:9:6:11 | <this> | 0 |
|
||||||
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod | methods3.kt:6:34:6:39 | x | 1 |
|
| methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | methods3.kt:6:37:6:42 | x | 1 |
|
||||||
| methods4.kt:3:1:11:1 | equals | methods4.kt:3:1:11:1 | other | 0 |
|
| methods4.kt:3:1:11:1 | equals | methods4.kt:3:1:11:1 | other | 0 |
|
||||||
| methods4.kt:5:3:9:3 | equals | methods4.kt:5:3:9:3 | other | 0 |
|
| methods4.kt:5:3:9:3 | equals | methods4.kt:5:3:9:3 | other | 0 |
|
||||||
| methods4.kt:7:5:7:34 | m | methods4.kt:7:11:7:29 | x | 0 |
|
| methods4.kt:7:5:7:34 | m | methods4.kt:7:11:7:29 | x | 0 |
|
||||||
|
| methods5.kt:5:3:5:27 | a | methods5.kt:5:13:5:18 | i | 0 |
|
||||||
|
| methods5.kt:9:3:9:32 | f1 | methods5.kt:9:12:9:17 | <this> | 0 |
|
||||||
|
| methods5.kt:9:3:9:32 | f1 | methods5.kt:9:22:9:27 | i | 1 |
|
||||||
|
| methods5.kt:13:1:13:14 | equals | methods5.kt:13:1:13:14 | other | 0 |
|
||||||
| methods.kt:2:1:3:1 | topLevelMethod | methods.kt:2:20:2:25 | x | 0 |
|
| methods.kt:2:1:3:1 | topLevelMethod | methods.kt:2:20:2:25 | x | 0 |
|
||||||
| methods.kt:2:1:3:1 | topLevelMethod | methods.kt:2:28:2:33 | y | 1 |
|
| methods.kt:2:1:3:1 | topLevelMethod | methods.kt:2:28:2:33 | y | 1 |
|
||||||
| methods.kt:5:1:13:1 | equals | methods.kt:5:1:13:1 | other | 0 |
|
| methods.kt:5:1:13:1 | equals | methods.kt:5:1:13:1 | other | 0 |
|
||||||
|
|||||||
Reference in New Issue
Block a user