FIR renderer: avoid StackOverflow when rendering loop jump condition
For example,
```
do {
...
} while(
when (...) {
... -> break
}
)
```
That `break` condition is `when` expression, and while visiting its
branch result, we will see the same `break` again.
This commit is contained in:
committed by
TeamCityServer
parent
b4a5eec5f4
commit
bb242f022f
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
fun FirElement.renderWithType(mode: FirRenderer.RenderMode = FirRenderer.RenderMode.Normal): String = buildString {
|
fun FirElement.renderWithType(mode: FirRenderer.RenderMode = FirRenderer.RenderMode.Normal): String = buildString {
|
||||||
@@ -780,12 +781,28 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
|||||||
whileLoop.block.accept(this)
|
whileLoop.block.accept(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val loopJumpStack = Stack<FirLoopJump>()
|
||||||
|
|
||||||
override fun visitLoopJump(loopJump: FirLoopJump) {
|
override fun visitLoopJump(loopJump: FirLoopJump) {
|
||||||
|
if (loopJumpStack.contains(loopJump)) {
|
||||||
|
// For example,
|
||||||
|
// do {
|
||||||
|
// ...
|
||||||
|
// } while(
|
||||||
|
// when (...) {
|
||||||
|
// ... -> break
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// That `break` condition is `when` expression, and while visiting its branch result, we will see the same `break` again.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loopJumpStack.push(loopJump)
|
||||||
val target = loopJump.target
|
val target = loopJump.target
|
||||||
val labeledElement = target.labeledElement
|
val labeledElement = target.labeledElement
|
||||||
print("@@@[")
|
print("@@@[")
|
||||||
labeledElement.condition.accept(this)
|
labeledElement.condition.accept(this)
|
||||||
print("] ")
|
print("] ")
|
||||||
|
loopJumpStack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBreakExpression(breakExpression: FirBreakExpression) {
|
override fun visitBreakExpression(breakExpression: FirBreakExpression) {
|
||||||
|
|||||||
Reference in New Issue
Block a user