Skip to content

Commit dabc956

Browse files
committed
Unify loop break/continue statement handling between java and kotlin
1 parent b609f1e commit dabc956

File tree

6 files changed

+49
-75
lines changed

6 files changed

+49
-75
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,8 +2153,6 @@ open class KotlinFileExtractor(
21532153
}
21542154
}
21552155

2156-
private val loopIdMap: MutableMap<IrLoop, Label<out DbKtloopstmt>> = mutableMapOf()
2157-
21582156
// todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
21592157
private val declarationStack: Stack<IrDeclaration> = Stack()
21602158

@@ -2402,32 +2400,10 @@ open class KotlinFileExtractor(
24022400
}
24032401
}
24042402
is IrWhileLoop -> {
2405-
val stmtParent = parent.stmt(e, callable)
2406-
val id = tw.getFreshIdLabel<DbWhilestmt>()
2407-
loopIdMap[e] = id
2408-
val locId = tw.getLocation(e)
2409-
tw.writeStmts_whilestmt(id, stmtParent.parent, stmtParent.idx, callable)
2410-
tw.writeHasLocation(id, locId)
2411-
extractExpressionExpr(e.condition, callable, id, 0, id)
2412-
val body = e.body
2413-
if(body != null) {
2414-
extractExpressionStmt(body, callable, id, 1)
2415-
}
2416-
loopIdMap.remove(e)
2403+
extractLoop(e, parent, callable)
24172404
}
24182405
is IrDoWhileLoop -> {
2419-
val stmtParent = parent.stmt(e, callable)
2420-
val id = tw.getFreshIdLabel<DbDostmt>()
2421-
loopIdMap[e] = id
2422-
val locId = tw.getLocation(e)
2423-
tw.writeStmts_dostmt(id, stmtParent.parent, stmtParent.idx, callable)
2424-
tw.writeHasLocation(id, locId)
2425-
extractExpressionExpr(e.condition, callable, id, 0, id)
2426-
val body = e.body
2427-
if(body != null) {
2428-
extractExpressionStmt(body, callable, id, 1)
2429-
}
2430-
loopIdMap.remove(e)
2406+
extractLoop(e, parent, callable)
24312407
}
24322408
is IrInstanceInitializerCall -> {
24332409
val stmtParent = parent.stmt(e, callable)
@@ -2928,6 +2904,49 @@ open class KotlinFileExtractor(
29282904
}
29292905
}
29302906

2907+
private fun extractLoop(
2908+
loop: IrLoop,
2909+
stmtExprParent: StmtExprParent,
2910+
callable: Label<out DbCallable>
2911+
) {
2912+
val stmtParent = stmtExprParent.stmt(loop, callable)
2913+
val locId = tw.getLocation(loop)
2914+
2915+
val idx: Int
2916+
val parent: Label<out DbStmtparent>
2917+
2918+
val label = loop.label
2919+
if (label != null) {
2920+
val labeledStmt = tw.getFreshIdLabel<DbLabeledstmt>()
2921+
tw.writeStmts_labeledstmt(labeledStmt, stmtParent.parent, stmtParent.idx, callable)
2922+
tw.writeHasLocation(labeledStmt, locId)
2923+
2924+
tw.writeNamestrings(label, "", labeledStmt)
2925+
idx = 0
2926+
parent = labeledStmt
2927+
} else {
2928+
idx = stmtParent.idx
2929+
parent = stmtParent.parent
2930+
}
2931+
2932+
val id = if (loop is IrWhileLoop) {
2933+
val id = tw.getFreshIdLabel<DbWhilestmt>()
2934+
tw.writeStmts_whilestmt(id, parent, idx, callable)
2935+
id
2936+
} else {
2937+
val id = tw.getFreshIdLabel<DbDostmt>()
2938+
tw.writeStmts_dostmt(id, parent, idx, callable)
2939+
id
2940+
}
2941+
2942+
tw.writeHasLocation(id, locId)
2943+
extractExpressionExpr(loop.condition, callable, id, 0, id)
2944+
val body = loop.body
2945+
if (body != null) {
2946+
extractExpressionStmt(body, callable, id, 1)
2947+
}
2948+
}
2949+
29312950
private fun IrValueParameter.isExtensionReceiver(): Boolean {
29322951
val parentFun = parent as? IrFunction ?: return false
29332952
return parentFun.extensionReceiverParameter == this
@@ -4201,7 +4220,7 @@ open class KotlinFileExtractor(
42014220

42024221
private fun extractBreakContinue(
42034222
e: IrBreakContinue,
4204-
id: Label<out DbBreakcontinuestmt>
4223+
id: Label<out DbNamedexprorstmt>
42054224
) {
42064225
with("break/continue", e) {
42074226
val locId = tw.getLocation(e)
@@ -4210,14 +4229,6 @@ open class KotlinFileExtractor(
42104229
if (label != null) {
42114230
tw.writeNamestrings(label, "", id)
42124231
}
4213-
4214-
val loopId = loopIdMap[e.loop]
4215-
if (loopId == null) {
4216-
logger.errorElement("Missing break/continue target", e)
4217-
return
4218-
}
4219-
4220-
tw.writeKtBreakContinueTargets(id, loopId)
42214232
}
42224233
}
42234234

java/ql/lib/config/semmlecode.dbscheme

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,17 +1165,6 @@ ktCommentOwners(
11651165
int owner: @top ref
11661166
)
11671167

1168-
@breakcontinuestmt = @breakstmt
1169-
| @continuestmt;
1170-
1171-
@ktloopstmt = @whilestmt
1172-
| @dostmt;
1173-
1174-
ktBreakContinueTargets(
1175-
unique int id: @breakcontinuestmt ref,
1176-
int target: @ktloopstmt ref
1177-
)
1178-
11791168
ktExtensionFunctions(
11801169
unique int id: @method ref,
11811170
int typeid: @type ref,

java/ql/lib/semmle/code/java/Statement.qll

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -888,27 +888,3 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr
888888

889889
override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" }
890890
}
891-
892-
/** A Kotlin loop statement. */
893-
class KtLoopStmt extends Stmt, @ktloopstmt {
894-
KtLoopStmt() {
895-
this instanceof WhileStmt or
896-
this instanceof DoStmt
897-
}
898-
}
899-
900-
/** A Kotlin `break` or `continue` statement. */
901-
abstract class KtBreakContinueStmt extends Stmt, @breakcontinuestmt {
902-
KtLoopStmt loop;
903-
904-
KtBreakContinueStmt() { ktBreakContinueTargets(this, loop) }
905-
906-
/** Gets the target loop statement of this `break`. */
907-
KtLoopStmt getLoopStmt() { result = loop }
908-
}
909-
910-
/** A Kotlin `break` statement. */
911-
class KtBreakStmt extends BreakStmt, KtBreakContinueStmt { }
912-
913-
/** A Kotlin `continue` statement. */
914-
class KtContinueStmt extends ContinueStmt, KtBreakContinueStmt { }
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
breakLabel
22
| stmts.kt:25:24:25:33 | break | loop |
33
continueLabel
4-
breakTarget
4+
jumpTarget
55
| stmts.kt:25:24:25:33 | break | stmts.kt:23:11:27:5 | while (...) |
6-
continueTarget
76
| stmts.kt:29:9:29:16 | continue | stmts.kt:28:5:29:16 | while (...) |

java/ql/test/kotlin/library-tests/stmts/loops.ql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@ query predicate breakLabel(BreakStmt s, string label) { s.getLabel() = label }
44

55
query predicate continueLabel(ContinueStmt s, string label) { s.getLabel() = label }
66

7-
query predicate breakTarget(KtBreakStmt s, KtLoopStmt l) { s.getLoopStmt() = l }
8-
9-
query predicate continueTarget(KtContinueStmt s, KtLoopStmt l) { s.getLoopStmt() = l }
7+
query predicate jumpTarget(JumpStmt s, StmtParent p) { s.getTarget() = p }

java/ql/test/kotlin/library-tests/stmts/stmts.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enclosing
8080
| stmts.kt:18:52:18:52 | <Expr>; | ExprStmt |
8181
| stmts.kt:19:5:19:16 | return ... | ReturnStmt |
8282
| stmts.kt:22:27:30:1 | { ... } | BlockStmt |
83+
| stmts.kt:23:11:27:5 | <Label>: ... | LabeledStmt |
8384
| stmts.kt:23:11:27:5 | while (...) | WhileStmt |
8485
| stmts.kt:23:27:27:5 | { ... } | BlockStmt |
8586
| stmts.kt:24:9:26:25 | do ... while (...) | DoStmt |

0 commit comments

Comments
 (0)