From 5770450b785a60724cfaf886f0c9c9d1a45e1665 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 27 Oct 2011 19:11:06 +0400 Subject: [PATCH] Parameter added, constructor for enum supported --- src/org/jetbrains/jet/j2k/Converter.java | 43 +++++++- src/org/jetbrains/jet/j2k/ast/Class.java | 14 ++- .../jetbrains/jet/j2k/ast/Constructor.java | 22 ++++ src/org/jetbrains/jet/j2k/ast/Enum.java | 31 +++++- .../jetbrains/jet/j2k/ast/EnumConstant.java | 20 ++++ src/org/jetbrains/jet/j2k/ast/Field.java | 8 +- src/org/jetbrains/jet/j2k/ast/Function.java | 6 +- src/org/jetbrains/jet/j2k/ast/INode.java | 2 +- src/org/jetbrains/jet/j2k/ast/Parameter.java | 22 ++++ .../jetbrains/jet/j2k/ast/ParameterList.java | 23 ++++ .../jet/j2k/visitors/ElementVisitor.java | 9 ++ test/org/jetbrains/jet/j2k/ast/EnumTest.java | 102 ++++++++++++++++-- 12 files changed, 281 insertions(+), 21 deletions(-) create mode 100644 src/org/jetbrains/jet/j2k/ast/Constructor.java create mode 100644 src/org/jetbrains/jet/j2k/ast/EnumConstant.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Parameter.java create mode 100644 src/org/jetbrains/jet/j2k/ast/ParameterList.java diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java index f4089902c55..defa3ad6c35 100644 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -59,6 +59,12 @@ public class Converter { } private static Field fieldToField(PsiField field) { + if (field instanceof PsiEnumConstant) // TODO: remove instanceof + return new EnumConstant( + new IdentifierImpl(field.getName()), // TODO + typeToType(field.getType()), + elementToElement(((PsiEnumConstant) field).getArgumentList()) + ); return new Field( new IdentifierImpl(field.getName()), // TODO typeToType(field.getType()), @@ -76,8 +82,25 @@ public class Converter { } @NotNull - private static Function methodToFunction(PsiMethod t, boolean notEmpty) { - return new Function(new IdentifierImpl(t.getName()), typeToType(t.getReturnType()), bodyToBlock(t.getBody(), notEmpty)); + private static Function methodToFunction(PsiMethod method, boolean notEmpty) { + final IdentifierImpl identifier = new IdentifierImpl(method.getName()); + final Type type = typeToType(method.getReturnType()); + final Block body = bodyToBlock(method.getBody(), notEmpty); + final Element params = elementToElement(method.getParameterList()); + + if (method.isConstructor()) + return new Constructor( + identifier, + type, + params, + body + ); + return new Function( + identifier, + type, + params, + body + ); } @NotNull @@ -173,4 +196,20 @@ public class Converter { return new Import(t.getImportReference().getQualifiedName()); // TODO: use identifier return new Import(""); } + + @NotNull + public static List parametersToParameterList(PsiParameter[] parameters) { + List result = new LinkedList(); + for (PsiParameter t : parameters) { + result.add(parameterToParameter(t)); + } + return result; + } + + private static Parameter parameterToParameter(PsiParameter parameter) { + return new Parameter( + new IdentifierImpl(parameter.getName()), // TODO: remove + typeToType(parameter.getType()) + ); + } } diff --git a/src/org/jetbrains/jet/j2k/ast/Class.java b/src/org/jetbrains/jet/j2k/ast/Class.java index 658c11693ab..29395972876 100644 --- a/src/org/jetbrains/jet/j2k/ast/Class.java +++ b/src/org/jetbrains/jet/j2k/ast/Class.java @@ -3,6 +3,7 @@ package org.jetbrains.jet.j2k.ast; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.j2k.util.AstUtil; +import java.util.LinkedList; import java.util.List; /** @@ -22,13 +23,22 @@ public class Class extends Node { myFields = fields; } + @NotNull + protected List methodsExceptConstructors() { + final LinkedList result = new LinkedList(); + for (Function m : myMethods) + if (m.getKind() != Kind.CONSTRUCTOR) + result.add(m); + return result; + } + @NotNull @Override public String toKotlin() { return TYPE + SPACE + myName.toKotlin() + SPACE + "{" + N + - AstUtil.joinNodes(myInnerClasses, N) + N + - AstUtil.joinNodes(myMethods, N) + N + AstUtil.joinNodes(myFields, N) + N + + AstUtil.joinNodes(methodsExceptConstructors(), N) + N + + AstUtil.joinNodes(myInnerClasses, N) + N + "}"; } } diff --git a/src/org/jetbrains/jet/j2k/ast/Constructor.java b/src/org/jetbrains/jet/j2k/ast/Constructor.java new file mode 100644 index 00000000000..6f758dfe1e6 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Constructor.java @@ -0,0 +1,22 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class Constructor extends Function { + public Constructor(Identifier identifier, Type type, Element params, Block block) { + super(identifier, type, params, block); + } + + public String primary() { + return "(" + myParams.toKotlin() + ")"; + } + + @NotNull + @Override + public Kind getKind() { + return Kind.CONSTRUCTOR; + } +} \ No newline at end of file diff --git a/src/org/jetbrains/jet/j2k/ast/Enum.java b/src/org/jetbrains/jet/j2k/ast/Enum.java index c390e79b8f2..3b9ec1e2573 100644 --- a/src/org/jetbrains/jet/j2k/ast/Enum.java +++ b/src/org/jetbrains/jet/j2k/ast/Enum.java @@ -1,5 +1,9 @@ package org.jetbrains.jet.j2k.ast; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.j2k.util.AstUtil; + import java.util.List; /** @@ -8,6 +12,31 @@ import java.util.List; public class Enum extends Class { public Enum(Identifier name, List innerClasses, List methods, List fields) { super(name, innerClasses, methods, fields); - TYPE = "enum"; + } + + @Nullable + private Constructor getPrimaryConstructor() { + for (Function m : myMethods) + if (m.getKind() == Kind.CONSTRUCTOR) + return (Constructor) m; + return null; + } + + private String primaryConstructorToKotlin() { + Constructor maybeConstructor = getPrimaryConstructor(); + if (maybeConstructor != null) + return maybeConstructor.primary(); + return EMPTY; + } + + + @NotNull + @Override + public String toKotlin() { + return "enum" + SPACE + myName.toKotlin() + primaryConstructorToKotlin() + SPACE + "{" + N + + AstUtil.joinNodes(myFields, N) + N + + AstUtil.joinNodes(methodsExceptConstructors(), N) + N + + AstUtil.joinNodes(myInnerClasses, N) + N + + "}"; } } diff --git a/src/org/jetbrains/jet/j2k/ast/EnumConstant.java b/src/org/jetbrains/jet/j2k/ast/EnumConstant.java new file mode 100644 index 00000000000..59dea9f914e --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/EnumConstant.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class EnumConstant extends Field { + public EnumConstant(Identifier identifier, Type type, Element params) { + super(identifier, type, params); + } + + @NotNull + @Override + public String toKotlin() { + if (myInitializer.toKotlin().isEmpty()) + return myIdentifier.toKotlin(); + return myIdentifier.toKotlin() + "(" + myInitializer.toKotlin() + ")"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Field.java b/src/org/jetbrains/jet/j2k/ast/Field.java index 8d6090a2cd2..f500e621093 100644 --- a/src/org/jetbrains/jet/j2k/ast/Field.java +++ b/src/org/jetbrains/jet/j2k/ast/Field.java @@ -6,11 +6,11 @@ import org.jetbrains.annotations.NotNull; * @author ignatov */ public class Field extends Node { - private Identifier myIdentifier; - private Type myType; - private Expression myInitializer; + protected Identifier myIdentifier; + protected Type myType; + protected Element myInitializer; - public Field(Identifier identifier, Type type, Expression initializer) { + public Field(Identifier identifier, Type type, Element initializer) { myIdentifier = identifier; myType = type; myInitializer = initializer; diff --git a/src/org/jetbrains/jet/j2k/ast/Function.java b/src/org/jetbrains/jet/j2k/ast/Function.java index 3a5903a8165..262d063bdff 100644 --- a/src/org/jetbrains/jet/j2k/ast/Function.java +++ b/src/org/jetbrains/jet/j2k/ast/Function.java @@ -8,18 +8,20 @@ import org.jetbrains.annotations.NotNull; public class Function extends Node { private Identifier myName; private Type myType; + protected Element myParams; private Block myBlock; - public Function(Identifier name, Type type, Block block) { + public Function(Identifier name, Type type, Element params, Block block) { myName = name; myType = type; + myParams = params; myBlock = block; } @NotNull @Override public String toKotlin() { - return "fun" + SPACE + myName.toKotlin() + "(" + ")" + SPACE + COLON + SPACE + myType.toKotlin() + SPACE + + return "fun" + SPACE + myName.toKotlin() + "(" + myParams.toKotlin() + ")" + SPACE + COLON + SPACE + myType.toKotlin() + SPACE + myBlock.toKotlin(); } } diff --git a/src/org/jetbrains/jet/j2k/ast/INode.java b/src/org/jetbrains/jet/j2k/ast/INode.java index 57edb34a38c..f8f359ee55a 100644 --- a/src/org/jetbrains/jet/j2k/ast/INode.java +++ b/src/org/jetbrains/jet/j2k/ast/INode.java @@ -13,6 +13,6 @@ public interface INode { public Kind getKind(); public enum Kind { - UNDEFINED, TYPE, + UNDEFINED, TYPE, CONSTRUCTOR, } } diff --git a/src/org/jetbrains/jet/j2k/ast/Parameter.java b/src/org/jetbrains/jet/j2k/ast/Parameter.java new file mode 100644 index 00000000000..40fd542b34d --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Parameter.java @@ -0,0 +1,22 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class Parameter extends Expression { + private IdentifierImpl myIdentifier; + private Type myType; + + public Parameter(IdentifierImpl identifier, Type type) { + myIdentifier = identifier; + myType = type; + } + + @NotNull + @Override + public String toKotlin() { + return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/ParameterList.java b/src/org/jetbrains/jet/j2k/ast/ParameterList.java new file mode 100644 index 00000000000..06470e1d7a9 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/ParameterList.java @@ -0,0 +1,23 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.util.AstUtil; + +import java.util.List; + +/** + * @author ignatov + */ +public class ParameterList extends Expression { + private List myParameters; + + public ParameterList(List parameters) { + myParameters = parameters; + } + + @NotNull + @Override + public String toKotlin() { + return AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE); + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java index 044bd709f36..d045c6741f2 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java @@ -3,7 +3,9 @@ package org.jetbrains.jet.j2k.visitors; import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiExpressionList; import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.PsiParameterList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.Converter; import org.jetbrains.jet.j2k.ast.*; import static org.jetbrains.jet.j2k.Converter.*; @@ -31,7 +33,14 @@ public class ElementVisitor extends JavaElementVisitor implements Visitor { expressionsToExpressionList(list.getExpressions()), typesToTypeList(list.getExpressionTypes()) ); + } + @Override + public void visitParameterList(PsiParameterList list) { + super.visitParameterList(list); + myResult = new ParameterList( + Converter.parametersToParameterList(list.getParameters()) + ); } @NotNull diff --git a/test/org/jetbrains/jet/j2k/ast/EnumTest.java b/test/org/jetbrains/jet/j2k/ast/EnumTest.java index da270403b3c..bf17217ee23 100644 --- a/test/org/jetbrains/jet/j2k/ast/EnumTest.java +++ b/test/org/jetbrains/jet/j2k/ast/EnumTest.java @@ -14,15 +14,99 @@ public class EnumTest extends JetTestCaseBase { ); } -// public void testTypeSafeEnum() throws Exception { + public void testTypeSafeEnum() throws Exception { + Assert.assertEquals( + classToKotlin("enum Coin { PENNY, NICKEL, DIME, QUARTER; }"), + "enum Coin {\n" + + "PENNY\n" + + "NICKEL\n" + + "DIME\n" + + "QUARTER\n" + + "}" + ); + } + + // + public void testOverrideToString() throws Exception { + Assert.assertEquals( + classToKotlin( + + "enum Color {" + + " WHITE, BLACK, RED, YELLOW, BLUE;" + + "@Override String toString() {" + + " return \"COLOR\";" + + "}" + + "}"), + "enum Color {\n" + + "WHITE\n" + + "BLACK\n" + + "RED\n" + + "YELLOW\n" + + "BLUE\n" + + "fun toString() : String? {\n" + + "return \"COLOR\"\n" + + "}\n" + + "}" + ); + } + + public void testFields() throws Exception { + Assert.assertEquals( + classToKotlin( + "enum Color {\n" + + " WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);\n" + + "\n" + + " private int code;\n" + + "\n" + + " private Color(int c) {\n" + + " code = c;\n" + + " }\n" + + "\n" + + " public int getCode() {\n" + + " return code;\n" + + " }"), + "enum Color(c : Int) {\n" + + "WHITE(21)\n" + + "BLACK(22)\n" + + "RED(23)\n" + + "YELLOW(24)\n" + + "BLUE(25)\n" + + "var code : Int\n" + + "fun getCode() : Int {\n" + + "return code\n" + + "}\n" + + "}" + ); + } + +// public void testTwoConstructors() throws Exception { // Assert.assertEquals( -// classToKotlin("enum Coin { PENNY, NICKEL, DIME, QUARTER; }"), -// "enum Coin {\n" + -// "PENNY\n" + -// "NICKEL\n" + -// "DIME\n" + -// "QUARTER\n" + -// "}" +// classToKotlin( +// "enum MultEnum {\n" + +// " GREMLIN(\"UTILITY\"),\n" + +// " MORT(30);\n" + +// " \n" + +// " MultEnum(String s) {\n" + +// " }\n" + +// " \n" + +// " MultEnum(int dmg) {\n" + +// " }"), +// "" // TODO: will fail // ); // } -} +// +// public void testInterfaceImplementation() throws Exception { +// Assert.assertEquals( +// classToKotlin( +// "enum Color implements Runnable {\n" + +// " WHITE, BLACK, RED, YELLOW, BLUE;\n" + +// "\n" + +// " public void run() {\n" + +// " System.out.println(\"name()=\" + name() +\n" + +// " \", toString()=\" + toString());\n" + +// " }\n" + +// "}"), +// "" +// ); +// } + }