New J2K: Add Java for loop to Kotlin while or for in loop conversion
This commit is contained in:
committed by
Ilya Kirillov
parent
07f99fe0d2
commit
ed61aac4fd
@@ -50,6 +50,7 @@ object ConversionsRunner {
|
||||
+BinaryExpressionConversion()
|
||||
+SwitchStatementConversion(context)
|
||||
+InstanceofConversion()
|
||||
+ForConversion(context)
|
||||
}
|
||||
|
||||
fun doApply(trees: List<JKTreeElement>, context: ConversionContext) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
|
||||
class JKSymbolProvider {
|
||||
@@ -36,6 +37,7 @@ class JKSymbolProvider {
|
||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
||||
is PsiField -> JKMultiverseFieldSymbol(psi)
|
||||
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi)
|
||||
is KtProperty -> JKMultiversePropertySymbol(psi)
|
||||
else -> TODO(psi::class.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,15 @@ class NewCodeBuilder {
|
||||
printer.print("/* !!! Hit visitElement for element type: ${treeElement::class} !!! */")
|
||||
}
|
||||
|
||||
override fun visitKtForInStatement(ktForInStatement: JKKtForInStatement) {
|
||||
printer.printWithNoIndent("for (")
|
||||
printer.printWithNoIndent(ktForInStatement.variableIdentifier.value)
|
||||
printer.printWithNoIndent(" in ")
|
||||
ktForInStatement.iterationExpression.accept(this)
|
||||
printer.printWithNoIndent(") ")
|
||||
ktForInStatement.body.accept(this)
|
||||
}
|
||||
|
||||
override fun visitDoWhileStatement(doWhileStatement: JKDoWhileStatement) {
|
||||
printer.printWithNoIndent("do")
|
||||
doWhileStatement.body.accept(this)
|
||||
@@ -226,6 +235,13 @@ class NewCodeBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitKtOperatorExpression(ktOperatorExpression: JKKtOperatorExpression) {
|
||||
ktOperatorExpression.receiver.accept(this)
|
||||
printer.printWithNoIndent(" ")
|
||||
printer.printWithNoIndent(ktOperatorExpression.identifier.name)
|
||||
printer.printWithNoIndent(" ")
|
||||
ktOperatorExpression.argument.accept(this)
|
||||
}
|
||||
|
||||
override fun visitIfElseExpression(ifElseExpression: JKIfElseExpression) {
|
||||
printer.printWithNoIndent("if (")
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
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
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
|
||||
class ForConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||
private val referenceSearcher: ReferenceSearcher
|
||||
get() = context.converter.converterServices.oldServices.referenceSearcher
|
||||
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKJavaForLoopStatement) return recurse(element)
|
||||
|
||||
convertToForeach(element)?.also { return recurse(it) }
|
||||
convertToWhile(element)?.also { return recurse(it) }
|
||||
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
private fun convertToWhile(loopStatement: JKJavaForLoopStatement): JKStatement? {
|
||||
val whileBody = createWhileBody(loopStatement)
|
||||
|
||||
val whileStatement =
|
||||
JKWhileStatementImpl(
|
||||
if (loopStatement.condition !is JKStubExpression) loopStatement.condition.detached()
|
||||
else JKKtLiteralExpressionImpl("true", JKLiteralExpression.LiteralType.BOOLEAN),
|
||||
whileBody
|
||||
)
|
||||
val whileStatement = JKWhileStatementImpl(condition, whileBody)
|
||||
|
||||
if (loopStatement.initializer is JKEmptyStatement) return whileStatement
|
||||
//TODO check for error conflict
|
||||
return JKBlockStatementImpl(JKBlockImpl(listOf(loopStatement.initializer.detached(), whileStatement)))
|
||||
}
|
||||
|
||||
private fun createWhileBody(loopStatement: JKJavaForLoopStatement): JKStatement {
|
||||
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
|
||||
val statements = listOf(loopStatement.updater, element)
|
||||
return recurse(JKBlockStatementImpl(JKBlockImpl(statements)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val body = loopStatement.body
|
||||
|
||||
if (body is JKBlockStatement) {
|
||||
val initializer = loopStatement.initializer
|
||||
val hasNameConflict =
|
||||
initializer is JKDeclarationStatement && initializer.declaredStatements.any { loopVar ->
|
||||
loopVar is JKLocalVariable && body.statements.any { statement ->
|
||||
statement is JKDeclarationStatement && statement.declaredStatements.any {
|
||||
it is JKLocalVariable && it.name == loopVar.name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val statements =
|
||||
if (hasNameConflict) {
|
||||
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement.updater)
|
||||
} else {
|
||||
body.block.statements + loopStatement.updater
|
||||
}
|
||||
return JKBlockStatementImpl(JKBlockImpl(statements.map { it.detached() }))
|
||||
} else {
|
||||
val statements =
|
||||
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement::updater.detached())
|
||||
return JKBlockStatementImpl(JKBlockImpl(statements.map { it.detached() }))
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertToForeach(loopStatement: JKJavaForLoopStatement): JKKtForInStatement? {
|
||||
val loopVar =
|
||||
(loopStatement.initializer as? JKDeclarationStatement)?.declaredStatements?.singleOrNull() as? JKLocalVariable ?: return null
|
||||
val loopVarPsi = loopVar.psi<PsiLocalVariable>() ?: return null
|
||||
val condition = loopStatement.condition as? JKBinaryExpression ?: return null
|
||||
if (!loopVarPsi.hasWriteAccesses(referenceSearcher, loopStatement.body.psi())
|
||||
&& !loopVarPsi.hasWriteAccesses(referenceSearcher, loopStatement.condition.psi())
|
||||
) {
|
||||
val left = condition.left as? JKFieldAccessExpression ?: return null
|
||||
val right = condition.right
|
||||
if (right.psi<PsiExpression>()?.type in listOf(PsiType.DOUBLE, PsiType.FLOAT, PsiType.CHAR)) return null
|
||||
if (left.identifier.target != loopVar) return null
|
||||
val start = loopVar.initializer
|
||||
val operationType =
|
||||
(loopStatement.updater as? JKExpressionStatement)?.expression?.isVariableIncrementOrDecrement(loopVar)
|
||||
val reversed = when ((operationType as? JKJavaOperatorImpl)?.token) {
|
||||
JavaTokenType.PLUSPLUS -> false
|
||||
JavaTokenType.MINUSMINUS -> true
|
||||
else -> return null
|
||||
}
|
||||
val inclusive = when ((condition.operator as? JKJavaOperatorImpl)?.token ?: (condition.operator as? JKKtOperatorImpl)?.token) {
|
||||
JavaTokenType.LT, KtTokens.LT -> if (reversed) return null else false
|
||||
JavaTokenType.LE, KtTokens.LTEQ -> if (reversed) return null else true
|
||||
JavaTokenType.GT, KtTokens.GT -> if (reversed) false else return null
|
||||
JavaTokenType.GE, KtTokens.GTEQ -> if (reversed) true else return null
|
||||
JavaTokenType.NE, KtTokens.EXCLEQ -> false
|
||||
else -> return null
|
||||
}
|
||||
val range = forIterationRange(start, right, reversed, inclusive, loopVarPsi)
|
||||
//TODO for loop explicitType
|
||||
// val explicitType = if (context.converter.settings.specifyLocalVariableTypeByDefault)
|
||||
// JKJavaPrimitiveTypeImpl.INT
|
||||
// else null
|
||||
return JKKtForInStatementImpl(
|
||||
loopVar.name.detached(),
|
||||
range.detached(),
|
||||
loopStatement.body.detached()
|
||||
)
|
||||
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun forIterationRange(
|
||||
start: JKExpression,
|
||||
bound: JKExpression,
|
||||
reversed: Boolean,
|
||||
inclusiveComparison: Boolean,
|
||||
psiContext: PsiElement
|
||||
): JKExpression {
|
||||
indicesIterationRange(start, bound, reversed, inclusiveComparison)?.also { return it }
|
||||
if (start.parent != null) start.detach(start.parent!!)
|
||||
if (bound.parent != null) bound.detach(bound.parent!!)
|
||||
return when {
|
||||
reversed -> downToExpression(
|
||||
start,
|
||||
convertBound(bound, if (inclusiveComparison) 0 else +1),
|
||||
context,
|
||||
psiContext
|
||||
)
|
||||
bound !is JKKtLiteralExpression && !inclusiveComparison ->
|
||||
untilToExpression(
|
||||
start,
|
||||
convertBound(bound, 0),
|
||||
context,
|
||||
psiContext
|
||||
)
|
||||
else -> JKBinaryExpressionImpl(
|
||||
start,
|
||||
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
||||
JKKtOperatorImpl.tokenToOperator[KtTokens.RANGE]!!
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertBound(bound: JKExpression, correction: Int): JKExpression {
|
||||
if (correction == 0) return bound
|
||||
|
||||
if (bound is JKLiteralExpression && bound.type == JKLiteralExpression.LiteralType.INT) {
|
||||
val value = bound.literal.toInt()
|
||||
return JKKtLiteralExpressionImpl((value + correction).toString(), bound.type)
|
||||
}
|
||||
|
||||
val sign = if (correction > 0) KtTokens.PLUS else KtTokens.MINUS
|
||||
return JKBinaryExpressionImpl(
|
||||
bound,
|
||||
JKKtLiteralExpressionImpl(Math.abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||
JKKtOperatorImpl.tokenToOperator[sign]!!
|
||||
)
|
||||
}
|
||||
|
||||
private fun indicesIterationRange(
|
||||
start: JKExpression,
|
||||
bound: JKExpression,
|
||||
reversed: Boolean,
|
||||
inclusiveComparison: Boolean
|
||||
): JKExpression? {
|
||||
val collectionSizeExpression =
|
||||
if (reversed) {
|
||||
if (!inclusiveComparison) return null
|
||||
|
||||
if ((bound as? JKLiteralExpression)?.literal?.toIntOrNull() != 0) return null
|
||||
|
||||
if (start !is JKBinaryExpression) return null
|
||||
if ((start.operator as? JKKtOperatorImpl)?.token != KtTokens.MINUS) return null
|
||||
if ((start.right as? JKLiteralExpression)?.literal?.toIntOrNull() != 1) return null
|
||||
start.left
|
||||
} else {
|
||||
if (inclusiveComparison) return null
|
||||
if ((start as? JKLiteralExpression)?.literal?.toIntOrNull() != 0) return null
|
||||
bound
|
||||
} as? JKQualifiedExpression ?: return null
|
||||
|
||||
val indices = indicesByCollectionSize(collectionSizeExpression)
|
||||
?: indicesByArrayLength(collectionSizeExpression)
|
||||
?: return null
|
||||
|
||||
val psiContext = collectionSizeExpression.psi<PsiExpression>() ?: return null
|
||||
return if (reversed) {
|
||||
val reversedSymbol = context.symbolProvider.provideDirectSymbol(
|
||||
multiResolveFqName(ClassId.fromString("kotlin/collections/reversed"), psiContext).first()
|
||||
) as JKMethodSymbol
|
||||
JKQualifiedExpressionImpl(
|
||||
indices.detached(),
|
||||
JKKtQualifierImpl.DOT,
|
||||
JKJavaMethodCallExpressionImpl(reversedSymbol, JKExpressionListImpl())
|
||||
)
|
||||
} else indices
|
||||
}
|
||||
|
||||
|
||||
private fun indicesByCollectionSize(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
|
||||
val methodCall = javaSizeCall.selector as? JKMethodCallExpression ?: return null
|
||||
//TODO check if receiver type is Collection
|
||||
if (methodCall.identifier.name == "size" && methodCall.arguments.expressions.isEmpty()) {
|
||||
return toIndicesCall(javaSizeCall)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun indicesByArrayLength(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
|
||||
val methodCall = javaSizeCall.selector as? JKFieldAccessExpression ?: return null
|
||||
val receiverType = javaSizeCall.receiver.type(context)
|
||||
//TODO check if receiver type is kotlin.array
|
||||
if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) {
|
||||
return toIndicesCall(javaSizeCall)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun toIndicesCall(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
|
||||
val psiContext = javaSizeCall.psi<PsiExpression>() ?: return null
|
||||
val indiciesSymbol = context.symbolProvider.provideDirectSymbol(
|
||||
multiResolveFqName(ClassId.fromString("kotlin/collections/indices"), psiContext).first()
|
||||
) as JKMultiversePropertySymbol
|
||||
javaSizeCall.selector = JKFieldAccessExpressionImpl(indiciesSymbol)
|
||||
return javaSizeCall
|
||||
}
|
||||
|
||||
|
||||
private fun JKExpression.isVariableIncrementOrDecrement(variable: JKLocalVariable): JKOperator? {
|
||||
val pair = when (this) {
|
||||
is JKPostfixExpression -> operator to expression
|
||||
is JKPrefixExpression -> operator to expression
|
||||
else -> return null
|
||||
}
|
||||
if ((pair.second as? JKFieldAccessExpression)?.identifier?.target != variable) return null
|
||||
return pair.first
|
||||
}
|
||||
|
||||
private inline fun <reified ElementType : PsiElement> JKElement.psi() =
|
||||
context.backAnnotator(this) as? ElementType
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.j2k.conversions
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.tree.JKExpression
|
||||
import org.jetbrains.kotlin.j2k.tree.JKKtOperatorExpression
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKKtOperatorExpressionImpl
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKMethodSymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
fun untilToExpression(
|
||||
from: JKExpression,
|
||||
to: JKExpression,
|
||||
conversionContext: ConversionContext,
|
||||
psiContext: PsiElement
|
||||
): JKKtOperatorExpression =
|
||||
rangeExpression(
|
||||
from,
|
||||
to,
|
||||
"until",
|
||||
conversionContext,
|
||||
psiContext
|
||||
)
|
||||
|
||||
fun downToExpression(
|
||||
from: JKExpression,
|
||||
to: JKExpression,
|
||||
conversionContext: ConversionContext,
|
||||
psiContext: PsiElement
|
||||
): JKKtOperatorExpression =
|
||||
rangeExpression(
|
||||
from,
|
||||
to,
|
||||
"downTo",
|
||||
conversionContext,
|
||||
psiContext
|
||||
)
|
||||
|
||||
fun rangeExpression(
|
||||
from: JKExpression,
|
||||
to: JKExpression,
|
||||
operatorName: String,
|
||||
conversionContext: ConversionContext,
|
||||
psiContext: PsiElement
|
||||
): JKKtOperatorExpressionImpl {
|
||||
val symbol = conversionContext.symbolProvider.provideDirectSymbol(
|
||||
multiResolveFqName(ClassId.fromString("kotlin/ranges/$operatorName"), psiContext).first()
|
||||
) as JKMethodSymbol
|
||||
if (from.parent != null) from.detach(from.parent!!)
|
||||
if (to.parent != null) to.detach(to.parent!!)
|
||||
return JKKtOperatorExpressionImpl(from, symbol, to)
|
||||
}
|
||||
@@ -70,6 +70,7 @@ class JKJavaOperatorImpl private constructor(val token: IElementType) : JKOperat
|
||||
JavaTokenType.MINUSMINUS -> "--"
|
||||
JavaTokenType.PLUSPLUS -> "++"
|
||||
JavaTokenType.EXCL -> "!"
|
||||
JavaTokenType.ASTERISKEQ -> "*="
|
||||
else -> TODO("TODO $token")
|
||||
}
|
||||
|
||||
|
||||
@@ -375,4 +375,10 @@ class JKDelegationConstructorCallImpl(
|
||||
|
||||
class JKFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKFieldAccessExpression, JKElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFieldAccessExpression(this, data)
|
||||
}
|
||||
}
|
||||
val JKStatement.statements: List<JKStatement>
|
||||
get() =
|
||||
when (this) {
|
||||
is JKBlockStatement -> block.statements
|
||||
else -> listOf(this)
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitor
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
class JKKtPropertyImpl(
|
||||
@@ -265,4 +266,27 @@ fun JKClass.getOrCreateInitDeclaration(): JKKtInitDeclaration {
|
||||
val newDeclaration = JKKtInitDeclarationImpl(JKBlockImpl())
|
||||
declarationList += newDeclaration
|
||||
return newDeclaration
|
||||
}
|
||||
|
||||
class JKKtForInStatementImpl(variableIdentifier: JKNameIdentifier, iterationExpression: JKExpression, body: JKStatement) :
|
||||
JKKtForInStatement,
|
||||
JKBranchElementBase() {
|
||||
override var variableIdentifier: JKNameIdentifier by child(variableIdentifier)
|
||||
override var iterationExpression: JKExpression by child(iterationExpression)
|
||||
override var body: JKStatement by child(body)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtForInStatement(this, data)
|
||||
}
|
||||
|
||||
class JKKtOperatorExpressionImpl(
|
||||
receiver: JKExpression,
|
||||
override var identifier: JKMethodSymbol,
|
||||
argument: JKExpression
|
||||
) : JKKtOperatorExpression, JKBranchElementBase() {
|
||||
override var receiver: JKExpression by child(receiver)
|
||||
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)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.j2k.tree.JKMethod
|
||||
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
|
||||
interface JKSymbol {
|
||||
val target: Any
|
||||
@@ -120,13 +121,21 @@ class JKMultiverseFieldSymbol(override val target: PsiField) : JKFieldSymbol {
|
||||
get() = target.name // TODO("Fix this")
|
||||
}
|
||||
|
||||
class JKMultiversePropertySymbol(override val target: KtProperty) : JKFieldSymbol {
|
||||
override val name: String
|
||||
get() = target.name!!
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String
|
||||
get() = target.name!! // TODO("Fix this")
|
||||
}
|
||||
|
||||
class JKUnresolvedField(override val target: String) : JKFieldSymbol {
|
||||
constructor(target: PsiReference) : this(target.canonicalText)
|
||||
|
||||
override val declaredIn: JKSymbol
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
override val fqName: String = target
|
||||
|
||||
override val name: String
|
||||
get() = target
|
||||
}
|
||||
|
||||
@@ -107,3 +107,4 @@ interface JKJavaLabelSwitchCase : JKJavaSwitchCase {
|
||||
var label: JKExpression
|
||||
}
|
||||
|
||||
interface JKJavaContinueStatement: JKStatement
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k.tree
|
||||
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.JKMethodSymbol
|
||||
|
||||
interface JKKtProperty : JKField {
|
||||
val getter: JKBlock
|
||||
val setter: JKBlock
|
||||
@@ -83,4 +85,16 @@ interface JKKtIsExpression : JKExpression {
|
||||
|
||||
interface JKKtInitDeclaration : JKDeclaration {
|
||||
var block: JKBlock
|
||||
}
|
||||
|
||||
interface JKKtForInStatement : JKStatement {
|
||||
var variableIdentifier: JKNameIdentifier
|
||||
var iterationExpression: JKExpression
|
||||
var body: JKStatement
|
||||
}
|
||||
|
||||
interface JKKtOperatorExpression : JKExpression {
|
||||
var receiver: JKExpression
|
||||
var identifier: JKMethodSymbol
|
||||
var argument: JKExpression
|
||||
}
|
||||
@@ -81,3 +81,6 @@ inline fun <reified T> JKElement.getParentOfType(): T? {
|
||||
p = p.parent
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : JKElement> T.detached() =
|
||||
also { if (parent != null) detach(parent!!) }
|
||||
|
||||
@@ -69,6 +69,7 @@ interface JKVisitor<out R, in D> {
|
||||
fun visitJavaInstanceOfExpression(javaInstanceOfExpression: JKJavaInstanceOfExpression, data: D): R = visitExpression(javaInstanceOfExpression, data)
|
||||
fun visitJavaPolyadicExpression(javaPolyadicExpression: JKJavaPolyadicExpression, data: D): R = visitExpression(javaPolyadicExpression, data)
|
||||
fun visitJavaAssignmentExpression(javaAssignmentExpression: JKJavaAssignmentExpression, data: D): R = visitExpression(javaAssignmentExpression, data)
|
||||
fun visitJavaContinueStatement(javaContinueStatement: JKJavaContinueStatement, data: D): R = visitStatement(javaContinueStatement, data)
|
||||
fun visitJavaSwitchStatement(javaSwitchStatement: JKJavaSwitchStatement, data: D): R = visitStatement(javaSwitchStatement, data)
|
||||
fun visitJavaSwitchCase(javaSwitchCase: JKJavaSwitchCase, data: D): R = visitTreeElement(javaSwitchCase, data)
|
||||
fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase, data: D): R = visitJavaSwitchCase(javaDefaultSwitchCase, data)
|
||||
@@ -90,4 +91,6 @@ interface JKVisitor<out R, in D> {
|
||||
fun visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel, data: D): R = visitKtWhenLabel(ktValueWhenLabel, data)
|
||||
fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: D): R = visitExpression(ktIsExpression, data)
|
||||
fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration, data: D): R = visitDeclaration(ktInitDeclaration, data)
|
||||
fun visitKtForInStatement(ktForInStatement: JKKtForInStatement, data: D): R = visitStatement(ktForInStatement, data)
|
||||
fun visitKtOperatorExpression(ktOperatorExpression: JKKtOperatorExpression, data: D): R = visitExpression(ktOperatorExpression, data)
|
||||
}
|
||||
|
||||
@@ -143,6 +143,8 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
||||
override fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase, data: Nothing?) = visitJavaDefaultSwitchCase(javaDefaultSwitchCase)
|
||||
fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase) = visitJavaSwitchCase(javaLabelSwitchCase, null)
|
||||
override fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase, data: Nothing?) = visitJavaLabelSwitchCase(javaLabelSwitchCase)
|
||||
fun visitJavaContinueStatement(javaContinueStatement: JKJavaContinueStatement) = visitStatement(javaContinueStatement, null)
|
||||
override fun visitJavaContinueStatement(javaContinueStatement: JKJavaContinueStatement, data: Nothing?) = visitJavaContinueStatement(javaContinueStatement)
|
||||
fun visitKtProperty(ktProperty: JKKtProperty) = visitField(ktProperty, null)
|
||||
override fun visitKtProperty(ktProperty: JKKtProperty, data: Nothing?) = visitKtProperty(ktProperty)
|
||||
fun visitKtFunction(ktFunction: JKKtFunction) = visitMethod(ktFunction, null)
|
||||
@@ -177,4 +179,8 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
||||
override fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: Nothing?) = visitKtIsExpression(ktIsExpression)
|
||||
fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration) = visitDeclaration(ktInitDeclaration, null)
|
||||
override fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration, data: Nothing?) = visitKtInitDeclaration(ktInitDeclaration)
|
||||
fun visitKtForInStatement(ktForInStatement: JKKtForInStatement) = visitStatement(ktForInStatement, null)
|
||||
override fun visitKtForInStatement(ktForInStatement: JKKtForInStatement, data: Nothing?) = visitKtForInStatement(ktForInStatement)
|
||||
fun visitKtOperatorExpression(ktOperatorExpression: JKKtOperatorExpression) = visitExpression(ktOperatorExpression, null)
|
||||
override fun visitKtOperatorExpression(ktOperatorExpression: JKKtOperatorExpression, data: Nothing?) = visitKtOperatorExpression(ktOperatorExpression)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user