Java to Kotlin converter: refactored code moving all knowledge about factory function internals into ConstructorConverter
This commit is contained in:
@@ -37,7 +37,21 @@ class ConstructorConverter(private val converter: Converter) {
|
||||
}
|
||||
else {
|
||||
val params = converter.convertParameterList(constructor.getParameterList())
|
||||
var body = postProcessBody(converter.convertBlock(constructor.getBody()))
|
||||
val bodyConverter = converter.withExpressionVisitor { object : ExpressionVisitor(it, mapOf()/*TODO: see KT-5327*/) {
|
||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||
if (isQualifierEmptyOrThis(expression)) {
|
||||
val field = expression.getReference()?.resolve() as? PsiField
|
||||
if (field != null && field.getContainingClass() == constructor.getContainingClass()) {
|
||||
val isNullable = typeConverter.variableNullability(field).isNullable(converter.settings)
|
||||
result = QualifiedExpression(tempValIdentifier(), Identifier(expression.getReferenceName()!!, isNullable).assignNoPrototype())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
super.visitReferenceExpression(expression)
|
||||
}
|
||||
}}
|
||||
var body = postProcessBody(bodyConverter.convertBlock(constructor.getBody()))
|
||||
val containingClass = constructor.getContainingClass()
|
||||
val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList())
|
||||
val factoryFunctionType = ClassType(containingClass?.declarationIdentifier() ?: Identifier.Empty,
|
||||
@@ -84,8 +98,8 @@ class ConstructorConverter(private val converter: Converter) {
|
||||
}
|
||||
}
|
||||
|
||||
val correctedConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) }
|
||||
postProcessBody(correctedConverter.convertBlock(body, false, { !statementsToRemove.contains(it) }))
|
||||
val bodyConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) }
|
||||
postProcessBody(bodyConverter.convertBlock(body, false, { !statementsToRemove.contains(it) }))
|
||||
}
|
||||
else {
|
||||
Block.Empty
|
||||
@@ -163,7 +177,7 @@ class ConstructorConverter(private val converter: Converter) {
|
||||
var keepStatement = true
|
||||
if (statement is AssignmentExpression) {
|
||||
val assignee = statement.left
|
||||
if (assignee is QualifiedExpression && (assignee.qualifier as? Identifier)?.name == FactoryFunction.tempValName) {
|
||||
if (assignee is QualifiedExpression && (assignee.qualifier as? Identifier)?.name == tempValName) {
|
||||
val name = (assignee.identifier as Identifier).name
|
||||
for (field in finalOrWithEmptyInitializerFields) {
|
||||
if (name == field.identifier.name) {
|
||||
@@ -185,14 +199,14 @@ class ConstructorConverter(private val converter: Converter) {
|
||||
className.name,
|
||||
finalOrWithEmptyInitializerFields.map { initializers[it]!! }).assignNoPrototype()
|
||||
if (statements.isNotEmpty()) {
|
||||
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(),
|
||||
val localVar = LocalVariable(tempValIdentifier(),
|
||||
Annotations.Empty,
|
||||
Modifiers.Empty,
|
||||
null,
|
||||
initializer,
|
||||
true).assignNoPrototype()
|
||||
statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype())
|
||||
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
|
||||
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||
}
|
||||
else {
|
||||
statements.add(ReturnStatement(initializer).assignNoPrototype())
|
||||
@@ -235,16 +249,19 @@ class ConstructorConverter(private val converter: Converter) {
|
||||
statements[i] = ReturnStatement(constructorCall).assignNoPrototype()
|
||||
return statements
|
||||
}
|
||||
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype()
|
||||
val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype()
|
||||
statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
|
||||
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||
return statements
|
||||
}
|
||||
|
||||
private fun ClassBody.factoryFunctions() = classObjectMembers.filterIsInstance(javaClass<FactoryFunction>())
|
||||
|
||||
private val tempValName: String = "__"
|
||||
private fun tempValIdentifier(): Identifier = Identifier(tempValName, false).assignNoPrototype()
|
||||
}
|
||||
@@ -58,28 +58,4 @@ class FactoryFunction(annotations: Annotations,
|
||||
parameterList: ParameterList,
|
||||
typeParameterList: TypeParameterList,
|
||||
block: Block)
|
||||
: Function(Identifier("create").assignNoPrototype(), annotations, modifiers, returnType, typeParameterList, parameterList, block, false) {
|
||||
|
||||
/*
|
||||
public fun toFactoryFunction(containingClass: Class?): Function {
|
||||
val statements = ArrayList(block?.statements ?: listOf())
|
||||
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||
val newBlock = Block(statements, block?.lBrace ?: LBrace().assignNoPrototype(), block?.rBrace ?: RBrace().assignNoPrototype())
|
||||
if (block != null) {
|
||||
newBlock.assignPrototypesFrom(block!!)
|
||||
}
|
||||
|
||||
val typeParameters = if (containingClass != null) containingClass.typeParameterList.parameters else listOf()
|
||||
val typeParameterList = TypeParameterList(typeParameters).assignNoPrototype()
|
||||
|
||||
val returnType = ClassType(containingClass?.name ?: Identifier.Empty, typeParameters, Nullability.NotNull, converter.settings).assignNoPrototype()
|
||||
return Function(converter, Identifier("create").assignNoPrototype(), annotations, modifiers,
|
||||
returnType, typeParameterList, parameterList, newBlock, false).assignPrototypesFrom(this)
|
||||
}
|
||||
*/
|
||||
|
||||
class object {
|
||||
public val tempValName: String = "__"
|
||||
public fun tempValIdentifier(): Identifier = Identifier(tempValName, false).assignNoPrototype()
|
||||
}
|
||||
}
|
||||
: Function(Identifier("create").assignNoPrototype(), annotations, modifiers, returnType, typeParameterList, parameterList, block, false)
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
||||
import org.jetbrains.jet.lang.psi.JetParameter
|
||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
|
||||
|
||||
class ExpressionVisitor(private val converter: Converter,
|
||||
open class ExpressionVisitor(private val converter: Converter,
|
||||
private val usageReplacementMap: Map<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
|
||||
private val typeConverter = converter.typeConverter
|
||||
|
||||
@@ -308,27 +308,17 @@ class ExpressionVisitor(private val converter: Converter,
|
||||
}
|
||||
|
||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||
val referencedName = expression.getReferenceName()!!
|
||||
val referenceName = expression.getReferenceName()!!
|
||||
val target = expression.getReference()?.resolve()
|
||||
val isNullable = if (target is PsiVariable) typeConverter.variableNullability(target).isNullable(converter.settings) else false
|
||||
|
||||
val containingConstructor = expression.getContainingConstructor()
|
||||
val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor()
|
||||
if (insideSecondaryConstructor &&
|
||||
isQualifierEmptyOrThis(expression) &&
|
||||
(expression.getReference()?.resolve() as? PsiField)?.getContainingClass() == containingConstructor!!.getContainingClass()) {
|
||||
result = QualifiedExpression(FactoryFunction.tempValIdentifier(), Identifier(referencedName, isNullable).assignNoPrototype())
|
||||
return
|
||||
}
|
||||
|
||||
var identifier = Identifier(referencedName, isNullable).assignNoPrototype()
|
||||
val qualifier = expression.getQualifierExpression()
|
||||
|
||||
if (qualifier != null && qualifier.getType() is PsiArrayType && referencedName == "length") {
|
||||
var identifier = Identifier(referenceName, isNullable).assignNoPrototype()
|
||||
if (qualifier != null && qualifier.getType() is PsiArrayType && referenceName == "length") {
|
||||
identifier = Identifier("size", isNullable).assignNoPrototype()
|
||||
}
|
||||
else if (qualifier != null) {
|
||||
if (referencedName == JvmAbi.CLASS_OBJECT_FIELD || referencedName == JvmAbi.INSTANCE_FIELD) {
|
||||
if (referenceName == JvmAbi.CLASS_OBJECT_FIELD || referenceName == JvmAbi.INSTANCE_FIELD) {
|
||||
if (target is LightField) { //TODO: should be KotlinLightField with check of origin here, see KT-5188
|
||||
result = converter.convertExpression(qualifier)
|
||||
return
|
||||
@@ -349,7 +339,7 @@ class ExpressionVisitor(private val converter: Converter,
|
||||
&& !PsiTreeUtil.isAncestor(target.getContainingClass(), expression, true)
|
||||
&& !isStaticallyImported(target, expression)) {
|
||||
var member: PsiMember = target
|
||||
var code = Identifier.toKotlin(referencedName)
|
||||
var code = Identifier.toKotlin(referenceName)
|
||||
while (member.getContainingClass() != null) {
|
||||
code = Identifier.toKotlin(member.getContainingClass()!!.getName()!!) + "." + code
|
||||
member = member.getContainingClass()!!
|
||||
|
||||
Reference in New Issue
Block a user