diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java index 36ea5c9313e..0cd3dbf7dcb 100644 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -40,13 +40,19 @@ public class Converter { @NotNull public static AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) { - // TODO: replace by Block, use class.getChild() method - return new AnonymousClass( - classesToClassList(anonymousClass.getAllInnerClasses()), - methodsToFunctionList(anonymousClass.getMethods()), - fieldsToFieldList(anonymousClass.getAllFields()), - initializersToInitializerList(anonymousClass.getInitializers()) - ); + return new AnonymousClass(getMembers(anonymousClass)); + } + + private static List getMembers(PsiClass psiClass) { + List members = new LinkedList(); + for (PsiElement e : psiClass.getChildren()) { + if (e instanceof PsiMethod) members.add(methodToFunction((PsiMethod) e, true)); + else if (e instanceof PsiField) members.add(fieldToField((PsiField) e)); + else if (e instanceof PsiClass) members.add(classToClass((PsiClass) e)); + else if (e instanceof PsiClassInitializer) members.add(initializerToInitializer((PsiClassInitializer) e)); + else if (e instanceof PsiMember) System.out.println(e.getClass() + " " + e.getText()); + } + return members; } @NotNull @@ -88,16 +94,15 @@ public class Converter { @NotNull private static Class classToClass(@NotNull PsiClass psiClass) { final Set modifiers = modifiersListToModifiersSet(psiClass.getModifierList()); - final List innerClasses = classesToClassList(psiClass.getAllInnerClasses()); - final List methods = methodsToFunctionList(psiClass.getMethods()); final List fields = fieldsToFieldList(psiClass.getFields()); - final List anonymousInitializers = initializersToInitializerList(psiClass.getInitializers()); final List typeParameters = elementsToElementList(psiClass.getTypeParameters()); final List implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes()); final List extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes()); final IdentifierImpl name = new IdentifierImpl(psiClass.getName()); final List baseClassParams = new LinkedList(); + List members = getMembers(psiClass); + // we try to find super() call and generate class declaration like that: class A(name: String, i : Int) : Base(name) final SuperVisitor visitor = new SuperVisitor(); psiClass.accept(visitor); @@ -114,49 +119,52 @@ public class Converter { final List finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields); final Map initializers = new HashMap(); - for (final Function f : methods) { - for (Field fo : finalOrWithEmptyInitializer) { - String init = getDefaultInitializer(fo); - initializers.put(fo.getIdentifier().toKotlin(), init); - } - + for (final Member m : members) { // and modify secondaries - if (f.getKind() == INode.Kind.CONSTRUCTOR && !((Constructor) f).isPrimary()) { - final List newStatements = new LinkedList(); + if (m.getKind() == INode.Kind.CONSTRUCTOR) { + Function f = (Function)m; + if (!((Constructor) f).isPrimary()) { + for (Field fo : finalOrWithEmptyInitializer) { + String init = getDefaultInitializer(fo); + initializers.put(fo.getIdentifier().toKotlin(), init); + } - for (Statement s : f.getBlock().getStatements()) { - boolean isRemoved = false; + final List newStatements = new LinkedList(); - if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { - final AssignmentExpression assignmentExpression = (AssignmentExpression) s; - if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) { - for (Field fo : finalOrWithEmptyInitializer) { - final String id = fo.getIdentifier().toKotlin(); - if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) { - initializers.put(id, assignmentExpression.getRight().toKotlin()); - isRemoved = true; + for (Statement s : f.getBlock().getStatements()) { + boolean isRemoved = false; + + if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { + final AssignmentExpression assignmentExpression = (AssignmentExpression) s; + if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) { + for (Field fo : finalOrWithEmptyInitializer) { + final String id = fo.getIdentifier().toKotlin(); + if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) { + initializers.put(id, assignmentExpression.getRight().toKotlin()); + isRemoved = true; + } } } } + if (!isRemoved) { + newStatements.add(s); + } } - if (!isRemoved) { - newStatements.add(s); - } + + newStatements.add( + 0, + new DummyStringStatement( + "val __ = " + createPrimaryConstructorInvocation( + name.toKotlin(), + finalOrWithEmptyInitializer, + initializers))); + + f.setBlock(new Block(newStatements)); } - - newStatements.add( - 0, - new DummyStringStatement( - "val __ = " + createPrimaryConstructorInvocation( - name.toKotlin(), - finalOrWithEmptyInitializer, - initializers))); - - f.setBlock(new Block(newStatements)); } } - methods.add( + members.add( new Constructor( Identifier.EMPTY_IDENTIFIER, Collections.emptySet(), @@ -170,18 +178,10 @@ public class Converter { } if (psiClass.isInterface()) - return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, innerClasses, methods, fields, anonymousInitializers); + return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, members); if (psiClass.isEnum()) - return new Enum(name, modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, - innerClasses, methods, fieldsToFieldListForEnums(psiClass.getAllFields()), anonymousInitializers); - return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, anonymousInitializers); - } - - @NotNull - private static List initializersToInitializerList(@NotNull PsiClassInitializer[] initializers) { - List result = new LinkedList(); - for (PsiClassInitializer i : initializers) result.add(initializerToInitializer(i)); - return result; + return new Enum(name, modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, members); + return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members); } @NotNull @@ -206,31 +206,6 @@ public class Converter { } } - // hack for enums, we remove methods: - // private int ordinal() { ... } - // private String name() { ... } - // those methods any enum class inherits from java.lang.Enum - @NotNull - private static List fieldsToFieldListForEnums(@NotNull PsiField[] fields) { - List result = new LinkedList(); - for (PsiField f : fields) { - if ((f.getName().equals("ordinal") - && f.getType().getCanonicalText().equals("int") - && f.hasModifierProperty(PsiModifier.PRIVATE) - && f.hasModifierProperty(PsiModifier.FINAL) - ) || - (f.getName().equals("name") - && f.getType().getCanonicalText().equals("java.lang.String") - && f.hasModifierProperty(PsiModifier.PRIVATE) - && f.hasModifierProperty(PsiModifier.FINAL) - )) - continue; - - result.add(fieldToField(f)); - } - return result; - } - @NotNull private static List fieldsToFieldList(@NotNull PsiField[] fields) { List result = new LinkedList(); @@ -256,13 +231,6 @@ public class Converter { ); } - @NotNull - private static List methodsToFunctionList(@NotNull PsiMethod[] methods) { - List result = new LinkedList(); - for (PsiMethod t : methods) result.add(methodToFunction(t, true)); - return result; - } - @Nullable private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) { ThisVisitor tv = new ThisVisitor(); diff --git a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java index 45fd78b622b..e8a87d2b3f7 100644 --- a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java +++ b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java @@ -9,17 +9,15 @@ import java.util.List; * @author ignatov */ public class AnonymousClass extends Class { - public AnonymousClass(List innerClasses, List methods, List fields, List initializers) { + public AnonymousClass(List members) { super(new IdentifierImpl("anonClass"), Collections.emptySet(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), - innerClasses, - methods, - fields, - initializers); + members + ); } @NotNull diff --git a/src/org/jetbrains/jet/j2k/ast/Class.java b/src/org/jetbrains/jet/j2k/ast/Class.java index 37fa884aa57..3a40d66a427 100644 --- a/src/org/jetbrains/jet/j2k/ast/Class.java +++ b/src/org/jetbrains/jet/j2k/ast/Class.java @@ -18,31 +18,26 @@ public class Class extends Member { String TYPE = "class"; final Identifier myName; private final List myBaseClassParams; - private final List myInitializers; + private List myMembers; private final List myTypeParameters; private final List myExtendsTypes; private final List myImplementsTypes; - final List myInnerClasses; - private final List myMethods; - final List myFields; public Class(Identifier name, Set modifiers, List typeParameters, List extendsTypes, - List baseClassParams, List implementsTypes, List innerClasses, List methods, List fields, List initializers) { + List baseClassParams, List implementsTypes, List members) { myName = name; myBaseClassParams = baseClassParams; myModifiers = modifiers; myTypeParameters = typeParameters; myExtendsTypes = extendsTypes; myImplementsTypes = implementsTypes; - myInnerClasses = innerClasses; - myMethods = methods; - myFields = fields; - myInitializers = initializers; + myMembers = members; } + @Nullable private Constructor getPrimaryConstructor() { - for (Function m : myMethods) + for (Member m : myMembers) if (m.getKind() == Kind.CONSTRUCTOR) if (((Constructor) m).isPrimary()) return (Constructor) m; @@ -82,9 +77,9 @@ public class Class extends Member { } @NotNull - List methodsExceptConstructors() { - final LinkedList result = new LinkedList(); - for (Function m : myMethods) + LinkedList membersExceptConstructors() { + final LinkedList result = new LinkedList(); + for (Member m : myMembers) if (m.getKind() != Kind.CONSTRUCTOR) result.add(m); return result; @@ -93,12 +88,13 @@ public class Class extends Member { @NotNull List secondaryConstructorsAsStaticInitFunction() { final LinkedList result = new LinkedList(); - for (Function m : myMethods) + for (Member m : myMembers) if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) { + Function f = (Function) m; Set modifiers = new HashSet(m.myModifiers); modifiers.add(Modifier.STATIC); - final List statements = m.getBlock().getStatements(); + final List statements = f.getBlock().getStatements(); statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages final Block block = new Block(statements); @@ -106,8 +102,8 @@ public class Class extends Member { new IdentifierImpl("init"), modifiers, new ClassType(myName), - m.getTypeParameters(), - m.getParams(), + f.getTypeParameters(), + f.getParams(), block )); } @@ -164,11 +160,8 @@ public class Class extends Member { String bodyToKotlin() { return SPACE + "{" + N + - AstUtil.joinNodes(getNonStatic(myFields), N) + N + - AstUtil.joinNodes(getNonStatic(myInitializers), N) + N + + AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N + classObjectToKotlin() + N + - AstUtil.joinNodes(getNonStatic(methodsExceptConstructors()), N) + N + - AstUtil.joinNodes(getNonStatic(myInnerClasses), N) + N + primaryConstructorBodyToKotlin() + N + "}"; } @@ -190,17 +183,11 @@ public class Class extends Member { } private String classObjectToKotlin() { - final List staticMethods = new LinkedList(secondaryConstructorsAsStaticInitFunction()); - staticMethods.addAll(getStatic(methodsExceptConstructors())); - final List staticFields = getStatic(myFields); - final List staticInitializers = getStatic(myInitializers); - final List staticInnerClasses = getStatic(myInnerClasses); - if (staticFields.size() + staticMethods.size() + staticInnerClasses.size() + staticInitializers.size() > 0) { + final List staticMembers = new LinkedList(secondaryConstructorsAsStaticInitFunction()); + staticMembers.addAll(getStatic(membersExceptConstructors())); + if (staticMembers.size() > 0) { return "class" + SPACE + "object" + SPACE + "{" + N + - AstUtil.joinNodes(staticFields, N) + N + - AstUtil.joinNodes(staticInitializers, N) + N + - AstUtil.joinNodes(staticMethods, N) + N + - AstUtil.joinNodes(staticInnerClasses, N) + N + + AstUtil.joinNodes(staticMembers, N) + N + "}"; } return EMPTY; diff --git a/src/org/jetbrains/jet/j2k/ast/Enum.java b/src/org/jetbrains/jet/j2k/ast/Enum.java index d781e944196..9e9c1659e7f 100644 --- a/src/org/jetbrains/jet/j2k/ast/Enum.java +++ b/src/org/jetbrains/jet/j2k/ast/Enum.java @@ -10,11 +10,12 @@ import java.util.Set; * @author ignatov */ public class Enum extends Class { - public Enum(Identifier name, Set modifiers, List typeParameters, List extendsTypes, List baseClassParams, List implementsTypes, List innerClasses, List methods, List fields, List initializers) { - super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); + public Enum(Identifier name, Set modifiers, List typeParameters, List extendsTypes, + List baseClassParams, List implementsTypes, List members) { + super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members); } - String primaryConstructorSignatureToKotlin() { + String primaryConstructorSignatureToKotlin() { String s = super.primaryConstructorSignatureToKotlin(); return s.equals("()") ? EMPTY : s; } @@ -27,10 +28,9 @@ public class Enum extends Class { @NotNull @Override public String toKotlin() { - return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N + - AstUtil.joinNodes(myFields, N) + N + - AstUtil.joinNodes(methodsExceptConstructors(), N) + N + - AstUtil.joinNodes(myInnerClasses, N) + N + + return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() + + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N + + AstUtil.joinNodes(membersExceptConstructors(), N) + N + primaryConstructorBodyToKotlin() + N + "}"; } diff --git a/src/org/jetbrains/jet/j2k/ast/Trait.java b/src/org/jetbrains/jet/j2k/ast/Trait.java index 8f39b8d9193..60bcd122add 100644 --- a/src/org/jetbrains/jet/j2k/ast/Trait.java +++ b/src/org/jetbrains/jet/j2k/ast/Trait.java @@ -7,8 +7,9 @@ import java.util.Set; * @author ignatov */ public class Trait extends Class { - public Trait(Identifier name, Set modifiers, List typeParameters, List extendsTypes, List baseClassParams, List implementsTypes, List innerClasses, List methods, List fields, List initializers) { - super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); + public Trait(Identifier name, Set modifiers, List typeParameters, List extendsTypes, + List baseClassParams, List implementsTypes, List members) { + super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members); TYPE = "trait"; } diff --git a/testData/ast/class/class/oneStaticFieldOneNonStatic.kt b/testData/ast/class/class/oneStaticFieldOneNonStatic.kt index ebff54572d4..fe55d4cafd3 100644 --- a/testData/ast/class/class/oneStaticFieldOneNonStatic.kt +++ b/testData/ast/class/class/oneStaticFieldOneNonStatic.kt @@ -1,8 +1,8 @@ class S() { -class object { -var myI : Int = 10 -} open fun sB() : Boolean { return true } +class object { +var myI : Int = 10 +} } \ No newline at end of file diff --git a/testData/ast/class/class/oneStaticMethodOneNonStatic.kt b/testData/ast/class/class/oneStaticMethodOneNonStatic.kt index a50ebaff602..382ea95f5b0 100644 --- a/testData/ast/class/class/oneStaticMethodOneNonStatic.kt +++ b/testData/ast/class/class/oneStaticMethodOneNonStatic.kt @@ -1,10 +1,10 @@ class S() { +open fun sB() : Boolean { +return true +} class object { open fun sI() : Int { return 1 } } -open fun sB() : Boolean { -return true -} } \ No newline at end of file diff --git a/testData/ast/constructors/file/identifier.kt b/testData/ast/constructors/file/identifier.kt index 71bfa01998e..384974d68f7 100644 --- a/testData/ast/constructors/file/identifier.kt +++ b/testData/ast/constructors/file/identifier.kt @@ -2,6 +2,9 @@ public open class Identifier(myName : String?, myHasDollar : Boolean) { private val myName : String? private var myHasDollar : Boolean private var myNullable : Boolean = true +open public fun getName() : String? { +return myName +} class object { open public fun init(name : String?) : Identifier { val __ = Identifier(name, false) @@ -18,9 +21,6 @@ __.myNullable = isNullable return __ } } -open public fun getName() : String? { -return myName -} { $myName = myName $myHasDollar = myHasDollar