now we use members instead of bunch inner classes, fields and methods

This commit is contained in:
Sergey Ignatov
2011-11-17 12:54:37 +04:00
parent 773bc1ced2
commit 62bfb55973
8 changed files with 93 additions and 139 deletions
+53 -85
View File
@@ -40,13 +40,19 @@ public class Converter {
@NotNull @NotNull
public static AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) { public static AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
// TODO: replace by Block, use class.getChild() method return new AnonymousClass(getMembers(anonymousClass));
return new AnonymousClass( }
classesToClassList(anonymousClass.getAllInnerClasses()),
methodsToFunctionList(anonymousClass.getMethods()), private static List<Member> getMembers(PsiClass psiClass) {
fieldsToFieldList(anonymousClass.getAllFields()), List<Member> members = new LinkedList<Member>();
initializersToInitializerList(anonymousClass.getInitializers()) 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 @NotNull
@@ -88,16 +94,15 @@ public class Converter {
@NotNull @NotNull
private static Class classToClass(@NotNull PsiClass psiClass) { private static Class classToClass(@NotNull PsiClass psiClass) {
final Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList()); final Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList());
final List<Class> innerClasses = classesToClassList(psiClass.getAllInnerClasses());
final List<Function> methods = methodsToFunctionList(psiClass.getMethods());
final List<Field> fields = fieldsToFieldList(psiClass.getFields()); final List<Field> fields = fieldsToFieldList(psiClass.getFields());
final List<Initializer> anonymousInitializers = initializersToInitializerList(psiClass.getInitializers());
final List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters()); final List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters());
final List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes()); final List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes());
final List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes()); final List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes());
final IdentifierImpl name = new IdentifierImpl(psiClass.getName()); final IdentifierImpl name = new IdentifierImpl(psiClass.getName());
final List<Expression> baseClassParams = new LinkedList<Expression>(); final List<Expression> baseClassParams = new LinkedList<Expression>();
List<Member> members = getMembers(psiClass);
// we try to find super() call and generate class declaration like that: class A(name: String, i : Int) : Base(name) // 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(); final SuperVisitor visitor = new SuperVisitor();
psiClass.accept(visitor); psiClass.accept(visitor);
@@ -114,49 +119,52 @@ public class Converter {
final List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields); final List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields);
final Map<String, String> initializers = new HashMap<String, String>(); final Map<String, String> initializers = new HashMap<String, String>();
for (final Function f : methods) { for (final Member m : members) {
for (Field fo : finalOrWithEmptyInitializer) {
String init = getDefaultInitializer(fo);
initializers.put(fo.getIdentifier().toKotlin(), init);
}
// and modify secondaries // and modify secondaries
if (f.getKind() == INode.Kind.CONSTRUCTOR && !((Constructor) f).isPrimary()) { if (m.getKind() == INode.Kind.CONSTRUCTOR) {
final List<Statement> newStatements = new LinkedList<Statement>(); 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()) { final List<Statement> newStatements = new LinkedList<Statement>();
boolean isRemoved = false;
if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { for (Statement s : f.getBlock().getStatements()) {
final AssignmentExpression assignmentExpression = (AssignmentExpression) s; boolean isRemoved = false;
if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
for (Field fo : finalOrWithEmptyInitializer) { if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) {
final String id = fo.getIdentifier().toKotlin(); final AssignmentExpression assignmentExpression = (AssignmentExpression) s;
if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) { if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
initializers.put(id, assignmentExpression.getRight().toKotlin()); for (Field fo : finalOrWithEmptyInitializer) {
isRemoved = true; 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( new Constructor(
Identifier.EMPTY_IDENTIFIER, Identifier.EMPTY_IDENTIFIER,
Collections.<String>emptySet(), Collections.<String>emptySet(),
@@ -170,18 +178,10 @@ public class Converter {
} }
if (psiClass.isInterface()) if (psiClass.isInterface())
return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, innerClasses, methods, fields, anonymousInitializers); return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, members);
if (psiClass.isEnum()) if (psiClass.isEnum())
return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, members);
innerClasses, methods, fieldsToFieldListForEnums(psiClass.getAllFields()), anonymousInitializers); return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, anonymousInitializers);
}
@NotNull
private static List<Initializer> initializersToInitializerList(@NotNull PsiClassInitializer[] initializers) {
List<Initializer> result = new LinkedList<Initializer>();
for (PsiClassInitializer i : initializers) result.add(initializerToInitializer(i));
return result;
} }
@NotNull @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<Field> fieldsToFieldListForEnums(@NotNull PsiField[] fields) {
List<Field> result = new LinkedList<Field>();
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 @NotNull
private static List<Field> fieldsToFieldList(@NotNull PsiField[] fields) { private static List<Field> fieldsToFieldList(@NotNull PsiField[] fields) {
List<Field> result = new LinkedList<Field>(); List<Field> result = new LinkedList<Field>();
@@ -256,13 +231,6 @@ public class Converter {
); );
} }
@NotNull
private static List<Function> methodsToFunctionList(@NotNull PsiMethod[] methods) {
List<Function> result = new LinkedList<Function>();
for (PsiMethod t : methods) result.add(methodToFunction(t, true));
return result;
}
@Nullable @Nullable
private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) { private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) {
ThisVisitor tv = new ThisVisitor(); ThisVisitor tv = new ThisVisitor();
@@ -9,17 +9,15 @@ import java.util.List;
* @author ignatov * @author ignatov
*/ */
public class AnonymousClass extends Class { public class AnonymousClass extends Class {
public AnonymousClass(List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public AnonymousClass(List<Member> members) {
super(new IdentifierImpl("anonClass"), super(new IdentifierImpl("anonClass"),
Collections.<String>emptySet(), Collections.<String>emptySet(),
Collections.<Element>emptyList(), Collections.<Element>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
Collections.<Expression>emptyList(), Collections.<Expression>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
innerClasses, members
methods, );
fields,
initializers);
} }
@NotNull @NotNull
+18 -31
View File
@@ -18,31 +18,26 @@ public class Class extends Member {
String TYPE = "class"; String TYPE = "class";
final Identifier myName; final Identifier myName;
private final List<Expression> myBaseClassParams; private final List<Expression> myBaseClassParams;
private final List<Initializer> myInitializers; private List<? extends Member> myMembers;
private final List<Element> myTypeParameters; private final List<Element> myTypeParameters;
private final List<Type> myExtendsTypes; private final List<Type> myExtendsTypes;
private final List<Type> myImplementsTypes; private final List<Type> myImplementsTypes;
final List<Class> myInnerClasses;
private final List<Function> myMethods;
final List<Field> myFields;
public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { List<Expression> baseClassParams, List<Type> implementsTypes, List<? extends Member> members) {
myName = name; myName = name;
myBaseClassParams = baseClassParams; myBaseClassParams = baseClassParams;
myModifiers = modifiers; myModifiers = modifiers;
myTypeParameters = typeParameters; myTypeParameters = typeParameters;
myExtendsTypes = extendsTypes; myExtendsTypes = extendsTypes;
myImplementsTypes = implementsTypes; myImplementsTypes = implementsTypes;
myInnerClasses = innerClasses; myMembers = members;
myMethods = methods;
myFields = fields;
myInitializers = initializers;
} }
@Nullable @Nullable
private Constructor getPrimaryConstructor() { private Constructor getPrimaryConstructor() {
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() == Kind.CONSTRUCTOR) if (m.getKind() == Kind.CONSTRUCTOR)
if (((Constructor) m).isPrimary()) if (((Constructor) m).isPrimary())
return (Constructor) m; return (Constructor) m;
@@ -82,9 +77,9 @@ public class Class extends Member {
} }
@NotNull @NotNull
List<Function> methodsExceptConstructors() { LinkedList<Member> membersExceptConstructors() {
final LinkedList<Function> result = new LinkedList<Function>(); final LinkedList<Member> result = new LinkedList<Member>();
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() != Kind.CONSTRUCTOR) if (m.getKind() != Kind.CONSTRUCTOR)
result.add(m); result.add(m);
return result; return result;
@@ -93,12 +88,13 @@ public class Class extends Member {
@NotNull @NotNull
List<Function> secondaryConstructorsAsStaticInitFunction() { List<Function> secondaryConstructorsAsStaticInitFunction() {
final LinkedList<Function> result = new LinkedList<Function>(); final LinkedList<Function> result = new LinkedList<Function>();
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) { if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) {
Function f = (Function) m;
Set<String> modifiers = new HashSet<String>(m.myModifiers); Set<String> modifiers = new HashSet<String>(m.myModifiers);
modifiers.add(Modifier.STATIC); modifiers.add(Modifier.STATIC);
final List<Statement> statements = m.getBlock().getStatements(); final List<Statement> statements = f.getBlock().getStatements();
statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages
final Block block = new Block(statements); final Block block = new Block(statements);
@@ -106,8 +102,8 @@ public class Class extends Member {
new IdentifierImpl("init"), new IdentifierImpl("init"),
modifiers, modifiers,
new ClassType(myName), new ClassType(myName),
m.getTypeParameters(), f.getTypeParameters(),
m.getParams(), f.getParams(),
block block
)); ));
} }
@@ -164,11 +160,8 @@ public class Class extends Member {
String bodyToKotlin() { String bodyToKotlin() {
return SPACE + "{" + N + return SPACE + "{" + N +
AstUtil.joinNodes(getNonStatic(myFields), N) + N + AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N +
AstUtil.joinNodes(getNonStatic(myInitializers), N) + N +
classObjectToKotlin() + N + classObjectToKotlin() + N +
AstUtil.joinNodes(getNonStatic(methodsExceptConstructors()), N) + N +
AstUtil.joinNodes(getNonStatic(myInnerClasses), N) + N +
primaryConstructorBodyToKotlin() + N + primaryConstructorBodyToKotlin() + N +
"}"; "}";
} }
@@ -190,17 +183,11 @@ public class Class extends Member {
} }
private String classObjectToKotlin() { private String classObjectToKotlin() {
final List<Member> staticMethods = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction()); final List<Member> staticMembers = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction());
staticMethods.addAll(getStatic(methodsExceptConstructors())); staticMembers.addAll(getStatic(membersExceptConstructors()));
final List<Member> staticFields = getStatic(myFields); if (staticMembers.size() > 0) {
final List<Member> staticInitializers = getStatic(myInitializers);
final List<Member> staticInnerClasses = getStatic(myInnerClasses);
if (staticFields.size() + staticMethods.size() + staticInnerClasses.size() + staticInitializers.size() > 0) {
return "class" + SPACE + "object" + SPACE + "{" + N + return "class" + SPACE + "object" + SPACE + "{" + N +
AstUtil.joinNodes(staticFields, N) + N + AstUtil.joinNodes(staticMembers, N) + N +
AstUtil.joinNodes(staticInitializers, N) + N +
AstUtil.joinNodes(staticMethods, N) + N +
AstUtil.joinNodes(staticInnerClasses, N) + N +
"}"; "}";
} }
return EMPTY; return EMPTY;
+7 -7
View File
@@ -10,11 +10,12 @@ import java.util.Set;
* @author ignatov * @author ignatov
*/ */
public class Enum extends Class { public class Enum extends Class {
public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
} }
String primaryConstructorSignatureToKotlin() { String primaryConstructorSignatureToKotlin() {
String s = super.primaryConstructorSignatureToKotlin(); String s = super.primaryConstructorSignatureToKotlin();
return s.equals("()") ? EMPTY : s; return s.equals("()") ? EMPTY : s;
} }
@@ -27,10 +28,9 @@ public class Enum extends Class {
@NotNull @NotNull
@Override @Override
public String toKotlin() { public String toKotlin() {
return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N + return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() +
AstUtil.joinNodes(myFields, N) + N + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N +
AstUtil.joinNodes(methodsExceptConstructors(), N) + N + AstUtil.joinNodes(membersExceptConstructors(), N) + N +
AstUtil.joinNodes(myInnerClasses, N) + N +
primaryConstructorBodyToKotlin() + N + primaryConstructorBodyToKotlin() + N +
"}"; "}";
} }
+3 -2
View File
@@ -7,8 +7,9 @@ import java.util.Set;
* @author ignatov * @author ignatov
*/ */
public class Trait extends Class { public class Trait extends Class {
public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
TYPE = "trait"; TYPE = "trait";
} }
@@ -1,8 +1,8 @@
class S() { class S() {
class object {
var myI : Int = 10
}
open fun sB() : Boolean { open fun sB() : Boolean {
return true return true
} }
class object {
var myI : Int = 10
}
} }
@@ -1,10 +1,10 @@
class S() { class S() {
open fun sB() : Boolean {
return true
}
class object { class object {
open fun sI() : Int { open fun sI() : Int {
return 1 return 1
} }
} }
open fun sB() : Boolean {
return true
}
} }
+3 -3
View File
@@ -2,6 +2,9 @@ public open class Identifier(myName : String?, myHasDollar : Boolean) {
private val myName : String? private val myName : String?
private var myHasDollar : Boolean private var myHasDollar : Boolean
private var myNullable : Boolean = true private var myNullable : Boolean = true
open public fun getName() : String? {
return myName
}
class object { class object {
open public fun init(name : String?) : Identifier { open public fun init(name : String?) : Identifier {
val __ = Identifier(name, false) val __ = Identifier(name, false)
@@ -18,9 +21,6 @@ __.myNullable = isNullable
return __ return __
} }
} }
open public fun getName() : String? {
return myName
}
{ {
$myName = myName $myName = myName
$myHasDollar = myHasDollar $myHasDollar = myHasDollar