Java to Kotlin conversion: fixed a few bugs related to modifiers
#KT-4424 Fixed
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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() +
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ""
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user