WIP: add test for reflective calls

This commit is contained in:
Tamas Vajk
2022-02-16 16:06:00 +01:00
committed by Ian Lynagh
parent c4c254587e
commit 42803a161c
6 changed files with 105 additions and 1 deletions

View File

@@ -0,0 +1,46 @@
reflection.kt:
# 0| [CompilationUnit] reflection
# 3| 1: [Class] Reflection
# 3| 1: [Constructor] Reflection
# 3| 5: [BlockStmt] { ... }
# 3| 0: [SuperConstructorInvocationStmt] super(...)
# 3| 1: [ExprStmt] <Expr>;
# 3| 0: [MethodAccess] <obinit>(...)
# 4| 3: [Method] fn
#-----| 4: (Parameters)
# 4| 0: [Parameter] boo
# 4| 5: [BlockStmt] { ... }
# 5| 0: [LocalVariableDeclStmt] var ...;
# 5| 1: [LocalVariableDeclExpr] ref
# 5| 0: [MemberRefExpr] ...::...
# 5| -4: [AnonymousClass] new Function2<Ccc,Integer,Double>(...) { ... }
# 5| 1: [Constructor]
# 5| 5: [BlockStmt] { ... }
# 5| 0: [SuperConstructorInvocationStmt] super(...)
# 5| 1: [Method] invoke
#-----| 4: (Parameters)
# 5| 0: [Parameter] a0
# 5| 1: [Parameter] a1
# 5| 5: [BlockStmt] { ... }
# 5| 0: [ReturnStmt] return ...
# 5| 0: [MethodAccess] m(...)
# 5| -1: [VarAccess] a0
# 5| 0: [VarAccess] a1
# 5| -3: [TypeAccess] Function2<Ccc,Integer,Double>
# 6| 1: [ExprStmt] <Expr>;
# 6| 0: [MethodAccess] println(...)
# 6| -1: [TypeAccess] ConsoleKt
# 6| 0: [MethodAccess] getName(...)
# 6| -1: [VarAccess] ref
# 9| 4: [Class] Ccc
# 9| 1: [Constructor] Ccc
# 9| 5: [BlockStmt] { ... }
# 9| 0: [SuperConstructorInvocationStmt] super(...)
# 9| 1: [ExprStmt] <Expr>;
# 9| 0: [MethodAccess] <obinit>(...)
# 10| 3: [Method] m
#-----| 4: (Parameters)
# 10| 0: [Parameter] i
# 10| 5: [BlockStmt] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [DoubleLiteral] 5.0

View File

@@ -0,0 +1 @@
semmle/code/java/PrintAst.ql

View File

@@ -0,0 +1,5 @@
variableInitializerType
| reflection.kt:5:9:5:54 | KFunction<Double> ref | file://<external>/KFunction.class:0:0:0:0 | KFunction<Double> | reflection.kt:5:49:5:54 | new Function2<Ccc,Integer,Double>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Ccc,Integer,Double> | false |
| reflection.kt:5:9:5:54 | KFunction<Double> ref | file://<external>/KFunction.class:0:0:0:0 | KFunction<Double> | reflection.kt:5:49:5:54 | new Function2<Ccc,Integer,Double>(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | false |
invocation
| reflection.kt:6:21:6:24 | getName(...) | file://<external>/KCallable.class:0:0:0:0 | getName |

View File

@@ -0,0 +1,12 @@
import kotlin.reflect.KFunction2
class Reflection {
fun fn(boo: Boolean) {
val ref: KFunction2<Ccc, Int, Double> = Ccc::m
println(ref.name)
}
class Ccc {
fun m(i:Int):Double = 5.0
}
}

View File

@@ -0,0 +1,39 @@
import java
// Stop external filepaths from appearing in the results
class ClassOrInterfaceLocation extends ClassOrInterface {
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
exists(string fullPath | super.hasLocationInfo(fullPath, sl, sc, el, ec) |
if exists(this.getFile().getRelativePath())
then path = fullPath
else path = fullPath.regexpReplaceAll(".*/", "<external>/")
)
}
}
class CallableLocation extends Callable {
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
exists(string fullPath | super.hasLocationInfo(fullPath, sl, sc, el, ec) |
if exists(this.getFile().getRelativePath())
then path = fullPath
else path = fullPath.regexpReplaceAll(".*/", "<external>/")
)
}
}
query predicate variableInitializerType(
LocalVariableDecl decl, RefType t1, RefType t2, RefType t3, boolean implements
) {
decl.getType() = t1 and
decl.getInitializer().getType() = t2 and
t2.extendsOrImplements(t3) and
(
implements = true and t2.extendsOrImplements+(t1)
or
implements = false and not t2.extendsOrImplements+(t1)
)
}
query predicate invocation(Call c, Callable callee) {
c.getCallee() = callee and callee.getDeclaringType().getPackage().getName() = "kotlin.reflect"
}