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 {
|
else {
|
||||||
val params = converter.convertParameterList(constructor.getParameterList())
|
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 containingClass = constructor.getContainingClass()
|
||||||
val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList())
|
val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList())
|
||||||
val factoryFunctionType = ClassType(containingClass?.declarationIdentifier() ?: Identifier.Empty,
|
val factoryFunctionType = ClassType(containingClass?.declarationIdentifier() ?: Identifier.Empty,
|
||||||
@@ -84,8 +98,8 @@ class ConstructorConverter(private val converter: Converter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val correctedConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) }
|
val bodyConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) }
|
||||||
postProcessBody(correctedConverter.convertBlock(body, false, { !statementsToRemove.contains(it) }))
|
postProcessBody(bodyConverter.convertBlock(body, false, { !statementsToRemove.contains(it) }))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Block.Empty
|
Block.Empty
|
||||||
@@ -163,7 +177,7 @@ class ConstructorConverter(private val converter: Converter) {
|
|||||||
var keepStatement = true
|
var keepStatement = true
|
||||||
if (statement is AssignmentExpression) {
|
if (statement is AssignmentExpression) {
|
||||||
val assignee = statement.left
|
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
|
val name = (assignee.identifier as Identifier).name
|
||||||
for (field in finalOrWithEmptyInitializerFields) {
|
for (field in finalOrWithEmptyInitializerFields) {
|
||||||
if (name == field.identifier.name) {
|
if (name == field.identifier.name) {
|
||||||
@@ -185,14 +199,14 @@ class ConstructorConverter(private val converter: Converter) {
|
|||||||
className.name,
|
className.name,
|
||||||
finalOrWithEmptyInitializerFields.map { initializers[it]!! }).assignNoPrototype()
|
finalOrWithEmptyInitializerFields.map { initializers[it]!! }).assignNoPrototype()
|
||||||
if (statements.isNotEmpty()) {
|
if (statements.isNotEmpty()) {
|
||||||
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(),
|
val localVar = LocalVariable(tempValIdentifier(),
|
||||||
Annotations.Empty,
|
Annotations.Empty,
|
||||||
Modifiers.Empty,
|
Modifiers.Empty,
|
||||||
null,
|
null,
|
||||||
initializer,
|
initializer,
|
||||||
true).assignNoPrototype()
|
true).assignNoPrototype()
|
||||||
statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype())
|
statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype())
|
||||||
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
|
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
statements.add(ReturnStatement(initializer).assignNoPrototype())
|
statements.add(ReturnStatement(initializer).assignNoPrototype())
|
||||||
@@ -235,16 +249,19 @@ class ConstructorConverter(private val converter: Converter) {
|
|||||||
statements[i] = ReturnStatement(constructorCall).assignNoPrototype()
|
statements[i] = ReturnStatement(constructorCall).assignNoPrototype()
|
||||||
return statements
|
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()
|
statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
|
statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype())
|
||||||
return statements
|
return statements
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ClassBody.factoryFunctions() = classObjectMembers.filterIsInstance(javaClass<FactoryFunction>())
|
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,
|
parameterList: ParameterList,
|
||||||
typeParameterList: TypeParameterList,
|
typeParameterList: TypeParameterList,
|
||||||
block: Block)
|
block: Block)
|
||||||
: Function(Identifier("create").assignNoPrototype(), annotations, modifiers, returnType, typeParameterList, parameterList, block, false) {
|
: 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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.JetParameter
|
||||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration
|
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 usageReplacementMap: Map<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
|
||||||
private val typeConverter = converter.typeConverter
|
private val typeConverter = converter.typeConverter
|
||||||
|
|
||||||
@@ -308,27 +308,17 @@ class ExpressionVisitor(private val converter: Converter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
|
||||||
val referencedName = expression.getReferenceName()!!
|
val referenceName = expression.getReferenceName()!!
|
||||||
val target = expression.getReference()?.resolve()
|
val target = expression.getReference()?.resolve()
|
||||||
val isNullable = if (target is PsiVariable) typeConverter.variableNullability(target).isNullable(converter.settings) else false
|
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()
|
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()
|
identifier = Identifier("size", isNullable).assignNoPrototype()
|
||||||
}
|
}
|
||||||
else if (qualifier != null) {
|
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
|
if (target is LightField) { //TODO: should be KotlinLightField with check of origin here, see KT-5188
|
||||||
result = converter.convertExpression(qualifier)
|
result = converter.convertExpression(qualifier)
|
||||||
return
|
return
|
||||||
@@ -349,7 +339,7 @@ class ExpressionVisitor(private val converter: Converter,
|
|||||||
&& !PsiTreeUtil.isAncestor(target.getContainingClass(), expression, true)
|
&& !PsiTreeUtil.isAncestor(target.getContainingClass(), expression, true)
|
||||||
&& !isStaticallyImported(target, expression)) {
|
&& !isStaticallyImported(target, expression)) {
|
||||||
var member: PsiMember = target
|
var member: PsiMember = target
|
||||||
var code = Identifier.toKotlin(referencedName)
|
var code = Identifier.toKotlin(referenceName)
|
||||||
while (member.getContainingClass() != null) {
|
while (member.getContainingClass() != null) {
|
||||||
code = Identifier.toKotlin(member.getContainingClass()!!.getName()!!) + "." + code
|
code = Identifier.toKotlin(member.getContainingClass()!!.getName()!!) + "." + code
|
||||||
member = member.getContainingClass()!!
|
member = member.getContainingClass()!!
|
||||||
|
|||||||
Reference in New Issue
Block a user