New J2K: Use RecursiveApplicableConversionBase in FieldInitializersInPrimaryFromParamsConversion

This commit is contained in:
Ilya Kirillov
2018-11-03 13:26:06 +03:00
committed by Ilya Kirillov
parent 78c5b4acd5
commit 9e98e36ac7
2 changed files with 48 additions and 39 deletions
@@ -40,7 +40,7 @@ object ConversionsRunner {
+ConstructorConversion(context) +ConstructorConversion(context)
+PrimaryConstructorDetectConversion(context) +PrimaryConstructorDetectConversion(context)
+InsertDefaultPrimaryConstructorConversion(context) +InsertDefaultPrimaryConstructorConversion(context)
+FieldInitializersInPrimaryFromParamsConversion() +FieldInitializersInPrimaryFromParamsConversion(context)
+JavaMethodToKotlinFunctionConversion() +JavaMethodToKotlinFunctionConversion()
+LiteralConversion() +LiteralConversion()
+InnerClassConversion() +InnerClassConversion()
@@ -5,19 +5,30 @@
package org.jetbrains.kotlin.j2k.conversions package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.* import org.jetbrains.kotlin.j2k.tree.impl.*
class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversion() { class FieldInitializersInPrimaryFromParamsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun visitTreeElement(treeElement: JKTreeElement) { override fun applyToElement(element: JKTreeElement): JKTreeElement {
treeElement.acceptChildren(this, null) if (element !is JKClass) return recurse(element)
val primaryConstructorConversion = PrimaryConstructorConversion()
primaryConstructorConversion.runConversion(element, context)
element.getOrCreateInitDeclaration().block = JKBlockImpl(primaryConstructorConversion.initDeclarationStatements)
element.declarationList -= primaryConstructorConversion.declarationsToRemove
return recurse(element)
} }
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) { private class PrimaryConstructorConversion : RecursiveApplicableConversionBase() {
val containingClass = ktPrimaryConstructor.parentOfType<JKClass>() ?: return val initDeclarationStatements = mutableListOf<JKStatement>()
val declarationsToRemove = mutableListOf<JKDeclaration>()
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKKtPrimaryConstructor) return recurse(element)
val containingClass = element.parentOfType<JKClass>() ?: return recurse(element)
val removedStatements = mutableListOf<JKStatement>() val removedStatements = mutableListOf<JKStatement>()
for (constructorStatement in ktPrimaryConstructor.block.statements) { for (constructorStatement in element.block.statements) {
val assignmentExpression = val assignmentExpression =
(constructorStatement as? JKExpressionStatement)?.expression as? JKJavaAssignmentExpression ?: continue (constructorStatement as? JKExpressionStatement)?.expression as? JKJavaAssignmentExpression ?: continue
//TODO check if operator is `=` //TODO check if operator is `=`
@@ -25,26 +36,23 @@ class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversio
val fieldTarget = smartField.identifier.target as? JKJavaFieldImpl ?: continue val fieldTarget = smartField.identifier.target as? JKJavaFieldImpl ?: continue
val parameter = val parameter =
(assignmentExpression.expression as? JKFieldAccessExpression)?.identifier?.target as? JKParameter ?: continue (assignmentExpression.expression as? JKFieldAccessExpression)?.identifier?.target as? JKParameter ?: continue
if (ktPrimaryConstructor.parameters.contains(parameter)) { if (element.parameters.contains(parameter)) {
val fieldDeclaration = containingClass.declarationList.find { val fieldDeclaration = containingClass.declarationList.find {
(it as? JKField)?.name?.value == fieldTarget.name.value (it as? JKField)?.name?.value == fieldTarget.name.value
} as? JKField ?: continue } as? JKField ?: continue
if (!fieldDeclaration.type.type.equalsByName(parameter.type.type)) continue//TODO better way to compare types?? if (!fieldDeclaration.type.type.equalsByName(parameter.type.type)) continue//TODO better way to compare types??
parameter.modifierList = fieldDeclaration::modifierList.detached() parameter.modifierList = fieldDeclaration::modifierList.detached()
containingClass.declarationList -= fieldDeclaration declarationsToRemove += fieldDeclaration
if (parameter.name.value != fieldTarget.name.value) { if (parameter.name.value != fieldTarget.name.value) {
parameter.name = JKNameIdentifierImpl(fieldTarget.name.value) parameter.name = JKNameIdentifierImpl(fieldTarget.name.value)
} }
somethingChanged = true
removedStatements += constructorStatement removedStatements += constructorStatement
} }
} }
ktPrimaryConstructor.block.statements -= removedStatements initDeclarationStatements.addAll(element.block.statements - removedStatements)
if (ktPrimaryConstructor.block.statements.isNotEmpty()) { element.block.statements = emptyList()
ktPrimaryConstructor::block.detached() return element
containingClass.getOrCreateInitDeclaration().block = ktPrimaryConstructor.block
}
} }
private fun JKJavaAssignmentExpression.smartField(): JKFieldAccessExpression? { private fun JKJavaAssignmentExpression.smartField(): JKFieldAccessExpression? {
@@ -56,4 +64,5 @@ class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversio
else -> null else -> null
} }
} }
}
} }