From a714515527b833df35650b0b13d9042e29b63689 Mon Sep 17 00:00:00 2001 From: Ivan Cilcic Date: Thu, 18 Jul 2019 16:34:58 +0300 Subject: [PATCH] Write break and continue parsing (light tree to FIR) --- .../converter/ExpressionsConverter.kt | 44 +++++++++++++++++-- .../fir/lightTree/compare/TreesCompareTest.kt | 11 +++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 50fb48f3ddf..12a3073fb5a 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -8,13 +8,12 @@ package org.jetbrains.kotlin.fir.lightTree.converter import com.intellij.lang.LighterASTNode import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes.* -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirReference -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.builder.* import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousFunctionImpl import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousObjectImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirErrorLoop import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* @@ -34,7 +33,6 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirExplicitSuperReference import org.jetbrains.kotlin.fir.references.FirExplicitThisReference import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference -import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl @@ -83,6 +81,7 @@ class ExpressionsConverter( DO_WHILE -> convertDoWhile(expression) WHILE -> convertWhile(expression) FOR -> convertFor(expression) + BREAK, CONTINUE -> convertLoopJump(expression) RETURN -> convertReturn(expression) PARENTHESIZED, PROPERTY_DELEGATE, INDICES -> convertExpression(expression.getExpressionInParentheses()) THIS_EXPRESSION -> convertThisExpression(expression) @@ -750,6 +749,43 @@ class ExpressionsConverter( return null } + /** + * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseJump + * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitBreakExpression + * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitContinueExpression + */ + private fun convertLoopJump(jump: LighterASTNode): FirExpression { + var isBreak = true + var labelName: String? = null + jump.forEachChildren { + when (it.tokenType) { + CONTINUE_KEYWORD -> isBreak = false + //BREAK -> isBreak = true + LABEL_QUALIFIER -> labelName = it.getAsString().replace("@", "") + } + } + + return (if (isBreak) FirBreakExpressionImpl(session, null) else FirContinueExpressionImpl(session, null)).apply { + target = FirLoopTarget(labelName) + val lastLoop = FunctionUtil.firLoops.lastOrNull() + if (labelName == null) { + if (lastLoop != null) { + target.bind(lastLoop) + } else { + target.bind(FirErrorLoop(this@ExpressionsConverter.session, null, "Cannot bind unlabeled jump to a loop")) + } + } else { + for (firLoop in FunctionUtil.firLoops.asReversed()) { + if (firLoop.label?.name == labelName) { + target.bind(firLoop) + return this + } + } + target.bind(FirErrorLoop(this@ExpressionsConverter.session, null, "Cannot bind label $labelName to a loop")) + } + } + } + /** * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseReturn * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitReturnExpression diff --git a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt index 3aef4aef624..f69bd9837ec 100644 --- a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt +++ b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt @@ -293,4 +293,15 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() { visitAnonymousObject = true ) } + + fun testLoopJump() { + compare( + stubMode = false, + visitAnnotation = true, + visitLoopJump = true, + visitLoops = true, + visitConstExpression = true, + visitQualifiedAccessExpression = true + ) + } }