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()
|
+BinaryExpressionConversion()
|
||||||
+SwitchStatementConversion(context)
|
+SwitchStatementConversion(context)
|
||||||
+InstanceofConversion()
|
+InstanceofConversion()
|
||||||
|
+ForConversion(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doApply(trees: List<JKTreeElement>, context: ConversionContext) {
|
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.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
|
||||||
|
|
||||||
class JKSymbolProvider {
|
class JKSymbolProvider {
|
||||||
@@ -36,6 +37,7 @@ class JKSymbolProvider {
|
|||||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
||||||
is PsiField -> JKMultiverseFieldSymbol(psi)
|
is PsiField -> JKMultiverseFieldSymbol(psi)
|
||||||
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi)
|
is KtNamedFunction -> JKMultiverseFunctionSymbol(psi)
|
||||||
|
is KtProperty -> JKMultiversePropertySymbol(psi)
|
||||||
else -> TODO(psi::class.toString())
|
else -> TODO(psi::class.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,15 @@ class NewCodeBuilder {
|
|||||||
printer.print("/* !!! Hit visitElement for element type: ${treeElement::class} !!! */")
|
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) {
|
override fun visitDoWhileStatement(doWhileStatement: JKDoWhileStatement) {
|
||||||
printer.printWithNoIndent("do")
|
printer.printWithNoIndent("do")
|
||||||
doWhileStatement.body.accept(this)
|
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) {
|
override fun visitIfElseExpression(ifElseExpression: JKIfElseExpression) {
|
||||||
printer.printWithNoIndent("if (")
|
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.MINUSMINUS -> "--"
|
||||||
JavaTokenType.PLUSPLUS -> "++"
|
JavaTokenType.PLUSPLUS -> "++"
|
||||||
JavaTokenType.EXCL -> "!"
|
JavaTokenType.EXCL -> "!"
|
||||||
|
JavaTokenType.ASTERISKEQ -> "*="
|
||||||
else -> TODO("TODO $token")
|
else -> TODO("TODO $token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -376,3 +376,9 @@ class JKDelegationConstructorCallImpl(
|
|||||||
class JKFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKFieldAccessExpression, JKElementBase() {
|
class JKFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKFieldAccessExpression, JKElementBase() {
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFieldAccessExpression(this, data)
|
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.j2k.tree.visitors.JKVisitor
|
||||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
|
|
||||||
class JKKtPropertyImpl(
|
class JKKtPropertyImpl(
|
||||||
@@ -266,3 +267,26 @@ fun JKClass.getOrCreateInitDeclaration(): JKKtInitDeclaration {
|
|||||||
declarationList += newDeclaration
|
declarationList += newDeclaration
|
||||||
return 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.j2k.tree.JKTreeElement
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
|
|
||||||
interface JKSymbol {
|
interface JKSymbol {
|
||||||
val target: Any
|
val target: Any
|
||||||
@@ -120,13 +121,21 @@ class JKMultiverseFieldSymbol(override val target: PsiField) : JKFieldSymbol {
|
|||||||
get() = target.name // TODO("Fix this")
|
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 {
|
class JKUnresolvedField(override val target: String) : JKFieldSymbol {
|
||||||
constructor(target: PsiReference) : this(target.canonicalText)
|
constructor(target: PsiReference) : this(target.canonicalText)
|
||||||
|
|
||||||
override val declaredIn: JKSymbol
|
override val declaredIn: JKSymbol
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||||
override val fqName: String = target
|
override val fqName: String = target
|
||||||
|
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = target
|
get() = target
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,3 +107,4 @@ interface JKJavaLabelSwitchCase : JKJavaSwitchCase {
|
|||||||
var label: JKExpression
|
var label: JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface JKJavaContinueStatement: JKStatement
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k.tree
|
package org.jetbrains.kotlin.j2k.tree
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.j2k.tree.impl.JKMethodSymbol
|
||||||
|
|
||||||
interface JKKtProperty : JKField {
|
interface JKKtProperty : JKField {
|
||||||
val getter: JKBlock
|
val getter: JKBlock
|
||||||
val setter: JKBlock
|
val setter: JKBlock
|
||||||
@@ -84,3 +86,15 @@ interface JKKtIsExpression : JKExpression {
|
|||||||
interface JKKtInitDeclaration : JKDeclaration {
|
interface JKKtInitDeclaration : JKDeclaration {
|
||||||
var block: JKBlock
|
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
|
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 visitJavaInstanceOfExpression(javaInstanceOfExpression: JKJavaInstanceOfExpression, data: D): R = visitExpression(javaInstanceOfExpression, data)
|
||||||
fun visitJavaPolyadicExpression(javaPolyadicExpression: JKJavaPolyadicExpression, data: D): R = visitExpression(javaPolyadicExpression, data)
|
fun visitJavaPolyadicExpression(javaPolyadicExpression: JKJavaPolyadicExpression, data: D): R = visitExpression(javaPolyadicExpression, data)
|
||||||
fun visitJavaAssignmentExpression(javaAssignmentExpression: JKJavaAssignmentExpression, data: D): R = visitExpression(javaAssignmentExpression, 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 visitJavaSwitchStatement(javaSwitchStatement: JKJavaSwitchStatement, data: D): R = visitStatement(javaSwitchStatement, data)
|
||||||
fun visitJavaSwitchCase(javaSwitchCase: JKJavaSwitchCase, data: D): R = visitTreeElement(javaSwitchCase, data)
|
fun visitJavaSwitchCase(javaSwitchCase: JKJavaSwitchCase, data: D): R = visitTreeElement(javaSwitchCase, data)
|
||||||
fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase, data: D): R = visitJavaSwitchCase(javaDefaultSwitchCase, 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 visitKtValueWhenLabel(ktValueWhenLabel: JKKtValueWhenLabel, data: D): R = visitKtWhenLabel(ktValueWhenLabel, data)
|
||||||
fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: D): R = visitExpression(ktIsExpression, data)
|
fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: D): R = visitExpression(ktIsExpression, data)
|
||||||
fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration, data: D): R = visitDeclaration(ktInitDeclaration, 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)
|
override fun visitJavaDefaultSwitchCase(javaDefaultSwitchCase: JKJavaDefaultSwitchCase, data: Nothing?) = visitJavaDefaultSwitchCase(javaDefaultSwitchCase)
|
||||||
fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase) = visitJavaSwitchCase(javaLabelSwitchCase, null)
|
fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase) = visitJavaSwitchCase(javaLabelSwitchCase, null)
|
||||||
override fun visitJavaLabelSwitchCase(javaLabelSwitchCase: JKJavaLabelSwitchCase, data: Nothing?) = visitJavaLabelSwitchCase(javaLabelSwitchCase)
|
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)
|
fun visitKtProperty(ktProperty: JKKtProperty) = visitField(ktProperty, null)
|
||||||
override fun visitKtProperty(ktProperty: JKKtProperty, data: Nothing?) = visitKtProperty(ktProperty)
|
override fun visitKtProperty(ktProperty: JKKtProperty, data: Nothing?) = visitKtProperty(ktProperty)
|
||||||
fun visitKtFunction(ktFunction: JKKtFunction) = visitMethod(ktFunction, null)
|
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)
|
override fun visitKtIsExpression(ktIsExpression: JKKtIsExpression, data: Nothing?) = visitKtIsExpression(ktIsExpression)
|
||||||
fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration) = visitDeclaration(ktInitDeclaration, null)
|
fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration) = visitDeclaration(ktInitDeclaration, null)
|
||||||
override fun visitKtInitDeclaration(ktInitDeclaration: JKKtInitDeclaration, data: Nothing?) = visitKtInitDeclaration(ktInitDeclaration)
|
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