Java to Kotlin converter: no intermediate __ variable in factory function if body is simple

This commit is contained in:
Valentin Kipyatkov
2014-06-25 20:34:45 +04:00
parent 467ca77854
commit e76c3d4e9e
10 changed files with 56 additions and 53 deletions
+43 -27
View File
@@ -254,16 +254,23 @@ public class Converter private(val project: Project, val settings: ConverterSett
} }
} }
val initializer = MethodCallExpression.buildNotNull(null, className.name, finalOrWithEmptyInitializerFields.map { initializers[it]!! }) val initializer = MethodCallExpression.buildNotNull(null,
initializer.assignNoPrototype() className.name,
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), finalOrWithEmptyInitializerFields.map { initializers[it]!! }).assignNoPrototype()
Annotations.Empty, if (statements.isNotEmpty()) {
Modifiers.Empty, val localVar = LocalVariable(FactoryFunction.tempValIdentifier(),
null, Annotations.Empty,
initializer, Modifiers.Empty,
true).assignNoPrototype() null,
statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype()) initializer,
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype()) true).assignNoPrototype()
statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype())
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
}
else {
statements.add(ReturnStatement(initializer).assignNoPrototype())
}
factoryFunction.body = Block(statements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype()).assignNoPrototype() factoryFunction.body = Block(statements, LBrace().assignNoPrototype(), RBrace().assignNoPrototype()).assignNoPrototype()
} }
@@ -282,27 +289,36 @@ public class Converter private(val project: Project, val settings: ConverterSett
private fun correctFactoryFunctions(classBody: ClassBody, className: String) { private fun correctFactoryFunctions(classBody: ClassBody, className: String) {
for (factoryFunction in classBody.factoryFunctions()) { for (factoryFunction in classBody.factoryFunctions()) {
val body = factoryFunction.body!! val body = factoryFunction.body!!
val statements = ArrayList(body.statements) val statements = correctFactoryFunctionStatements(body, className)
// searching for other constructor call in form "this(...)"
// it's not necessary the first statement because of statements inserted for writable parameters
for (i in statements.indices) {
val statement = statements[i]
if (statement is MethodCallExpression) {
if ((statement.methodExpression as? Identifier)?.name == "this") {
val constructorCall = MethodCallExpression.buildNotNull(null, className, statement.arguments).assignPrototypesFrom(statement)
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype()
statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype()
break
}
}
}
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
factoryFunction.body = Block(statements, body.lBrace, body.rBrace).assignPrototypesFrom(body) factoryFunction.body = Block(statements, body.lBrace, body.rBrace).assignPrototypesFrom(body)
} }
} }
private fun correctFactoryFunctionStatements(body: Block, className: String): List<Statement> {
val statements = ArrayList(body.statements)
// searching for other constructor call in form "this(...)"
// it's not necessary the first statement because of statements inserted for writable parameters
for (i in statements.indices) {
val statement = statements[i]
if (statement is MethodCallExpression) {
if ((statement.methodExpression as? Identifier)?.name == "this") {
val constructorCall = MethodCallExpression.buildNotNull(null, className, statement.arguments).assignPrototypesFrom(statement)
if (i == statements.lastIndex) { // constructor call is the last statement - no intermediate variable needed
statements[i] = ReturnStatement(constructorCall).assignNoPrototype()
return statements
}
val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype()
statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype()
break
}
}
}
statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype())
return statements
}
private fun convertInitializer(initializer: PsiClassInitializer): Initializer { private fun convertInitializer(initializer: PsiClassInitializer): Initializer {
return Initializer(convertBlock(initializer.getBody()), convertModifiers(initializer)).assignPrototype(initializer) return Initializer(convertBlock(initializer.getBody()), convertModifiers(initializer)).assignPrototype(initializer)
} }
+2 -4
View File
@@ -5,12 +5,10 @@ import java.util.HashMap
class Test private() { class Test private() {
class object { class object {
fun create(): Test { fun create(): Test {
val __ = Test() return Test()
return __
} }
fun create(s: String): Test { fun create(s: String): Test {
val __ = Test() return Test()
return __
} }
} }
} }
@@ -10,8 +10,7 @@ class A// this is a primary constructor
// this is a secondary constructor // this is a secondary constructor
fun create(): A { fun create(): A {
val __ = A(1) return A(1)
return __
} // end of secondary constructor body } // end of secondary constructor body
} }
} }
@@ -2,13 +2,11 @@ class C(arg1: Int, arg2: Int, arg3: Int) {
class object { class object {
fun create(arg1: Int, arg2: Int): C { fun create(arg1: Int, arg2: Int): C {
val __ = C(arg1, arg2, 0) return C(arg1, arg2, 0)
return __
} }
fun create(arg1: Int): C { fun create(arg1: Int): C {
val __ = C(arg1, 0, 0) return C(arg1, 0, 0)
return __
} }
} }
} }
@@ -8,8 +8,7 @@ public class Identifier<T> private(private val myName: T, private val myHasDolla
class object { class object {
public fun <T> create(name: T): Identifier<T> { public fun <T> create(name: T): Identifier<T> {
val __ = Identifier(name, false) return Identifier(name, false)
return __
} }
public fun <T> create(name: T, isNullable: Boolean): Identifier<T> { public fun <T> create(name: T, isNullable: Boolean): Identifier<T> {
@@ -8,8 +8,7 @@ public class Identifier private(private val myName: String, private val myHasDol
class object { class object {
public fun create(name: String): Identifier { public fun create(name: String): Identifier {
val __ = Identifier(name, false) return Identifier(name, false)
return __
} }
public fun create(name: String, isNullable: Boolean): Identifier { public fun create(name: String, isNullable: Boolean): Identifier {
@@ -20,8 +20,7 @@ class C(arg1: Int, arg2: Int, arg3: Int) {
} }
fun create(arg1: Int): C { fun create(arg1: Int): C {
val __ = C(arg1, 0, 0) return C(arg1, 0, 0)
return __
} }
} }
} }
@@ -2,13 +2,11 @@ class C private(arg1: Int, arg2: Int, arg3: Int) {
class object { class object {
private fun create(arg1: Int, arg2: Int): C { private fun create(arg1: Int, arg2: Int): C {
val __ = C(arg1, arg2, 0) return C(arg1, arg2, 0)
return __
} }
public fun create(arg1: Int): C { public fun create(arg1: Int): C {
val __ = C(arg1, 0, 0) return C(arg1, 0, 0)
return __
} }
} }
} }
@@ -2,13 +2,11 @@ public class Test private(private val myName: String, var a: Boolean, var b: Dou
class object { class object {
public fun create(): Test { public fun create(): Test {
val __ = Test(0, false, 0.toDouble(), 0.toFloat(), 0, 0, 0, ' ') return Test(0, false, 0.toDouble(), 0.toFloat(), 0, 0, 0, ' ')
return __
} }
public fun create(name: String): Test { public fun create(name: String): Test {
val __ = Test(foo(name), false, 0.toDouble(), 0.toFloat(), 0, 0, 0, ' ') return Test(foo(name), false, 0.toDouble(), 0.toFloat(), 0, 0, 0, ' ')
return __
} }
fun foo(n: String): String { fun foo(n: String): String {
+1 -2
View File
@@ -8,8 +8,7 @@ public class Identifier<T> private(private val myName: T, private val myHasDolla
class object { class object {
public fun <T> create(name: T): Identifier<T> { public fun <T> create(name: T): Identifier<T> {
val __ = Identifier(name, false) return Identifier(name, false)
return __
} }
public fun <T> create(name: T, isNullable: Boolean): Identifier<T> { public fun <T> create(name: T, isNullable: Boolean): Identifier<T> {