Merge branch 'main' into ruby-mad-argument-self

This commit is contained in:
Rasmus Wriedt Larsen
2022-05-24 18:04:02 +02:00
2684 changed files with 223123 additions and 4071 deletions

View File

@@ -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",
]
}
}
}

View File

@@ -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

View File

@@ -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) + ')')

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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}\""
}

View File

@@ -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>()
}
/**

View File

@@ -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())
}
}
}

View File

@@ -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
}

View File

@@ -0,0 +1,5 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.SourceManager
typealias FileEntry = SourceManager.FileEntry

View File

@@ -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) }
}

View File

@@ -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)
}
}

View File

@@ -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()

View File

@@ -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
}

View File

@@ -0,0 +1,5 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.SourceManager
typealias FileEntry = SourceManager.FileEntry

View File

@@ -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) }
}

View File

@@ -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)
}
}

View File

@@ -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()

View File

@@ -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
}

View File

@@ -0,0 +1,5 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.IrFileEntry
typealias FileEntry = IrFileEntry

View File

@@ -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) }
}

View File

@@ -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)
}
}

View File

@@ -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()

View File

@@ -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."

View File

@@ -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"]
}
}

View File

@@ -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)

View File

@@ -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"]
}
}

View File

@@ -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"]
)
}
}

View File

@@ -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

View File

@@ -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
)
}

View File

@@ -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)
)
}

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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 =

View File

@@ -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 {

View File

@@ -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)
)
}

View File

@@ -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
)

View File

@@ -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.

View File

@@ -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.%")
}
}

View File

@@ -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
)
}

View File

@@ -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 {

View File

@@ -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"])
}
}

View File

@@ -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(), _)
}

View File

@@ -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()

View File

@@ -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"
)
}

View File

@@ -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`.
*/

View File

@@ -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"])
}
/**

View File

@@ -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 |

View File

@@ -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
}
}

View File

@@ -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 | { ... } |

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 | ... -> ... |

View File

@@ -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)
}
}

View 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)
}
}
}

View File

@@ -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 |

View 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

View File

@@ -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] ...->...

View File

@@ -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 |

View File

@@ -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

View File

@@ -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"

View File

@@ -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 |

View 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) { }
}

View File

@@ -0,0 +1,5 @@
import java
from Parameter p
where p.getCallable().fromSource()
select p, p.getType().toString(), p.getType().(ParameterizedType).getATypeArgument().toString()

View File

@@ -1,2 +1,4 @@
diagnostics
#select
| Integer |
| Object |

View File

@@ -1 +1,3 @@
fun test(m: Map<Int, Int>) = m.getOrDefault(1, 2)
fun test2(s: String) = s.length

View File

@@ -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() }

View File

@@ -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 |

View File

@@ -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"
}

View File

@@ -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");
}
}

View File

@@ -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 |

View File

@@ -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"
}

View File

@@ -0,0 +1,7 @@
import java.util.*
class x {
fun test() {
val ll = Arrays.asList("a", "b")
}
}

View File

@@ -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 |

View File

@@ -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

View File

@@ -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?>) {
}
}

View File

@@ -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(), ", ")

View File

@@ -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

View File

@@ -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

View File

@@ -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. |