base class params added to the class declaration

This commit is contained in:
Sergey Ignatov
2011-11-14 17:29:38 +04:00
parent 26b96d9562
commit 016064c273
23 changed files with 132 additions and 56 deletions
+40 -8
View File
@@ -85,9 +85,26 @@ public class Converter {
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>();
// for (PsiType t : psiClass.getExtendsListTypes())
// if (t != null && t instanceof PsiClassType) {
// final PsiClass resolve = ((PsiClassType) t).resolve();
// if (resolve != null) {
final SuperVisitor visitor = new SuperVisitor();
psiClass.accept(visitor);
final HashSet<PsiExpressionList> resolvedSuperCallParameters = visitor.getResolvedSuperCallParameters();
if (resolvedSuperCallParameters.size() == 1)
baseClassParams.addAll(
expressionsToExpressionList(
resolvedSuperCallParameters.toArray(new PsiExpressionList[1])[0].getExpressions()
)
);
// }
// }
// we create primary constructor // we create primary constructor
if (!psiClass.isEnum() && !psiClass.isInterface() && getPrimaryConstructor(psiClass) == null) { if (!psiClass.isEnum() && !psiClass.isInterface() && getPrimaryConstructorForThisCase(psiClass) == null) {
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>();
@@ -147,11 +164,11 @@ public class Converter {
} }
if (psiClass.isInterface()) if (psiClass.isInterface())
return new Trait(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields); return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, innerClasses, methods, fields);
if (psiClass.isEnum()) if (psiClass.isEnum())
return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), implementsTypes, return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes,
innerClasses, methods, fieldsToFieldListForEnums(psiClass.getAllFields())); innerClasses, methods, fieldsToFieldListForEnums(psiClass.getAllFields()));
return new Class(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields); return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields);
} }
private static String getDefaultInitializer(Field f) { private static String getDefaultInitializer(Field f) {
@@ -219,7 +236,7 @@ public class Converter {
} }
@Nullable @Nullable
public static PsiMethod getPrimaryConstructor(PsiClass psiClass) { public static PsiMethod getPrimaryConstructorForThisCase(PsiClass psiClass) {
ThisVisitor tv = new ThisVisitor(); ThisVisitor tv = new ThisVisitor();
psiClass.accept(tv); psiClass.accept(tv);
return tv.getPrimaryConstructor(); return tv.getPrimaryConstructor();
@@ -233,7 +250,7 @@ public class Converter {
if (parent.getConstructors().length == 1) if (parent.getConstructors().length == 1)
return true; return true;
else { else {
PsiMethod c = getPrimaryConstructor(parent); // TODO: move up to classToClass() method PsiMethod c = getPrimaryConstructorForThisCase(parent); // TODO: move up to classToClass() method
if (c != null && c.hashCode() == constructor.hashCode()) if (c != null && c.hashCode() == constructor.hashCode())
return true; return true;
} }
@@ -241,6 +258,22 @@ public class Converter {
return false; return false;
} }
@Nullable
public static PsiMethod getPrimaryConstructor(@NotNull PsiClass psiClass) { // TODO
for (PsiMethod c : psiClass.getConstructors())
if (isConstructorPrimary(c))
return c;
return null;
}
private static List<Statement> removeEmpty(List<Statement> statements) {
List<Statement> result = new LinkedList<Statement>();
for (Statement s : statements)
if (s != Statement.EMPTY_STATEMENT && s != Expression.EMPTY_EXPRESSION)
result.add(s);
return result;
}
@NotNull @NotNull
private static Function methodToFunction(PsiMethod method, boolean notEmpty) { private static Function methodToFunction(PsiMethod method, boolean notEmpty) {
final IdentifierImpl identifier = new IdentifierImpl(method.getName()); final IdentifierImpl identifier = new IdentifierImpl(method.getName());
@@ -257,14 +290,13 @@ public class Converter {
if (method.isConstructor()) { // TODO: simplify if (method.isConstructor()) { // TODO: simplify
boolean isPrimary = isConstructorPrimary(method); boolean isPrimary = isConstructorPrimary(method);
return new Constructor( return new Constructor(
identifier, identifier,
modifiers, modifiers,
type, type,
typeParameters, typeParameters,
params, params,
body, new Block(removeEmpty(body.getStatements()), false),
isPrimary isPrimary
); );
} }
@@ -14,6 +14,7 @@ public class AnonymousClass extends Class {
Collections.<String>emptySet(), Collections.<String>emptySet(),
Collections.<Element>emptyList(), Collections.<Element>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
Collections.<Expression>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
innerClasses, innerClasses,
methods, methods,
+20 -7
View File
@@ -9,12 +9,15 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static org.jetbrains.jet.j2k.util.AstUtil.*;
/** /**
* @author ignatov * @author ignatov
*/ */
public class Class extends Member { 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<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;
@@ -23,8 +26,9 @@ public class Class extends Member {
final List<Field> myFields; 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<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields) { List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields) {
myName = name; myName = name;
myBaseClassParams = baseClassParams;
myModifiers = modifiers; myModifiers = modifiers;
myTypeParameters = typeParameters; myTypeParameters = typeParameters;
myExtendsTypes = extendsTypes; myExtendsTypes = extendsTypes;
@@ -70,7 +74,7 @@ public class Class extends Member {
for (Element t : myTypeParameters) for (Element t : myTypeParameters)
if (t instanceof TypeParameter) if (t instanceof TypeParameter)
wheres.add(((TypeParameter) t).getWhereToKotlin()); wheres.add(((TypeParameter) t).getWhereToKotlin());
return SPACE + "where" + SPACE + AstUtil.join(wheres, COMMA_WITH_SPACE) + SPACE; return SPACE + "where" + SPACE + join(wheres, COMMA_WITH_SPACE) + SPACE;
} }
return EMPTY; return EMPTY;
} }
@@ -112,14 +116,23 @@ public class Class extends Member {
return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY; return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
} }
List<String> baseClassSignatureWithParams() {
if (TYPE.equals("class") && myExtendsTypes.size() == 1) {
LinkedList<String> result = new LinkedList<String>();
result.add(myExtendsTypes.get(0).toKotlin() + "(" + joinNodes(myBaseClassParams, COMMA_WITH_SPACE) + ")");
return result;
} else
return nodesToKotlin(myExtendsTypes);
}
String implementTypesToKotlin() { String implementTypesToKotlin() {
List<Type> allTypes = new LinkedList<Type>() { List<String> allTypes = new LinkedList<String>() {
{ {
addAll(myExtendsTypes); addAll(baseClassSignatureWithParams());
addAll(myImplementsTypes); addAll(nodesToKotlin(myImplementsTypes));
} }
}; };
return allTypes.size() == 0 ? EMPTY : SPACE + COLON + SPACE + AstUtil.joinNodes(allTypes, COMMA_WITH_SPACE); return allTypes.size() == 0 ? EMPTY : SPACE + COLON + SPACE + join(allTypes, COMMA_WITH_SPACE);
} }
String modifiersToKotlin() { String modifiersToKotlin() {
@@ -134,7 +147,7 @@ public class Class extends Member {
modifierList.add(Modifier.OPEN); modifierList.add(Modifier.OPEN);
if (modifierList.size() > 0) if (modifierList.size() > 0)
return AstUtil.join(modifierList, SPACE) + SPACE; return join(modifierList, SPACE) + SPACE;
return EMPTY; return EMPTY;
} }
+2 -2
View File
@@ -11,8 +11,8 @@ 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<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields) { 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) {
super(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields); super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields);
} }
@Nullable @Nullable
+2 -2
View File
@@ -7,8 +7,8 @@ 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<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields) { 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) {
super(name, modifiers, typeParameters, extendsTypes, implementsTypes, innerClasses, methods, fields); super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields);
TYPE = "trait"; TYPE = "trait";
} }
+1 -1
View File
@@ -31,7 +31,7 @@ public class AstUtil {
return join(array.toArray(new String[array.size()]), delimiter); return join(array.toArray(new String[array.size()]), delimiter);
} }
private static List<String> nodesToKotlin(List<? extends INode> nodes) { public static List<String> nodesToKotlin(List<? extends INode> nodes) {
List<String> result = new LinkedList<String>(); List<String> result = new LinkedList<String>();
for (INode n : nodes) for (INode n : nodes)
result.add(n.toKotlin()); result.add(n.toKotlin());
@@ -164,12 +164,13 @@ public class ExpressionVisitor extends StatementVisitor implements Visitor {
@Override @Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) { public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression); super.visitMethodCallExpression(expression);
myResult = // TODO: not resolved if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression))
new MethodCallExpression( myResult = // TODO: not resolved
expressionToExpression(expression.getMethodExpression()), new MethodCallExpression(
elementToElement(expression.getArgumentList()), expressionToExpression(expression.getMethodExpression()),
typeToType(expression.getType()).isNullable() elementToElement(expression.getArgumentList()),
); typeToType(expression.getType()).isNullable()
);
} }
@Override @Override
@@ -305,7 +306,7 @@ public class ExpressionVisitor extends StatementVisitor implements Visitor {
return false; return false;
} }
private boolean isInsidePrimaryConstructor(PsiReferenceExpression expression) { private boolean isInsidePrimaryConstructor(PsiExpression expression) {
PsiElement context = expression.getContext(); PsiElement context = expression.getContext();
while (context != null) { while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
@@ -0,0 +1,38 @@
package org.jetbrains.jet.j2k.visitors;
import com.intellij.psi.*;
import java.util.HashSet;
/**
* @author ignatov
*/
public class SuperVisitor extends JavaRecursiveElementVisitor {
private HashSet<PsiExpressionList> myResolvedSuperCallParameters;
public SuperVisitor() {
myResolvedSuperCallParameters = new HashSet<PsiExpressionList>();
}
public HashSet<PsiExpressionList> getResolvedSuperCallParameters() {
return myResolvedSuperCallParameters;
}
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
if (isSuper(expression.getMethodExpression()))
myResolvedSuperCallParameters.add(expression.getArgumentList());
}
static boolean isSuper(PsiReference r) {
if (r.getCanonicalText().equals("super")) {
final PsiElement baseConstructor = r.resolve();
if (baseConstructor != null && baseConstructor instanceof PsiMethod && ((PsiMethod) baseConstructor).isConstructor()) {
return true;
}
}
return false;
}
}
@@ -14,10 +14,6 @@ import java.util.HashSet;
public class ThisVisitor extends JavaRecursiveElementVisitor { public class ThisVisitor extends JavaRecursiveElementVisitor {
HashSet<PsiMethod> myResolvedConstructors = new HashSet<PsiMethod>(); HashSet<PsiMethod> myResolvedConstructors = new HashSet<PsiMethod>();
public HashSet<PsiMethod> getResult() {
return myResolvedConstructors;
}
@Override @Override
public void visitReferenceExpression(PsiReferenceExpression expression) { public void visitReferenceExpression(PsiReferenceExpression expression) {
for (PsiReference r : expression.getReferences()) for (PsiReference r : expression.getReferences())
@@ -7,6 +7,4 @@ open public fun getColor() : String? {
return color return color
} }
abstract open public fun area() : Double abstract open public fun area() : Double
{
}
} }
@@ -1,2 +1,2 @@
class A() : Base, I { class A() : Base(), I {
} }
@@ -1,2 +1,2 @@
class A() : Base, I0, I1, I2 { class A() : Base(), I0, I1, I2 {
} }
@@ -1,2 +1,2 @@
class A() : Base { class A() : Base() {
} }
@@ -9,8 +9,6 @@ val __ = C(arg1, 0, 0)
return __ return __
} }
} }
{
}
} }
public open class User() { public open class User() {
class object { class object {
+1 -1
View File
@@ -2,7 +2,7 @@ open class A() {
open fun a() : Unit { open fun a() : Unit {
} }
} }
class B() : A { class B() : A() {
override fun a() : Unit { override fun a() : Unit {
} }
} }
@@ -2,11 +2,11 @@ open class A() {
open fun foo() : Unit { open fun foo() : Unit {
} }
} }
open class B() : A { open class B() : A() {
override fun foo() : Unit { override fun foo() : Unit {
} }
} }
open class C() : B { open class C() : B() {
override fun foo() : Unit { override fun foo() : Unit {
} }
} }
@@ -2,7 +2,7 @@ open class `$$$$$`() {
} }
open class `$`() { open class `$`() {
} }
open class `$$`(`$$$$` : `$$$$$`?) : `$` { open class `$$`(`$$$$` : `$$$$$`?) : `$`() {
val `$$$` : `$$$$$`? val `$$$` : `$$$$$`?
open public fun `$$$$$$`() : `$$$$$`? { open public fun `$$$$$$`() : `$$$$$`? {
return `$$$` return `$$$`
@@ -1,11 +1,12 @@
class B { class B {
void call() {} B(int i) {}
int call() {return 1;}
} }
class A extends B { class A extends B {
A() { A() {
super(); super(10);
} }
void call() { return super.call(); } int call() { return super.call(); }
} }
@@ -1,12 +1,10 @@
open class B() { open class B(i : Int) {
open fun call() : Unit { open fun call() : Int {
return 1
} }
} }
open class A() : B { open class A() : B(10) {
override fun call() : Unit { override fun call() : Int {
return super.call() return super.call()
} }
{
super()
}
} }
@@ -1,7 +1,7 @@
open class Base() { open class Base() {
open fun foo() : Unit open fun foo() : Unit
} }
open class A() : Base { open class A() : Base() {
open class C() { open class C() {
open fun test() : Unit { open fun test() : Unit {
super@A.foo() super@A.foo()
@@ -2,7 +2,7 @@ open class Base() {
open fun foo() : Unit { open fun foo() : Unit {
} }
} }
open class A() : Base { open class A() : Base() {
open class C() { open class C() {
open fun test() : Unit { open fun test() : Unit {
this@A.foo() this@A.foo()
@@ -1,2 +1,2 @@
class CC<T : INode?, K : Node?>() : A where T : Comparable<in T?>?, K : Collection<in K?>? { class CC<T : INode?, K : Node?>() : A() where T : Comparable<in T?>?, K : Collection<in K?>? {
} }
@@ -1,2 +1,2 @@
class C<T : INode?>() : A where T : Comparable<in T?>? { class C<T : INode?>() : A() where T : Comparable<in T?>? {
} }