New J2K: Implement assignment simplify conversion

This commit is contained in:
Dimach
2018-07-24 19:30:42 +03:00
committed by Ilya Kirillov
parent 77819be8f3
commit f3ffb2acfd
17 changed files with 108 additions and 40 deletions
@@ -33,6 +33,8 @@ object ConversionsRunner {
+AssignmentAsExpressionToAlsoConversion(context)
+AssignmentStatementValCreationConversion(context)
+AssignmentStatementOperatorConversion()
+AssignmentStatementSimplifyValConversion()
+AssignmentStatementSimplifyAlsoConversion()
+ConstructorConversion(context)
+PrimaryConstructorDetectConversion(context)
+InsertDefaultPrimaryConstructorConversion(context)
@@ -154,7 +154,7 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
val symbol = symbolProvider.provideSymbol(this)
val access = when (symbol) {
is JKClassSymbol -> JKClassAccessExpressionImpl(symbol)
is JKFieldSymbol -> JKJavaFieldAccessExpressionImpl(symbol)
is JKFieldSymbol -> JKFieldAccessExpressionImpl(symbol)
else -> TODO()
}
return qualifierExpression?.let { JKQualifiedExpressionImpl(it.toJK(), JKJavaQualifierImpl.DOT, access) } ?: access
@@ -326,8 +326,7 @@ class NewCodeBuilder {
private fun renderType(type: JKType) {
when (type) {
is JKClassType ->
(type.classReference as JKClassSymbol).fqName?.let { printer.printWithNoIndent(FqName(it).shortName().asString()) }
is JKClassType -> type.classReference.fqName?.let { printer.printWithNoIndent(FqName(it).shortName().asString()) }
is JKUnresolvedClassType -> printer.printWithNoIndent(type.name)
is JKContextType -> return
else -> printer.printWithNoIndent("Unit /* TODO: ${type::class} */")
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.j2k
import org.jetbrains.kotlin.j2k.tree.JKArrayAccessExpression
import org.jetbrains.kotlin.j2k.tree.JKElement
import org.jetbrains.kotlin.j2k.tree.JKKtFieldAccessExpression
import org.jetbrains.kotlin.j2k.tree.JKFieldAccessExpression
import org.jetbrains.kotlin.j2k.tree.impl.JKArrayAccessExpressionImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFieldAccessExpressionImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKFieldAccessExpressionImpl
fun <T : JKElement> T.copyTree(): T {
return when (this) {
is JKKtFieldAccessExpression -> JKKtFieldAccessExpressionImpl(identifier)
is JKFieldAccessExpression -> JKFieldAccessExpressionImpl(identifier)
is JKArrayAccessExpression -> JKArrayAccessExpressionImpl(expression.copyTree(), indexExpression.copyTree())
else -> TODO("Not supported+$this.toString()")
else -> TODO("Not supported ${this::class}")
} as T
}
@@ -8,24 +8,19 @@ package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.addToStdlib.cast
class AssignmentAsExpressionToAlsoConversion(val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaAssignmentExpression) return recurse(element)
val alsoSymbol = context.symbolProvider.provideDirectSymbol(
resolveFqName(ClassId.fromString("kotlin/also"), element.getParentOfType<JKClass>() ?: element, context)!!
) as JKMethodSymbol
val alsoExpression = JKKtAlsoCallExpressionImpl(
JKBlockStatementImpl(
JKBlockImpl(listOf(JKKtAssignmentStatementImpl(element.field, JKStubExpressionImpl(), element.operator)))
), alsoSymbol
), context.symbolProvider.provideByFqName("kotlin/also", context.backAnnotator.invoke(element.parentOfType<JKClass>()!!)!!)
).also {
it.statement.cast<JKBlockStatement>().block.statements.first().cast<JKKtAssignmentStatement>().expression =
JKKtFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it.parameter))
JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it.parameter))
}
element.invalidate()
@@ -22,7 +22,7 @@ class AssignmentStatementOperatorConversion : RecursiveApplicableConversionBase(
element.operator = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ] ?: return recurse(element)
val expr = element.expression
element.expression = JKStubExpressionImpl()
element.expression = JKBinaryExpressionImpl(expr, element.field.copyTree(), newOperator)
element.expression = JKBinaryExpressionImpl(element.field.copyTree(), expr, newOperator)
} else {
element.operator = newOperator
}
@@ -0,0 +1,29 @@
/*
* 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 org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKExpressionStatementImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKStubExpressionImpl
class AssignmentStatementSimplifyAlsoConversion : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKExpressionStatement) return recurse(element)
val qualifiedExpression = element.expression as? JKQualifiedExpression ?: return recurse(element)
val alsoCall = qualifiedExpression.selector as? JKKtAlsoCallExpression ?: return recurse(element)
return recurse(if (alsoCall.statement !is JKBlockStatement) alsoCall.statement.also {
alsoCall.statement = JKExpressionStatementImpl(JKStubExpressionImpl())
inlineVal(it, qualifiedExpression.receiver.also { qualifiedExpression.receiver = JKStubExpressionImpl() })
} else element)
}
private fun inlineVal(statement: JKStatement, expression: JKExpression) {
if (statement is JKKtAssignmentStatement) {
(statement.expression as? JKBinaryExpression)?.right = expression
if (statement.expression !is JKBinaryExpression) statement.expression = expression
}
}
}
@@ -0,0 +1,45 @@
/*
* 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 org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKStubExpressionImpl
class AssignmentStatementSimplifyValConversion : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKKtAlsoCallExpression) return recurse(element)
val codeBlock = (element.statement as? JKBlockStatement)?.block ?: return recurse(element)
if (codeBlock.statements.size > 1) {
val assignment = codeBlock.statements[1] as? JKKtAssignmentStatement ?: return recurse(element)
val declaration = codeBlock.statements[0] as? JKDeclarationStatement ?: return recurse(element)
when (declaration.declaredStatements.size) {
1 -> if (assignment.expression !is JKBinaryExpression) {
codeBlock.statements = listOf(assignment)
(assignment.field as JKQualifiedExpression).receiver = declaration.extractInitializerByIndex(0)
} else {
}
2 -> if (assignment.expression !is JKBinaryExpression) {
codeBlock.statements = listOf(assignment)
val arrayAccess = assignment.field as JKArrayAccessExpression
arrayAccess.expression = declaration.extractInitializerByIndex(0)
arrayAccess.indexExpression = declaration.extractInitializerByIndex(1)
} else {
}
}
}
if (codeBlock.statements.size == 1) {
element.statement = codeBlock.statements.first().also { codeBlock.statements = emptyList() }
}
return recurse(element)
}
private fun JKDeclarationStatement.extractInitializerByIndex(i: Int): JKExpression {
val variable = (declaredStatements[i] as JKLocalVariable)
return variable.initializer.also { variable.initializer = JKStubExpressionImpl() }
}
}
@@ -29,7 +29,7 @@ class AssignmentStatementValCreationConversion(val context: ConversionContext) :
JKNameIdentifierImpl("arr"),
ex1
).also {
assignableExpr.expression = JKKtFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
assignableExpr.expression = JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
}, JKLocalVariableImpl(
JKModifierListImpl(JKModalityModifierImpl(JKModalityModifier.Modality.FINAL)),
JKTypeElementImpl(JKJavaVoidType/*TODO*/),
@@ -37,7 +37,7 @@ class AssignmentStatementValCreationConversion(val context: ConversionContext) :
ex2
).also {
assignableExpr.indexExpression =
JKKtFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
}
)
)
@@ -55,7 +55,7 @@ class AssignmentStatementValCreationConversion(val context: ConversionContext) :
JKNameIdentifierImpl("arg"),
ex
).also {
assignableExpr.receiver = JKKtFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
assignableExpr.receiver = JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(it))
}
)
)
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKKtFieldAccessExpressionImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKFieldAccessExpressionImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKUniverseMethodSymbol
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -58,7 +58,7 @@ class DefaultArgumentsConversion(private val context: ConversionContext) : Recur
if (target is JKParameter) {
val newSymbol =
context.symbolProvider.provideUniverseSymbol(calledMethod.parameters[method.parameters.indexOf(target)])
return JKKtFieldAccessExpressionImpl(newSymbol)
return JKFieldAccessExpressionImpl(newSymbol)
}
}
@@ -101,10 +101,6 @@ class JKJavaMethodCallExpressionImpl(
override val arguments: JKExpressionList by child(arguments)
}
class JKJavaFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKJavaFieldAccessExpression, JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaFieldAccessExpression(this, data)
}
class JKJavaNewExpressionImpl(
override val constructorSymbol: JKMethodSymbol,
arguments: JKExpressionList
@@ -355,3 +355,7 @@ class JKDelegationConstructorCallImpl(
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitDelegationConstructorCall(this, data)
}
class JKFieldAccessExpressionImpl(override var identifier: JKFieldSymbol) : JKFieldAccessExpression, JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitFieldAccessExpression(this, data)
}
@@ -72,10 +72,6 @@ class JKKtCallExpressionImpl(
override var arguments: JKExpressionList by child(arguments)
}
class JKKtFieldAccessExpressionImpl(override val identifier: JKFieldSymbol) : JKKtFieldAccessExpression, JKElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtFieldAccessExpression(this, data)
}
class JKKtLiteralExpressionImpl(
override val literal: String,
override val type: JKLiteralExpression.LiteralType
@@ -114,6 +110,9 @@ class JKKtOperatorImpl private constructor(val token: KtSingleValueToken) : JKOp
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.EQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PLUSEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PLUSEQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.MINUSEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MINUSEQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ASTERISKEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.MULTEQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.DIVEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.DIVEQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.PERCEQ]!!] = JKKtOperatorImpl.tokenToOperator[KtTokens.PERCEQ]!!
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.AND]!!] = JKKtWordOperatorImpl("and")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.OR]!!] = JKKtWordOperatorImpl("or")
@@ -124,6 +123,10 @@ class JKKtOperatorImpl private constructor(val token: KtSingleValueToken) : JKOp
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.OREQ]!!] = JKKtWordOperatorImpl("or")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.ANDEQ]!!] = JKKtWordOperatorImpl("and")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.XOREQ]!!] = JKKtWordOperatorImpl("xor")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGTGTEQ]!!] = JKKtWordOperatorImpl("ushr")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.GTGTEQ]!!] = JKKtWordOperatorImpl("shr")
this[JKJavaOperatorImpl.tokenToOperator[JavaTokenType.LTLTEQ]!!] = JKKtWordOperatorImpl("shl")
}
}
}
@@ -139,9 +142,14 @@ class JKKtModifierImpl(override val type: JKKtModifier.KtModifierType) : JKKtMod
}
class JKKtAlsoCallExpressionImpl(
override val statement: JKStatement, override val identifier: JKMethodSymbol, override val parameterName: String = "it"
statement: JKStatement, override val identifier: JKMethodSymbol, override val parameterName: String = "it"
) : JKKtAlsoCallExpression, JKBranchElementBase() {
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtAlsoCallExpression(this, data)
override var statement
get() = arguments.expressions.first().cast<JKLambdaExpressionImpl>().statement
set(it) {
arguments.expressions.first().cast<JKLambdaExpressionImpl>().statement = it
}
val parameter
get() = arguments.expressions.first().cast<JKLambdaExpression>().parameters.first()
override var arguments: JKExpressionList by child(
@@ -26,8 +26,6 @@ interface JKJavaMethod : JKMethod, JKBranchElement {
interface JKJavaMethodCallExpression : JKMethodCallExpression
interface JKJavaFieldAccessExpression : JKFieldAccessExpression
interface JKJavaNewExpression : JKExpression {
val constructorSymbol: JKMethodSymbol
val arguments: JKExpressionList
@@ -52,10 +52,8 @@ interface JKKtModifier : JKModifier {
interface JKKtMethodCallExpression : JKMethodCallExpression
interface JKKtAlsoCallExpression : JKKtMethodCallExpression {
val statement: JKStatement
var statement: JKStatement
val parameterName: String
}
interface JKKtFieldAccessExpression : JKFieldAccessExpression
interface JKKtLiteralExpression : JKLiteralExpression
@@ -59,7 +59,6 @@ interface JKVisitor<out R, in D> {
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)
fun visitJavaFieldAccessExpression(javaFieldAccessExpression: JKJavaFieldAccessExpression, data: D): R = visitFieldAccessExpression(javaFieldAccessExpression, data)
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: D): R = visitExpression(javaNewExpression, data)
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression, data: D): R = visitExpression(javaDefaultNewExpression, data)
fun visitJavaModifier(javaModifier: JKJavaModifier, data: D): R = visitModifier(javaModifier, data)
@@ -81,6 +80,5 @@ interface JKVisitor<out R, in D> {
fun visitKtModifier(ktModifier: JKKtModifier, data: D): R = visitModifier(ktModifier, data)
fun visitKtMethodCallExpression(ktMethodCallExpression: JKKtMethodCallExpression, data: D): R = visitMethodCallExpression(ktMethodCallExpression, data)
fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression, data: D): R = visitKtMethodCallExpression(ktAlsoCallExpression, data)
fun visitKtFieldAccessExpression(ktFieldAccessExpression: JKKtFieldAccessExpression, data: D): R = visitFieldAccessExpression(ktFieldAccessExpression, data)
fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression, data: D): R = visitLiteralExpression(ktLiteralExpression, data)
}
@@ -115,8 +115,6 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
override fun visitJavaMethod(javaMethod: JKJavaMethod, data: Nothing?) = visitJavaMethod(javaMethod)
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression) = visitMethodCallExpression(javaMethodCallExpression, null)
override fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: Nothing?) = visitJavaMethodCallExpression(javaMethodCallExpression)
fun visitJavaFieldAccessExpression(javaFieldAccessExpression: JKJavaFieldAccessExpression) = visitFieldAccessExpression(javaFieldAccessExpression, null)
override fun visitJavaFieldAccessExpression(javaFieldAccessExpression: JKJavaFieldAccessExpression, data: Nothing?) = visitJavaFieldAccessExpression(javaFieldAccessExpression)
fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression) = visitExpression(javaNewExpression, null)
override fun visitJavaNewExpression(javaNewExpression: JKJavaNewExpression, data: Nothing?) = visitJavaNewExpression(javaNewExpression)
fun visitJavaDefaultNewExpression(javaDefaultNewExpression: JKJavaDefaultNewExpression) = visitExpression(javaDefaultNewExpression, null)
@@ -159,8 +157,6 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
override fun visitKtMethodCallExpression(ktMethodCallExpression: JKKtMethodCallExpression, data: Nothing?) = visitKtMethodCallExpression(ktMethodCallExpression)
fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression) = visitKtMethodCallExpression(ktAlsoCallExpression, null)
override fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression, data: Nothing?) = visitKtAlsoCallExpression(ktAlsoCallExpression)
fun visitKtFieldAccessExpression(ktFieldAccessExpression: JKKtFieldAccessExpression) = visitFieldAccessExpression(ktFieldAccessExpression, null)
override fun visitKtFieldAccessExpression(ktFieldAccessExpression: JKKtFieldAccessExpression, data: Nothing?) = visitKtFieldAccessExpression(ktFieldAccessExpression)
fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) = visitLiteralExpression(ktLiteralExpression, null)
override fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression, data: Nothing?) = visitKtLiteralExpression(ktLiteralExpression)
}