Java to Kotlin converter: code refactoring

This commit is contained in:
Valentin Kipyatkov
2014-06-30 16:23:32 +02:00
parent f8261a8b6e
commit 330c41fc61
2 changed files with 31 additions and 36 deletions
@@ -165,7 +165,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
if (constructor in constructorsToDrop) return null if (constructor in constructorsToDrop) return null
val params = converter.convertParameterList(constructor.getParameterList()) val params = converter.convertParameterList(constructor.getParameterList())
val bodyConverter = converter.withExpressionVisitor { object : ExpressionVisitor(it, mapOf()/*TODO: see KT-5327*/) { val bodyConverter = converter.withExpressionVisitor { object : ExpressionVisitor(it) {
override fun visitReferenceExpression(expression: PsiReferenceExpression) { override fun visitReferenceExpression(expression: PsiReferenceExpression) {
if (isQualifierEmptyOrThis(expression)) { if (isQualifierEmptyOrThis(expression)) {
val member = expression.getReference()?.resolve() as? PsiMember val member = expression.getReference()?.resolve() as? PsiMember
@@ -201,7 +201,8 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
val params = primaryConstructor!!.getParameterList().getParameters() val params = primaryConstructor!!.getParameterList().getParameters()
val parameterToField = HashMap<PsiParameter, Pair<PsiField, Type>>() val parameterToField = HashMap<PsiParameter, Pair<PsiField, Type>>()
val body = primaryConstructor.getBody() val body = primaryConstructor.getBody()
val usageReplacementMap = HashMap<PsiVariable, String>()
val parameterUsageReplacementMap = HashMap<String, String>()
val block = if (body != null) { val block = if (body != null) {
val statementsToRemove = HashSet<PsiStatement>() val statementsToRemove = HashSet<PsiStatement>()
for (parameter in params) { for (parameter in params) {
@@ -225,12 +226,12 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
membersToRemove.add(field) membersToRemove.add(field)
if (field.getName() != parameter.getName()) { if (field.getName() != parameter.getName()) {
usageReplacementMap.put(parameter, field.getName()!!) parameterUsageReplacementMap.put(parameter.getName()!!, field.getName()!!)
} }
} }
val bodyConverter = converter.withExpressionVisitor { val bodyConverter = converter.withExpressionVisitor {
object : ExpressionVisitor(it, usageReplacementMap) { object : ReplacingExpressionVisitor(this, parameterUsageReplacementMap, it) {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
if (expression.isSuperConstructorCall()) return // skip it if (expression.isSuperConstructorCall()) return // skip it
super.visitMethodCallExpression(expression) super.visitMethodCallExpression(expression)
@@ -244,26 +245,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
} }
// we need to replace renamed parameter usages in base class constructor arguments and in default values // we need to replace renamed parameter usages in base class constructor arguments and in default values
// we match simply by name because of default parameter values refer to parameters of other constructor val correctedConverter = converter.withExpressionVisitor { ReplacingExpressionVisitor(this, parameterUsageReplacementMap, it) }
val byNameUsageReplacementMap = usageReplacementMap.map { it.key.getName() to it.value }.toMap()
val correctedConverter = converter.withExpressionVisitor {
object : ExpressionVisitor(it, mapOf()) {
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
if (expression.getQualifier() == null) {
val replacement = byNameUsageReplacementMap[expression.getReferenceName()]
if (replacement != null) {
val target = expression.getReference()?.resolve()
if (target is PsiParameter && target.getDeclarationScope().isConstructor()) {
result = Identifier(replacement, typeConverter.variableNullability(target).isNullable(converter.settings))
return
}
}
}
super.visitReferenceExpression(expression)
}
}
}
val statement = primaryConstructor.getBody()?.getStatements()?.firstOrNull() val statement = primaryConstructor.getBody()?.getStatements()?.firstOrNull()
val methodCall = (statement as? PsiExpressionStatement)?.getExpression() as? PsiMethodCallExpression val methodCall = (statement as? PsiExpressionStatement)?.getExpression() as? PsiMethodCallExpression
@@ -462,4 +444,27 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter
val ref = getMethodExpression() val ref = getMethodExpression()
return ref.getCanonicalText() == "super" && ref.resolve()?.isConstructor() ?: false return ref.getCanonicalText() == "super" && ref.resolve()?.isConstructor() ?: false
} }
private /*inner*//*TODO:KT-5343*/ open class ReplacingExpressionVisitor(
val owner: ConstructorConverter,
val parameterUsageReplacementMap: Map<String, String>, converter: Converter) : ExpressionVisitor(converter) {
override fun visitReferenceExpression(expression: PsiReferenceExpression) {
if (expression.getQualifier() == null) {
val replacement = parameterUsageReplacementMap[expression.getReferenceName()]
if (replacement != null) {
val target = expression.getReference()?.resolve()
if (target is PsiParameter) {
val scope = target.getDeclarationScope()
// we do not check for exactly this constructor because default values reference parameters in other constructors
if (scope.isConstructor() && scope.getParent() == owner.psiClass) {
result = Identifier(replacement, owner.typeConverter.variableNullability(target).isNullable(owner.converter.settings))
return
}
}
}
}
super.visitReferenceExpression(expression)
}
}
} }
@@ -36,8 +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
open class ExpressionVisitor(private val converter: Converter, open class ExpressionVisitor(private val converter: Converter) : JavaElementVisitor() {
private val usageReplacementMap: Map<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
private val typeConverter = converter.typeConverter private val typeConverter = converter.typeConverter
public var result: Expression = Expression.Empty public var result: Expression = Expression.Empty
@@ -333,14 +332,6 @@ open class ExpressionVisitor(private val converter: Converter,
result = Identifier(code, false, false) result = Identifier(code, false, false)
return return
} }
if (target is PsiVariable) {
val replacement = usageReplacementMap[target]
if (replacement != null) {
identifier = Identifier(replacement, isNullable)
}
}
} }
result = if (qualifier != null) QualifiedExpression(converter.convertExpression(qualifier), identifier) else identifier result = if (qualifier != null) QualifiedExpression(converter.convertExpression(qualifier), identifier) else identifier
@@ -368,8 +359,7 @@ open class ExpressionVisitor(private val converter: Converter,
result = MethodCallExpression.buildNotNull(converter.convertExpression(operand), typeConversion) result = MethodCallExpression.buildNotNull(converter.convertExpression(operand), typeConversion)
} }
else { else {
result = TypeCastExpression(typeConverter.convertType(castType.getType()), result = TypeCastExpression(typeConverter.convertType(castType.getType()), converter.convertExpression(operand))
converter.convertExpression(operand))
} }
} }