New J2K: Add continue statement

This commit is contained in:
Ilya Kirillov
2018-10-15 15:02:31 +03:00
committed by Ilya Kirillov
parent ed61aac4fd
commit 0a08467b45
9 changed files with 71 additions and 10 deletions
@@ -391,6 +391,12 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
else
JKBreakStatementImpl()
}
is PsiContinueStatement -> {
val label = labelIdentifier?.let {
JKLabelTextImpl(JKNameIdentifierImpl(it.text))
} ?: JKLabelEmptyImpl()
JKContinueStatementImpl(label)
}
else -> TODO("for ${this::class}")
}.also {
if (this != null) backAnnotation[it] = this
@@ -300,6 +300,21 @@ class NewCodeBuilder {
printer.printWithNoIndent("super")
}
override fun visitContinueStatement(continueStatement: JKContinueStatement) {
printer.printWithNoIndent("continue ")
continueStatement.label.accept(this)
}
override fun visitLabelEmpty(labelEmpty: JKLabelEmpty) {
}
override fun visitLabelText(labelText: JKLabelText) {
printer.printWithNoIndent("@")
labelText.label.accept(this)
printer.printWithNoIndent(" ")
}
override fun visitPostfixExpression(postfixExpression: JKPostfixExpression) {
postfixExpression.expression.accept(this)
printer.printWithNoIndent(postfixExpression.operator.operatorText)
@@ -6,12 +6,9 @@
package org.jetbrains.kotlin.j2k.conversions
import com.intellij.psi.*
import jdk.nashorn.internal.ir.BlockStatement
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.ReferenceSearcher
import org.jetbrains.kotlin.j2k.ast.*
import org.jetbrains.kotlin.j2k.hasWriteAccesses
import org.jetbrains.kotlin.j2k.isInSingleLine
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.*
import org.jetbrains.kotlin.lexer.KtTokens
@@ -51,8 +48,9 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
if (loopStatement.updater is JKEmptyStatement) return loopStatement::body.detached()
val continueStatementConverter = object : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaContinueStatement) return recurse(element)
//TODO ??? if (statement.findContinuedStatement()?.toContinuedLoop() != this@ForConverter.statement) return null
if (element !is JKContinueStatement) return recurse(element)
val elementPsi = element.psi<PsiContinueStatement>()!!
if (elementPsi.findContinuedStatement()?.toContinuedLoop() != loopStatement.psi<PsiForStatement>()) return recurse(element)
val statements = listOf(loopStatement.updater, element)
return recurse(JKBlockStatementImpl(JKBlockImpl(statements)))
}
@@ -129,6 +127,14 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
return null
}
private fun PsiStatement.toContinuedLoop(): PsiLoopStatement? {
return when (this) {
is PsiLoopStatement -> this
is PsiLabeledStatement -> statement?.toContinuedLoop()
else -> null
}
}
private fun forIterationRange(
start: JKExpression,
bound: JKExpression,
@@ -71,6 +71,7 @@ class JKJavaOperatorImpl private constructor(val token: IElementType) : JKOperat
JavaTokenType.PLUSPLUS -> "++"
JavaTokenType.EXCL -> "!"
JavaTokenType.ASTERISKEQ -> "*="
JavaTokenType.EQEQ -> "=="
else -> TODO("TODO $token")
}
@@ -381,4 +381,17 @@ val JKStatement.statements: List<JKStatement>
when (this) {
is JKBlockStatement -> block.statements
else -> listOf(this)
}
}
class JKLabelEmptyImpl : JKLabelEmpty, JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLabelEmpty(this, data)
}
class JKLabelTextImpl(label: JKNameIdentifier) : JKLabelText, JKBranchElementBase() {
override val label: JKNameIdentifier by child(label)
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLabelText(this, data)
}
class JKContinueStatementImpl(label: JKLabel) : JKContinueStatement, JKBranchElementBase() {
override var label: JKLabel by child(label)
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitContinueStatement(this, data)
}
@@ -286,7 +286,3 @@ class JKKtOperatorExpressionImpl(
override var argument: JKExpression by child(argument)
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtOperatorExpression(this, data)
}
class JKJavaContinueStatementImpl() : JKJavaContinueStatement, JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaContinueStatement(this, data)
}
@@ -250,3 +250,15 @@ interface JKDelegationConstructorCall : JKMethodCallExpression {
val expression: JKExpression
override val arguments: JKExpressionList
}
interface JKLabel : JKTreeElement
interface JKLabelEmpty : JKLabel
interface JKLabelText : JKLabel {
val label: JKNameIdentifier
}
interface JKContinueStatement : JKStatement {
var label: JKLabel
}
@@ -54,6 +54,10 @@ interface JKVisitor<out R, in D> {
fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: D): R = visitExpression(assignableExpression, data)
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: D): R = visitExpression(lambdaExpression, data)
fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall, data: D): R = visitMethodCallExpression(delegationConstructorCall, data)
fun visitLabel(label: JKLabel, data: D): R = visitTreeElement(label, data)
fun visitLabelEmpty(labelEmpty: JKLabelEmpty, data: D): R = visitLabel(labelEmpty, data)
fun visitLabelText(labelText: JKLabelText, data: D): R = visitLabel(labelText, data)
fun visitContinueStatement(continueStatement: JKContinueStatement, data: D): R = visitStatement(continueStatement, data)
fun visitJavaField(javaField: JKJavaField, data: D): R = visitField(javaField, data)
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: D): R = visitMethodCallExpression(javaMethodCallExpression, data)
@@ -105,6 +105,14 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: Nothing?) = visitLambdaExpression(lambdaExpression)
fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall, null)
override fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall, data: Nothing?) = visitDelegationConstructorCall(delegationConstructorCall)
fun visitLabel(label: JKLabel) = visitTreeElement(label, null)
override fun visitLabel(label: JKLabel, data: Nothing?) = visitLabel(label)
fun visitLabelEmpty(labelEmpty: JKLabelEmpty) = visitLabel(labelEmpty, null)
override fun visitLabelEmpty(labelEmpty: JKLabelEmpty, data: Nothing?) = visitLabelEmpty(labelEmpty)
fun visitLabelText(labelText: JKLabelText) = visitLabel(labelText, null)
override fun visitLabelText(labelText: JKLabelText, data: Nothing?) = visitLabelText(labelText)
fun visitContinueStatement(continueStatement: JKContinueStatement) = visitStatement(continueStatement, null)
override fun visitContinueStatement(continueStatement: JKContinueStatement, data: Nothing?) = visitContinueStatement(continueStatement)
fun visitJavaField(javaField: JKJavaField) = visitField(javaField, null)
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
fun visitJavaMethod(javaMethod: JKJavaMethod) = visitMethod(javaMethod, null)