Add lateinit test to print the extracted AST

This commit is contained in:
Tamas Vajk
2022-10-05 16:08:57 +02:00
parent 082544e88c
commit 46fb9865ac
5 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
test.kt:
# 0| [CompilationUnit] test
# 1| 1: [Class] LateInit
# 1| 1: [Constructor] LateInit
# 1| 5: [BlockStmt] { ... }
# 1| 0: [SuperConstructorInvocationStmt] super(...)
# 1| 1: [BlockStmt] { ... }
# 2| 2: [FieldDeclaration] LateInit test0;
# 2| -1: [TypeAccess] LateInit
# 2| 3: [Method] getTest0$private
# 2| 3: [TypeAccess] LateInit
# 2| 5: [BlockStmt] { ... }
# 2| 0: [ReturnStmt] return ...
# 2| 0: [VarAccess] this.test0
# 2| -1: [ThisAccess] this
# 2| 4: [Method] setTest0$private
# 2| 3: [TypeAccess] Unit
#-----| 4: (Parameters)
# 2| 0: [Parameter] <set-?>
# 2| 0: [TypeAccess] LateInit
# 2| 5: [BlockStmt] { ... }
# 2| 0: [ExprStmt] <Expr>;
# 2| 0: [AssignExpr] ...=...
# 2| 0: [VarAccess] this.test0
# 2| -1: [ThisAccess] this
# 2| 1: [VarAccess] <set-?>
# 4| 5: [Method] f
# 4| 3: [TypeAccess] Unit
# 4| 5: [BlockStmt] { ... }
# 4| 0: [ReturnStmt] return ...
# 4| 0: [MethodAccess] println(...)
# 4| -1: [TypeAccess] ConsoleKt
# 4| 0: [StringLiteral] a
# 6| 6: [Method] init
# 6| 3: [TypeAccess] LateInit
# 6| 5: [BlockStmt] { ... }
# 6| 0: [ReturnStmt] return ...
# 6| 0: [ClassInstanceExpr] new LateInit(...)
# 6| -3: [TypeAccess] LateInit
# 8| 7: [Method] fn
# 8| 3: [TypeAccess] Unit
# 8| 5: [BlockStmt] { ... }
# 9| 0: [ExprStmt] <Expr>;
# 9| 0: [MethodAccess] f(...)
# 9| -1: [MethodAccess] getTest0$private(...)
# 9| -1: [ThisAccess] this
# 10| 1: [ExprStmt] <Expr>;
# 10| 0: [WhenExpr] when ...
# 10| 0: [WhenBranch] ... -> ...
# 10| 0: [MethodAccess] isInitialized(...)
# 10| -1: [TypeAccess] LateinitKt
# 10| 0: [PropertyRefExpr] ...::...
# 10| -4: [AnonymousClass] new KMutableProperty0<LateInit>(...) { ... }
# 10| 1: [Constructor]
#-----| 4: (Parameters)
# 10| 0: [Parameter] <dispatchReceiver>
# 10| 5: [BlockStmt] { ... }
# 10| 0: [SuperConstructorInvocationStmt] super(...)
# 10| 1: [ExprStmt] <Expr>;
# 10| 0: [AssignExpr] ...=...
# 10| 0: [VarAccess] this.<dispatchReceiver>
# 10| -1: [ThisAccess] this
# 10| 1: [VarAccess] <dispatchReceiver>
# 10| 2: [FieldDeclaration] LateInit <dispatchReceiver>;
# 10| -1: [TypeAccess] LateInit
# 10| 3: [Method] get
# 10| 5: [BlockStmt] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [MethodAccess] getTest0$private(...)
# 10| -1: [VarAccess] this.<dispatchReceiver>
# 10| -1: [ThisAccess] this
# 10| 4: [Method] invoke
# 10| 5: [BlockStmt] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [MethodAccess] get(...)
# 10| -1: [ThisAccess] this
# 10| 5: [Method] set
#-----| 4: (Parameters)
# 10| 0: [Parameter] a0
# 10| 5: [BlockStmt] { ... }
# 10| 0: [ReturnStmt] return ...
# 10| 0: [MethodAccess] setTest0$private(...)
# 10| -1: [VarAccess] this.<dispatchReceiver>
# 10| -1: [ThisAccess] this
# 10| 0: [VarAccess] a0
# 10| -3: [TypeAccess] KMutableProperty0<LateInit>
# 10| 0: [TypeAccess] LateInit
# 10| 0: [ThisAccess] this
# 10| 1: [BlockStmt] { ... }
# 13| 2: [LocalVariableDeclStmt] var ...;
# 13| 1: [LocalVariableDeclExpr] test1
# 14| 3: [ExprStmt] <Expr>;
# 14| 0: [MethodAccess] f(...)
# 14| -1: [VarAccess] test1

View File

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

View File

@@ -0,0 +1,8 @@
| test.kt:4:15:4:26 | println(...) | file://<external>/ConsoleKt.class:0:0:0:0 | println |
| test.kt:9:9:9:13 | getTest0$private(...) | test.kt:2:22:2:40 | getTest0$private |
| test.kt:9:15:9:17 | f(...) | test.kt:4:5:4:26 | f |
| test.kt:10:13:10:23 | get(...) | test.kt:10:13:10:23 | get |
| test.kt:10:13:10:23 | getTest0$private(...) | test.kt:2:22:2:40 | getTest0$private |
| test.kt:10:13:10:23 | setTest0$private(...) | test.kt:2:22:2:40 | setTest0$private |
| test.kt:10:25:10:37 | isInitialized(...) | file://<external>/LateinitKt.class:0:0:0:0 | isInitialized |
| test.kt:14:15:14:17 | f(...) | test.kt:4:5:4:26 | f |

View File

@@ -0,0 +1,16 @@
public class LateInit {
private lateinit var test0: LateInit
fun f() = println("a")
fun init() = LateInit()
fun fn() {
test0.f() // This is preceded by a null-check and a throw in bytecode, in IR it's a simple call
if (this::test0.isInitialized) { // This is converted to a null-check in bytecode, in IR it's a call to `LateinitKt.isInitialized`
}
lateinit var test1: LateInit
test1.f() // This is replaced by `Intrinsics.throwUninitializedPropertyAccessException` in bytecode, in IR it's a simple call
}
}

View File

@@ -0,0 +1,13 @@
import java
class MethodLocation extends Method {
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 calls(MethodAccess ma, Method m) { ma.getMethod() = m }