Skip to content

Commit 381bcf7

Browse files
authored
Merge pull request #9153 from tamasvajk/kotlin-simplify-loop-breaks-1
Kotlin: Unify loop `break`/`continue` statement handling between java and kotlin
2 parents 6230a3a + cf18a9a commit 381bcf7

File tree

13 files changed

+5370
-2835
lines changed

13 files changed

+5370
-2835
lines changed

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

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2197,8 +2197,6 @@ open class KotlinFileExtractor(
21972197
}
21982198
}
21992199

2200-
private val loopIdMap: MutableMap<IrLoop, Label<out DbKtloopstmt>> = mutableMapOf()
2201-
22022200
// todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
22032201
private val declarationStack: Stack<IrDeclaration> = Stack()
22042202

@@ -2446,32 +2444,10 @@ open class KotlinFileExtractor(
24462444
}
24472445
}
24482446
is IrWhileLoop -> {
2449-
val stmtParent = parent.stmt(e, callable)
2450-
val id = tw.getFreshIdLabel<DbWhilestmt>()
2451-
loopIdMap[e] = id
2452-
val locId = tw.getLocation(e)
2453-
tw.writeStmts_whilestmt(id, stmtParent.parent, stmtParent.idx, callable)
2454-
tw.writeHasLocation(id, locId)
2455-
extractExpressionExpr(e.condition, callable, id, 0, id)
2456-
val body = e.body
2457-
if(body != null) {
2458-
extractExpressionStmt(body, callable, id, 1)
2459-
}
2460-
loopIdMap.remove(e)
2447+
extractLoop(e, parent, callable)
24612448
}
24622449
is IrDoWhileLoop -> {
2463-
val stmtParent = parent.stmt(e, callable)
2464-
val id = tw.getFreshIdLabel<DbDostmt>()
2465-
loopIdMap[e] = id
2466-
val locId = tw.getLocation(e)
2467-
tw.writeStmts_dostmt(id, stmtParent.parent, stmtParent.idx, callable)
2468-
tw.writeHasLocation(id, locId)
2469-
extractExpressionExpr(e.condition, callable, id, 0, id)
2470-
val body = e.body
2471-
if(body != null) {
2472-
extractExpressionStmt(body, callable, id, 1)
2473-
}
2474-
loopIdMap.remove(e)
2450+
extractLoop(e, parent, callable)
24752451
}
24762452
is IrInstanceInitializerCall -> {
24772453
val irConstructor = declarationStack.peek() as? IrConstructor
@@ -2988,6 +2964,49 @@ open class KotlinFileExtractor(
29882964
}
29892965
}
29902966

2967+
private fun extractLoop(
2968+
loop: IrLoop,
2969+
stmtExprParent: StmtExprParent,
2970+
callable: Label<out DbCallable>
2971+
) {
2972+
val stmtParent = stmtExprParent.stmt(loop, callable)
2973+
val locId = tw.getLocation(loop)
2974+
2975+
val idx: Int
2976+
val parent: Label<out DbStmtparent>
2977+
2978+
val label = loop.label
2979+
if (label != null) {
2980+
val labeledStmt = tw.getFreshIdLabel<DbLabeledstmt>()
2981+
tw.writeStmts_labeledstmt(labeledStmt, stmtParent.parent, stmtParent.idx, callable)
2982+
tw.writeHasLocation(labeledStmt, locId)
2983+
2984+
tw.writeNamestrings(label, "", labeledStmt)
2985+
idx = 0
2986+
parent = labeledStmt
2987+
} else {
2988+
idx = stmtParent.idx
2989+
parent = stmtParent.parent
2990+
}
2991+
2992+
val id = if (loop is IrWhileLoop) {
2993+
val id = tw.getFreshIdLabel<DbWhilestmt>()
2994+
tw.writeStmts_whilestmt(id, parent, idx, callable)
2995+
id
2996+
} else {
2997+
val id = tw.getFreshIdLabel<DbDostmt>()
2998+
tw.writeStmts_dostmt(id, parent, idx, callable)
2999+
id
3000+
}
3001+
3002+
tw.writeHasLocation(id, locId)
3003+
extractExpressionExpr(loop.condition, callable, id, 0, id)
3004+
val body = loop.body
3005+
if (body != null) {
3006+
extractExpressionStmt(body, callable, id, 1)
3007+
}
3008+
}
3009+
29913010
private fun IrValueParameter.isExtensionReceiver(): Boolean {
29923011
val parentFun = parent as? IrFunction ?: return false
29933012
return parentFun.extensionReceiverParameter == this
@@ -4261,7 +4280,7 @@ open class KotlinFileExtractor(
42614280

42624281
private fun extractBreakContinue(
42634282
e: IrBreakContinue,
4264-
id: Label<out DbBreakcontinuestmt>
4283+
id: Label<out DbNamedexprorstmt>
42654284
) {
42664285
with("break/continue", e) {
42674286
val locId = tw.getLocation(e)
@@ -4270,14 +4289,6 @@ open class KotlinFileExtractor(
42704289
if (label != null) {
42714290
tw.writeNamestrings(label, "", id)
42724291
}
4273-
4274-
val loopId = loopIdMap[e.loop]
4275-
if (loopId == null) {
4276-
logger.errorElement("Missing break/continue target", e)
4277-
return
4278-
}
4279-
4280-
tw.writeKtBreakContinueTargets(id, loopId)
42814292
}
42824293
}
42834294

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs.

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,

0 commit comments

Comments
 (0)