New J2K: Add primary constructor initializers conversion

This commit is contained in:
Ilya Kirillov
2018-10-09 12:29:36 +03:00
committed by Ilya Kirillov
parent 2aafeda33b
commit a7e0f18a57
5 changed files with 62 additions and 5 deletions
@@ -39,6 +39,7 @@ object ConversionsRunner {
+ConstructorConversion(context)
+PrimaryConstructorDetectConversion(context)
+InsertDefaultPrimaryConstructorConversion(context)
+FieldInitializersInPrimaryFromParamsConversion()
+JavaMethodToKotlinFunctionConversion()
+LiteralConversion()
+InnerClassConversion()
@@ -103,7 +103,10 @@ class NewCodeBuilder {
)
}
override fun visitMutabilityModifier(mutabilityModifier: JKMutabilityModifier) {}
override fun visitMutabilityModifier(mutabilityModifier: JKMutabilityModifier) {
if (mutabilityModifier.mutability == Mutability.NonMutable) printer.print("val")
else printer.print("var")
}
override fun visitKtModifier(ktModifier: JKKtModifier) {
printer.printWithNoIndent(
@@ -189,7 +192,8 @@ class NewCodeBuilder {
override fun visitParameter(parameter: JKParameter) {
printer.printWithNoIndent(parameter.name.value, ": ")
parameter.modifierList.accept(this)
printer.printWithNoIndent(" ", parameter.name.value, ": ")
parameter.type.accept(this)
if (parameter.initializer !is JKStubExpression) {
printer.printWithNoIndent(" = ")
@@ -0,0 +1,52 @@
/*
* 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.JKJavaFieldImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKNameIdentifierImpl
class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversion() {
override fun visitTreeElement(treeElement: JKTreeElement) {
treeElement.acceptChildren(this, null)
}
override fun visitKtPrimaryConstructor(ktPrimaryConstructor: JKKtPrimaryConstructor) {
for (constructorStatement in ktPrimaryConstructor.block.statements) {
val assignmentExpression =
(constructorStatement as? JKExpressionStatement)?.expression as? JKJavaAssignmentExpression ?: continue
//TODO check if operator is `=`
val smartField = assignmentExpression.smartField() ?: continue
val fieldTarget = smartField.identifier.target as? JKJavaFieldImpl ?: continue
val parameter =
(assignmentExpression.expression as? JKFieldAccessExpression)?.identifier?.target as? JKParameter ?: continue
if (ktPrimaryConstructor.parameters.contains(parameter)) {
val containingClass = ktPrimaryConstructor.parentOfType<JKClass>() ?: continue
val fieldDeclaration = containingClass.declarationList.find {
(it as? JKField)?.name?.value == fieldTarget.name.value
} ?: continue
parameter.modifierList = (fieldDeclaration as JKField).modifierList.also { it.detach(it.parent!!) }
containingClass.declarationList -= fieldDeclaration
if (parameter.name.value != fieldTarget.name.value) {
parameter.name = JKNameIdentifierImpl(fieldTarget.name.value)
}
somethingChanged = true
}
}
}
private fun JKJavaAssignmentExpression.smartField(): JKFieldAccessExpression? {
val field = this.field
return when (field) {
is JKQualifiedExpression ->
(field.selector as? JKFieldAccessExpression)?.takeIf { field.receiver is JKThisExpression }
is JKFieldAccessExpression -> field
else -> null
}
}
}
@@ -89,7 +89,7 @@ class JKParameterImpl(
override var modifierList by child(modifierList)
override var initializer by child(initializer)
override val name by child(name)
override var name by child(name)
override var type by child(type)
}
@@ -218,7 +218,7 @@ class JKLocalVariableImpl(modifierList: JKModifierList, type: JKTypeElement, nam
JKLocalVariable, JKBranchElementBase() {
override var modifierList by child(modifierList)
override var initializer by child(initializer)
override val name by child(name)
override var name by child(name)
override val type by child(type)
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitLocalVariable(this, data)
@@ -66,7 +66,7 @@ interface JKMethod : JKDeclaration, JKModifierListOwner {
interface JKField : JKDeclaration, JKModifierListOwner {
val type: JKTypeElement
val name: JKNameIdentifier
var name: JKNameIdentifier
var initializer: JKExpression
}