J2K: converting of enum constants overriding members

This commit is contained in:
Valentin Kipyatkov
2015-05-27 14:45:47 +03:00
parent bb0b3fcd0c
commit 0a2983d602
14 changed files with 115 additions and 20 deletions
@@ -153,11 +153,6 @@ class CodeConverter(
private fun PsiPrefixExpression.isLiteralWithSign() private fun PsiPrefixExpression.isLiteralWithSign()
= getOperand() is PsiLiteralExpression && getOperationTokenType() in setOf(JavaTokenType.PLUS, JavaTokenType.MINUS) = 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 { private fun needConversion(actual: PsiType, expected: PsiType): Boolean {
val expectedStr = expected.getCanonicalText() val expectedStr = expected.getCanonicalText()
val actualStr = actual.getCanonicalText() val actualStr = actual.getCanonicalText()
+13 -5
View File
@@ -176,7 +176,9 @@ class Converter private(
} }
psiClass.isEnum() -> { 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) Enum(name, annotations, modifiers, typeParameters, implementsTypes, classBody)
} }
@@ -307,10 +309,11 @@ class Converter private(
val name = correction?.identifier ?: field.declarationIdentifier() val name = correction?.identifier ?: field.declarationIdentifier()
val converted = if (field is PsiEnumConstant) { val converted = if (field is PsiEnumConstant) {
val argumentList = field.getArgumentList() val argumentList = field.getArgumentList()
EnumConstant(name, val params = deferredElement { codeConverter ->
annotations, ExpressionList(codeConverter.convertExpressions(argumentList?.getExpressions() ?: arrayOf<PsiExpression>())).assignPrototype(argumentList)
modifiers, }
deferredElement { codeConverter -> ExpressionList(codeConverter.convertExpressions(argumentList?.getExpressions() ?: arrayOf<PsiExpression>())).assignPrototype(argumentList) }) val body = field.getInitializingClass()?.let { convertAnonymousClassBody(it) }
EnumConstant(name, annotations, modifiers, params, body)
} }
else { else {
val isVal = isVal(referenceSearcher, field) val isVal = isVal(referenceSearcher, field)
@@ -551,6 +554,11 @@ class Converter private(
.assignPrototype(owner.getModifierList(), CommentsAndSpacesInheritance(blankLinesBefore = false)) .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( private val MODIFIERS_MAP = listOf(
PsiModifier.ABSTRACT to Modifier.ABSTRACT, PsiModifier.ABSTRACT to Modifier.ABSTRACT,
PsiModifier.PUBLIC to Modifier.PUBLIC, PsiModifier.PUBLIC to Modifier.PUBLIC,
@@ -327,7 +327,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
result = NewClassExpression(classRefConverted, result = NewClassExpression(classRefConverted,
convertArguments(expression), convertArguments(expression),
codeConverter.convertExpression(qualifier), codeConverter.convertExpression(qualifier),
if (anonymousClass != null) codeConverter.convertAnonymousClassBody(anonymousClass) else null) if (anonymousClass != null) converter.convertAnonymousClassBody(anonymousClass) else null)
} }
} }
@@ -21,6 +21,6 @@ import org.jetbrains.kotlin.j2k.CodeBuilder
class AnonymousClassBody(body: ClassBody, val extendsInterface: Boolean) class AnonymousClassBody(body: ClassBody, val extendsInterface: Boolean)
: Class(Identifier.Empty, Annotations.Empty, Modifiers.Empty, TypeParameterList.Empty, listOf(), null, listOf(), body) { : Class(Identifier.Empty, Annotations.Empty, Modifiers.Empty, TypeParameterList.Empty, listOf(), null, listOf(), body) {
override fun generateCode(builder: CodeBuilder) { override fun generateCode(builder: CodeBuilder) {
body.append(builder) body.appendTo(builder)
} }
} }
@@ -45,7 +45,7 @@ open class Class(
appendBaseTypes(builder) appendBaseTypes(builder)
typeParameterList.appendWhere(builder) typeParameterList.appendWhere(builder)
body.append(builder) body.appendTo(builder)
} }
protected open val keyword: String protected open val keyword: String
@@ -33,7 +33,7 @@ class ClassBody (
val rBrace: RBrace, val rBrace: RBrace,
val isEnumBody: Boolean) { val isEnumBody: Boolean) {
fun append(builder: CodeBuilder) { fun appendTo(builder: CodeBuilder) {
val membersFiltered = members.filter { !it.isEmpty } val membersFiltered = members.filter { !it.isEmpty }
if (membersFiltered.isEmpty() && companionObjectMembers.isEmpty()) return if (membersFiltered.isEmpty() && companionObjectMembers.isEmpty()) return
+1 -1
View File
@@ -38,6 +38,6 @@ class Enum(
appendBaseTypes(builder) appendBaseTypes(builder)
body.append(builder) body.appendTo(builder)
} }
} }
@@ -22,15 +22,19 @@ class EnumConstant(
val identifier: Identifier, val identifier: Identifier,
annotations: Annotations, annotations: Annotations,
modifiers: Modifiers, modifiers: Modifiers,
val params: DeferredElement<ExpressionList> val params: DeferredElement<ExpressionList>,
val body: AnonymousClassBody?
) : Member(annotations, modifiers) { ) : Member(annotations, modifiers) {
override fun generateCode(builder: CodeBuilder) { override fun generateCode(builder: CodeBuilder) {
if (params.isEmpty) { builder append annotations append identifier
builder append annotations append identifier
return if (!params.isEmpty) {
builder append "(" append params append ")"
} }
builder append annotations append identifier append "(" append params append ")" if (body != null) {
builder append body
}
} }
} }
@@ -0,0 +1,11 @@
public enum E {
A,
B {
@Override
void bar() {
}
};
void bar(){}
}
@@ -0,0 +1,11 @@
public enum class E {
A,
B {
override fun bar() {
}
};
open fun bar() {
}
}
@@ -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();
}
@@ -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()
}
@@ -1612,6 +1612,18 @@ public class JavaToKotlinConverterForWebDemoTestGenerated extends AbstractJavaTo
doTest(fileName); 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") @TestMetadata("emptyEnum.java")
public void testEmptyEnum() throws Exception { public void testEmptyEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java"); String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java");
@@ -1612,6 +1612,18 @@ public class JavaToKotlinConverterSingleFileTestGenerated extends AbstractJavaTo
doTest(fileName); 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") @TestMetadata("emptyEnum.java")
public void testEmptyEnum() throws Exception { public void testEmptyEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java"); String fileName = JetTestUtils.navigationMetadata("j2k/testData/fileOrElement/enum/emptyEnum.java");