Unify loop break/continue statement handling between java and kotlin

This commit is contained in:
Tamas Vajk
2022-05-03 10:48:51 +02:00
parent b609f1ea52
commit dabc956dbf
6 changed files with 49 additions and 75 deletions

View File

@@ -2153,8 +2153,6 @@ open class KotlinFileExtractor(
} }
} }
private val loopIdMap: MutableMap<IrLoop, Label<out DbKtloopstmt>> = mutableMapOf()
// todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain // todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
private val declarationStack: Stack<IrDeclaration> = Stack() private val declarationStack: Stack<IrDeclaration> = Stack()
@@ -2402,32 +2400,10 @@ open class KotlinFileExtractor(
} }
} }
is IrWhileLoop -> { is IrWhileLoop -> {
val stmtParent = parent.stmt(e, callable) extractLoop(e, parent, callable)
val id = tw.getFreshIdLabel<DbWhilestmt>()
loopIdMap[e] = id
val locId = tw.getLocation(e)
tw.writeStmts_whilestmt(id, stmtParent.parent, stmtParent.idx, callable)
tw.writeHasLocation(id, locId)
extractExpressionExpr(e.condition, callable, id, 0, id)
val body = e.body
if(body != null) {
extractExpressionStmt(body, callable, id, 1)
}
loopIdMap.remove(e)
} }
is IrDoWhileLoop -> { is IrDoWhileLoop -> {
val stmtParent = parent.stmt(e, callable) extractLoop(e, parent, callable)
val id = tw.getFreshIdLabel<DbDostmt>()
loopIdMap[e] = id
val locId = tw.getLocation(e)
tw.writeStmts_dostmt(id, stmtParent.parent, stmtParent.idx, callable)
tw.writeHasLocation(id, locId)
extractExpressionExpr(e.condition, callable, id, 0, id)
val body = e.body
if(body != null) {
extractExpressionStmt(body, callable, id, 1)
}
loopIdMap.remove(e)
} }
is IrInstanceInitializerCall -> { is IrInstanceInitializerCall -> {
val stmtParent = parent.stmt(e, callable) val stmtParent = parent.stmt(e, callable)
@@ -2928,6 +2904,49 @@ open class KotlinFileExtractor(
} }
} }
private fun extractLoop(
loop: IrLoop,
stmtExprParent: StmtExprParent,
callable: Label<out DbCallable>
) {
val stmtParent = stmtExprParent.stmt(loop, callable)
val locId = tw.getLocation(loop)
val idx: Int
val parent: Label<out DbStmtparent>
val label = loop.label
if (label != null) {
val labeledStmt = tw.getFreshIdLabel<DbLabeledstmt>()
tw.writeStmts_labeledstmt(labeledStmt, stmtParent.parent, stmtParent.idx, callable)
tw.writeHasLocation(labeledStmt, locId)
tw.writeNamestrings(label, "", labeledStmt)
idx = 0
parent = labeledStmt
} else {
idx = stmtParent.idx
parent = stmtParent.parent
}
val id = if (loop is IrWhileLoop) {
val id = tw.getFreshIdLabel<DbWhilestmt>()
tw.writeStmts_whilestmt(id, parent, idx, callable)
id
} else {
val id = tw.getFreshIdLabel<DbDostmt>()
tw.writeStmts_dostmt(id, parent, idx, callable)
id
}
tw.writeHasLocation(id, locId)
extractExpressionExpr(loop.condition, callable, id, 0, id)
val body = loop.body
if (body != null) {
extractExpressionStmt(body, callable, id, 1)
}
}
private fun IrValueParameter.isExtensionReceiver(): Boolean { private fun IrValueParameter.isExtensionReceiver(): Boolean {
val parentFun = parent as? IrFunction ?: return false val parentFun = parent as? IrFunction ?: return false
return parentFun.extensionReceiverParameter == this return parentFun.extensionReceiverParameter == this
@@ -4201,7 +4220,7 @@ open class KotlinFileExtractor(
private fun extractBreakContinue( private fun extractBreakContinue(
e: IrBreakContinue, e: IrBreakContinue,
id: Label<out DbBreakcontinuestmt> id: Label<out DbNamedexprorstmt>
) { ) {
with("break/continue", e) { with("break/continue", e) {
val locId = tw.getLocation(e) val locId = tw.getLocation(e)
@@ -4210,14 +4229,6 @@ open class KotlinFileExtractor(
if (label != null) { if (label != null) {
tw.writeNamestrings(label, "", id) tw.writeNamestrings(label, "", id)
} }
val loopId = loopIdMap[e.loop]
if (loopId == null) {
logger.errorElement("Missing break/continue target", e)
return
}
tw.writeKtBreakContinueTargets(id, loopId)
} }
} }

View File

@@ -1165,17 +1165,6 @@ ktCommentOwners(
int owner: @top ref int owner: @top ref
) )
@breakcontinuestmt = @breakstmt
| @continuestmt;
@ktloopstmt = @whilestmt
| @dostmt;
ktBreakContinueTargets(
unique int id: @breakcontinuestmt ref,
int target: @ktloopstmt ref
)
ktExtensionFunctions( ktExtensionFunctions(
unique int id: @method ref, unique int id: @method ref,
int typeid: @type ref, int typeid: @type ref,

View File

@@ -888,27 +888,3 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr
override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" } override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" }
} }
/** A Kotlin loop statement. */
class KtLoopStmt extends Stmt, @ktloopstmt {
KtLoopStmt() {
this instanceof WhileStmt or
this instanceof DoStmt
}
}
/** A Kotlin `break` or `continue` statement. */
abstract class KtBreakContinueStmt extends Stmt, @breakcontinuestmt {
KtLoopStmt loop;
KtBreakContinueStmt() { ktBreakContinueTargets(this, loop) }
/** Gets the target loop statement of this `break`. */
KtLoopStmt getLoopStmt() { result = loop }
}
/** A Kotlin `break` statement. */
class KtBreakStmt extends BreakStmt, KtBreakContinueStmt { }
/** A Kotlin `continue` statement. */
class KtContinueStmt extends ContinueStmt, KtBreakContinueStmt { }

View File

@@ -1,7 +1,6 @@
breakLabel breakLabel
| stmts.kt:25:24:25:33 | break | loop | | stmts.kt:25:24:25:33 | break | loop |
continueLabel continueLabel
breakTarget jumpTarget
| stmts.kt:25:24:25:33 | break | stmts.kt:23:11:27:5 | while (...) | | stmts.kt:25:24:25:33 | break | stmts.kt:23:11:27:5 | while (...) |
continueTarget
| stmts.kt:29:9:29:16 | continue | stmts.kt:28:5:29:16 | while (...) | | stmts.kt:29:9:29:16 | continue | stmts.kt:28:5:29:16 | while (...) |

View File

@@ -4,6 +4,4 @@ query predicate breakLabel(BreakStmt s, string label) { s.getLabel() = label }
query predicate continueLabel(ContinueStmt s, string label) { s.getLabel() = label } query predicate continueLabel(ContinueStmt s, string label) { s.getLabel() = label }
query predicate breakTarget(KtBreakStmt s, KtLoopStmt l) { s.getLoopStmt() = l } query predicate jumpTarget(JumpStmt s, StmtParent p) { s.getTarget() = p }
query predicate continueTarget(KtContinueStmt s, KtLoopStmt l) { s.getLoopStmt() = l }

View File

@@ -80,6 +80,7 @@ enclosing
| stmts.kt:18:52:18:52 | <Expr>; | ExprStmt | | stmts.kt:18:52:18:52 | <Expr>; | ExprStmt |
| stmts.kt:19:5:19:16 | return ... | ReturnStmt | | stmts.kt:19:5:19:16 | return ... | ReturnStmt |
| stmts.kt:22:27:30:1 | { ... } | BlockStmt | | stmts.kt:22:27:30:1 | { ... } | BlockStmt |
| stmts.kt:23:11:27:5 | <Label>: ... | LabeledStmt |
| stmts.kt:23:11:27:5 | while (...) | WhileStmt | | stmts.kt:23:11:27:5 | while (...) | WhileStmt |
| stmts.kt:23:27:27:5 | { ... } | BlockStmt | | stmts.kt:23:27:27:5 | { ... } | BlockStmt |
| stmts.kt:24:9:26:25 | do ... while (...) | DoStmt | | stmts.kt:24:9:26:25 | do ... while (...) | DoStmt |