mirror of
https://github.com/github/codeql.git
synced 2026-01-29 06:12:58 +01:00
Merge branch 'main' into ruby-mad-argument-self
This commit is contained in:
@@ -30,8 +30,13 @@ sourceSets {
|
||||
// change the excludes for building with other versions:
|
||||
excludes = [
|
||||
"utils/versions/v_1_4_32/*.kt",
|
||||
"utils/versions/v_1_5_0/*.kt",
|
||||
"utils/versions/v_1_5_10/*.kt",
|
||||
"utils/versions/v_1_5_21/*.kt",
|
||||
"utils/versions/v_1_5_31/*.kt",
|
||||
"utils/versions/v_1_6_10/*.kt"]
|
||||
"utils/versions/v_1_6_10/*.kt",
|
||||
// "utils/versions/v_1_6_20/*.kt",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,12 @@ def is_windows():
|
||||
return True
|
||||
return False
|
||||
|
||||
# kotlinc might be kotlinc.bat or kotlinc.cmd on Windows, so we use `which` to find out what it is
|
||||
kotlinc = shutil.which('kotlinc')
|
||||
if kotlinc is None:
|
||||
print("Cannot build the Kotlin extractor: no kotlinc found on your PATH", file = sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
kotlinc = 'kotlinc.bat' if is_windows() else 'kotlinc'
|
||||
javac = 'javac'
|
||||
kotlin_dependency_folder = args.dependencies
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -18,13 +19,19 @@ def version_string_to_tuple(version):
|
||||
m = re.match(r'([0-9]+)\.([0-9]+)\.([0-9]+)', version)
|
||||
return tuple([int(m.group(i)) for i in range(1, 4)])
|
||||
|
||||
many_versions = [ '1.4.32', '1.5.31', '1.6.10', '1.6.20' ]
|
||||
many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.21', '1.5.31', '1.6.10', '1.6.20' ]
|
||||
|
||||
many_versions_tuples = [version_string_to_tuple(v) for v in many_versions]
|
||||
|
||||
class KotlincNotFoundException(Exception):
|
||||
pass
|
||||
|
||||
def get_single_version(fakeVersionOutput = None):
|
||||
# TODO: `shell=True` is a workaround to get CI working on Windows. It breaks the build on Linux.
|
||||
versionOutput = subprocess.run(['kotlinc', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=is_windows()).stderr if fakeVersionOutput is None else fakeVersionOutput
|
||||
# kotlinc might be kotlinc.bat or kotlinc.cmd on Windows, so we use `which` to find out what it is
|
||||
kotlinc = shutil.which('kotlinc')
|
||||
if kotlinc is None:
|
||||
raise KotlincNotFoundException()
|
||||
versionOutput = subprocess.run([kotlinc, '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True).stderr if fakeVersionOutput is None else fakeVersionOutput
|
||||
m = re.match(r'.* kotlinc-jvm ([0-9]+\.[0-9]+\.[0-9]+) .*', versionOutput)
|
||||
if m is None:
|
||||
raise Exception('Cannot detect version of kotlinc (got ' + str(versionOutput) + ')')
|
||||
|
||||
@@ -21,7 +21,7 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
|
||||
|
||||
fun extractLater(d: IrDeclaration, signature: String): Boolean {
|
||||
if (d !is IrClass && !isExternalFileClassMember(d)) {
|
||||
logger.warnElement("External declaration is neither a class, nor a top-level declaration", d)
|
||||
logger.errorElement("External declaration is neither a class, nor a top-level declaration", d)
|
||||
return false
|
||||
}
|
||||
val ret = externalDeclsDone.add(d)
|
||||
@@ -64,7 +64,7 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
|
||||
|
||||
val containingClass = getContainingClassOrSelf(irDecl)
|
||||
if (containingClass == null) {
|
||||
logger.warnElement("Unable to get containing class", irDecl)
|
||||
logger.errorElement("Unable to get containing class", irDecl)
|
||||
return
|
||||
}
|
||||
val binaryPath = getIrClassBinaryPath(containingClass)
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.lang.management.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import com.semmle.util.files.FileUtil
|
||||
@@ -108,6 +109,7 @@ class KotlinExtractorExtension(
|
||||
logger.flush()
|
||||
logger.info("Extraction for invocation TRAP file $invocationTrapFile")
|
||||
logger.flush()
|
||||
logPeakMemoryUsage(logger, "before extractor")
|
||||
if (System.getenv("CODEQL_EXTRACTOR_JAVA_KOTLIN_DUMP") == "true") {
|
||||
logger.info("moduleFragment:\n" + moduleFragment.dump())
|
||||
}
|
||||
@@ -127,6 +129,7 @@ class KotlinExtractorExtension(
|
||||
fileTrapWriter.writeCompilation_compiling_files_completed(compilation, index, fileExtractionProblems.extractionResult())
|
||||
}
|
||||
loggerBase.printLimitedDiagnosticCounts(tw)
|
||||
logPeakMemoryUsage(logger, "after extractor")
|
||||
logger.info("Extraction completed")
|
||||
logger.flush()
|
||||
val compilationTimeMs = System.currentTimeMillis() - startTimeMs
|
||||
@@ -135,10 +138,28 @@ class KotlinExtractorExtension(
|
||||
loggerBase.close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun logPeakMemoryUsage(logger: Logger, time: String) {
|
||||
logger.info("Peak memory: Usage $time")
|
||||
|
||||
val beans = ManagementFactory.getMemoryPoolMXBeans()
|
||||
var heap: Long = 0
|
||||
var nonheap: Long = 0
|
||||
for (bean in beans) {
|
||||
val peak = bean.getPeakUsage().getUsed()
|
||||
val kind = when (bean.getType()) {
|
||||
MemoryType.HEAP -> { heap += peak; "heap" }
|
||||
MemoryType.NON_HEAP -> { nonheap += peak; "non-heap" }
|
||||
else -> "unknown"
|
||||
}
|
||||
logger.info("Peak memory: * Peak for $kind bean ${bean.getName()} is $peak")
|
||||
}
|
||||
logger.info("Peak memory: * Total heap peak: $heap")
|
||||
logger.info("Peak memory: * Total non-heap peak: $nonheap")
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinExtractorGlobalState {
|
||||
val genericSpecialisationsExtracted = HashSet<String>()
|
||||
// These three record mappings of classes, functions and fields that should be replaced wherever they are found.
|
||||
// As of now these are only used to fix IR generated by the Gradle Android Extensions plugin, hence e.g. IrProperty
|
||||
// doesn't have a map as that plugin doesn't generate them. If and when these are used more widely additional maps
|
||||
|
||||
@@ -173,19 +173,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int): Label<out DbTypevariable>? {
|
||||
with("type parameter", tp) {
|
||||
val parentId: Label<out DbClassorinterfaceorcallable>? = when (val parent = tp.parent) {
|
||||
is IrFunction -> useFunction(parent)
|
||||
is IrClass -> useClassSource(parent)
|
||||
else -> {
|
||||
logger.errorElement("Unexpected type parameter parent", tp)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
if (parentId == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val parentId = getTypeParameterParentLabel(tp) ?: return null
|
||||
val id = tw.getLabelFor<DbTypevariable>(getTypeParameterLabel(tp))
|
||||
|
||||
// Note apparentIndex does not necessarily equal `tp.index`, because at least constructor type parameters
|
||||
@@ -282,7 +270,7 @@ open class KotlinFileExtractor(
|
||||
if (kind == ClassKind.ENUM_CLASS) {
|
||||
tw.writeIsEnumType(classId)
|
||||
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) {
|
||||
logger.warnElement("Unrecognised class kind $kind", c)
|
||||
logger.errorElement("Unrecognised class kind $kind", c)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,17 +322,7 @@ open class KotlinFileExtractor(
|
||||
val typeParamSubstitution =
|
||||
when (argsIncludingOuterClasses) {
|
||||
null -> { x: IrType, _: TypeContext, _: IrPluginContext -> x.toRawType() }
|
||||
else -> {
|
||||
makeTypeGenericSubstitutionMap(c, argsIncludingOuterClasses).let {
|
||||
{ x: IrType, useContext: TypeContext, pluginContext: IrPluginContext ->
|
||||
x.substituteTypeAndArguments(
|
||||
it,
|
||||
useContext,
|
||||
pluginContext
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> makeGenericSubstitutionFunction(c, argsIncludingOuterClasses)
|
||||
}
|
||||
|
||||
c.declarations.map {
|
||||
@@ -426,8 +404,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
extractClassModifiers(c, id)
|
||||
val forceExtractSupertypeMembers = !isExternalDeclaration(c)
|
||||
extractClassSupertypes(c, id, inReceiverContext = forceExtractSupertypeMembers)
|
||||
extractClassSupertypes(c, id, inReceiverContext = true) // inReceiverContext = true is specified to force extraction of member prototypes of base types
|
||||
|
||||
return id
|
||||
}
|
||||
@@ -511,12 +488,12 @@ open class KotlinFileExtractor(
|
||||
return FieldResult(instanceId, instanceName)
|
||||
}
|
||||
|
||||
private fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>, idx: Int, typeSubstitution: TypeSubstitution?, parentSourceDeclaration: Label<out DbCallable>, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, extractTypeAccess: Boolean): TypeResults {
|
||||
private fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>, idx: Int, typeSubstitution: TypeSubstitution?, parentSourceDeclaration: Label<out DbCallable>, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, extractTypeAccess: Boolean, locOverride: Label<DbLocation>? = null): TypeResults {
|
||||
with("value parameter", vp) {
|
||||
val location = getLocation(vp, classTypeArgsIncludingOuterClasses)
|
||||
val location = locOverride ?: getLocation(vp, classTypeArgsIncludingOuterClasses)
|
||||
val id = useValueParameter(vp, parent)
|
||||
if (extractTypeAccess) {
|
||||
extractTypeAccessRecursive(vp.type, location, id, -1)
|
||||
extractTypeAccessRecursive(typeSubstitution?.let { it(vp.type, TypeContext.OTHER, pluginContext) } ?: vp.type, location, id, -1)
|
||||
}
|
||||
return extractValueParameter(id, vp.type, vp.name.asString(), location, parent, idx, typeSubstitution, useValueParameter(vp, parentSourceDeclaration), vp.isVararg)
|
||||
}
|
||||
@@ -571,7 +548,7 @@ open class KotlinFileExtractor(
|
||||
val constructorId = useFunction<DbConstructor>(enclosingConstructor)
|
||||
val enclosingClass = enclosingConstructor.parentClassOrNull
|
||||
if (enclosingClass == null) {
|
||||
logger.warnElement("Constructor's parent is not a class", enclosingConstructor)
|
||||
logger.errorElement("Constructor's parent is not a class", enclosingConstructor)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -676,7 +653,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>? = null): Label<out DbCallable>? {
|
||||
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>? = null, locOverride: Label<DbLocation>? = null): Label<out DbCallable>? {
|
||||
if (isFake(f)) return null
|
||||
|
||||
with("function", f) {
|
||||
@@ -694,7 +671,7 @@ open class KotlinFileExtractor(
|
||||
useFunction<DbCallable>(f, parentId, classTypeArgsIncludingOuterClasses, noReplace = true)
|
||||
|
||||
val sourceDeclaration =
|
||||
if (typeSubstitution != null)
|
||||
if (typeSubstitution != null && idOverride == null)
|
||||
useFunction(f)
|
||||
else
|
||||
id
|
||||
@@ -702,13 +679,13 @@ open class KotlinFileExtractor(
|
||||
val extReceiver = f.extensionReceiverParameter
|
||||
val idxOffset = if (extReceiver != null) 1 else 0
|
||||
val paramTypes = f.valueParameters.mapIndexed { i, vp ->
|
||||
extractValueParameter(vp, id, i + idxOffset, typeSubstitution, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses)
|
||||
extractValueParameter(vp, id, i + idxOffset, typeSubstitution, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, locOverride)
|
||||
}
|
||||
val allParamTypes = if (extReceiver != null) {
|
||||
val extendedType = useType(extReceiver.type)
|
||||
tw.writeKtExtensionFunctions(id.cast<DbMethod>(), extendedType.javaResult.id, extendedType.kotlinResult.id)
|
||||
|
||||
val t = extractValueParameter(extReceiver, id, 0, null, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses)
|
||||
val t = extractValueParameter(extReceiver, id, 0, null, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, locOverride)
|
||||
listOf(t) + paramTypes
|
||||
} else {
|
||||
paramTypes
|
||||
@@ -718,7 +695,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
val substReturnType = typeSubstitution?.let { it(f.returnType, TypeContext.RETURN, pluginContext) } ?: f.returnType
|
||||
|
||||
val locId = getLocation(f, classTypeArgsIncludingOuterClasses)
|
||||
val locId = locOverride ?: getLocation(f, classTypeArgsIncludingOuterClasses)
|
||||
|
||||
if (f.symbol is IrConstructorSymbol) {
|
||||
val unitType = useType(pluginContext.irBuiltIns.unitType, TypeContext.RETURN)
|
||||
@@ -738,7 +715,7 @@ open class KotlinFileExtractor(
|
||||
tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id)
|
||||
|
||||
if (extractMethodAndParameterTypeAccesses) {
|
||||
extractTypeAccessRecursive(f.returnType, locId, id, -1)
|
||||
extractTypeAccessRecursive(substReturnType, locId, id, -1)
|
||||
}
|
||||
|
||||
if (shortName.nameInDB != shortName.kotlinName) {
|
||||
@@ -829,13 +806,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
} else {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
logger.errorElement("IrProperty without a getter", p)
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (!p.isVar) {
|
||||
logger.errorElement("!isVar property with a setter", p)
|
||||
logger.warnElement("!isVar property with a setter", p)
|
||||
}
|
||||
val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (setterId != null) {
|
||||
@@ -843,7 +820,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
} else {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.errorElement("isVar property without a setter", p)
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1374,6 +1351,23 @@ open class KotlinFileExtractor(
|
||||
return fn
|
||||
}
|
||||
|
||||
private fun findTopLevelPropertyOrWarn(propertyFilter: String, type: String, warnAgainstElement: IrElement): IrProperty? {
|
||||
|
||||
val prop = pluginContext.referenceProperties(FqName(propertyFilter))
|
||||
.firstOrNull { it.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type }
|
||||
?.owner
|
||||
|
||||
if (prop != null) {
|
||||
if (prop.parentClassOrNull != null) {
|
||||
extractExternalClassLater(prop.parentAsClass)
|
||||
}
|
||||
} else {
|
||||
logger.errorElement("Couldn't find JVM intrinsic property $propertyFilter in $type", warnAgainstElement)
|
||||
}
|
||||
|
||||
return prop
|
||||
}
|
||||
|
||||
val javaLangString by lazy {
|
||||
val result = pluginContext.referenceClass(FqName("java.lang.String"))?.owner
|
||||
result?.let { extractExternalClassLater(it) }
|
||||
@@ -1662,7 +1656,7 @@ open class KotlinFileExtractor(
|
||||
// as they can't be extracted as external dependencies.
|
||||
isBuiltinCallInternal(c, "less") -> {
|
||||
if(c.origin != IrStatementOrigin.LT) {
|
||||
logger.errorElement("Unexpected origin for LT: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for LT: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbLtexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1672,7 +1666,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "lessOrEqual") -> {
|
||||
if(c.origin != IrStatementOrigin.LTEQ) {
|
||||
logger.errorElement("Unexpected origin for LTEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for LTEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbLeexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1682,7 +1676,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "greater") -> {
|
||||
if(c.origin != IrStatementOrigin.GT) {
|
||||
logger.errorElement("Unexpected origin for GT: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for GT: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbGtexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1692,7 +1686,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "greaterOrEqual") -> {
|
||||
if(c.origin != IrStatementOrigin.GTEQ) {
|
||||
logger.errorElement("Unexpected origin for GTEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for GTEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbGeexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1702,7 +1696,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "EQEQ") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQ) {
|
||||
logger.errorElement("Unexpected origin for EQEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for EQEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbValueeqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1712,7 +1706,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "EQEQEQ") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQEQ) {
|
||||
logger.errorElement("Unexpected origin for EQEQEQ: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for EQEQEQ: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbEqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1722,7 +1716,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "ieee754equals") -> {
|
||||
if(c.origin != IrStatementOrigin.EQEQ) {
|
||||
logger.errorElement("Unexpected origin for ieee754equals: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for ieee754equals: ${c.origin}", c)
|
||||
}
|
||||
val id = tw.getFreshIdLabel<DbEqexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -1732,7 +1726,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isBuiltinCallInternal(c, "CHECK_NOT_NULL") -> {
|
||||
if(c.origin != IrStatementOrigin.EXCLEXCL) {
|
||||
logger.errorElement("Unexpected origin for CHECK_NOT_NULL: ${c.origin}", c)
|
||||
logger.warnElement("Unexpected origin for CHECK_NOT_NULL: ${c.origin}", c)
|
||||
}
|
||||
|
||||
val id = tw.getFreshIdLabel<DbNotnullexpr>()
|
||||
@@ -1887,6 +1881,27 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
}
|
||||
isBuiltinCall(c, "<get-java>", "kotlin.jvm") -> {
|
||||
// Special case for KClass<*>.java, which is used in the Parcelize plugin. In normal cases, this is already rewritten to the property referenced below:
|
||||
findTopLevelPropertyOrWarn("kotlin.jvm.java", "kotlin.jvm.JvmClassMappingKt", c)?.let { javaProp ->
|
||||
val getter = javaProp.getter
|
||||
if (getter == null) {
|
||||
logger.error("Couldn't find getter of `kotlin.jvm.JvmClassMappingKt::java`")
|
||||
return
|
||||
}
|
||||
|
||||
val ext = c.extensionReceiver
|
||||
if (ext == null) {
|
||||
logger.errorElement("No extension receiver found for `KClass::java` call", c)
|
||||
return
|
||||
}
|
||||
|
||||
val argType = (ext.type as? IrSimpleType)?.arguments?.firstOrNull()?.typeOrNull
|
||||
val typeArguments = if (argType == null) listOf() else listOf(argType)
|
||||
|
||||
extractRawMethodAccess(getter, c, callable, parent, idx, enclosingStmt, listOf(), null, ext, typeArguments)
|
||||
}
|
||||
}
|
||||
isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") && c.origin == IrStatementOrigin.FOR_LOOP_ITERATOR -> {
|
||||
findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", "kotlin.jvm.internal.ArrayIteratorKt", c)?.let { iteratorFn ->
|
||||
extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, listOf((c.dispatchReceiver!!.type as IrSimpleType).arguments.first().typeOrNull!!))
|
||||
@@ -2378,7 +2393,7 @@ open class KotlinFileExtractor(
|
||||
val stmtParent = parent.stmt(e, callable)
|
||||
val irConstructor = declarationStack.peek() as? IrConstructor
|
||||
if (irConstructor == null) {
|
||||
logger.warnElement("IrInstanceInitializerCall outside constructor", e)
|
||||
logger.errorElement("IrInstanceInitializerCall outside constructor", e)
|
||||
return
|
||||
}
|
||||
extractInstanceInitializerBlock(stmtParent, irConstructor)
|
||||
@@ -3352,7 +3367,7 @@ open class KotlinFileExtractor(
|
||||
) {
|
||||
with("function reference", functionReferenceExpr) {
|
||||
val target = functionReferenceExpr.reflectionTarget ?: run {
|
||||
logger.errorElement("Expected to find reflection target for function reference. Using underlying symbol instead.", functionReferenceExpr)
|
||||
logger.warnElement("Expected to find reflection target for function reference. Using underlying symbol instead.", functionReferenceExpr)
|
||||
functionReferenceExpr.symbol
|
||||
}
|
||||
|
||||
@@ -4014,7 +4029,12 @@ open class KotlinFileExtractor(
|
||||
helper.extractParameterToFieldAssignmentInConstructor("<fn>", functionType, fieldId, 0, 1)
|
||||
|
||||
// add implementation function
|
||||
extractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, null, null, ids.function)
|
||||
val classTypeArgs = (e.type as? IrSimpleType)?.arguments
|
||||
val typeSub = classTypeArgs?.let { makeGenericSubstitutionFunction(typeOwner, it) }
|
||||
|
||||
fun trySub(t: IrType, context: TypeContext) = if (typeSub == null) t else typeSub(t, context, pluginContext)
|
||||
|
||||
extractFunction(samMember, classId, extractBody = false, extractMethodAndParameterTypeAccesses = true, typeSub, classTypeArgs, idOverride = ids.function, locOverride = tw.getLocation(e))
|
||||
|
||||
//body
|
||||
val blockId = tw.getFreshIdLabel<DbBlock>()
|
||||
@@ -4037,7 +4057,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
// Call to original `invoke`:
|
||||
val callId = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val callType = useType(samMember.returnType)
|
||||
val callType = useType(trySub(samMember.returnType, TypeContext.RETURN))
|
||||
tw.writeExprs_methodaccess(callId, callType.javaResult.id, returnId, 0)
|
||||
tw.writeExprsKotlinType(callId, callType.kotlinResult.id)
|
||||
extractCommonExpr(callId)
|
||||
@@ -4061,7 +4081,7 @@ open class KotlinFileExtractor(
|
||||
|
||||
fun extractArgument(p: IrValueParameter, idx: Int, parent: Label<out DbExprparent>) {
|
||||
val argsAccessId = tw.getFreshIdLabel<DbVaraccess>()
|
||||
val paramType = useType(p.type)
|
||||
val paramType = useType(trySub(p.type, TypeContext.OTHER))
|
||||
tw.writeExprs_varaccess(argsAccessId, paramType.javaResult.id, parent, idx)
|
||||
tw.writeExprsKotlinType(argsAccessId, paramType.kotlinResult.id)
|
||||
extractCommonExpr(argsAccessId)
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.semmle.extractor.java.OdasaOutput
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.allOverridden
|
||||
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -215,6 +216,17 @@ open class KotlinUsesExtractor(
|
||||
fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
|
||||
getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap()
|
||||
|
||||
fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>) =
|
||||
makeTypeGenericSubstitutionMap(c, argsIncludingOuterClasses).let {
|
||||
{ x: IrType, useContext: TypeContext, pluginContext: IrPluginContext ->
|
||||
x.substituteTypeAndArguments(
|
||||
it,
|
||||
useContext,
|
||||
pluginContext
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// The Kotlin compiler internal representation of Outer<A, B>.Inner<C, D>.InnerInner<E, F>.someFunction<G, H>.LocalClass<I, J> is LocalClass<I, J, G, H, E, F, C, D, A, B>. This function returns [A, B, C, D, E, F, G, H, I, J].
|
||||
fun orderTypeArgsLeftToRight(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): List<IrTypeArgument>? {
|
||||
if(argsIncludingOuterClasses.isNullOrEmpty())
|
||||
@@ -242,10 +254,12 @@ open class KotlinUsesExtractor(
|
||||
val extractClass = substituteClass ?: c
|
||||
|
||||
// `KFunction1<T1,T2>` is substituted by `KFunction<T>`. The last type argument is the return type.
|
||||
// Similarly Function23 and above get replaced by kotlin.jvm.functions.FunctionN with only one type arg, the result type.
|
||||
// References to SomeGeneric<T1, T2, ...> where SomeGeneric is declared SomeGeneric<T1, T2, ...> are extracted
|
||||
// as if they were references to the unbound type SomeGeneric.
|
||||
val extractedTypeArgs = when {
|
||||
c.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
|
||||
extractClass.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
|
||||
extractClass.fqNameWhenAvailable == FqName("kotlin.jvm.functions.FunctionN") && typeArgs != null && typeArgs.isNotEmpty() -> listOf(typeArgs.last())
|
||||
typeArgs != null && isUnspecialised(c, typeArgs) -> listOf()
|
||||
else -> typeArgs
|
||||
}
|
||||
@@ -407,7 +421,7 @@ open class KotlinUsesExtractor(
|
||||
extractorWithCSource.extractClassInstance(c, argsIncludingOuterClasses)
|
||||
}
|
||||
|
||||
if (inReceiverContext && globalExtensionState.genericSpecialisationsExtracted.add(classLabelResult.classLabel)) {
|
||||
if (inReceiverContext && tw.lm.genericSpecialisationsExtracted.add(classLabelResult.classLabel)) {
|
||||
val supertypeMode = if (argsIncludingOuterClasses == null) ExtractSupertypesMode.Raw else ExtractSupertypesMode.Specialised(argsIncludingOuterClasses)
|
||||
extractorWithCSource.extractClassSupertypes(c, classLabel, supertypeMode, true)
|
||||
extractorWithCSource.extractNonPrivateMemberPrototypes(c, argsIncludingOuterClasses, classLabel)
|
||||
@@ -947,7 +961,19 @@ open class KotlinUsesExtractor(
|
||||
decl.name == f.name &&
|
||||
decl.valueParameters.size == f.valueParameters.size
|
||||
} ?:
|
||||
run {
|
||||
// Or check property accessors:
|
||||
if (f.isAccessor) {
|
||||
val prop = javaClass.declarations.filterIsInstance<IrProperty>().find { decl ->
|
||||
decl.name == (f.propertyIfAccessor as IrProperty).name
|
||||
}
|
||||
if (prop?.getter?.name == f.name)
|
||||
prop.getter
|
||||
else if (prop?.setter?.name == f.name)
|
||||
prop.setter
|
||||
else null
|
||||
} else {
|
||||
null
|
||||
} ?: run {
|
||||
val parentFqName = parentClass.fqNameWhenAvailable?.asString()
|
||||
if (!expectedMissingEquivalents.contains(parentFqName)) {
|
||||
logger.warn("Couldn't find a Java equivalent function to $parentFqName.${f.name} in ${javaClass.fqNameWhenAvailable}")
|
||||
@@ -1083,8 +1109,21 @@ open class KotlinUsesExtractor(
|
||||
return classTypeResult.id
|
||||
}
|
||||
|
||||
fun getTypeParameterParentLabel(param: IrTypeParameter) =
|
||||
param.parent.let {
|
||||
when (it) {
|
||||
is IrClass -> useClassSource(it)
|
||||
is IrFunction -> useFunction(it, noReplace = true)
|
||||
else -> { logger.error("Unexpected type parameter parent $it"); null }
|
||||
}
|
||||
}
|
||||
|
||||
fun getTypeParameterLabel(param: IrTypeParameter): String {
|
||||
val parentLabel = useDeclarationParent(param.parent, false)
|
||||
// Use this instead of `useDeclarationParent` so we can use useFunction with noReplace = true,
|
||||
// ensuring that e.g. a method-scoped type variable declared on kotlin.String.transform <R> gets
|
||||
// a different name to the corresponding java.lang.String.transform <R>, even though useFunction
|
||||
// will usually replace references to one function with the other.
|
||||
val parentLabel = getTypeParameterParentLabel(param)
|
||||
return "@\"typevar;{$parentLabel};${param.name}\""
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,15 @@ class TrapLabelManager {
|
||||
val anonymousTypeMapping: MutableMap<IrClass, TypeResults> = mutableMapOf()
|
||||
|
||||
val locallyVisibleFunctionLabelMapping: MutableMap<IrFunction, LocallyVisibleFunctionLabels> = mutableMapOf()
|
||||
|
||||
/**
|
||||
* The set of labels of generic specialisations that we have extracted
|
||||
* in this TRAP file.
|
||||
* We can't easily avoid duplication between TRAP files, as the labels
|
||||
* contain references to other labels, so we just accept this
|
||||
* duplication.
|
||||
*/
|
||||
val genericSpecialisationsExtracted = HashSet<String>()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,36 @@ enum class Severity(val sev: Int) {
|
||||
ErrorGlobal(8)
|
||||
}
|
||||
|
||||
class LogMessage(private val kind: String, private val message: String) {
|
||||
val timestamp: String
|
||||
init {
|
||||
timestamp = "${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}"
|
||||
}
|
||||
|
||||
fun toText(): String {
|
||||
return "[$timestamp K] [$kind] $message"
|
||||
}
|
||||
|
||||
private fun escape(str: String): String {
|
||||
return str.replace("\\", "\\\\")
|
||||
.replace("\"", "\\\"")
|
||||
.replace("/", "\\/")
|
||||
.replace("\b", "\\b")
|
||||
.replace("\u000C", "\\f")
|
||||
.replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
.replace("\t", "\\t")
|
||||
}
|
||||
|
||||
fun toJsonLine(): String {
|
||||
val kvs = listOf(Pair("origin", "CodeQL Kotlin extractor"),
|
||||
Pair("timestamp", timestamp),
|
||||
Pair("kind", kind),
|
||||
Pair("message", message))
|
||||
return "{ " + kvs.map { p -> "\"${p.first}\": \"${escape(p.second)}\""}.joinToString(", ") + " }\n"
|
||||
}
|
||||
}
|
||||
|
||||
data class ExtractorContext(val kind: String, val element: IrElement, val name: String, val loc: String)
|
||||
|
||||
open class LoggerBase(val logCounter: LogCounter) {
|
||||
@@ -54,10 +84,6 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun timestamp(): String {
|
||||
return "[${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} K]"
|
||||
}
|
||||
|
||||
private fun getDiagnosticLocation(): String? {
|
||||
val st = Exception().stackTrace
|
||||
for(x in st) {
|
||||
@@ -84,7 +110,6 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
fun diagnostic(tw: TrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) {
|
||||
val diagnosticLoc = getDiagnosticLocation()
|
||||
val diagnosticLocStr = if(diagnosticLoc == null) "<unknown location>" else diagnosticLoc
|
||||
val extraInfoStr = if (extraInfo == null) "" else (extraInfo + "\n")
|
||||
val suffix =
|
||||
if(diagnosticLoc == null) {
|
||||
" Missing caller information.\n"
|
||||
@@ -100,8 +125,10 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
}
|
||||
val fullMsgBuilder = StringBuilder()
|
||||
fullMsgBuilder.append(msg)
|
||||
fullMsgBuilder.append('\n')
|
||||
fullMsgBuilder.append(extraInfoStr)
|
||||
if (extraInfo != null) {
|
||||
fullMsgBuilder.append('\n')
|
||||
fullMsgBuilder.append(extraInfo)
|
||||
}
|
||||
|
||||
val iter = extractorContextStack.listIterator(extractorContextStack.size)
|
||||
while (iter.hasPrevious()) {
|
||||
@@ -111,38 +138,38 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
fullMsgBuilder.append(suffix)
|
||||
|
||||
val fullMsg = fullMsgBuilder.toString()
|
||||
val ts = timestamp()
|
||||
val locStr = if (locationString == null) "" else "At " + locationString + ": "
|
||||
val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR"
|
||||
val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg")
|
||||
// We don't actually make the location until after the `return` above
|
||||
val locationId = mkLocationId()
|
||||
val diagLabel = tw.getFreshIdLabel<DbDiagnostic>()
|
||||
tw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "$ts $fullMsg", locationId)
|
||||
tw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId)
|
||||
tw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++)
|
||||
val locStr = if (locationString == null) "" else "At " + locationString + ": "
|
||||
val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR"
|
||||
logStream.write("$ts [$kind] Diagnostic($diagnosticLocStr): $locStr$fullMsg")
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
|
||||
fun trace(tw: TrapWriter, msg: String) {
|
||||
if (verbosity >= 4) {
|
||||
val fullMsg = "${timestamp()} [TRACE] $msg"
|
||||
tw.writeComment(fullMsg)
|
||||
logStream.write(fullMsg + "\n")
|
||||
val logMessage = LogMessage("TRACE", msg)
|
||||
tw.writeComment(logMessage.toText())
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
}
|
||||
|
||||
fun debug(tw: TrapWriter, msg: String) {
|
||||
if (verbosity >= 4) {
|
||||
val fullMsg = "${timestamp()} [DEBUG] $msg"
|
||||
tw.writeComment(fullMsg)
|
||||
logStream.write(fullMsg + "\n")
|
||||
val logMessage = LogMessage("DEBUG", msg)
|
||||
tw.writeComment(logMessage.toText())
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
}
|
||||
|
||||
fun info(tw: TrapWriter, msg: String) {
|
||||
if (verbosity >= 3) {
|
||||
val fullMsg = "${timestamp()} [INFO] $msg"
|
||||
tw.writeComment(fullMsg)
|
||||
logStream.write(fullMsg + "\n")
|
||||
val logMessage = LogMessage("INFO", msg)
|
||||
tw.writeComment(logMessage.toText())
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +187,12 @@ open class LoggerBase(val logCounter: LogCounter) {
|
||||
fun printLimitedDiagnosticCounts(tw: TrapWriter) {
|
||||
for((caller, count) in logCounter.diagnosticCounts) {
|
||||
if(count >= logCounter.diagnosticLimit) {
|
||||
val msg = "Total of $count diagnostics from $caller.\n"
|
||||
tw.writeComment(msg)
|
||||
logStream.write(msg)
|
||||
// We don't know if this location relates to an error
|
||||
// or a warning, so we just declare hitting the limit
|
||||
// to be an error regardless.
|
||||
val logMessage = LogMessage("ERROR", "Total of $count diagnostics from $caller.")
|
||||
tw.writeComment(logMessage.toText())
|
||||
logStream.write(logMessage.toJsonLine())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.KotlinUsesExtractor
|
||||
import com.github.codeql.Severity
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun <TIrStub> KotlinUsesExtractor.getIrStubFromDescriptor(generateStub: (DeclarationStubGenerator) -> TIrStub) : TIrStub? =
|
||||
(pluginContext.symbolTable as? SymbolTable) ?.let {
|
||||
val stubGenerator = DeclarationStubGenerator(pluginContext.moduleDescriptor, it, pluginContext.languageVersionSettings)
|
||||
generateStub(stubGenerator)
|
||||
} ?: run {
|
||||
logger.error("Plugin context has no symbol table, couldn't get IR stub")
|
||||
null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
|
||||
typealias FileEntry = SourceManager.FileEntry
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
|
||||
fun functionN(pluginContext: IrPluginContext): (Int) -> IrClass {
|
||||
return { i -> pluginContext.irBuiltIns.functionFactory.functionN(i) }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isRawType
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
|
||||
|
||||
fun IrSimpleType.isRawType() = this.isRawType()
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.KotlinUsesExtractor
|
||||
import com.github.codeql.Severity
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun <TIrStub> KotlinUsesExtractor.getIrStubFromDescriptor(generateStub: (DeclarationStubGenerator) -> TIrStub) : TIrStub? =
|
||||
(pluginContext.symbolTable as? SymbolTable) ?.let {
|
||||
val stubGenerator = DeclarationStubGenerator(pluginContext.moduleDescriptor, it, pluginContext.languageVersionSettings)
|
||||
generateStub(stubGenerator)
|
||||
} ?: run {
|
||||
logger.error("Plugin context has no symbol table, couldn't get IR stub")
|
||||
null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
|
||||
typealias FileEntry = SourceManager.FileEntry
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
|
||||
fun functionN(pluginContext: IrPluginContext): (Int) -> IrClass {
|
||||
return { i -> pluginContext.irBuiltIns.functionFactory.functionN(i) }
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isRawType
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
|
||||
|
||||
fun IrSimpleType.isRawType() = this.isRawType()
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.KotlinUsesExtractor
|
||||
import com.github.codeql.Severity
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun <TIrStub> KotlinUsesExtractor.getIrStubFromDescriptor(generateStub: (DeclarationStubGenerator) -> TIrStub) : TIrStub? =
|
||||
(pluginContext.symbolTable as? SymbolTable) ?.let {
|
||||
val stubGenerator = DeclarationStubGeneratorImpl(pluginContext.moduleDescriptor, it, pluginContext.languageVersionSettings)
|
||||
generateStub(stubGenerator)
|
||||
} ?: run {
|
||||
logger.error("Plugin context has no symbol table, couldn't get IR stub")
|
||||
null
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrFileEntry
|
||||
|
||||
typealias FileEntry = IrFileEntry
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
|
||||
fun functionN(pluginContext: IrPluginContext): (Int) -> IrClass {
|
||||
return { i -> pluginContext.irBuiltIns.functionFactory.functionN(i) }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isRawType
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
|
||||
|
||||
fun IrSimpleType.isRawType() = this.isRawType()
|
||||
@@ -1,11 +1,15 @@
|
||||
import java
|
||||
|
||||
class InstantiatedType extends ParameterizedType {
|
||||
InstantiatedType() { typeArgs(_, _, this) }
|
||||
}
|
||||
|
||||
Type getAMentionedType(RefType type) {
|
||||
result = type
|
||||
or
|
||||
result = getAMentionedType(type).(Array).getElementType()
|
||||
or
|
||||
result = getAMentionedType(type).(ParameterizedType).getATypeArgument()
|
||||
result = getAMentionedType(type).(InstantiatedType).getATypeArgument()
|
||||
or
|
||||
result = getAMentionedType(type).(NestedType).getEnclosingType()
|
||||
}
|
||||
@@ -24,17 +28,26 @@ Type getATypeUsedInClass(RefType type) {
|
||||
result = getAMentionedType(getATypeUsedInClass(type))
|
||||
}
|
||||
|
||||
Element getEnclosingElementStar(RefType e) {
|
||||
result = e
|
||||
or
|
||||
result.contains(e)
|
||||
}
|
||||
|
||||
TypeVariable getATypeVariableInScope(RefType type) {
|
||||
result = type.getACallable().(GenericCallable).getATypeParameter()
|
||||
or
|
||||
result = type.(GenericType).getATypeParameter()
|
||||
or
|
||||
result = getAMentionedType(type.(ParameterizedType).getATypeArgument())
|
||||
or
|
||||
result = getATypeVariableInScope(type.getEnclosingType())
|
||||
exists(Element e | e = getEnclosingElementStar(type) |
|
||||
result = e.(RefType).getACallable().(GenericCallable).getATypeParameter()
|
||||
or
|
||||
result = e.(GenericType).getATypeParameter()
|
||||
or
|
||||
result = e.(GenericCallable).getATypeParameter()
|
||||
or
|
||||
result = getAMentionedType(e.(InstantiatedType).getATypeArgument())
|
||||
)
|
||||
}
|
||||
|
||||
from ClassOrInterface typeUser, TypeVariable outOfScope
|
||||
where
|
||||
outOfScope = getAMentionedType(typeUser) and not outOfScope = getATypeVariableInScope(typeUser)
|
||||
select "Type " + typeUser + " uses out-of-scope type variable " + outOfScope
|
||||
outOfScope = getATypeUsedInClass(typeUser) and not outOfScope = getATypeVariableInScope(typeUser)
|
||||
select "Type " + typeUser + " uses out-of-scope type variable " + outOfScope +
|
||||
". Note the Java extractor is known to sometimes do this; the Kotlin extractor should not."
|
||||
|
||||
@@ -92,7 +92,7 @@ class CollectionMutation extends MethodAccess {
|
||||
/** A method that queries the contents of a collection without mutating it. */
|
||||
class CollectionQueryMethod extends CollectionMethod {
|
||||
CollectionQueryMethod() {
|
||||
pragma[only_bind_into](this).getName().regexpMatch("contains|containsAll|get|size|peek")
|
||||
pragma[only_bind_into](this).getName() = ["contains", "containsAll", "get", "size", "peek"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ private module ControlFlowGraphImpl {
|
||||
* That is, contexts where the control-flow edges depend on `value` given that `b` ends
|
||||
* with a `booleanCompletion(value, _)`.
|
||||
*/
|
||||
private predicate inBooleanContext(Expr b) {
|
||||
private predicate inBooleanContext(ControlFlowNode b) {
|
||||
exists(LogicExpr logexpr |
|
||||
logexpr.(BinaryExpr).getLeftOperand() = b
|
||||
or
|
||||
@@ -316,6 +316,10 @@ private module ControlFlowGraphImpl {
|
||||
inBooleanContext(whenexpr) and
|
||||
whenexpr.getBranch(_).getAResult() = b
|
||||
)
|
||||
or
|
||||
inBooleanContext(b.(ExprStmt).getExpr())
|
||||
or
|
||||
inBooleanContext(b.(StmtExpr).getStmt())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -907,7 +911,8 @@ private module ControlFlowGraphImpl {
|
||||
)
|
||||
or
|
||||
// the last node in an `ExprStmt` is the last node in the expression
|
||||
last(n.(ExprStmt).getExpr(), last, completion) and completion = NormalCompletion()
|
||||
last(n.(ExprStmt).getExpr(), last, completion) and
|
||||
completion instanceof NormalOrBooleanCompletion
|
||||
or
|
||||
// the last node in a `StmtExpr` is the last node in the statement
|
||||
last(n.(StmtExpr).getStmt(), last, completion)
|
||||
|
||||
@@ -59,9 +59,8 @@ class MapMutation extends MethodAccess {
|
||||
/** A method that queries the contents of the map it belongs to without mutating it. */
|
||||
class MapQueryMethod extends MapMethod {
|
||||
MapQueryMethod() {
|
||||
pragma[only_bind_into](this)
|
||||
.getName()
|
||||
.regexpMatch("get|containsKey|containsValue|entrySet|keySet|values|isEmpty|size")
|
||||
pragma[only_bind_into](this).getName() =
|
||||
["get", "containsKey", "containsValue", "entrySet", "keySet", "values", "isEmpty", "size"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1002,7 +1002,9 @@ class FunctionalInterface extends Interface {
|
||||
* and `double`.
|
||||
*/
|
||||
class PrimitiveType extends Type, @primitive {
|
||||
PrimitiveType() { this.getName().regexpMatch("float|double|int|boolean|short|byte|char|long") }
|
||||
PrimitiveType() {
|
||||
this.getName() = ["float", "double", "int", "boolean", "short", "byte", "char", "long"]
|
||||
}
|
||||
|
||||
/** Gets the boxed type corresponding to this primitive type. */
|
||||
BoxedType getBoxedType() { result.getPrimitiveType() = this }
|
||||
@@ -1217,9 +1219,9 @@ predicate erasedHaveIntersection(RefType t1, RefType t2) {
|
||||
class IntegralType extends Type {
|
||||
IntegralType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name.regexpMatch("byte|char|short|int|long")
|
||||
name = ["byte", "char", "short", "int", "long"]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1228,7 +1230,7 @@ class IntegralType extends Type {
|
||||
class BooleanType extends Type {
|
||||
BooleanType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name = "boolean"
|
||||
)
|
||||
@@ -1239,7 +1241,7 @@ class BooleanType extends Type {
|
||||
class CharacterType extends Type {
|
||||
CharacterType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name = "char"
|
||||
)
|
||||
@@ -1250,10 +1252,9 @@ class CharacterType extends Type {
|
||||
class NumericType extends Type {
|
||||
NumericType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or
|
||||
name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name.regexpMatch("byte|short|int|long|double|float")
|
||||
name = ["byte", "short", "int", "long", "double", "float"]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1262,9 +1263,9 @@ class NumericType extends Type {
|
||||
class NumericOrCharType extends Type {
|
||||
NumericOrCharType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name.regexpMatch("byte|char|short|int|long|double|float")
|
||||
name = ["byte", "char", "short", "int", "long", "double", "float"]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1273,9 +1274,9 @@ class NumericOrCharType extends Type {
|
||||
class FloatingPointType extends Type {
|
||||
FloatingPointType() {
|
||||
exists(string name |
|
||||
name = this.(PrimitiveType).getName() or name = this.(BoxedType).getPrimitiveType().getName()
|
||||
name = [this.(PrimitiveType).getName(), this.(BoxedType).getPrimitiveType().getName()]
|
||||
|
|
||||
name.regexpMatch("float|double")
|
||||
name = ["float", "double"]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,15 +337,15 @@ private predicate safeCast(Type fromtyp, Type totyp) {
|
||||
exists(PrimitiveType pfrom, PrimitiveType pto | pfrom = fromtyp and pto = totyp |
|
||||
pfrom = pto
|
||||
or
|
||||
pfrom.hasName("char") and pto.getName().regexpMatch("int|long|float|double")
|
||||
pfrom.hasName("char") and pto.hasName(["int", "long", "float", "double"])
|
||||
or
|
||||
pfrom.hasName("byte") and pto.getName().regexpMatch("short|int|long|float|double")
|
||||
pfrom.hasName("byte") and pto.hasName(["short", "int", "long", "float", "double"])
|
||||
or
|
||||
pfrom.hasName("short") and pto.getName().regexpMatch("int|long|float|double")
|
||||
pfrom.hasName("short") and pto.hasName(["int", "long", "float", "double"])
|
||||
or
|
||||
pfrom.hasName("int") and pto.getName().regexpMatch("long|float|double")
|
||||
pfrom.hasName("int") and pto.hasName(["long", "float", "double"])
|
||||
or
|
||||
pfrom.hasName("long") and pto.getName().regexpMatch("float|double")
|
||||
pfrom.hasName("long") and pto.hasName(["float", "double"])
|
||||
or
|
||||
pfrom.hasName("float") and pto.hasName("double")
|
||||
or
|
||||
|
||||
@@ -10,7 +10,7 @@ private module DispatchImpl {
|
||||
DataFlowCallable viableCallable(DataFlowCall c) {
|
||||
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
|
||||
or
|
||||
result.(SummarizedCallable).asCallable() = c.asCall().getCallee().getSourceDeclaration()
|
||||
result.asCallable().(SummarizedCallable) = c.asCall().getCallee().getSourceDeclaration()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +118,7 @@ private module DispatchImpl {
|
||||
not failsUnification(t, t2)
|
||||
)
|
||||
or
|
||||
result.asCallable() = def and result instanceof SummarizedCallable
|
||||
result.asCallable() = def and def instanceof SummarizedCallable
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -216,10 +216,9 @@ private module LambdaFlow {
|
||||
or
|
||||
// jump step
|
||||
exists(Node mid, DataFlowType t0 |
|
||||
revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and
|
||||
revLambdaFlow(lambdaCall, kind, mid, t0, _, _, lastCall) and
|
||||
toReturn = false and
|
||||
toJump = true and
|
||||
lastCall = TDataFlowCallNone()
|
||||
toJump = true
|
||||
|
|
||||
jumpStepCached(node, mid) and
|
||||
t = t0
|
||||
@@ -789,24 +788,31 @@ private module Cached {
|
||||
cached
|
||||
predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) }
|
||||
|
||||
cached
|
||||
predicate storeSet(
|
||||
Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType
|
||||
) {
|
||||
storeStep(node1, c, node2) and
|
||||
contentType = getNodeDataFlowType(node1) and
|
||||
containerType = getNodeDataFlowType(node2)
|
||||
or
|
||||
exists(Node n1, Node n2 |
|
||||
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
|
||||
n2 = node2.(PostUpdateNode).getPreUpdateNode()
|
||||
|
|
||||
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
|
||||
or
|
||||
readSet(n2, c, n1) and
|
||||
contentType = getNodeDataFlowType(n1) and
|
||||
containerType = getNodeDataFlowType(n2)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate store(
|
||||
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
|
||||
) {
|
||||
exists(ContentSet cs | c = cs.getAStoreContent() |
|
||||
storeStep(node1, cs, node2) and
|
||||
contentType = getNodeDataFlowType(node1) and
|
||||
containerType = getNodeDataFlowType(node2)
|
||||
or
|
||||
exists(Node n1, Node n2 |
|
||||
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
|
||||
n2 = node2.(PostUpdateNode).getPreUpdateNode()
|
||||
|
|
||||
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, cs, contentType), n1)
|
||||
or
|
||||
readSet(n2, cs, n1) and
|
||||
contentType = getNodeDataFlowType(n1) and
|
||||
containerType = getNodeDataFlowType(n2)
|
||||
)
|
||||
exists(ContentSet cs |
|
||||
c = cs.getAStoreContent() and storeSet(node1, cs, node2, contentType, containerType)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,14 +14,14 @@ newtype TNode =
|
||||
not e.getParent*() instanceof Annotation
|
||||
} or
|
||||
TExplicitParameterNode(Parameter p) {
|
||||
exists(p.getCallable().getBody()) or p.getCallable() = any(SummarizedCallable sc).asCallable()
|
||||
exists(p.getCallable().getBody()) or p.getCallable() instanceof SummarizedCallable
|
||||
} or
|
||||
TImplicitVarargsArray(Call c) {
|
||||
c.getCallee().isVarargs() and
|
||||
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
|
||||
} or
|
||||
TInstanceParameterNode(Callable c) {
|
||||
(exists(c.getBody()) or c = any(SummarizedCallable sc).asCallable()) and
|
||||
(exists(c.getBody()) or c instanceof SummarizedCallable) and
|
||||
not c.isStatic()
|
||||
} or
|
||||
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
|
||||
@@ -336,7 +336,7 @@ module Private {
|
||||
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
|
||||
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
|
||||
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
|
||||
n = TSummaryInternalNode(result, _) or
|
||||
n = TSummaryInternalNode(result.asCallable(), _) or
|
||||
result.asFieldScope() = n.(FieldValueNode).getField()
|
||||
}
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
/** Gets the data flow node that this call targets. */
|
||||
Node getReceiver() { result = receiver }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result = c }
|
||||
override DataFlowCallable getEnclosingCallable() { result.asCallable() = c }
|
||||
|
||||
override string toString() { result = "[summary] call to " + receiver + " in " + c }
|
||||
|
||||
@@ -378,7 +378,7 @@ predicate forceHighPrecision(Content c) {
|
||||
predicate nodeIsHidden(Node n) {
|
||||
n instanceof SummaryNode
|
||||
or
|
||||
n.(ParameterNode).isParameterOf(any(SummarizedCallable c).asCallable(), _)
|
||||
n.(ParameterNode).isParameterOf(any(SummarizedCallable c), _)
|
||||
}
|
||||
|
||||
class LambdaCallKind = Method; // the "apply" method in the functional interface
|
||||
|
||||
@@ -75,7 +75,9 @@ private module ThisFlow {
|
||||
* local (intra-procedural) steps.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate localFlow(Node node1, Node node2) { localFlowStep*(node1, node2) }
|
||||
predicate localFlow(Node node1, Node node2) { node1 = node2 or localFlowStepPlus(node1, node2) }
|
||||
|
||||
private predicate localFlowStepPlus(Node node1, Node node2) = fastTC(localFlowStep/2)(node1, node2)
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `e1` to `e2` in zero or more
|
||||
@@ -97,27 +99,43 @@ predicate hasNonlocalValue(FieldRead fr) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` in one local step.
|
||||
*/
|
||||
predicate localFlowStep(Node node1, Node node2) {
|
||||
simpleLocalFlowStep(node1, node2)
|
||||
or
|
||||
adjacentUseUse(node1.asExpr(), node2.asExpr())
|
||||
or
|
||||
// Simple flow through library code is included in the exposed local
|
||||
// step relation, even though flow is technically inter-procedural
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStep(node1, node2, true)
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` in one local step.
|
||||
*/
|
||||
cached
|
||||
predicate localFlowStep(Node node1, Node node2) {
|
||||
simpleLocalFlowStep0(node1, node2)
|
||||
or
|
||||
adjacentUseUse(node1.asExpr(), node2.asExpr())
|
||||
or
|
||||
// Simple flow through library code is included in the exposed local
|
||||
// step relation, even though flow is technically inter-procedural
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(node1, node2, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* This is the local flow predicate that's used as a building block in global
|
||||
* data flow. It may have less flow than the `localFlowStep` predicate.
|
||||
*/
|
||||
cached
|
||||
predicate simpleLocalFlowStep(Node node1, Node node2) {
|
||||
simpleLocalFlowStep0(node1, node2)
|
||||
or
|
||||
any(AdditionalValueStep a).step(node1, node2) and
|
||||
pragma[only_bind_out](node1.getEnclosingCallable()) =
|
||||
pragma[only_bind_out](node2.getEnclosingCallable()) and
|
||||
// prevent recursive call
|
||||
(any(AdditionalValueStep a).step(_, _) implies any())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* This is the local flow predicate that's used as a building block in global
|
||||
* data flow. It may have less flow than the `localFlowStep` predicate.
|
||||
*/
|
||||
cached
|
||||
predicate simpleLocalFlowStep(Node node1, Node node2) {
|
||||
import Cached
|
||||
|
||||
private predicate simpleLocalFlowStep0(Node node1, Node node2) {
|
||||
TaintTrackingUtil::forceCachingInSameStage() and
|
||||
// Variable flow steps through adjacent def-use and use-use pairs.
|
||||
exists(SsaExplicitUpdate upd |
|
||||
@@ -136,7 +154,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
|
||||
not exists(FieldRead fr |
|
||||
hasNonlocalValue(fr) and fr.getField().isStatic() and fr = node1.asExpr()
|
||||
) and
|
||||
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(node1)
|
||||
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(node1, _)
|
||||
or
|
||||
ThisFlow::adjacentThisRefs(node1, node2)
|
||||
or
|
||||
@@ -166,10 +184,6 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
|
||||
or
|
||||
any(AdditionalValueStep a).step(node1, node2) and
|
||||
pragma[only_bind_out](node1.getEnclosingCallable()) =
|
||||
pragma[only_bind_out](node2.getEnclosingCallable())
|
||||
}
|
||||
|
||||
private newtype TContent =
|
||||
|
||||
@@ -195,7 +195,10 @@ module Public {
|
||||
}
|
||||
|
||||
/** A callable with a flow summary. */
|
||||
abstract class SummarizedCallable extends DataFlowCallable {
|
||||
abstract class SummarizedCallable extends SummarizedCallableBase {
|
||||
bindingset[this]
|
||||
SummarizedCallable() { any() }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from `input` to `output` through this callable.
|
||||
*
|
||||
@@ -493,7 +496,7 @@ module Private {
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
parameterReadState(c, state, pos) and
|
||||
result.(ParamNode).isParameterOf(c, pos)
|
||||
result.(ParamNode).isParameterOf(inject(c), pos)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -621,7 +624,7 @@ module Private {
|
||||
predicate summaryPostUpdateNode(Node post, Node pre) {
|
||||
exists(SummarizedCallable c, ParameterPosition pos |
|
||||
isParameterPostUpdate(post, c, pos) and
|
||||
pre.(ParamNode).isParameterOf(c, pos)
|
||||
pre.(ParamNode).isParameterOf(inject(c), pos)
|
||||
)
|
||||
or
|
||||
exists(SummarizedCallable callable, SummaryComponentStack s |
|
||||
@@ -644,7 +647,7 @@ module Private {
|
||||
* node, and back out to `p`.
|
||||
*/
|
||||
predicate summaryAllowParameterReturnInSelf(ParamNode p) {
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(c, ppos) |
|
||||
exists(SummarizedCallable c, ParameterPosition ppos | p.isParameterOf(inject(c), ppos) |
|
||||
exists(SummaryComponentStack inputContents, SummaryComponentStack outputContents |
|
||||
summary(c, inputContents, outputContents, _) and
|
||||
inputContents.bottom() = pragma[only_bind_into](TArgumentSummaryComponent(ppos)) and
|
||||
@@ -748,13 +751,16 @@ module Private {
|
||||
private predicate viableParam(
|
||||
DataFlowCall call, SummarizedCallable sc, ParameterPosition ppos, ParamNode p
|
||||
) {
|
||||
p.isParameterOf(sc, ppos) and
|
||||
sc = viableCallable(call)
|
||||
exists(DataFlowCallable c |
|
||||
c = inject(sc) and
|
||||
p.isParameterOf(c, ppos) and
|
||||
c = viableCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg) {
|
||||
exists(ParameterPosition ppos, SummarizedCallable sc |
|
||||
private ParamNode summaryArgParam0(DataFlowCall call, ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParameterPosition ppos |
|
||||
argumentPositionMatch(call, arg, ppos) and
|
||||
viableParam(call, sc, ppos, result)
|
||||
)
|
||||
@@ -768,9 +774,9 @@ module Private {
|
||||
* or expects contents.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate prohibitsUseUseFlow(ArgNode arg) {
|
||||
predicate prohibitsUseUseFlow(ArgNode arg, SummarizedCallable sc) {
|
||||
exists(ParamNode p, Node mid, ParameterPosition ppos, Node ret |
|
||||
p = summaryArgParam0(_, arg) and
|
||||
p = summaryArgParam0(_, arg, sc) and
|
||||
p.isParameterOf(_, ppos) and
|
||||
summaryLocalStep(p, mid, true) and
|
||||
summaryLocalStep(mid, ret, true) and
|
||||
@@ -782,27 +788,42 @@ module Private {
|
||||
}
|
||||
|
||||
bindingset[ret]
|
||||
private ParamNode summaryArgParam(ArgNode arg, ReturnNodeExt ret, OutNodeExt out) {
|
||||
private ParamNode summaryArgParam(
|
||||
ArgNode arg, ReturnNodeExt ret, OutNodeExt out, SummarizedCallable sc
|
||||
) {
|
||||
exists(DataFlowCall call, ReturnKindExt rk |
|
||||
result = summaryArgParam0(call, arg) and
|
||||
pragma[only_bind_out](ret).getKind() = pragma[only_bind_into](rk) and
|
||||
result = summaryArgParam0(call, arg, sc) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
out = pragma[only_bind_into](rk).getAnOutNode(call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` flows to `out` using a simple flow summary, that is, a flow
|
||||
* summary without reads and stores.
|
||||
* Holds if `arg` flows to `out` using a simple value-preserving flow
|
||||
* summary, that is, a flow summary without reads and stores.
|
||||
*
|
||||
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStep(ArgNode arg, Node out, boolean preservesValue) {
|
||||
exists(ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out), ret, preservesValue)
|
||||
predicate summaryThroughStepValue(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnKind rk, ReturnNode ret, DataFlowCall call |
|
||||
summaryLocalStep(summaryArgParam0(call, arg, sc), ret, true) and
|
||||
ret.getKind() = pragma[only_bind_into](rk) and
|
||||
out = getAnOutNode(call, pragma[only_bind_into](rk))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` flows to `out` using a simple flow summary involving taint
|
||||
* step, that is, a flow summary without reads and stores.
|
||||
*
|
||||
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryThroughStepTaint(ArgNode arg, Node out, SummarizedCallable sc) {
|
||||
exists(ReturnNodeExt ret | summaryLocalStep(summaryArgParam(arg, ret, out, sc), ret, false))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a read(+taint) of `c` from `arg` to `out` using a
|
||||
* flow summary.
|
||||
@@ -810,9 +831,9 @@ module Private {
|
||||
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out) {
|
||||
predicate summaryGetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryReadStep(summaryArgParam(arg, ret, out), c, mid) and
|
||||
summaryReadStep(summaryArgParam(arg, ret, out, sc), c, mid) and
|
||||
summaryLocalStep(mid, ret, _)
|
||||
)
|
||||
}
|
||||
@@ -824,9 +845,9 @@ module Private {
|
||||
* NOTE: This step should not be used in global data-flow/taint-tracking, but may
|
||||
* be useful to include in the exposed local data-flow/taint-tracking relations.
|
||||
*/
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out) {
|
||||
predicate summarySetterStep(ArgNode arg, ContentSet c, Node out, SummarizedCallable sc) {
|
||||
exists(Node mid, ReturnNodeExt ret |
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out), mid, _) and
|
||||
summaryLocalStep(summaryArgParam(arg, ret, out, sc), mid, _) and
|
||||
summaryStoreStep(mid, c, ret)
|
||||
)
|
||||
}
|
||||
@@ -910,11 +931,18 @@ module Private {
|
||||
private class SummarizedCallableExternal extends SummarizedCallable {
|
||||
SummarizedCallableExternal() { summaryElement(this, _, _, _, _) }
|
||||
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
AccessPath inSpec, AccessPath outSpec, string kind
|
||||
) {
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false) and
|
||||
not this.clearsContent(_, _)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
|
||||
summaryElement(this, inSpec, outSpec, kind, false)
|
||||
or
|
||||
summaryElement(this, inSpec, outSpec, kind, true) and
|
||||
not summaryElement(this, _, _, _, false)
|
||||
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
|
||||
}
|
||||
|
||||
override predicate propagatesFlow(
|
||||
@@ -931,7 +959,7 @@ module Private {
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAutoGenerated() { summaryElement(this, _, _, _, true) }
|
||||
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
|
||||
}
|
||||
|
||||
/** Holds if component `c` of specification `spec` cannot be parsed. */
|
||||
@@ -1067,7 +1095,7 @@ module Private {
|
||||
/** Provides a query predicate for outputting a set of relevant flow summaries. */
|
||||
module TestOutput {
|
||||
/** A flow summary to include in the `summary/3` query predicate. */
|
||||
abstract class RelevantSummarizedCallable extends SummarizedCallable {
|
||||
abstract class RelevantSummarizedCallable instanceof SummarizedCallable {
|
||||
/** Gets the string representation of this callable used by `summary/1`. */
|
||||
abstract string getCallableCsv();
|
||||
|
||||
@@ -1075,8 +1103,10 @@ module Private {
|
||||
predicate relevantSummary(
|
||||
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
|
||||
) {
|
||||
this.propagatesFlow(input, output, preservesValue)
|
||||
super.propagatesFlow(input, output, preservesValue)
|
||||
}
|
||||
|
||||
string toString() { result = super.toString() }
|
||||
}
|
||||
|
||||
/** Render the kind in the format used in flow summaries. */
|
||||
@@ -1087,7 +1117,7 @@ module Private {
|
||||
}
|
||||
|
||||
private string renderGenerated(RelevantSummarizedCallable c) {
|
||||
if c.isAutoGenerated() then result = "generated:" else result = ""
|
||||
if c.(SummarizedCallable).isAutoGenerated() then result = "generated:" else result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1117,19 +1147,21 @@ module Private {
|
||||
*/
|
||||
module RenderSummarizedCallable {
|
||||
/** A summarized callable to include in the graph. */
|
||||
abstract class RelevantSummarizedCallable extends SummarizedCallable { }
|
||||
abstract class RelevantSummarizedCallable instanceof SummarizedCallable {
|
||||
string toString() { result = super.toString() }
|
||||
}
|
||||
|
||||
private newtype TNodeOrCall =
|
||||
MkNode(Node n) {
|
||||
exists(RelevantSummarizedCallable c |
|
||||
n = summaryNode(c, _)
|
||||
or
|
||||
n.(ParamNode).isParameterOf(c, _)
|
||||
n.(ParamNode).isParameterOf(inject(c), _)
|
||||
)
|
||||
} or
|
||||
MkCall(DataFlowCall call) {
|
||||
call = summaryDataFlowCall(_) and
|
||||
call.getEnclosingCallable() instanceof RelevantSummarizedCallable
|
||||
call.getEnclosingCallable() = inject(any(RelevantSummarizedCallable c))
|
||||
}
|
||||
|
||||
private class NodeOrCall extends TNodeOrCall {
|
||||
|
||||
@@ -14,6 +14,10 @@ private module FlowSummaries {
|
||||
private import semmle.code.java.dataflow.FlowSummary as F
|
||||
}
|
||||
|
||||
class SummarizedCallableBase = Callable;
|
||||
|
||||
DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c }
|
||||
|
||||
/** Gets the parameter position of the instance parameter. */
|
||||
int instanceParameterPosition() { result = -1 }
|
||||
|
||||
@@ -28,7 +32,7 @@ DataFlowType getContentType(Content c) { result = c.getType() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
|
||||
result = getErasedRepr(c.asCallable().getReturnType()) and
|
||||
result = getErasedRepr(c.getReturnType()) and
|
||||
exists(rk)
|
||||
}
|
||||
|
||||
@@ -56,14 +60,12 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
|
||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||
* stating whether the summary is autogenerated.
|
||||
*/
|
||||
predicate summaryElement(
|
||||
DataFlowCallable c, string input, string output, string kind, boolean generated
|
||||
) {
|
||||
predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) {
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and
|
||||
c.asCallable() = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
c = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,14 +51,14 @@ private module Cached {
|
||||
or
|
||||
// Simple flow through library code is included in the exposed local
|
||||
// step relation, even though flow is technically inter-procedural
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStep(src, sink, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _)
|
||||
or
|
||||
// Treat container flow as taint for the local taint flow relation
|
||||
exists(DataFlow::Content c | containerContent(c) |
|
||||
readStep(src, c, sink) or
|
||||
storeStep(src, c, sink) or
|
||||
FlowSummaryImpl::Private::Steps::summaryGetterStep(src, c, sink) or
|
||||
FlowSummaryImpl::Private::Steps::summarySetterStep(src, c, sink)
|
||||
FlowSummaryImpl::Private::Steps::summaryGetterStep(src, c, sink, _) or
|
||||
FlowSummaryImpl::Private::Steps::summarySetterStep(src, c, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ private predicate localAdditionalTaintUpdateStep(Expr src, Expr sink) {
|
||||
|
||||
private class BulkData extends RefType {
|
||||
BulkData() {
|
||||
this.(Array).getElementType().(PrimitiveType).getName().regexpMatch("byte|char")
|
||||
this.(Array).getElementType().(PrimitiveType).hasName(["byte", "char"])
|
||||
or
|
||||
exists(RefType t | this.getASourceSupertype*() = t |
|
||||
t.hasQualifiedName("java.io", "InputStream") or
|
||||
@@ -321,7 +321,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
|
||||
exists(Method springResponseEntityOfOk |
|
||||
sink.getMethod() = springResponseEntityOfOk and
|
||||
springResponseEntityOfOk.getDeclaringType() instanceof SpringResponseEntity and
|
||||
springResponseEntityOfOk.getName().regexpMatch("ok|of") and
|
||||
springResponseEntityOfOk.hasName(["ok", "of"]) and
|
||||
tracked = sink.getArgument(0) and
|
||||
tracked.getType() instanceof TypeString
|
||||
)
|
||||
@@ -329,7 +329,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
|
||||
exists(Method springResponseEntityBody |
|
||||
sink.getMethod() = springResponseEntityBody and
|
||||
springResponseEntityBody.getDeclaringType() instanceof SpringResponseEntityBodyBuilder and
|
||||
springResponseEntityBody.getName().regexpMatch("body") and
|
||||
springResponseEntityBody.hasName("body") and
|
||||
tracked = sink.getArgument(0) and
|
||||
tracked.getType() instanceof TypeString
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ class FitFixtureEntryPoint extends CallableEntryPoint {
|
||||
* FitNesse entry points externally defined.
|
||||
*/
|
||||
class FitNesseSlimEntryPointData extends ExternalData {
|
||||
FitNesseSlimEntryPointData() { getDataPath().matches("fitnesse.csv") }
|
||||
FitNesseSlimEntryPointData() { getDataPath() = "fitnesse.csv" }
|
||||
|
||||
/**
|
||||
* Gets the class name.
|
||||
|
||||
@@ -85,7 +85,7 @@ class MockitoInitedTest extends Class {
|
||||
*/
|
||||
class MockitoAnnotation extends Annotation {
|
||||
MockitoAnnotation() {
|
||||
this.getType().getPackage().getName().matches("org.mockito") or
|
||||
this.getType().getPackage().hasName("org.mockito") or
|
||||
this.getType().getPackage().getName().matches("org.mockito.%")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,22 @@ class LiveLiteral extends MethodAccess {
|
||||
not this.getEnclosingCallable() instanceof LiveLiteralMethod
|
||||
}
|
||||
|
||||
/** Gets the constant value that backs this live literal. */
|
||||
/**
|
||||
* Live literal classes consist of the following:
|
||||
* - A private field holding the constant value that backs this live literal.
|
||||
* - A private getter to access the constant value.
|
||||
* - A public getter that either calls the private getter and returns its result or,
|
||||
* if live literals are activated, returns the value of a dynamic state object that is initialized with
|
||||
* the constant value.
|
||||
*
|
||||
* This predicate gets the constant value held by the private field.
|
||||
*/
|
||||
CompileTimeConstantExpr getValue() {
|
||||
result =
|
||||
any(ReturnStmt r | this.getMethod().calls*(r.getEnclosingCallable()))
|
||||
.getResult()
|
||||
.(VarAccess)
|
||||
.getVariable()
|
||||
.getInitializer()
|
||||
exists(MethodAccess getterCall, VarAccess va |
|
||||
methodReturns(this.getMethod(), getterCall) and
|
||||
methodReturns(getterCall.getMethod(), va) and
|
||||
result = va.getVariable().getInitializer()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getValue().toString() }
|
||||
@@ -31,3 +39,10 @@ class LiveLiteral extends MethodAccess {
|
||||
class LiveLiteralMethod extends Method {
|
||||
LiveLiteralMethod() { this.getDeclaringType().getName().matches("LiveLiterals$%") }
|
||||
}
|
||||
|
||||
private predicate methodReturns(Method m, Expr res) {
|
||||
exists(ReturnStmt r |
|
||||
r.getResult() = res and
|
||||
r.getEnclosingCallable() = m
|
||||
)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ private class SliceProviderLifecycleStep extends AdditionalValueStep {
|
||||
|
||||
private class SliceActionsInheritTaint extends DataFlow::SyntheticFieldContent,
|
||||
TaintInheritingContent {
|
||||
SliceActionsInheritTaint() { this.getField().matches("androidx.slice.Slice.action") }
|
||||
SliceActionsInheritTaint() { this.getField() = "androidx.slice.Slice.action" }
|
||||
}
|
||||
|
||||
private class SliceBuildersSummaryModels extends SummaryModelCsv {
|
||||
|
||||
@@ -20,7 +20,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
|
||||
DefaultSafeExternalApiMethod() {
|
||||
this instanceof EqualsMethod
|
||||
or
|
||||
this.getName().regexpMatch("size|length|compareTo|getClass|lastIndexOf")
|
||||
this.hasName(["size", "length", "compareTo", "getClass", "lastIndexOf"])
|
||||
or
|
||||
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "Validate")
|
||||
or
|
||||
@@ -42,7 +42,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
|
||||
this.getName() = "isDigit"
|
||||
or
|
||||
this.getDeclaringType().hasQualifiedName("java.lang", "String") and
|
||||
this.getName().regexpMatch("equalsIgnoreCase|regionMatches")
|
||||
this.hasName(["equalsIgnoreCase", "regionMatches"])
|
||||
or
|
||||
this.getDeclaringType().hasQualifiedName("java.lang", "Boolean") and
|
||||
this.getName() = "parseBoolean"
|
||||
@@ -51,7 +51,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
|
||||
this.getName() = "closeQuietly"
|
||||
or
|
||||
this.getDeclaringType().hasQualifiedName("org.springframework.util", "StringUtils") and
|
||||
this.getName().regexpMatch("hasText|isEmpty")
|
||||
this.hasName(["hasText", "isEmpty"])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class ExternalApi extends Callable {
|
||||
|
||||
/** Holds if this API has a supported summary. */
|
||||
predicate hasSummary() {
|
||||
this = any(SummarizedCallable sc).asCallable() or
|
||||
this instanceof SummarizedCallable or
|
||||
TaintTracking::localAdditionalTaintStep(this.getAnInput(), _)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ predicate looksLikeResolveClassStep(DataFlow::Node fromNode, DataFlow::Node toNo
|
||||
m = ma.getMethod() and arg = ma.getArgument(i)
|
||||
|
|
||||
m.getReturnType() instanceof TypeClass and
|
||||
m.getName().toLowerCase().regexpMatch("resolve|load|class|type") and
|
||||
m.getName().toLowerCase() = ["resolve", "load", "class", "type"] and
|
||||
arg.getType() instanceof TypeString and
|
||||
arg = fromNode.asExpr() and
|
||||
ma = toNode.asExpr()
|
||||
@@ -52,7 +52,7 @@ predicate looksLikeInstantiateClassStep(DataFlow::Node fromNode, DataFlow::Node
|
||||
m = ma.getMethod() and arg = ma.getArgument(i)
|
||||
|
|
||||
m.getReturnType() instanceof TypeObject and
|
||||
m.getName().toLowerCase().regexpMatch("instantiate|instance|create|make|getbean") and
|
||||
m.getName().toLowerCase() = ["instantiate", "instance", "create", "make", "getbean"] and
|
||||
arg.getType() instanceof TypeClass and
|
||||
arg = fromNode.asExpr() and
|
||||
ma = toNode.asExpr()
|
||||
|
||||
@@ -134,6 +134,6 @@ predicate springUrlRedirectTaintStep(DataFlow::Node fromNode, DataFlow::Node toN
|
||||
predicate nonLocationHeaderSanitizer(DataFlow::Node node) {
|
||||
exists(HttpHeadersAddSetMethodAccess ma, Argument firstArg | node.asExpr() = ma.getArgument(1) |
|
||||
firstArg = ma.getArgument(0) and
|
||||
not firstArg.(CompileTimeConstantExpr).getStringValue().matches("Location")
|
||||
not firstArg.(CompileTimeConstantExpr).getStringValue() = "Location"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -97,26 +97,6 @@ private class SafeValidatorFlowConfig extends DataFlow3::Configuration {
|
||||
override int fieldFlowBranchLimit() { result = 0 }
|
||||
}
|
||||
|
||||
/** The class `org.dom4j.DocumentHelper`. */
|
||||
class DocumentHelper extends RefType {
|
||||
DocumentHelper() { this.hasQualifiedName("org.dom4j", "DocumentHelper") }
|
||||
}
|
||||
|
||||
/** A call to `DocumentHelper.parseText`. */
|
||||
class DocumentHelperParseText extends XmlParserCall {
|
||||
DocumentHelperParseText() {
|
||||
exists(Method m |
|
||||
this.getMethod() = m and
|
||||
m.getDeclaringType() instanceof DocumentHelper and
|
||||
m.hasName("parseText")
|
||||
)
|
||||
}
|
||||
|
||||
override Expr getSink() { result = this.getArgument(0) }
|
||||
|
||||
override predicate isSafe() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The classes `org.apache.commons.digester3.Digester`, `org.apache.commons.digester.Digester` or `org.apache.tomcat.util.digester.Digester`.
|
||||
*/
|
||||
|
||||
@@ -111,7 +111,7 @@ string asPartialModel(TargetApiSpecific api) {
|
||||
}
|
||||
|
||||
private predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
|
||||
t.getName().regexpMatch("byte|char|Byte|Character")
|
||||
t.hasName(["byte", "char", "Byte", "Character"])
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,40 +1,26 @@
|
||||
edges
|
||||
| XXE.java:22:43:22:66 | getInputStream(...) : ServletInputStream | XXE.java:24:18:24:35 | servletInputStream |
|
||||
| XXE.java:29:23:29:41 | getReader(...) : BufferedReader | XXE.java:32:17:32:18 | br : BufferedReader |
|
||||
| XXE.java:32:17:32:18 | br : BufferedReader | XXE.java:32:17:32:29 | readLine(...) : String |
|
||||
| XXE.java:32:17:32:29 | readLine(...) : String | XXE.java:33:22:33:24 | str : String |
|
||||
| XXE.java:33:4:33:13 | listString [post update] : StringBuilder | XXE.java:35:48:35:57 | listString : StringBuilder |
|
||||
| XXE.java:33:22:33:24 | str : String | XXE.java:33:4:33:13 | listString [post update] : StringBuilder |
|
||||
| XXE.java:35:48:35:57 | listString : StringBuilder | XXE.java:35:48:35:68 | toString(...) |
|
||||
| XXE.java:40:43:40:66 | getInputStream(...) : ServletInputStream | XXE.java:44:42:44:59 | servletInputStream : ServletInputStream |
|
||||
| XXE.java:44:25:44:60 | new StreamSource(...) : StreamSource | XXE.java:45:22:45:27 | source |
|
||||
| XXE.java:44:42:44:59 | servletInputStream : ServletInputStream | XXE.java:44:25:44:60 | new StreamSource(...) : StreamSource |
|
||||
| XXE.java:50:43:50:66 | getInputStream(...) : ServletInputStream | XXE.java:51:42:51:59 | servletInputStream : ServletInputStream |
|
||||
| XXE.java:51:27:51:60 | new XMLDecoder(...) : XMLDecoder | XXE.java:52:3:52:12 | xmlDecoder |
|
||||
| XXE.java:51:42:51:59 | servletInputStream : ServletInputStream | XXE.java:51:27:51:60 | new XMLDecoder(...) : XMLDecoder |
|
||||
| XXE.java:29:43:29:66 | getInputStream(...) : ServletInputStream | XXE.java:33:42:33:59 | servletInputStream : ServletInputStream |
|
||||
| XXE.java:33:25:33:60 | new StreamSource(...) : StreamSource | XXE.java:34:22:34:27 | source |
|
||||
| XXE.java:33:42:33:59 | servletInputStream : ServletInputStream | XXE.java:33:25:33:60 | new StreamSource(...) : StreamSource |
|
||||
| XXE.java:39:43:39:66 | getInputStream(...) : ServletInputStream | XXE.java:40:42:40:59 | servletInputStream : ServletInputStream |
|
||||
| XXE.java:40:27:40:60 | new XMLDecoder(...) : XMLDecoder | XXE.java:41:3:41:12 | xmlDecoder |
|
||||
| XXE.java:40:42:40:59 | servletInputStream : ServletInputStream | XXE.java:40:27:40:60 | new XMLDecoder(...) : XMLDecoder |
|
||||
nodes
|
||||
| XXE.java:22:43:22:66 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XXE.java:24:18:24:35 | servletInputStream | semmle.label | servletInputStream |
|
||||
| XXE.java:29:23:29:41 | getReader(...) : BufferedReader | semmle.label | getReader(...) : BufferedReader |
|
||||
| XXE.java:32:17:32:18 | br : BufferedReader | semmle.label | br : BufferedReader |
|
||||
| XXE.java:32:17:32:29 | readLine(...) : String | semmle.label | readLine(...) : String |
|
||||
| XXE.java:33:4:33:13 | listString [post update] : StringBuilder | semmle.label | listString [post update] : StringBuilder |
|
||||
| XXE.java:33:22:33:24 | str : String | semmle.label | str : String |
|
||||
| XXE.java:35:48:35:57 | listString : StringBuilder | semmle.label | listString : StringBuilder |
|
||||
| XXE.java:35:48:35:68 | toString(...) | semmle.label | toString(...) |
|
||||
| XXE.java:40:43:40:66 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XXE.java:44:25:44:60 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
||||
| XXE.java:44:42:44:59 | servletInputStream : ServletInputStream | semmle.label | servletInputStream : ServletInputStream |
|
||||
| XXE.java:45:22:45:27 | source | semmle.label | source |
|
||||
| XXE.java:50:43:50:66 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XXE.java:51:27:51:60 | new XMLDecoder(...) : XMLDecoder | semmle.label | new XMLDecoder(...) : XMLDecoder |
|
||||
| XXE.java:51:42:51:59 | servletInputStream : ServletInputStream | semmle.label | servletInputStream : ServletInputStream |
|
||||
| XXE.java:52:3:52:12 | xmlDecoder | semmle.label | xmlDecoder |
|
||||
| XXE.java:57:49:57:72 | getInputStream(...) | semmle.label | getInputStream(...) |
|
||||
| XXE.java:29:43:29:66 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XXE.java:33:25:33:60 | new StreamSource(...) : StreamSource | semmle.label | new StreamSource(...) : StreamSource |
|
||||
| XXE.java:33:42:33:59 | servletInputStream : ServletInputStream | semmle.label | servletInputStream : ServletInputStream |
|
||||
| XXE.java:34:22:34:27 | source | semmle.label | source |
|
||||
| XXE.java:39:43:39:66 | getInputStream(...) : ServletInputStream | semmle.label | getInputStream(...) : ServletInputStream |
|
||||
| XXE.java:40:27:40:60 | new XMLDecoder(...) : XMLDecoder | semmle.label | new XMLDecoder(...) : XMLDecoder |
|
||||
| XXE.java:40:42:40:59 | servletInputStream : ServletInputStream | semmle.label | servletInputStream : ServletInputStream |
|
||||
| XXE.java:41:3:41:12 | xmlDecoder | semmle.label | xmlDecoder |
|
||||
| XXE.java:46:49:46:72 | getInputStream(...) | semmle.label | getInputStream(...) |
|
||||
subpaths
|
||||
#select
|
||||
| XXE.java:24:18:24:35 | servletInputStream | XXE.java:22:43:22:66 | getInputStream(...) : ServletInputStream | XXE.java:24:18:24:35 | servletInputStream | Unsafe parsing of XML file from $@. | XXE.java:22:43:22:66 | getInputStream(...) | user input |
|
||||
| XXE.java:35:48:35:68 | toString(...) | XXE.java:29:23:29:41 | getReader(...) : BufferedReader | XXE.java:35:48:35:68 | toString(...) | Unsafe parsing of XML file from $@. | XXE.java:29:23:29:41 | getReader(...) | user input |
|
||||
| XXE.java:45:22:45:27 | source | XXE.java:40:43:40:66 | getInputStream(...) : ServletInputStream | XXE.java:45:22:45:27 | source | Unsafe parsing of XML file from $@. | XXE.java:40:43:40:66 | getInputStream(...) | user input |
|
||||
| XXE.java:52:3:52:12 | xmlDecoder | XXE.java:50:43:50:66 | getInputStream(...) : ServletInputStream | XXE.java:52:3:52:12 | xmlDecoder | Unsafe parsing of XML file from $@. | XXE.java:50:43:50:66 | getInputStream(...) | user input |
|
||||
| XXE.java:57:49:57:72 | getInputStream(...) | XXE.java:57:49:57:72 | getInputStream(...) | XXE.java:57:49:57:72 | getInputStream(...) | Unsafe parsing of XML file from $@. | XXE.java:57:49:57:72 | getInputStream(...) | user input |
|
||||
| XXE.java:34:22:34:27 | source | XXE.java:29:43:29:66 | getInputStream(...) : ServletInputStream | XXE.java:34:22:34:27 | source | Unsafe parsing of XML file from $@. | XXE.java:29:43:29:66 | getInputStream(...) | user input |
|
||||
| XXE.java:41:3:41:12 | xmlDecoder | XXE.java:39:43:39:66 | getInputStream(...) : ServletInputStream | XXE.java:41:3:41:12 | xmlDecoder | Unsafe parsing of XML file from $@. | XXE.java:39:43:39:66 | getInputStream(...) | user input |
|
||||
| XXE.java:46:49:46:72 | getInputStream(...) | XXE.java:46:49:46:72 | getInputStream(...) | XXE.java:46:49:46:72 | getInputStream(...) | Unsafe parsing of XML file from $@. | XXE.java:46:49:46:72 | getInputStream(...) | user input |
|
||||
|
||||
@@ -21,40 +21,29 @@ public class XXE {
|
||||
public void bad1(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
ServletInputStream servletInputStream = request.getInputStream();
|
||||
Digester digester = new Digester();
|
||||
digester.parse(servletInputStream); //bad
|
||||
digester.parse(servletInputStream); // bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "bad2")
|
||||
public void bad2(HttpServletRequest request) throws Exception {
|
||||
BufferedReader br = request.getReader();
|
||||
String str = "";
|
||||
StringBuilder listString = new StringBuilder();
|
||||
while ((str = br.readLine()) != null) {
|
||||
listString.append(str).append("\n");
|
||||
}
|
||||
Document document = DocumentHelper.parseText(listString.toString()); //bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "bad3")
|
||||
public void bad3(HttpServletRequest request) throws Exception {
|
||||
ServletInputStream servletInputStream = request.getInputStream();
|
||||
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
|
||||
Schema schema = factory.newSchema();
|
||||
Validator validator = schema.newValidator();
|
||||
StreamSource source = new StreamSource(servletInputStream);
|
||||
validator.validate(source); //bad
|
||||
validator.validate(source); // bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "bad3")
|
||||
public void bad3(HttpServletRequest request) throws Exception {
|
||||
ServletInputStream servletInputStream = request.getInputStream();
|
||||
XMLDecoder xmlDecoder = new XMLDecoder(servletInputStream);
|
||||
xmlDecoder.readObject(); // bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "bad4")
|
||||
public void bad4(HttpServletRequest request) throws Exception {
|
||||
ServletInputStream servletInputStream = request.getInputStream();
|
||||
XMLDecoder xmlDecoder = new XMLDecoder(servletInputStream);
|
||||
xmlDecoder.readObject(); //bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "bad5")
|
||||
public void bad5(HttpServletRequest request) throws Exception {
|
||||
Document document = ParserHelper.loadDocument(request.getInputStream()); //bad
|
||||
Document document = ParserHelper.loadDocument(request.getInputStream()); // bad
|
||||
}
|
||||
|
||||
@PostMapping(value = "good1")
|
||||
@@ -88,4 +77,16 @@ public class XXE {
|
||||
StreamSource source = new StreamSource(listString.toString());
|
||||
validator.validate(source);
|
||||
}
|
||||
|
||||
@PostMapping(value = "good3")
|
||||
public void good3(HttpServletRequest request) throws Exception {
|
||||
BufferedReader br = request.getReader();
|
||||
String str = "";
|
||||
StringBuilder listString = new StringBuilder();
|
||||
while ((str = br.readLine()) != null) {
|
||||
listString.append(str).append("\n");
|
||||
}
|
||||
// parseText falls back to a default SAXReader, which is safe
|
||||
Document document = DocumentHelper.parseText(listString.toString()); // Safe
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,5 +53,4 @@
|
||||
| Test.kt:118:37:124:1 | { ... } | Test.kt:121:9:121:9 | <Expr>; |
|
||||
| Test.kt:118:37:124:1 | { ... } | Test.kt:122:12:122:16 | ... -> ... |
|
||||
| Test.kt:118:37:124:1 | { ... } | Test.kt:123:8:123:10 | { ... } |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:118:1:124:1 | fn_when |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:123:8:123:10 | { ... } |
|
||||
|
||||
@@ -41,4 +41,5 @@
|
||||
| Test.kt:118:37:124:1 | { ... } | Test.kt:122:12:122:16 | ... -> ... |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:118:1:124:1 | fn_when |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:123:8:123:10 | { ... } |
|
||||
| Test.kt:122:12:122:16 | ... -> ... | Test.kt:118:1:124:1 | fn_when |
|
||||
| Test.kt:123:8:123:10 | { ... } | Test.kt:118:1:124:1 | fn_when |
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
missingSuccessor
|
||||
| Test.kt:122:12:122:16 | false |
|
||||
#select
|
||||
| Test.kt:0:0:0:0 | TestKt | Class | file://:0:0:0:0 | <none> | <none> |
|
||||
| Test.kt:3:1:80:1 | Test | Class | file://:0:0:0:0 | <none> | <none> |
|
||||
@@ -257,6 +256,6 @@ missingSuccessor
|
||||
| Test.kt:121:9:121:9 | y | VarAccess | Test.kt:123:8:123:10 | { ... } | BlockStmt |
|
||||
| Test.kt:122:12:122:16 | ... -> ... | WhenBranch | Test.kt:122:12:122:16 | true | BooleanLiteral |
|
||||
| Test.kt:122:12:122:16 | <Expr>; | ExprStmt | Test.kt:122:12:122:16 | false | BooleanLiteral |
|
||||
| Test.kt:122:12:122:16 | false | BooleanLiteral | file://:0:0:0:0 | <none> | <none> |
|
||||
| Test.kt:122:12:122:16 | false | BooleanLiteral | Test.kt:118:1:124:1 | fn_when | Method |
|
||||
| Test.kt:122:12:122:16 | true | BooleanLiteral | Test.kt:122:12:122:16 | <Expr>; | ExprStmt |
|
||||
| Test.kt:123:8:123:10 | { ... } | BlockStmt | Test.kt:118:1:124:1 | fn_when | Method |
|
||||
|
||||
@@ -220,8 +220,4 @@
|
||||
| Test.kt:121:4:121:9 | ... -> ... | Test.kt:118:37:124:1 | { ... } |
|
||||
| Test.kt:121:4:121:9 | ... -> ... | Test.kt:119:2:123:12 | <Expr>; |
|
||||
| Test.kt:121:4:121:9 | ... -> ... | Test.kt:120:3:123:10 | ... -> ... |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:118:37:124:1 | { ... } |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:119:2:123:12 | <Expr>; |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:120:3:123:10 | ... -> ... |
|
||||
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:121:4:121:9 | ... -> ... |
|
||||
| Test.kt:122:12:122:16 | <Expr>; | Test.kt:122:12:122:16 | ... -> ... |
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
class Processor {
|
||||
fun <R> process(f: () -> R) : R {
|
||||
fun <R1> process(f: () -> R1) : R1 {
|
||||
return f()
|
||||
}
|
||||
|
||||
fun <T, R> process(f: (T) -> R, arg: T) : R {
|
||||
fun <T, R2> process(f: (T) -> R2, arg: T) : R2 {
|
||||
return f(arg)
|
||||
}
|
||||
|
||||
fun <T0, T1, R> process(f: (T0, T1) -> R, arg0: T0, arg1: T1) : R {
|
||||
fun <T0, T1, R3> process(f: (T0, T1) -> R3, arg0: T0, arg1: T1) : R3 {
|
||||
return f(arg0, arg1)
|
||||
}
|
||||
|
||||
fun <T, R> process(
|
||||
f: (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T) -> R,
|
||||
a: T, b: T) : R {
|
||||
fun <T, R4> process(
|
||||
f: (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T) -> R4,
|
||||
a: T, b: T) : R4 {
|
||||
return f(a,b,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a)
|
||||
}
|
||||
|
||||
fun <T, R> processExt(f: T.(T) -> R, ext: T, arg: T) : R {
|
||||
fun <T, R5> processExt(f: T.(T) -> R5, ext: T, arg: T) : R5 {
|
||||
return ext.f(arg)
|
||||
}
|
||||
}
|
||||
|
||||
20
java/ql/test/kotlin/library-tests/dataflow/summaries/list.kt
Normal file
20
java/ql/test/kotlin/library-tests/dataflow/summaries/list.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
class ListFlowTest {
|
||||
fun <T> taint(t: T) = t
|
||||
fun sink(a: Any) {}
|
||||
|
||||
fun test(l: MutableList<String>) {
|
||||
l[0] = taint("a")
|
||||
sink(l)
|
||||
sink(l[0])
|
||||
for (s in l) {
|
||||
sink(s)
|
||||
}
|
||||
|
||||
val a = arrayOf(taint("a"), "b")
|
||||
sink(a)
|
||||
sink(a[0])
|
||||
for (s in a) {
|
||||
sink(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
| list.kt:6:23:6:23 | a | list.kt:7:14:7:14 | l |
|
||||
| list.kt:6:23:6:23 | a | list.kt:8:14:8:17 | get(...) |
|
||||
| list.kt:6:23:6:23 | a | list.kt:10:18:10:18 | s |
|
||||
| list.kt:13:32:13:32 | a | list.kt:14:14:14:14 | a |
|
||||
| list.kt:13:32:13:32 | a | list.kt:15:14:15:17 | ...[...] |
|
||||
| list.kt:13:32:13:32 | a | list.kt:17:18:17:18 | s |
|
||||
19
java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql
Normal file
19
java/ql/test/kotlin/library-tests/dataflow/summaries/test.ql
Normal file
@@ -0,0 +1,19 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:mad-summaries" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().hasName("taint")
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().hasName("sink")
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
@@ -4867,20 +4867,20 @@ samConversion.kt:
|
||||
# 2| 0: [VarAccess] this.<fn>
|
||||
# 2| -1: [ThisAccess] this
|
||||
# 2| 1: [VarAccess] <fn>
|
||||
# 2| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 2| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 2| 0: [TypeAccess] Integer
|
||||
# 2| 1: [TypeAccess] Boolean
|
||||
# 17| 3: [Method] accept
|
||||
# 17| 3: [TypeAccess] boolean
|
||||
# 2| 1: [Method] accept
|
||||
# 2| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 17| 0: [Parameter] i
|
||||
# 17| 0: [TypeAccess] int
|
||||
# 2| 0: [Parameter] i
|
||||
# 2| 0: [TypeAccess] int
|
||||
# 2| 5: [BlockStmt] { ... }
|
||||
# 2| 0: [ReturnStmt] return ...
|
||||
# 2| 0: [MethodAccess] invoke(...)
|
||||
# 2| -1: [VarAccess] <fn>
|
||||
# 2| 0: [VarAccess] i
|
||||
# 2| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 2| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 2| 0: [TypeAccess] Integer
|
||||
# 2| 1: [TypeAccess] Boolean
|
||||
# 2| -3: [TypeAccess] IntPredicate
|
||||
# 2| 0: [LambdaExpr] ...->...
|
||||
# 2| -4: [AnonymousClass] new Function1<Integer,Boolean>(...) { ... }
|
||||
@@ -4918,24 +4918,24 @@ samConversion.kt:
|
||||
# 4| 0: [VarAccess] this.<fn>
|
||||
# 4| -1: [ThisAccess] this
|
||||
# 4| 1: [VarAccess] <fn>
|
||||
# 4| 1: [FieldDeclaration] Function2<Integer,Integer,Unit> <fn>;
|
||||
# 4| -1: [TypeAccess] Function2<Integer,Integer,Unit>
|
||||
# 4| 0: [TypeAccess] Integer
|
||||
# 4| 1: [TypeAccess] Integer
|
||||
# 4| 2: [TypeAccess] Unit
|
||||
# 23| 3: [Method] fn1
|
||||
# 23| 3: [TypeAccess] Unit
|
||||
# 4| 1: [Method] fn1
|
||||
# 4| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 23| 0: [Parameter] i
|
||||
# 23| 0: [TypeAccess] int
|
||||
# 23| 1: [Parameter] j
|
||||
# 23| 0: [TypeAccess] int
|
||||
# 4| 0: [Parameter] i
|
||||
# 4| 0: [TypeAccess] int
|
||||
# 4| 1: [Parameter] j
|
||||
# 4| 0: [TypeAccess] int
|
||||
# 4| 5: [BlockStmt] { ... }
|
||||
# 4| 0: [ReturnStmt] return ...
|
||||
# 4| 0: [MethodAccess] invoke(...)
|
||||
# 4| -1: [VarAccess] <fn>
|
||||
# 4| 0: [VarAccess] i
|
||||
# 4| 1: [VarAccess] j
|
||||
# 4| 1: [FieldDeclaration] Function2<Integer,Integer,Unit> <fn>;
|
||||
# 4| -1: [TypeAccess] Function2<Integer,Integer,Unit>
|
||||
# 4| 0: [TypeAccess] Integer
|
||||
# 4| 1: [TypeAccess] Integer
|
||||
# 4| 2: [TypeAccess] Unit
|
||||
# 4| -3: [TypeAccess] InterfaceFn1
|
||||
# 4| 0: [LambdaExpr] ...->...
|
||||
# 4| -4: [AnonymousClass] new Function2<Integer,Integer,Unit>(...) { ... }
|
||||
@@ -4972,24 +4972,24 @@ samConversion.kt:
|
||||
# 5| 0: [VarAccess] this.<fn>
|
||||
# 5| -1: [ThisAccess] this
|
||||
# 5| 1: [VarAccess] <fn>
|
||||
# 5| 1: [FieldDeclaration] Function2<Integer,Integer,Unit> <fn>;
|
||||
# 5| -1: [TypeAccess] Function2<Integer,Integer,Unit>
|
||||
# 5| 0: [TypeAccess] Integer
|
||||
# 5| 1: [TypeAccess] Integer
|
||||
# 5| 2: [TypeAccess] Unit
|
||||
# 23| 3: [Method] fn1
|
||||
# 23| 3: [TypeAccess] Unit
|
||||
# 5| 1: [Method] fn1
|
||||
# 5| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 23| 0: [Parameter] i
|
||||
# 23| 0: [TypeAccess] int
|
||||
# 23| 1: [Parameter] j
|
||||
# 23| 0: [TypeAccess] int
|
||||
# 5| 0: [Parameter] i
|
||||
# 5| 0: [TypeAccess] int
|
||||
# 5| 1: [Parameter] j
|
||||
# 5| 0: [TypeAccess] int
|
||||
# 5| 5: [BlockStmt] { ... }
|
||||
# 5| 0: [ReturnStmt] return ...
|
||||
# 5| 0: [MethodAccess] invoke(...)
|
||||
# 5| -1: [VarAccess] <fn>
|
||||
# 5| 0: [VarAccess] i
|
||||
# 5| 1: [VarAccess] j
|
||||
# 5| 1: [FieldDeclaration] Function2<Integer,Integer,Unit> <fn>;
|
||||
# 5| -1: [TypeAccess] Function2<Integer,Integer,Unit>
|
||||
# 5| 0: [TypeAccess] Integer
|
||||
# 5| 1: [TypeAccess] Integer
|
||||
# 5| 2: [TypeAccess] Unit
|
||||
# 5| -3: [TypeAccess] InterfaceFn1
|
||||
# 5| 0: [MemberRefExpr] ...::...
|
||||
# 5| -4: [AnonymousClass] new Function2<Integer,Integer,Unit>(...) { ... }
|
||||
@@ -5026,24 +5026,24 @@ samConversion.kt:
|
||||
# 7| 0: [VarAccess] this.<fn>
|
||||
# 7| -1: [ThisAccess] this
|
||||
# 7| 1: [VarAccess] <fn>
|
||||
# 7| 1: [FieldDeclaration] Function2<String,Integer,Boolean> <fn>;
|
||||
# 7| -1: [TypeAccess] Function2<String,Integer,Boolean>
|
||||
# 7| 0: [TypeAccess] String
|
||||
# 7| 1: [TypeAccess] Integer
|
||||
# 7| 2: [TypeAccess] Boolean
|
||||
# 27| 3: [ExtensionMethod] ext
|
||||
# 27| 3: [TypeAccess] boolean
|
||||
# 7| 1: [ExtensionMethod] ext
|
||||
# 7| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 27| 0: [Parameter] <this>
|
||||
# 27| 0: [TypeAccess] String
|
||||
# 27| 1: [Parameter] i
|
||||
# 27| 0: [TypeAccess] int
|
||||
# 7| 0: [Parameter] <this>
|
||||
# 7| 0: [TypeAccess] String
|
||||
# 7| 1: [Parameter] i
|
||||
# 7| 0: [TypeAccess] int
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ReturnStmt] return ...
|
||||
# 7| 0: [MethodAccess] invoke(...)
|
||||
# 7| -1: [VarAccess] <fn>
|
||||
# 7| 0: [ExtensionReceiverAccess] this
|
||||
# 7| 1: [VarAccess] i
|
||||
# 7| 1: [FieldDeclaration] Function2<String,Integer,Boolean> <fn>;
|
||||
# 7| -1: [TypeAccess] Function2<String,Integer,Boolean>
|
||||
# 7| 0: [TypeAccess] String
|
||||
# 7| 1: [TypeAccess] Integer
|
||||
# 7| 2: [TypeAccess] Boolean
|
||||
# 7| -3: [TypeAccess] InterfaceFnExt1
|
||||
# 7| 0: [LambdaExpr] ...->...
|
||||
# 7| -4: [AnonymousClass] new Function2<String,Integer,Boolean>(...) { ... }
|
||||
@@ -5082,20 +5082,20 @@ samConversion.kt:
|
||||
# 9| 0: [VarAccess] this.<fn>
|
||||
# 9| -1: [ThisAccess] this
|
||||
# 9| 1: [VarAccess] <fn>
|
||||
# 9| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 9| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 9| 0: [TypeAccess] Integer
|
||||
# 9| 1: [TypeAccess] Boolean
|
||||
# 17| 3: [Method] accept
|
||||
# 17| 3: [TypeAccess] boolean
|
||||
# 9| 1: [Method] accept
|
||||
# 9| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 17| 0: [Parameter] i
|
||||
# 17| 0: [TypeAccess] int
|
||||
# 9| 0: [Parameter] i
|
||||
# 9| 0: [TypeAccess] int
|
||||
# 9| 5: [BlockStmt] { ... }
|
||||
# 9| 0: [ReturnStmt] return ...
|
||||
# 9| 0: [MethodAccess] invoke(...)
|
||||
# 9| -1: [VarAccess] <fn>
|
||||
# 9| 0: [VarAccess] i
|
||||
# 9| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 9| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 9| 0: [TypeAccess] Integer
|
||||
# 9| 1: [TypeAccess] Boolean
|
||||
# 9| -3: [TypeAccess] IntPredicate
|
||||
# 9| 0: [WhenExpr] when ...
|
||||
# 9| 0: [WhenBranch] ... -> ...
|
||||
@@ -5347,55 +5347,65 @@ samConversion.kt:
|
||||
# 42| 0: [TypeAccess] BigArityPredicate
|
||||
# 42| 1: [ClassInstanceExpr] new (...)
|
||||
# 42| -4: [AnonymousClass] new BigArityPredicate(...) { ... }
|
||||
# 31| 1: [Method] accept
|
||||
# 31| 3: [TypeAccess] boolean
|
||||
# 42| 1: [Constructor]
|
||||
#-----| 4: (Parameters)
|
||||
# 31| 0: [Parameter] i0
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 1: [Parameter] i1
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 2: [Parameter] i2
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 3: [Parameter] i3
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 4: [Parameter] i4
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 5: [Parameter] i5
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 6: [Parameter] i6
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 7: [Parameter] i7
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 8: [Parameter] i8
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 9: [Parameter] i9
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 32| 10: [Parameter] i10
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 11: [Parameter] i11
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 12: [Parameter] i12
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 13: [Parameter] i13
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 14: [Parameter] i14
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 15: [Parameter] i15
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 16: [Parameter] i16
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 17: [Parameter] i17
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 18: [Parameter] i18
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 19: [Parameter] i19
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 33| 20: [Parameter] i20
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 33| 21: [Parameter] i21
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 33| 22: [Parameter] i22
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 42| 0: [Parameter] <fn>
|
||||
# 42| 5: [BlockStmt] { ... }
|
||||
# 42| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 42| 1: [ExprStmt] <Expr>;
|
||||
# 42| 0: [AssignExpr] ...=...
|
||||
# 42| 0: [VarAccess] this.<fn>
|
||||
# 42| -1: [ThisAccess] this
|
||||
# 42| 1: [VarAccess] <fn>
|
||||
# 42| 1: [Method] accept
|
||||
# 42| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 42| 0: [Parameter] i0
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 1: [Parameter] i1
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 2: [Parameter] i2
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 3: [Parameter] i3
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 4: [Parameter] i4
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 5: [Parameter] i5
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 6: [Parameter] i6
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 7: [Parameter] i7
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 8: [Parameter] i8
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 9: [Parameter] i9
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 10: [Parameter] i10
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 11: [Parameter] i11
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 12: [Parameter] i12
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 13: [Parameter] i13
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 14: [Parameter] i14
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 15: [Parameter] i15
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 16: [Parameter] i16
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 17: [Parameter] i17
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 18: [Parameter] i18
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 19: [Parameter] i19
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 20: [Parameter] i20
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 21: [Parameter] i21
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 22: [Parameter] i22
|
||||
# 42| 0: [TypeAccess] int
|
||||
# 42| 5: [BlockStmt] { ... }
|
||||
# 42| 0: [ReturnStmt] return ...
|
||||
# 42| 0: [MethodAccess] invoke(...)
|
||||
@@ -5427,17 +5437,7 @@ samConversion.kt:
|
||||
# 42| 22: [VarAccess] i22
|
||||
# 42| -1: [TypeAccess] Object
|
||||
# 42| 0: [IntegerLiteral] 23
|
||||
# 42| 2: [Constructor]
|
||||
#-----| 4: (Parameters)
|
||||
# 42| 0: [Parameter] <fn>
|
||||
# 42| 5: [BlockStmt] { ... }
|
||||
# 42| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 42| 1: [ExprStmt] <Expr>;
|
||||
# 42| 0: [AssignExpr] ...=...
|
||||
# 42| 0: [VarAccess] this.<fn>
|
||||
# 42| -1: [ThisAccess] this
|
||||
# 42| 1: [VarAccess] <fn>
|
||||
# 42| 2: [FieldDeclaration] FunctionN<Boolean> <fn>;
|
||||
# 42| 1: [FieldDeclaration] FunctionN<Boolean> <fn>;
|
||||
# 42| -1: [TypeAccess] FunctionN<Boolean>
|
||||
# 42| 0: [TypeAccess] Boolean
|
||||
# 42| -3: [TypeAccess] BigArityPredicate
|
||||
@@ -5448,55 +5448,65 @@ samConversion.kt:
|
||||
# 43| 0: [TypeAccess] BigArityPredicate
|
||||
# 43| 1: [ClassInstanceExpr] new (...)
|
||||
# 43| -4: [AnonymousClass] new BigArityPredicate(...) { ... }
|
||||
# 31| 1: [Method] accept
|
||||
# 31| 3: [TypeAccess] boolean
|
||||
# 43| 1: [Constructor]
|
||||
#-----| 4: (Parameters)
|
||||
# 31| 0: [Parameter] i0
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 1: [Parameter] i1
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 2: [Parameter] i2
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 3: [Parameter] i3
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 4: [Parameter] i4
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 5: [Parameter] i5
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 6: [Parameter] i6
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 7: [Parameter] i7
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 8: [Parameter] i8
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 31| 9: [Parameter] i9
|
||||
# 31| 0: [TypeAccess] int
|
||||
# 32| 10: [Parameter] i10
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 11: [Parameter] i11
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 12: [Parameter] i12
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 13: [Parameter] i13
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 14: [Parameter] i14
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 15: [Parameter] i15
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 16: [Parameter] i16
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 17: [Parameter] i17
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 18: [Parameter] i18
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 32| 19: [Parameter] i19
|
||||
# 32| 0: [TypeAccess] int
|
||||
# 33| 20: [Parameter] i20
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 33| 21: [Parameter] i21
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 33| 22: [Parameter] i22
|
||||
# 33| 0: [TypeAccess] int
|
||||
# 43| 0: [Parameter] <fn>
|
||||
# 43| 5: [BlockStmt] { ... }
|
||||
# 43| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 43| 1: [ExprStmt] <Expr>;
|
||||
# 43| 0: [AssignExpr] ...=...
|
||||
# 43| 0: [VarAccess] this.<fn>
|
||||
# 43| -1: [ThisAccess] this
|
||||
# 43| 1: [VarAccess] <fn>
|
||||
# 43| 1: [Method] accept
|
||||
# 43| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 43| 0: [Parameter] i0
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 1: [Parameter] i1
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 2: [Parameter] i2
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 3: [Parameter] i3
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 4: [Parameter] i4
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 5: [Parameter] i5
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 6: [Parameter] i6
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 7: [Parameter] i7
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 8: [Parameter] i8
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 9: [Parameter] i9
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 10: [Parameter] i10
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 11: [Parameter] i11
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 12: [Parameter] i12
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 13: [Parameter] i13
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 14: [Parameter] i14
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 15: [Parameter] i15
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 16: [Parameter] i16
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 17: [Parameter] i17
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 18: [Parameter] i18
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 19: [Parameter] i19
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 20: [Parameter] i20
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 21: [Parameter] i21
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 22: [Parameter] i22
|
||||
# 43| 0: [TypeAccess] int
|
||||
# 43| 5: [BlockStmt] { ... }
|
||||
# 43| 0: [ReturnStmt] return ...
|
||||
# 43| 0: [MethodAccess] invoke(...)
|
||||
@@ -5528,17 +5538,7 @@ samConversion.kt:
|
||||
# 43| 22: [VarAccess] i22
|
||||
# 43| -1: [TypeAccess] Object
|
||||
# 43| 0: [IntegerLiteral] 23
|
||||
# 43| 2: [Constructor]
|
||||
#-----| 4: (Parameters)
|
||||
# 43| 0: [Parameter] <fn>
|
||||
# 43| 5: [BlockStmt] { ... }
|
||||
# 43| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 43| 1: [ExprStmt] <Expr>;
|
||||
# 43| 0: [AssignExpr] ...=...
|
||||
# 43| 0: [VarAccess] this.<fn>
|
||||
# 43| -1: [ThisAccess] this
|
||||
# 43| 1: [VarAccess] <fn>
|
||||
# 43| 2: [FieldDeclaration] FunctionN<Boolean> <fn>;
|
||||
# 43| 1: [FieldDeclaration] FunctionN<Boolean> <fn>;
|
||||
# 43| -1: [TypeAccess] FunctionN<Boolean>
|
||||
# 43| 0: [TypeAccess] Boolean
|
||||
# 43| -3: [TypeAccess] BigArityPredicate
|
||||
@@ -5740,20 +5740,20 @@ samConversion.kt:
|
||||
# 46| 0: [VarAccess] this.<fn>
|
||||
# 46| -1: [ThisAccess] this
|
||||
# 46| 1: [VarAccess] <fn>
|
||||
# 46| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 46| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 46| 0: [TypeAccess] Integer
|
||||
# 46| 1: [TypeAccess] Boolean
|
||||
# 50| 3: [Method] fn
|
||||
# 50| 3: [TypeAccess] boolean
|
||||
# 46| 1: [Method] fn
|
||||
# 46| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 50| 0: [Parameter] i
|
||||
# 50| 0: [TypeAccess] T
|
||||
# 46| 0: [Parameter] i
|
||||
# 46| 0: [TypeAccess] Integer
|
||||
# 46| 5: [BlockStmt] { ... }
|
||||
# 46| 0: [ReturnStmt] return ...
|
||||
# 46| 0: [MethodAccess] invoke(...)
|
||||
# 46| -1: [VarAccess] <fn>
|
||||
# 46| 0: [VarAccess] i
|
||||
# 46| 1: [FieldDeclaration] Function1<Integer,Boolean> <fn>;
|
||||
# 46| -1: [TypeAccess] Function1<Integer,Boolean>
|
||||
# 46| 0: [TypeAccess] Integer
|
||||
# 46| 1: [TypeAccess] Boolean
|
||||
# 46| -3: [TypeAccess] SomePredicate<Integer>
|
||||
# 46| 0: [TypeAccess] Integer
|
||||
# 46| 0: [LambdaExpr] ...->...
|
||||
|
||||
@@ -2889,14 +2889,16 @@
|
||||
| samConversion.kt:2:18:2:45 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr |
|
||||
| samConversion.kt:2:18:2:45 | ...=... | samConversion.kt:2:18:2:45 | | AssignExpr |
|
||||
| samConversion.kt:2:18:2:45 | <fn> | samConversion.kt:2:18:2:45 | | VarAccess |
|
||||
| samConversion.kt:2:18:2:45 | <fn> | samConversion.kt:17:5:17:31 | accept | VarAccess |
|
||||
| samConversion.kt:2:18:2:45 | <fn> | samConversion.kt:2:18:2:45 | accept | VarAccess |
|
||||
| samConversion.kt:2:18:2:45 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | Function1<Integer,Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | IntPredicate | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | IntPredicate | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | i | samConversion.kt:17:5:17:31 | accept | VarAccess |
|
||||
| samConversion.kt:2:18:2:45 | invoke(...) | samConversion.kt:17:5:17:31 | accept | MethodAccess |
|
||||
| samConversion.kt:2:18:2:45 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | i | samConversion.kt:2:18:2:45 | accept | VarAccess |
|
||||
| samConversion.kt:2:18:2:45 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:2:18:2:45 | invoke(...) | samConversion.kt:2:18:2:45 | accept | MethodAccess |
|
||||
| samConversion.kt:2:18:2:45 | new (...) | samConversion.kt:1:1:14:1 | main | ClassInstanceExpr |
|
||||
| samConversion.kt:2:18:2:45 | this | samConversion.kt:2:18:2:45 | | ThisAccess |
|
||||
| samConversion.kt:2:18:2:45 | this.<fn> | samConversion.kt:2:18:2:45 | | VarAccess |
|
||||
@@ -2915,16 +2917,19 @@
|
||||
| samConversion.kt:4:14:4:42 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr |
|
||||
| samConversion.kt:4:14:4:42 | ...=... | samConversion.kt:4:14:4:42 | | AssignExpr |
|
||||
| samConversion.kt:4:14:4:42 | <fn> | samConversion.kt:4:14:4:42 | | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | <fn> | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | <fn> | samConversion.kt:4:14:4:42 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | Function2<Integer,Integer,Unit> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | InterfaceFn1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | InterfaceFn1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | i | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | invoke(...) | samConversion.kt:23:5:23:27 | fn1 | MethodAccess |
|
||||
| samConversion.kt:4:14:4:42 | j | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | i | samConversion.kt:4:14:4:42 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:4:14:4:42 | invoke(...) | samConversion.kt:4:14:4:42 | fn1 | MethodAccess |
|
||||
| samConversion.kt:4:14:4:42 | j | samConversion.kt:4:14:4:42 | fn1 | VarAccess |
|
||||
| samConversion.kt:4:14:4:42 | new (...) | samConversion.kt:1:1:14:1 | main | ClassInstanceExpr |
|
||||
| samConversion.kt:4:14:4:42 | this | samConversion.kt:4:14:4:42 | | ThisAccess |
|
||||
| samConversion.kt:4:14:4:42 | this.<fn> | samConversion.kt:4:14:4:42 | | VarAccess |
|
||||
@@ -2941,16 +2946,19 @@
|
||||
| samConversion.kt:5:14:5:32 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr |
|
||||
| samConversion.kt:5:14:5:32 | ...=... | samConversion.kt:5:14:5:32 | | AssignExpr |
|
||||
| samConversion.kt:5:14:5:32 | <fn> | samConversion.kt:5:14:5:32 | | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | <fn> | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | <fn> | samConversion.kt:5:14:5:32 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | Function2<Integer,Integer,Unit> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | InterfaceFn1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | InterfaceFn1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | i | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | invoke(...) | samConversion.kt:23:5:23:27 | fn1 | MethodAccess |
|
||||
| samConversion.kt:5:14:5:32 | j | samConversion.kt:23:5:23:27 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | i | samConversion.kt:5:14:5:32 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:5:14:5:32 | invoke(...) | samConversion.kt:5:14:5:32 | fn1 | MethodAccess |
|
||||
| samConversion.kt:5:14:5:32 | j | samConversion.kt:5:14:5:32 | fn1 | VarAccess |
|
||||
| samConversion.kt:5:14:5:32 | new (...) | samConversion.kt:1:1:14:1 | main | ClassInstanceExpr |
|
||||
| samConversion.kt:5:14:5:32 | this | samConversion.kt:5:14:5:32 | | ThisAccess |
|
||||
| samConversion.kt:5:14:5:32 | this.<fn> | samConversion.kt:5:14:5:32 | | VarAccess |
|
||||
@@ -2967,18 +2975,21 @@
|
||||
| samConversion.kt:7:13:7:46 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr |
|
||||
| samConversion.kt:7:13:7:46 | ...=... | samConversion.kt:7:13:7:46 | | AssignExpr |
|
||||
| samConversion.kt:7:13:7:46 | <fn> | samConversion.kt:7:13:7:46 | | VarAccess |
|
||||
| samConversion.kt:7:13:7:46 | <fn> | samConversion.kt:27:5:27:35 | ext | VarAccess |
|
||||
| samConversion.kt:7:13:7:46 | <fn> | samConversion.kt:7:13:7:46 | ext | VarAccess |
|
||||
| samConversion.kt:7:13:7:46 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | Function2<String,Integer,Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | InterfaceFnExt1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | InterfaceFnExt1 | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | String | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | i | samConversion.kt:27:5:27:35 | ext | VarAccess |
|
||||
| samConversion.kt:7:13:7:46 | invoke(...) | samConversion.kt:27:5:27:35 | ext | MethodAccess |
|
||||
| samConversion.kt:7:13:7:46 | String | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | i | samConversion.kt:7:13:7:46 | ext | VarAccess |
|
||||
| samConversion.kt:7:13:7:46 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:7:13:7:46 | invoke(...) | samConversion.kt:7:13:7:46 | ext | MethodAccess |
|
||||
| samConversion.kt:7:13:7:46 | new (...) | samConversion.kt:1:1:14:1 | main | ClassInstanceExpr |
|
||||
| samConversion.kt:7:13:7:46 | this | samConversion.kt:7:13:7:46 | | ThisAccess |
|
||||
| samConversion.kt:7:13:7:46 | this | samConversion.kt:27:5:27:35 | ext | ExtensionReceiverAccess |
|
||||
| samConversion.kt:7:13:7:46 | this | samConversion.kt:7:13:7:46 | ext | ExtensionReceiverAccess |
|
||||
| samConversion.kt:7:13:7:46 | this.<fn> | samConversion.kt:7:13:7:46 | | VarAccess |
|
||||
| samConversion.kt:7:29:7:46 | ...->... | samConversion.kt:1:1:14:1 | main | LambdaExpr |
|
||||
| samConversion.kt:7:29:7:46 | Boolean | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
@@ -2995,14 +3006,16 @@
|
||||
| samConversion.kt:9:13:13:6 | (...)... | samConversion.kt:1:1:14:1 | main | CastExpr |
|
||||
| samConversion.kt:9:13:13:6 | ...=... | samConversion.kt:9:13:13:6 | | AssignExpr |
|
||||
| samConversion.kt:9:13:13:6 | <fn> | samConversion.kt:9:13:13:6 | | VarAccess |
|
||||
| samConversion.kt:9:13:13:6 | <fn> | samConversion.kt:17:5:17:31 | accept | VarAccess |
|
||||
| samConversion.kt:9:13:13:6 | <fn> | samConversion.kt:9:13:13:6 | accept | VarAccess |
|
||||
| samConversion.kt:9:13:13:6 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | Function1<Integer,Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | IntPredicate | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | IntPredicate | samConversion.kt:1:1:14:1 | main | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | i | samConversion.kt:17:5:17:31 | accept | VarAccess |
|
||||
| samConversion.kt:9:13:13:6 | invoke(...) | samConversion.kt:17:5:17:31 | accept | MethodAccess |
|
||||
| samConversion.kt:9:13:13:6 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | i | samConversion.kt:9:13:13:6 | accept | VarAccess |
|
||||
| samConversion.kt:9:13:13:6 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:9:13:13:6 | invoke(...) | samConversion.kt:9:13:13:6 | accept | MethodAccess |
|
||||
| samConversion.kt:9:13:13:6 | new (...) | samConversion.kt:1:1:14:1 | main | ClassInstanceExpr |
|
||||
| samConversion.kt:9:13:13:6 | this | samConversion.kt:9:13:13:6 | | ThisAccess |
|
||||
| samConversion.kt:9:13:13:6 | this.<fn> | samConversion.kt:9:13:13:6 | | VarAccess |
|
||||
@@ -3032,100 +3045,39 @@
|
||||
| samConversion.kt:12:22:12:22 | 2 | samConversion.kt:11:12:13:5 | invoke | IntegerLiteral |
|
||||
| samConversion.kt:12:27:12:27 | 1 | samConversion.kt:11:12:13:5 | invoke | IntegerLiteral |
|
||||
| samConversion.kt:17:5:17:31 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:17:5:17:31 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:17:5:17:31 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:17:16:17:21 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:17:16:17:21 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:17:16:17:21 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:20:1:20:27 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:20:9:20:14 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:20:17:20:22 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:5:23:27 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:5:23:27 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:5:23:27 | Unit | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:13:23:18 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:13:23:18 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:13:23:18 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:21:23:26 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:21:23:26 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:23:21:23:26 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:5:27:35 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:5:27:35 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:9:27:14 | String | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:9:27:14 | String | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:20:27:25 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:27:20:27:25 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:5:33:53 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:5:33:53 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:5:33:53 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:16:31:22 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:16:31:22 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:16:31:22 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:25:31:31 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:25:31:31 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:25:31:31 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:34:31:40 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:34:31:40 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:34:31:40 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:43:31:49 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:43:31:49 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:43:31:49 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:52:31:58 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:52:31:58 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:52:31:58 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:61:31:67 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:61:31:67 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:61:31:67 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:70:31:76 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:70:31:76 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:70:31:76 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:79:31:85 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:79:31:85 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:79:31:85 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:88:31:94 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:88:31:94 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:88:31:94 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:97:31:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:97:31:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:31:97:31:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:16:32:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:16:32:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:16:32:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:26:32:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:26:32:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:26:32:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:36:32:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:36:32:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:36:32:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:46:32:53 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:46:32:53 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:46:32:53 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:56:32:63 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:56:32:63 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:56:32:63 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:66:32:73 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:66:32:73 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:66:32:73 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:76:32:83 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:76:32:83 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:76:32:83 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:86:32:93 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:86:32:93 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:86:32:93 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:96:32:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:96:32:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:96:32:103 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:106:32:113 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:106:32:113 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:32:106:32:113 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:16:33:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:16:33:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:16:33:23 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:26:33:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:26:33:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:26:33:33 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:36:33:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:36:33:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:33:36:33:43 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:36:1:38:52 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:36:8:36:14 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
@@ -3276,86 +3228,134 @@
|
||||
| samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess |
|
||||
| samConversion.kt:41:13:41:16 | int | samConversion.kt:41:13:41:16 | invoke | TypeAccess |
|
||||
| samConversion.kt:42:5:42:32 | b | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr |
|
||||
| samConversion.kt:42:13:42:32 | 23 | samConversion.kt:31:5:33:53 | accept | IntegerLiteral |
|
||||
| samConversion.kt:42:13:42:32 | 23 | samConversion.kt:42:13:42:32 | accept | IntegerLiteral |
|
||||
| samConversion.kt:42:13:42:32 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr |
|
||||
| samConversion.kt:42:13:42:32 | ...=... | samConversion.kt:42:13:42:32 | | AssignExpr |
|
||||
| samConversion.kt:42:13:42:32 | <fn> | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | <fn> | samConversion.kt:42:13:42:32 | | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | <fn> | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | BigArityPredicate | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | BigArityPredicate | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | FunctionN<Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | Object | samConversion.kt:31:5:33:53 | accept | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | i0 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i1 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i2 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i3 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i4 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i5 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i6 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i7 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i8 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i9 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i10 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i11 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i12 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i13 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i14 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i15 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i16 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i17 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i18 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i19 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i20 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i21 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i22 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | invoke(...) | samConversion.kt:31:5:33:53 | accept | MethodAccess |
|
||||
| samConversion.kt:42:13:42:32 | Object | samConversion.kt:42:13:42:32 | accept | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | i0 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i1 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i2 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i3 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i4 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i5 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i6 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i7 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i8 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i9 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i10 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i11 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i12 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i13 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i14 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i15 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i16 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i17 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i18 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i19 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i20 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i21 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | i22 | samConversion.kt:42:13:42:32 | accept | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:42:13:42:32 | invoke(...) | samConversion.kt:42:13:42:32 | accept | MethodAccess |
|
||||
| samConversion.kt:42:13:42:32 | new (...) | samConversion.kt:40:1:47:1 | fn | ClassInstanceExpr |
|
||||
| samConversion.kt:42:13:42:32 | new Object[] | samConversion.kt:31:5:33:53 | accept | ArrayCreationExpr |
|
||||
| samConversion.kt:42:13:42:32 | new Object[] | samConversion.kt:42:13:42:32 | accept | ArrayCreationExpr |
|
||||
| samConversion.kt:42:13:42:32 | this | samConversion.kt:42:13:42:32 | | ThisAccess |
|
||||
| samConversion.kt:42:13:42:32 | this.<fn> | samConversion.kt:42:13:42:32 | | VarAccess |
|
||||
| samConversion.kt:42:13:42:32 | {...} | samConversion.kt:31:5:33:53 | accept | ArrayInit |
|
||||
| samConversion.kt:42:13:42:32 | {...} | samConversion.kt:42:13:42:32 | accept | ArrayInit |
|
||||
| samConversion.kt:42:31:42:31 | a | samConversion.kt:40:1:47:1 | fn | VarAccess |
|
||||
| samConversion.kt:43:5:45:68 | c | samConversion.kt:40:1:47:1 | fn | LocalVariableDeclExpr |
|
||||
| samConversion.kt:43:13:45:68 | 23 | samConversion.kt:31:5:33:53 | accept | IntegerLiteral |
|
||||
| samConversion.kt:43:13:45:68 | 23 | samConversion.kt:43:13:45:68 | accept | IntegerLiteral |
|
||||
| samConversion.kt:43:13:45:68 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr |
|
||||
| samConversion.kt:43:13:45:68 | ...=... | samConversion.kt:43:13:45:68 | | AssignExpr |
|
||||
| samConversion.kt:43:13:45:68 | <fn> | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | <fn> | samConversion.kt:43:13:45:68 | | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | <fn> | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | BigArityPredicate | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | BigArityPredicate | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | FunctionN<Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | Object | samConversion.kt:31:5:33:53 | accept | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | i0 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i1 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i2 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i3 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i4 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i5 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i6 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i7 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i8 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i9 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i10 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i11 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i12 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i13 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i14 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i15 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i16 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i17 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i18 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i19 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i20 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i21 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i22 | samConversion.kt:31:5:33:53 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | invoke(...) | samConversion.kt:31:5:33:53 | accept | MethodAccess |
|
||||
| samConversion.kt:43:13:45:68 | Object | samConversion.kt:43:13:45:68 | accept | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | i0 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i1 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i2 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i3 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i4 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i5 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i6 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i7 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i8 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i9 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i10 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i11 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i12 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i13 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i14 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i15 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i16 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i17 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i18 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i19 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i20 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i21 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | i22 | samConversion.kt:43:13:45:68 | accept | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:43:13:45:68 | invoke(...) | samConversion.kt:43:13:45:68 | accept | MethodAccess |
|
||||
| samConversion.kt:43:13:45:68 | new (...) | samConversion.kt:40:1:47:1 | fn | ClassInstanceExpr |
|
||||
| samConversion.kt:43:13:45:68 | new Object[] | samConversion.kt:31:5:33:53 | accept | ArrayCreationExpr |
|
||||
| samConversion.kt:43:13:45:68 | new Object[] | samConversion.kt:43:13:45:68 | accept | ArrayCreationExpr |
|
||||
| samConversion.kt:43:13:45:68 | this | samConversion.kt:43:13:45:68 | | ThisAccess |
|
||||
| samConversion.kt:43:13:45:68 | this.<fn> | samConversion.kt:43:13:45:68 | | VarAccess |
|
||||
| samConversion.kt:43:13:45:68 | {...} | samConversion.kt:31:5:33:53 | accept | ArrayInit |
|
||||
| samConversion.kt:43:13:45:68 | {...} | samConversion.kt:43:13:45:68 | accept | ArrayInit |
|
||||
| samConversion.kt:43:31:45:68 | 0 | samConversion.kt:43:31:45:68 | invoke | IntegerLiteral |
|
||||
| samConversion.kt:43:31:45:68 | 1 | samConversion.kt:43:31:45:68 | invoke | IntegerLiteral |
|
||||
| samConversion.kt:43:31:45:68 | 2 | samConversion.kt:43:31:45:68 | invoke | IntegerLiteral |
|
||||
@@ -3505,16 +3505,18 @@
|
||||
| samConversion.kt:46:13:46:44 | (...)... | samConversion.kt:40:1:47:1 | fn | CastExpr |
|
||||
| samConversion.kt:46:13:46:44 | ...=... | samConversion.kt:46:13:46:44 | | AssignExpr |
|
||||
| samConversion.kt:46:13:46:44 | <fn> | samConversion.kt:46:13:46:44 | | VarAccess |
|
||||
| samConversion.kt:46:13:46:44 | <fn> | samConversion.kt:50:5:50:25 | fn | VarAccess |
|
||||
| samConversion.kt:46:13:46:44 | <fn> | samConversion.kt:46:13:46:44 | fn | VarAccess |
|
||||
| samConversion.kt:46:13:46:44 | Boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | Function1<Integer,Boolean> | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | Integer | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | Integer | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | Integer | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | SomePredicate<Integer> | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | SomePredicate<Integer> | samConversion.kt:40:1:47:1 | fn | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | i | samConversion.kt:50:5:50:25 | fn | VarAccess |
|
||||
| samConversion.kt:46:13:46:44 | invoke(...) | samConversion.kt:50:5:50:25 | fn | MethodAccess |
|
||||
| samConversion.kt:46:13:46:44 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:13:46:44 | i | samConversion.kt:46:13:46:44 | fn | VarAccess |
|
||||
| samConversion.kt:46:13:46:44 | invoke(...) | samConversion.kt:46:13:46:44 | fn | MethodAccess |
|
||||
| samConversion.kt:46:13:46:44 | new (...) | samConversion.kt:40:1:47:1 | fn | ClassInstanceExpr |
|
||||
| samConversion.kt:46:13:46:44 | this | samConversion.kt:46:13:46:44 | | ThisAccess |
|
||||
| samConversion.kt:46:13:46:44 | this.<fn> | samConversion.kt:46:13:46:44 | | VarAccess |
|
||||
@@ -3526,8 +3528,6 @@
|
||||
| samConversion.kt:46:34:46:34 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:46:39:46:42 | true | samConversion.kt:46:32:46:44 | invoke | BooleanLiteral |
|
||||
| samConversion.kt:50:5:50:25 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:50:5:50:25 | boolean | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:50:12:50:15 | T | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| samConversion.kt:50:12:50:15 | T | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| whenExpr.kt:1:1:9:1 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
| whenExpr.kt:1:14:1:19 | int | file://:0:0:0:0 | <none> | TypeAccess |
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
isFinalField
|
||||
| test.kt:3:3:3:18 | x |
|
||||
#select
|
||||
| test.kt:3:3:3:18 | this.x | test.kt:6:10:6:10 | getX(...) |
|
||||
#select
|
||||
@@ -4,9 +4,7 @@ import semmle.code.java.dataflow.DataFlow
|
||||
class Config extends DataFlow::Configuration {
|
||||
Config() { this = "Config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().(CompileTimeConstantExpr).getStringValue() = "Source"
|
||||
}
|
||||
override predicate isSource(DataFlow::Node n) { n.asExpr().(StringLiteral).getValue() = "Source" }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().getName() = "sink"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.kt:4:5:4:138 | f1 | FunctionN<String> | String |
|
||||
| test.kt:5:5:5:134 | f2 | FunctionN<T1> | T1 |
|
||||
| test.kt:6:5:6:110 | f3 | FunctionN<T3> | T3 |
|
||||
8
java/ql/test/kotlin/library-tests/function-n/test.kt
Normal file
8
java/ql/test/kotlin/library-tests/function-n/test.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
class TakesLambdas {
|
||||
|
||||
fun <T1, T2, T3> test(
|
||||
f1: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> String,
|
||||
f2: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) -> T1,
|
||||
f3: (T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2, T2) -> T3) { }
|
||||
|
||||
}
|
||||
5
java/ql/test/kotlin/library-tests/function-n/test.ql
Normal file
5
java/ql/test/kotlin/library-tests/function-n/test.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Parameter p
|
||||
where p.getCallable().fromSource()
|
||||
select p, p.getType().toString(), p.getType().(ParameterizedType).getATypeArgument().toString()
|
||||
@@ -1,2 +1,4 @@
|
||||
diagnostics
|
||||
#select
|
||||
| Integer |
|
||||
| Object |
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
fun test(m: Map<Int, Int>) = m.getOrDefault(1, 2)
|
||||
|
||||
fun test2(s: String) = s.length
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import java
|
||||
import semmle.code.java.Diagnostics
|
||||
|
||||
from MethodAccess ma
|
||||
select ma.getCallee().getAParameter().getType().toString()
|
||||
|
||||
query predicate diagnostics(Diagnostic d) { any() }
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
test
|
||||
| file:///modules/java.base/java/util/List.class:0:0:0:0 | iterator | file:///modules/java.base/java/util/Collection.class:0:0:0:0 | iterator |
|
||||
test1
|
||||
| file:///modules/java.base/java/util/List.class:0:0:0:0 | iterator |
|
||||
@@ -0,0 +1,12 @@
|
||||
import java
|
||||
|
||||
query predicate test(Method m1, Method m2) {
|
||||
m1.getName() = "iterator" and
|
||||
m1.getDeclaringType().getQualifiedName() = "java.util.List" and
|
||||
m1.overrides(m2)
|
||||
}
|
||||
|
||||
query predicate test1(Method m1) {
|
||||
m1.getName() = "iterator" and
|
||||
m1.getDeclaringType().getQualifiedName() = "java.util.List"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class x {
|
||||
public final void test() {
|
||||
List<String> ll = Arrays.asList("a", "b");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
test
|
||||
| file:///modules/java.base/java/util/List.class:0:0:0:0 | iterator | file:///modules/java.base/java/util/Collection.class:0:0:0:0 | iterator |
|
||||
test1
|
||||
| file:///modules/java.base/java/util/List.class:0:0:0:0 | iterator |
|
||||
@@ -0,0 +1,12 @@
|
||||
import java
|
||||
|
||||
query predicate test(Method m1, Method m2) {
|
||||
m1.getName() = "iterator" and
|
||||
m1.getDeclaringType().getQualifiedName() = "java.util.List" and
|
||||
m1.overrides(m2)
|
||||
}
|
||||
|
||||
query predicate test1(Method m1) {
|
||||
m1.getName() = "iterator" and
|
||||
m1.getDeclaringType().getQualifiedName() = "java.util.List"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import java.util.*
|
||||
|
||||
class x {
|
||||
fun test() {
|
||||
val ll = Arrays.asList("a", "b")
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | [DATE TIME K] Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE'\n ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | [DATE TIME K] Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE'\n ...while extracting a expression (<no name>) at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | [DATE TIME K] Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE'\n ...while extracting a expression (<no name>) at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF'\n ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF'\n ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF'\n ...while extracting a expression (<no name>) at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF'\n ...while extracting a expression (<no name>) at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF'\n ...while extracting a expression (<no name>) at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | [DATE TIME K] Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF'\n ...while extracting a expression (<no name>) at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting '//A03BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression (<no name>) at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048577 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048577 | DATE TIME Truncated string of length 1048577\nTruncated string of length 1048577, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDE' ...while extracting a expression (<no name>) at long_string.kt:16:31:16:1048607\n ...while extracting a variable expr (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a variable (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a statement (longStringLiteral3) at long_string.kt:16:5:16:1048608\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A04BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting '//A05"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a file (long_comments.kt) at long_comments.kt:1:1:19:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression (<no name>) at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'A"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""', ending '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""CDEF' ...while extracting a expression (<no name>) at long_string.kt:18:31:18:2097181\n ...while extracting a variable expr (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a variable (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a statement (longStringLiteral5) at long_string.kt:18:5:18:2097182\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression (<no name>) at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
| file://:0:0:0:0 | Truncated string of length 1048578 | CodeQL Kotlin extractor | 2 | | Truncated string of length 1048578 | DATE TIME Truncated string of length 1048578\nTruncated string of length 1048578, starting 'ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', ending 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCDEF' ...while extracting a expression (<no name>) at long_string.kt:17:31:17:1048608\n ...while extracting a variable expr (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a variable (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a statement (longStringLiteral4) at long_string.kt:17:5:17:1048609\n ...while extracting a block body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a body (<no name>) at long_string.kt:13:22:19:1\n ...while extracting a function (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a declaration (longLiteralFun) at long_string.kt:13:1:19:1\n ...while extracting a file (long_string.kt) at long_string.kt:1:1:21:0\n |
|
||||
|
||||
@@ -3,5 +3,4 @@ import semmle.code.java.Diagnostics
|
||||
from Diagnostic d
|
||||
select d, d.getGeneratedBy(), d.getSeverity(), d.getTag(), d.getMessage(),
|
||||
d.getFullMessage()
|
||||
.regexpReplaceAll("^\\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} K\\] ",
|
||||
"[DATE TIME K] ")
|
||||
.regexpReplaceAll("^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} ", "DATE TIME ")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,13 +5,10 @@ class Foo {
|
||||
val propInt: Int = 1
|
||||
val propLong: Long = 1
|
||||
|
||||
/*
|
||||
TODO
|
||||
val propUByte: UByte = 1u
|
||||
val propUShort: UShort = 1u
|
||||
val propUInt: UInt = 1u
|
||||
val propULong: ULong = 1u
|
||||
*/
|
||||
|
||||
val propFloat: Float = 1.0f
|
||||
val propDouble: Double = 1.0
|
||||
@@ -25,14 +22,22 @@ TODO
|
||||
|
||||
val propNullableNothing: Nothing? = null
|
||||
|
||||
/*
|
||||
TODO
|
||||
val propArray: Array<Int> = arrayOf(1, 2, 3)
|
||||
|
||||
val propByteArray: ByteArray = byteArrayOf(1, 2, 3)
|
||||
val propShortArray: ShortArray = shortArrayOf(1, 2, 3)
|
||||
val propIntArray: IntArray = intArrayOf(1, 2, 3)
|
||||
val propLongArray: LongArray = longArrayOf(1, 2, 3)
|
||||
*/
|
||||
}
|
||||
|
||||
class Gen<T> {
|
||||
fun fn1(a: T) {
|
||||
val x: Gen<Gen<Int>> = Gen<Gen<Int>>()
|
||||
class Local<U> {}
|
||||
val y: Gen<Local<Int>> = Gen<Local<Int>>()
|
||||
val z = object { }
|
||||
}
|
||||
|
||||
fun fn2(a: Gen<out String>, b: Gen<in String>, c: Gen<in Nothing>, d: Gen<out Any?>) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import java
|
||||
|
||||
from Type t
|
||||
where
|
||||
t.fromSource()
|
||||
or
|
||||
exists(TypeAccess ta | ta.fromSource() and ta.getType() = t)
|
||||
select t.toString(), concat(t.getAPrimaryQlClass(), ", ")
|
||||
|
||||
@@ -22,5 +22,5 @@ class SummaryModelTest extends SummaryModelCsv {
|
||||
}
|
||||
|
||||
from DataFlow::Node node1, DataFlow::Node node2
|
||||
where FlowSummaryImpl::Private::Steps::summaryThroughStep(node1, node2, false)
|
||||
where FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(node1, node2, _)
|
||||
select node1, node2
|
||||
|
||||
@@ -16,7 +16,7 @@ from DataFlow::Node src, DataFlow::Node sink
|
||||
where
|
||||
(
|
||||
localAdditionalTaintStep(src, sink) or
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStep(src, sink, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(src, sink, _)
|
||||
) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryReadStep(src, _, sink) and
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| Type Test uses out-of-scope type variable K. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. |
|
||||
Reference in New Issue
Block a user