Java to Kotlin conversion: fixed a few bugs related to modifiers

#KT-4424 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-06-03 22:43:43 +04:00
parent ef8504eb39
commit 7c2473a5ef
15 changed files with 88 additions and 67 deletions
+17 -19
View File
@@ -137,6 +137,10 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
} }
if (settings.openByDefault && !modifiers.contains(Modifier.FINAL)) {
modifiers.add(Modifier.OPEN)
}
return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, classBodyElements) return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, classBodyElements)
} }
} }
@@ -231,16 +235,17 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
methodReturnType = method.getReturnType() methodReturnType = method.getReturnType()
val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull()) val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull())
val modifiers = HashSet(convertModifierList(method.getModifierList())) val modifiers = convertModifierList(method.getModifierList())
val containingClass = method.getContainingClass() val containingClass = method.getContainingClass()
if (containingClass != null && containingClass.isInterface()) {
modifiers.remove(Modifier.ABSTRACT)
}
if (containingClass != null && (containingClass.hasModifierProperty(PsiModifier.FINAL) || containingClass.isEnum())) { if (containingClass != null && (containingClass.hasModifierProperty(PsiModifier.FINAL) || containingClass.isEnum())) {
modifiers.add(Modifier.FINAL) modifiers.add(Modifier.FINAL)
} }
if (isOverride(method)) {
modifiers.add(Modifier.OVERRIDE)
}
if (settings.openByDefault && if (settings.openByDefault &&
!modifiers.contains(Modifier.ABSTRACT) && !modifiers.contains(Modifier.ABSTRACT) &&
!modifiers.contains(Modifier.FINAL) && !modifiers.contains(Modifier.FINAL) &&
@@ -248,11 +253,6 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
modifiers.add(Modifier.OPEN) modifiers.add(Modifier.OPEN)
} }
if (isOverride(method)) {
modifiers.add(Modifier.OVERRIDE)
modifiers.remove(Modifier.OPEN)
}
val comments = getComments(method) val comments = getComments(method)
if (method.isConstructor()) { if (method.isConstructor()) {
@@ -268,7 +268,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
val params = convertParameterList(method.getParameterList()) val params = convertParameterList(method.getParameterList())
val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) val typeParameterList = convertTypeParameterList(method.getTypeParameterList())
val block = convertBlock(method.getBody()) val block = convertBlock(method.getBody())
return Function(this, Identifier(method.getName()), comments, modifiers, returnType, typeParameterList, params, block) return Function(this, Identifier(method.getName()), comments, modifiers, returnType, typeParameterList, params, block, containingClass?.isInterface() ?: false)
} }
} }
finally { finally {
@@ -494,12 +494,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return Identifier(identifier.getText()!!) return Identifier(identifier.getText()!!)
} }
public fun convertModifierList(modifierList: PsiModifierList?): Set<Modifier> { public fun convertModifierList(modifierList: PsiModifierList?): MutableSet<Modifier> {
if (modifierList == null) return setOf() if (modifierList == null) return HashSet()
val modifiersSet = HashSet<Modifier>() val modifiersSet = HashSet<Modifier>()
if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT)) //TODO: map
if (modifierList.hasModifierProperty(PsiModifier.ABSTRACT))
modifiersSet.add(Modifier.ABSTRACT) modifiersSet.add(Modifier.ABSTRACT)
if (modifierList.hasModifierProperty(PsiModifier.FINAL)) if (modifierList.hasModifierProperty(PsiModifier.FINAL))
@@ -508,16 +509,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
if (modifierList.hasModifierProperty(PsiModifier.STATIC)) if (modifierList.hasModifierProperty(PsiModifier.STATIC))
modifiersSet.add(Modifier.STATIC) modifiersSet.add(Modifier.STATIC)
if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC)) if (modifierList.hasModifierProperty(PsiModifier.PUBLIC))
modifiersSet.add(Modifier.PUBLIC) modifiersSet.add(Modifier.PUBLIC)
if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED)) if (modifierList.hasModifierProperty(PsiModifier.PROTECTED))
modifiersSet.add(Modifier.PROTECTED) modifiersSet.add(Modifier.PROTECTED)
if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)) if (modifierList.hasModifierProperty(PsiModifier.PRIVATE))
modifiersSet.add(Modifier.INTERNAL)
if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE))
modifiersSet.add(Modifier.PRIVATE) modifiersSet.add(Modifier.PRIVATE)
return modifiersSet return modifiersSet
+7 -14
View File
@@ -17,7 +17,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import java.util.HashSet
import java.util.ArrayList import java.util.ArrayList
open class Class( open class Class(
@@ -80,27 +79,21 @@ open class Class(
" : " + allTypes.makeString(", ") " : " + allTypes.makeString(", ")
} }
protected fun modifiersToKotlin(): String { protected open fun modifiersToKotlin(): String {
val modifierList = ArrayList<Modifier>() val modifierList = ArrayList<Modifier>()
val modifier = modifiers.accessModifier()
if (modifier != null) { modifiers.accessModifier()?.let { modifierList.add(it) }
modifierList.add(modifier)
} if (modifiers.contains(Modifier.ABSTRACT)) {
if (isAbstract()) {
modifierList.add(Modifier.ABSTRACT) modifierList.add(Modifier.ABSTRACT)
} }
else if (needsOpenModifier()) { else if (modifiers.contains(Modifier.OPEN)) {
modifierList.add(Modifier.OPEN) modifierList.add(Modifier.OPEN)
} }
return modifierList.toKotlin() return modifierList.toKotlin()
} }
protected open fun isDefinitelyFinal(): Boolean
= modifiers.contains(Modifier.FINAL)
protected open fun needsOpenModifier(): Boolean
= !isDefinitelyFinal() && converter.settings.openByDefault
fun bodyToKotlin(): String { fun bodyToKotlin(): String {
val innerBody = classMembers.nonStaticMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin() val innerBody = classMembers.nonStaticMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin()
return if (innerBody.trim().isNotEmpty()) " {" + innerBody + "}" else "" return if (innerBody.trim().isNotEmpty()) " {" + innerBody + "}" else ""
@@ -26,7 +26,7 @@ abstract class Constructor(
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
parameterList: ParameterList, parameterList: ParameterList,
block: Block block: Block
) : Function(converter, Identifier.Empty, comments, modifiers, Type.Empty, TypeParameterList.Empty, parameterList, block) ) : Function(converter, Identifier.Empty, comments, modifiers, Type.Empty, TypeParameterList.Empty, parameterList, block, false)
class PrimaryConstructor(converter: Converter, class PrimaryConstructor(converter: Converter,
comments: MemberComments, comments: MemberComments,
@@ -61,6 +61,6 @@ class SecondaryConstructor(converter: Converter,
typeParameters.addAll(containingClass.typeParameterList.parameters) typeParameters.addAll(containingClass.typeParameterList.parameters)
return Function(converter, Identifier("init"), MemberComments.Empty, modifiers, return Function(converter, Identifier("init"), MemberComments.Empty, modifiers,
ClassType(containingClass.name, typeParameters, false, converter), ClassType(containingClass.name, typeParameters, false, converter),
TypeParameterList(typeParameters), parameterList, block) TypeParameterList(typeParameters), parameterList, block, false)
} }
} }
@@ -34,8 +34,6 @@ class Enum(
override fun primaryConstructorSignatureToKotlin(): String override fun primaryConstructorSignatureToKotlin(): String
= classMembers.primaryConstructor?.signatureToKotlin() ?: "" = classMembers.primaryConstructor?.signatureToKotlin() ?: ""
override fun isDefinitelyFinal() = true
override fun toKotlin(): String { override fun toKotlin(): String {
return modifiersToKotlin() + return modifiersToKotlin() +
"enum class " + name.toKotlin() + "enum class " + name.toKotlin() +
+2 -5
View File
@@ -30,14 +30,11 @@ open class Field(
fun modifiersToKotlin(): String { fun modifiersToKotlin(): String {
val modifierList = ArrayList<Modifier>() val modifierList = ArrayList<Modifier>()
if (isAbstract()) { if (modifiers.contains(Modifier.ABSTRACT)) {
modifierList.add(Modifier.ABSTRACT) modifierList.add(Modifier.ABSTRACT)
} }
val modifier = modifiers.accessModifier() modifiers.accessModifier()?.let { modifierList.add(it) }
if (modifier != null) {
modifierList.add(modifier)
}
return modifierList.toKotlin() + (if (isVal()) "val " else "var ") return modifierList.toKotlin() + (if (isVal()) "val " else "var ")
} }
@@ -27,7 +27,8 @@ open class Function(
val `type`: Type, val `type`: Type,
val typeParameterList: TypeParameterList, val typeParameterList: TypeParameterList,
val parameterList: ParameterList, val parameterList: ParameterList,
var block: Block? var block: Block?,
val isInTrait: Boolean
) : Member(comments, modifiers) { ) : Member(comments, modifiers) {
private fun modifiersToKotlin(): String { private fun modifiersToKotlin(): String {
@@ -42,11 +43,11 @@ open class Function(
resultingModifiers.add(accessModifier) resultingModifiers.add(accessModifier)
} }
if (isAbstract()) { if (modifiers.contains(Modifier.ABSTRACT) && !isInTrait) {
resultingModifiers.add(Modifier.ABSTRACT) resultingModifiers.add(Modifier.ABSTRACT)
} }
if (modifiers.contains(Modifier.OPEN)) { if (modifiers.contains(Modifier.OPEN) && !isOverride) {
resultingModifiers.add(Modifier.OPEN) resultingModifiers.add(Modifier.OPEN)
} }
@@ -25,7 +25,6 @@ class MemberComments(elements: List<Element>) : WhiteSpaceSeparatedElementList(e
} }
abstract class Member(val comments: MemberComments, val modifiers: Set<Modifier>) : Element { abstract class Member(val comments: MemberComments, val modifiers: Set<Modifier>) : Element {
fun isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT)
fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC) fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC)
fun commentsToKotlin(): String = comments.toKotlin() fun commentsToKotlin(): String = comments.toKotlin()
} }
+3 -14
View File
@@ -16,37 +16,26 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.Modifier.PUBLIC
import org.jetbrains.jet.j2k.ast.Modifier.PROTECTED
import org.jetbrains.jet.j2k.ast.Modifier.PRIVATE
import org.jetbrains.jet.j2k.ast.Modifier.INTERNAL
enum class Modifier(val name: String) { enum class Modifier(val name: String) {
PUBLIC: Modifier("public") PUBLIC: Modifier("public")
PROTECTED: Modifier("protected") PROTECTED: Modifier("protected")
PRIVATE: Modifier("private") PRIVATE: Modifier("private")
INTERNAL: Modifier("internal")
STATIC: Modifier("static") STATIC: Modifier("static")
ABSTRACT: Modifier("abstract") ABSTRACT: Modifier("abstract")
FINAL: Modifier("final") FINAL: Modifier("final")
OPEN: Modifier("open") OPEN: Modifier("open")
OVERRIDE: Modifier("override") OVERRIDE: Modifier("override")
public fun toKotlin(): String? { public fun toKotlin(): String = name
return when(this) {
INTERNAL -> null
else -> name
}
}
} }
val ACCESS_MODIFIERS = setOf(PUBLIC, PROTECTED, PRIVATE, INTERNAL) val ACCESS_MODIFIERS = setOf(Modifier.PUBLIC, Modifier.PROTECTED, Modifier.PRIVATE)
fun Collection<Modifier>.accessModifier(): Modifier? { fun Collection<Modifier>.accessModifier(): Modifier? {
return firstOrNull { ACCESS_MODIFIERS.contains(it) } return firstOrNull { ACCESS_MODIFIERS.contains(it) }
} }
fun Collection<Modifier>.toKotlin(): String fun Collection<Modifier>.toKotlin(): String
= if (isNotEmpty()) map { it.toKotlin() }.filterNotNull().makeString(" ") + " " else "" = if (isNotEmpty()) map { it.toKotlin() }.makeString(" ") + " " else ""
+8 -1
View File
@@ -17,6 +17,7 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import java.util.ArrayList
class Trait( class Trait(
converter: Converter, converter: Converter,
@@ -35,5 +36,11 @@ class Trait(
get() = "trait" get() = "trait"
override fun primaryConstructorSignatureToKotlin() = "" override fun primaryConstructorSignatureToKotlin() = ""
override fun needsOpenModifier() = false
override fun modifiersToKotlin(): String {
val modifierList = ArrayList<Modifier>()
modifiers.accessModifier()?.let { modifierList.add(it) }
return modifierList.toKotlin()
}
} }
@@ -1982,6 +1982,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/settings"), Pattern.compile("^(.+)\\.java$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/settings"), Pattern.compile("^(.+)\\.java$"), true);
} }
@TestMetadata("openByDefault.java")
public void testOpenByDefault() throws Exception {
doTest("j2k/tests/testData/ast/settings/openByDefault.java");
}
@TestMetadata("specifyLocalVariableTypeByDefault.java") @TestMetadata("specifyLocalVariableTypeByDefault.java")
public void testSpecifyLocalVariableTypeByDefault() throws Exception { public void testSpecifyLocalVariableTypeByDefault() throws Exception {
doTest("j2k/tests/testData/ast/settings/specifyLocalVariableTypeByDefault.java"); doTest("j2k/tests/testData/ast/settings/specifyLocalVariableTypeByDefault.java");
@@ -0,0 +1,34 @@
// !openByDefault: true
open class A() {
open fun foo1() {
}
private fun foo2() {
}
fun foo3() {
}
}
class B() {
fun foo() {
}
}
abstract class C() {
abstract fun foo()
}
trait I {
public fun foo()
}
open class D() : I {
override fun foo() {
}
}
enum class E {
fun foo(): Int {
return 0
}
}
@@ -1 +1 @@
abstract trait I trait I
@@ -1,7 +1,7 @@
trait INode { trait INode {
class object { class object {
val IN: String = "in" public val IN: String = "in"
val AT: String = "@" public val AT: String = "@"
val COMMA_WITH_SPACE: String = COMMA + SPACE public val COMMA_WITH_SPACE: String = COMMA + SPACE
} }
} }
@@ -1,4 +1,4 @@
trait INode { trait INode {
fun getTag(): Tag public fun getTag(): Tag
fun toKotlin(): String public fun toKotlin(): String
} }