From 0a2983d60221c5d58bef205890c54b73b5f9feaa Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 27 May 2015 14:45:47 +0300 Subject: [PATCH] J2K: converting of enum constants overriding members --- .../org/jetbrains/kotlin/j2k/CodeConverter.kt | 5 ---- j2k/src/org/jetbrains/kotlin/j2k/Converter.kt | 18 ++++++++++---- .../kotlin/j2k/ExpressionConverter.kt | 2 +- .../kotlin/j2k/ast/AnonymousClassBody.kt | 2 +- j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt | 2 +- .../org/jetbrains/kotlin/j2k/ast/ClassBody.kt | 2 +- j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt | 2 +- .../jetbrains/kotlin/j2k/ast/EnumConstant.kt | 14 +++++++---- .../enum/constantsWithBody1.java | 11 +++++++++ .../fileOrElement/enum/constantsWithBody1.kt | 11 +++++++++ .../enum/constantsWithBody2.java | 24 +++++++++++++++++++ .../fileOrElement/enum/constantsWithBody2.kt | 18 ++++++++++++++ ...otlinConverterForWebDemoTestGenerated.java | 12 ++++++++++ ...otlinConverterSingleFileTestGenerated.java | 12 ++++++++++ 14 files changed, 115 insertions(+), 20 deletions(-) create mode 100644 j2k/testData/fileOrElement/enum/constantsWithBody1.java create mode 100644 j2k/testData/fileOrElement/enum/constantsWithBody1.kt create mode 100644 j2k/testData/fileOrElement/enum/constantsWithBody2.java create mode 100644 j2k/testData/fileOrElement/enum/constantsWithBody2.kt diff --git a/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt index d945e9db841..35b6fc24fc5 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/CodeConverter.kt @@ -153,11 +153,6 @@ class CodeConverter( private fun PsiPrefixExpression.isLiteralWithSign() = getOperand() is PsiLiteralExpression && getOperationTokenType() in setOf(JavaTokenType.PLUS, JavaTokenType.MINUS) - public fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody { - return AnonymousClassBody(ClassBodyConverter(anonymousClass, converter, isOpenClass = false, isObject = false).convertBody(), - anonymousClass.getBaseClassType().resolve()?.isInterface() ?: false).assignPrototype(anonymousClass) - } - private fun needConversion(actual: PsiType, expected: PsiType): Boolean { val expectedStr = expected.getCanonicalText() val actualStr = actual.getCanonicalText() diff --git a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt index a8732e33adf..a879227b37a 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt @@ -176,7 +176,9 @@ class Converter private( } psiClass.isEnum() -> { - val classBody = ClassBodyConverter(psiClass, this, isOpenClass = false, isObject = false).convertBody() + modifiers = modifiers.without(Modifier.ABSTRACT) + val hasInheritors = psiClass.getFields().any { it is PsiEnumConstant && it.getInitializingClass() != null } + val classBody = ClassBodyConverter(psiClass, this, isOpenClass = hasInheritors, isObject = false).convertBody() Enum(name, annotations, modifiers, typeParameters, implementsTypes, classBody) } @@ -307,10 +309,11 @@ class Converter private( val name = correction?.identifier ?: field.declarationIdentifier() val converted = if (field is PsiEnumConstant) { val argumentList = field.getArgumentList() - EnumConstant(name, - annotations, - modifiers, - deferredElement { codeConverter -> ExpressionList(codeConverter.convertExpressions(argumentList?.getExpressions() ?: arrayOf())).assignPrototype(argumentList) }) + val params = deferredElement { codeConverter -> + ExpressionList(codeConverter.convertExpressions(argumentList?.getExpressions() ?: arrayOf())).assignPrototype(argumentList) + } + val body = field.getInitializingClass()?.let { convertAnonymousClassBody(it) } + EnumConstant(name, annotations, modifiers, params, body) } else { val isVal = isVal(referenceSearcher, field) @@ -551,6 +554,11 @@ class Converter private( .assignPrototype(owner.getModifierList(), CommentsAndSpacesInheritance(blankLinesBefore = false)) } + public fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody { + return AnonymousClassBody(ClassBodyConverter(anonymousClass, this, isOpenClass = false, isObject = false).convertBody(), + anonymousClass.getBaseClassType().resolve()?.isInterface() ?: false).assignPrototype(anonymousClass) + } + private val MODIFIERS_MAP = listOf( PsiModifier.ABSTRACT to Modifier.ABSTRACT, PsiModifier.PUBLIC to Modifier.PUBLIC, diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt index 13bca4a35de..27d8b6e1e65 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt @@ -327,7 +327,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter { result = NewClassExpression(classRefConverted, convertArguments(expression), codeConverter.convertExpression(qualifier), - if (anonymousClass != null) codeConverter.convertAnonymousClassBody(anonymousClass) else null) + if (anonymousClass != null) converter.convertAnonymousClassBody(anonymousClass) else null) } } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/AnonymousClassBody.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/AnonymousClassBody.kt index ffa2a7be4e6..ac1950bf3ab 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/AnonymousClassBody.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/AnonymousClassBody.kt @@ -21,6 +21,6 @@ import org.jetbrains.kotlin.j2k.CodeBuilder class AnonymousClassBody(body: ClassBody, val extendsInterface: Boolean) : Class(Identifier.Empty, Annotations.Empty, Modifiers.Empty, TypeParameterList.Empty, listOf(), null, listOf(), body) { override fun generateCode(builder: CodeBuilder) { - body.append(builder) + body.appendTo(builder) } } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt index 2f486f03044..c116e104a7f 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Class.kt @@ -45,7 +45,7 @@ open class Class( appendBaseTypes(builder) typeParameterList.appendWhere(builder) - body.append(builder) + body.appendTo(builder) } protected open val keyword: String diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt index d1931409e42..6296b1ae361 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/ClassBody.kt @@ -33,7 +33,7 @@ class ClassBody ( val rBrace: RBrace, val isEnumBody: Boolean) { - fun append(builder: CodeBuilder) { + fun appendTo(builder: CodeBuilder) { val membersFiltered = members.filter { !it.isEmpty } if (membersFiltered.isEmpty() && companionObjectMembers.isEmpty()) return diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt index 0abe9c0a637..026b5c76288 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Enum.kt @@ -38,6 +38,6 @@ class Enum( appendBaseTypes(builder) - body.append(builder) + body.appendTo(builder) } } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/EnumConstant.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/EnumConstant.kt index 520edeaee4e..82e8e104b1f 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/EnumConstant.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/EnumConstant.kt @@ -22,15 +22,19 @@ class EnumConstant( val identifier: Identifier, annotations: Annotations, modifiers: Modifiers, - val params: DeferredElement + val params: DeferredElement, + val body: AnonymousClassBody? ) : Member(annotations, modifiers) { override fun generateCode(builder: CodeBuilder) { - if (params.isEmpty) { - builder append annotations append identifier - return + builder append annotations append identifier + + if (!params.isEmpty) { + builder append "(" append params append ")" } - builder append annotations append identifier append "(" append params append ")" + if (body != null) { + builder append body + } } } diff --git a/j2k/testData/fileOrElement/enum/constantsWithBody1.java b/j2k/testData/fileOrElement/enum/constantsWithBody1.java new file mode 100644 index 00000000000..43c5cc73a75 --- /dev/null +++ b/j2k/testData/fileOrElement/enum/constantsWithBody1.java @@ -0,0 +1,11 @@ +public enum E { + A, + + B { + @Override + void bar() { + } + }; + + void bar(){} +} \ No newline at end of file diff --git a/j2k/testData/fileOrElement/enum/constantsWithBody1.kt b/j2k/testData/fileOrElement/enum/constantsWithBody1.kt new file mode 100644 index 00000000000..e90e1f09e3b --- /dev/null +++ b/j2k/testData/fileOrElement/enum/constantsWithBody1.kt @@ -0,0 +1,11 @@ +public enum class E { + A, + + B { + override fun bar() { + } + }; + + open fun bar() { + } +} diff --git a/j2k/testData/fileOrElement/enum/constantsWithBody2.java b/j2k/testData/fileOrElement/enum/constantsWithBody2.java new file mode 100644 index 00000000000..732081348a0 --- /dev/null +++ b/j2k/testData/fileOrElement/enum/constantsWithBody2.java @@ -0,0 +1,24 @@ +public enum E { + A(1) { + @Override + void bar() { + foo(this.p); + } + }, + + B(2) { + @Override + void bar() { + } + }; + + private int p; + + E(int p) { + this.p = p; + } + + void foo(int p) {} + + abstract void bar(); +} \ No newline at end of file diff --git a/j2k/testData/fileOrElement/enum/constantsWithBody2.kt b/j2k/testData/fileOrElement/enum/constantsWithBody2.kt new file mode 100644 index 00000000000..8301b1896c6 --- /dev/null +++ b/j2k/testData/fileOrElement/enum/constantsWithBody2.kt @@ -0,0 +1,18 @@ +// ERROR: Cannot access 'p': it is 'invisible_fake' in 'A' +public enum class E(private val p: Int) { + A(1) { + override fun bar() { + foo(this.p) + } + }, + + B(2) { + override fun bar() { + } + }; + + fun foo(p: Int) { + } + + abstract fun bar() +} diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java index 9e225d783f8..b41dfd58182 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterForWebDemoTestGenerated.java @@ -1612,6 +1612,18 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo doTest(fileName); } + @TestMetadata("constantsWithBody1.java") + public void testConstantsWithBody1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/constantsWithBody1.java"); + doTest(fileName); + } + + @TestMetadata("constantsWithBody2.java") + public void testConstantsWithBody2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/constantsWithBody2.java"); + doTest(fileName); + } + @TestMetadata("emptyEnum.java") public void testEmptyEnum() throws Exception { String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java"); diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java index dcdaaf34129..8b26ef7d919 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterSingleFileTestGenerated.java @@ -1612,6 +1612,18 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo doTest(fileName); } + @TestMetadata("constantsWithBody1.java") + public void testConstantsWithBody1() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/constantsWithBody1.java"); + doTest(fileName); + } + + @TestMetadata("constantsWithBody2.java") + public void testConstantsWithBody2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/constantsWithBody2.java"); + doTest(fileName); + } + @TestMetadata("emptyEnum.java") public void testEmptyEnum() throws Exception { String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java");