From 8cf4c809511530577a6c074917b4fd10e90c4aa7 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Thu, 27 Oct 2011 17:27:15 +0400 Subject: [PATCH] initial commit for j2k --- j2k.iml | 13 ++ j2k.ipr | 169 ++++++++++++++ src/org/jetbrains/jet/j2k/Converter.java | 176 +++++++++++++++ .../jet/j2k/ast/AssignmentExpression.java | 30 +++ .../jet/j2k/ast/BinaryExpression.java | 24 ++ src/org/jetbrains/jet/j2k/ast/Block.java | 37 ++++ src/org/jetbrains/jet/j2k/ast/Class.java | 34 +++ src/org/jetbrains/jet/j2k/ast/ClassType.java | 20 ++ .../jet/j2k/ast/DeclarationStatement.java | 33 +++ .../j2k/ast/DummyMethodCallExpression.java | 24 ++ src/org/jetbrains/jet/j2k/ast/Element.java | 7 + .../jetbrains/jet/j2k/ast/EmptyElement.java | 14 ++ .../jet/j2k/ast/EmptyExpression.java | 14 ++ .../jetbrains/jet/j2k/ast/EmptyStatement.java | 14 ++ src/org/jetbrains/jet/j2k/ast/EmptyType.java | 14 ++ src/org/jetbrains/jet/j2k/ast/Enum.java | 13 ++ src/org/jetbrains/jet/j2k/ast/Expression.java | 7 + .../jetbrains/jet/j2k/ast/ExpressionList.java | 29 +++ src/org/jetbrains/jet/j2k/ast/Field.java | 30 +++ src/org/jetbrains/jet/j2k/ast/File.java | 30 +++ src/org/jetbrains/jet/j2k/ast/Function.java | 25 +++ src/org/jetbrains/jet/j2k/ast/INode.java | 18 ++ src/org/jetbrains/jet/j2k/ast/Identifier.java | 10 + .../jetbrains/jet/j2k/ast/IdentifierImpl.java | 36 +++ src/org/jetbrains/jet/j2k/ast/Import.java | 20 ++ .../jet/j2k/ast/LiteralExpression.java | 20 ++ .../jetbrains/jet/j2k/ast/LocalVariable.java | 28 +++ .../jet/j2k/ast/MethodCallExpression.java | 22 ++ src/org/jetbrains/jet/j2k/ast/Node.java | 42 ++++ .../jetbrains/jet/j2k/ast/PrimitiveType.java | 20 ++ .../jet/j2k/ast/ReturnStatement.java | 20 ++ src/org/jetbrains/jet/j2k/ast/Statement.java | 7 + src/org/jetbrains/jet/j2k/ast/Trait.java | 13 ++ src/org/jetbrains/jet/j2k/ast/Type.java | 14 ++ src/org/jetbrains/jet/j2k/ast/Visitor.java | 11 + src/org/jetbrains/jet/j2k/util/AstUtil.java | 44 ++++ .../jet/j2k/visitors/ElementVisitor.java | 41 ++++ .../jet/j2k/visitors/ExpressionVisitor.java | 209 ++++++++++++++++++ .../jet/j2k/visitors/StatementVisitor.java | 141 ++++++++++++ .../jet/j2k/visitors/TypeVisitor.java | 67 ++++++ test/org/jetbrains/jet/j2k/FileTest.java | 60 +++++ .../jetbrains/jet/j2k/JetTestCaseBase.java | 200 +++++++++++++++++ .../jet/j2k/ast/AssignmentExpressionTest.java | 61 +++++ .../jet/j2k/ast/BinaryExpressionTest.java | 81 +++++++ test/org/jetbrains/jet/j2k/ast/ClassTest.java | 65 ++++++ .../jet/j2k/ast/DeclarationStatementTest.java | 33 +++ test/org/jetbrains/jet/j2k/ast/EnumTest.java | 28 +++ .../jetbrains/jet/j2k/ast/FunctionTest.java | 44 ++++ .../jet/j2k/ast/IdentifierImplTest.java | 11 + .../jet/j2k/ast/LocalVariableTest.java | 16 ++ .../jet/j2k/ast/MethodCallExpressionTest.java | 27 +++ .../jet/j2k/ast/ReturnStatementTest.java | 37 ++++ test/org/jetbrains/jet/j2k/ast/TraitTest.java | 45 ++++ 53 files changed, 2248 insertions(+) create mode 100644 j2k.iml create mode 100644 j2k.ipr create mode 100644 src/org/jetbrains/jet/j2k/Converter.java create mode 100644 src/org/jetbrains/jet/j2k/ast/AssignmentExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/BinaryExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Block.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Class.java create mode 100644 src/org/jetbrains/jet/j2k/ast/ClassType.java create mode 100644 src/org/jetbrains/jet/j2k/ast/DeclarationStatement.java create mode 100644 src/org/jetbrains/jet/j2k/ast/DummyMethodCallExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Element.java create mode 100644 src/org/jetbrains/jet/j2k/ast/EmptyElement.java create mode 100644 src/org/jetbrains/jet/j2k/ast/EmptyExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/EmptyStatement.java create mode 100644 src/org/jetbrains/jet/j2k/ast/EmptyType.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Enum.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Expression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/ExpressionList.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Field.java create mode 100644 src/org/jetbrains/jet/j2k/ast/File.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Function.java create mode 100644 src/org/jetbrains/jet/j2k/ast/INode.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Identifier.java create mode 100644 src/org/jetbrains/jet/j2k/ast/IdentifierImpl.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Import.java create mode 100644 src/org/jetbrains/jet/j2k/ast/LiteralExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/LocalVariable.java create mode 100644 src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Node.java create mode 100644 src/org/jetbrains/jet/j2k/ast/PrimitiveType.java create mode 100644 src/org/jetbrains/jet/j2k/ast/ReturnStatement.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Statement.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Trait.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Type.java create mode 100644 src/org/jetbrains/jet/j2k/ast/Visitor.java create mode 100644 src/org/jetbrains/jet/j2k/util/AstUtil.java create mode 100644 src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java create mode 100644 src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java create mode 100644 src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java create mode 100644 src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java create mode 100644 test/org/jetbrains/jet/j2k/FileTest.java create mode 100644 test/org/jetbrains/jet/j2k/JetTestCaseBase.java create mode 100644 test/org/jetbrains/jet/j2k/ast/AssignmentExpressionTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/BinaryExpressionTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/ClassTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/DeclarationStatementTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/EnumTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/FunctionTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/IdentifierImplTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/LocalVariableTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/MethodCallExpressionTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/ReturnStatementTest.java create mode 100644 test/org/jetbrains/jet/j2k/ast/TraitTest.java diff --git a/j2k.iml b/j2k.iml new file mode 100644 index 00000000000..06922e896d4 --- /dev/null +++ b/j2k.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/j2k.ipr b/j2k.ipr new file mode 100644 index 00000000000..784215e36c3 --- /dev/null +++ b/j2k.ipr @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://www.w3.org/1999/xhtml + + + + + + + + + diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java new file mode 100644 index 00000000000..f4089902c55 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -0,0 +1,176 @@ +package org.jetbrains.jet.j2k; + +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.ast.*; +import org.jetbrains.jet.j2k.ast.Class; +import org.jetbrains.jet.j2k.ast.Enum; +import org.jetbrains.jet.j2k.visitors.ElementVisitor; +import org.jetbrains.jet.j2k.visitors.ExpressionVisitor; +import org.jetbrains.jet.j2k.visitors.StatementVisitor; +import org.jetbrains.jet.j2k.visitors.TypeVisitor; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author ignatov + */ +public class Converter { + @NotNull + public static File fileToFile(PsiJavaFile javaFile) { + final PsiImportList importList = javaFile.getImportList(); + List imports = importList == null ? + new LinkedList() : + importsToImportList(importList.getAllImportStatements()); + return new File(javaFile.getPackageName(), imports, classesToClassList(javaFile.getClasses())); // TODO: use identifier + } + + @NotNull + private static List classesToClassList(PsiClass[] classes) { + List result = new LinkedList(); + for (PsiClass t : classes) { + result.add(classToClass(t)); + } + return result; + } + + public static Class classToClass(PsiClass psiClass) { + final List methods = methodsToFunctionList(psiClass.getMethods(), true); + + final List innerClasses = classesToClassList(psiClass.getAllInnerClasses()); + + final List fields = fieldsToFieldList(psiClass.getAllFields()); + + final IdentifierImpl name = new IdentifierImpl(psiClass.getName()); + if (psiClass.isInterface()) + return new Trait(name, innerClasses, methods, fields); + if (psiClass.isEnum()) + return new Enum(name, innerClasses, methods, fields); + return new Class(name, innerClasses, methods, fields); + } + + private static List fieldsToFieldList(PsiField[] fields) { + List result = new LinkedList(); + for (PsiField f : fields) { + result.add(fieldToField(f)); + } + return result; + } + + private static Field fieldToField(PsiField field) { + return new Field( + new IdentifierImpl(field.getName()), // TODO + typeToType(field.getType()), + expressionToExpression(field.getInitializer()) // TODO: add modifiers + ); + } + + @NotNull + private static List methodsToFunctionList(PsiMethod[] methods, boolean notEmpty) { + List result = new LinkedList(); + for (PsiMethod t : methods) { + result.add(methodToFunction(t, notEmpty)); + } + return result; + } + + @NotNull + private static Function methodToFunction(PsiMethod t, boolean notEmpty) { + return new Function(new IdentifierImpl(t.getName()), typeToType(t.getReturnType()), bodyToBlock(t.getBody(), notEmpty)); + } + + @NotNull + private static Block bodyToBlock(PsiCodeBlock body, boolean notEmpty) { + if (body == null) + return new Block(new LinkedList(), false); + return new Block(statementsToStatementList(body.getStatements()), notEmpty); + } + + @NotNull + public static List statementsToStatementList(PsiStatement[] statements) { + List result = new LinkedList(); + for (PsiStatement t : statements) { + result.add(statementToStatement(t)); + } + return result; + } + + @NotNull + public static Statement statementToStatement(PsiStatement t) { + final StatementVisitor statementVisitor = new StatementVisitor(); + t.accept(statementVisitor); + System.out.println(t.getClass()); + return statementVisitor.getStatement(); + } + + @NotNull + public static List expressionsToExpressionList(PsiExpression[] expressions) { + List result = new LinkedList(); + for (PsiExpression e : expressions) { + result.add(expressionToExpression(e)); + } + return result; + } + + @NotNull + public static Expression expressionToExpression(PsiExpression e) { + if (e == null) + return new EmptyExpression(); + final ExpressionVisitor expressionVisitor = new ExpressionVisitor(); + e.accept(expressionVisitor); + System.out.println(e.getClass()); + return expressionVisitor.getResult(); + } + + @NotNull + public static Element elementToElement(PsiElement e) { + final ElementVisitor elementVisitor = new ElementVisitor(); + e.accept(elementVisitor); + System.out.println(e.getClass()); + return elementVisitor.getResult(); + } + + @NotNull + public static List elementsToElementList(PsiElement[] elements) { + List result = new LinkedList(); + for (PsiElement e : elements) { + result.add(elementToElement(e)); + } + return result; + } + + @NotNull + public static Type typeToType(PsiType type) { + if (type == null) + return new EmptyType(); // TODO + TypeVisitor typeVisitor = new TypeVisitor(); + type.accept(typeVisitor); + return typeVisitor.getResult(); + } + + @NotNull + public static List typesToTypeList(PsiType[] types) { + List result = new LinkedList(); + for (PsiType t : types) { + result.add(typeToType(t)); + } + return result; + } + + @NotNull + private static List importsToImportList(PsiImportStatementBase[] imports) { + List result = new LinkedList(); + for (PsiImportStatementBase t : imports) { + result.add(importToImport(t)); + } + return result; + } + + @NotNull + private static Import importToImport(PsiImportStatementBase t) { + if (t.getImportReference() != null) + return new Import(t.getImportReference().getQualifiedName()); // TODO: use identifier + return new Import(""); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.java b/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.java new file mode 100644 index 00000000000..4353ac8753e --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class AssignmentExpression extends Expression { + private Expression myLeft; + private Expression myRight; + private String myOp; + + public AssignmentExpression(Expression left, Expression right) { + myLeft = left; + myRight = right; + myOp = EQUAL; + } + + public AssignmentExpression(Expression left, Expression right, String op) { + myLeft = left; + myRight = right; + myOp = op; + } + + @NotNull + @Override + public String toKotlin() { + return myLeft.toKotlin() + SPACE + myOp + SPACE + myRight.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/BinaryExpression.java b/src/org/jetbrains/jet/j2k/ast/BinaryExpression.java new file mode 100644 index 00000000000..bba976bf2a4 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/BinaryExpression.java @@ -0,0 +1,24 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class BinaryExpression extends Expression { + private Expression myLeft; + private Expression myRight; + private String myOp; + + public BinaryExpression(Expression left, Expression right, String op) { + myLeft = left; + myRight = right; + myOp = op; + } + + @NotNull + @Override + public String toKotlin() { + return "(" + myLeft.toKotlin() + SPACE + myOp + SPACE + myRight.toKotlin() + ")"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Block.java b/src/org/jetbrains/jet/j2k/ast/Block.java new file mode 100644 index 00000000000..5f164676a9c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Block.java @@ -0,0 +1,37 @@ +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 Block extends Statement { + private List myStatements; + private boolean myNotEmpty; + + public Block(List statements) { + myStatements = statements; + } + + public Block(List statements, boolean notEmpty) { + myStatements = statements; + myNotEmpty = notEmpty; + } + + private boolean isEmpty() { + return !myNotEmpty && myStatements.size() == 0; + } + + @NotNull + @Override + public String toKotlin() { + if (!isEmpty()) + return "{" + N + + AstUtil.joinNodes(myStatements, N) + N + + "}"; + return EMPTY; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Class.java b/src/org/jetbrains/jet/j2k/ast/Class.java new file mode 100644 index 00000000000..658c11693ab --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Class.java @@ -0,0 +1,34 @@ +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 Class extends Node { + protected String TYPE = "class"; + protected Identifier myName; + protected List myInnerClasses; + protected List myMethods; + protected List myFields; + + public Class(Identifier name, List innerClasses, List methods, List fields) { + myName = name; + myInnerClasses = innerClasses; + myMethods = methods; + myFields = fields; + } + + @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 + + "}"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/ClassType.java b/src/org/jetbrains/jet/j2k/ast/ClassType.java new file mode 100644 index 00000000000..73b6e43c7a2 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/ClassType.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class ClassType extends Type { + private Identifier myType; + + public ClassType(Identifier type) { + myType = type; + } + + @NotNull + @Override + public String toKotlin() { + return myType.toKotlin() + QUESTION; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/DeclarationStatement.java b/src/org/jetbrains/jet/j2k/ast/DeclarationStatement.java new file mode 100644 index 00000000000..c3135869842 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/DeclarationStatement.java @@ -0,0 +1,33 @@ +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; + +/** + * @author ignatov + */ +public class DeclarationStatement extends Statement { + private List myElements; + + public DeclarationStatement(List elements) { + myElements = elements; + } + + private List toStringList(List elements) { + List result = new LinkedList(); + for (String n : AstUtil.nodesToKotlin(elements)) + result.add( + "var" + SPACE + n + ); + return result; + } + + @NotNull + @Override + public String toKotlin() { + return AstUtil.join(toStringList(myElements), N); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/DummyMethodCallExpression.java b/src/org/jetbrains/jet/j2k/ast/DummyMethodCallExpression.java new file mode 100644 index 00000000000..6961b67e03c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/DummyMethodCallExpression.java @@ -0,0 +1,24 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class DummyMethodCallExpression extends Expression { + private Expression myWho; + private String myMethodName; + private Expression myWhat; + + public DummyMethodCallExpression(Expression who, String methodName, Expression what) { + myWho = who; + myMethodName = methodName; + myWhat = what; + } + + @NotNull + @Override + public String toKotlin() { + return myWho.toKotlin() + DOT + myMethodName + "(" + myWhat.toKotlin() + ")"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Element.java b/src/org/jetbrains/jet/j2k/ast/Element.java new file mode 100644 index 00000000000..013d70f05b4 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Element.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.j2k.ast; + +/** + * @author ignatov + */ +public abstract class Element extends Node { +} diff --git a/src/org/jetbrains/jet/j2k/ast/EmptyElement.java b/src/org/jetbrains/jet/j2k/ast/EmptyElement.java new file mode 100644 index 00000000000..2b68afe22f9 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/EmptyElement.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class EmptyElement extends Element { + @NotNull + @Override + public String toKotlin() { + return EMPTY; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/EmptyExpression.java b/src/org/jetbrains/jet/j2k/ast/EmptyExpression.java new file mode 100644 index 00000000000..c2ed1f7cb27 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/EmptyExpression.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class EmptyExpression extends Expression { + @NotNull + @Override + public String toKotlin() { + return EMPTY; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/EmptyStatement.java b/src/org/jetbrains/jet/j2k/ast/EmptyStatement.java new file mode 100644 index 00000000000..970a9d02539 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/EmptyStatement.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class EmptyStatement extends Statement { + @NotNull + @Override + public String toKotlin() { + return EMPTY; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/EmptyType.java b/src/org/jetbrains/jet/j2k/ast/EmptyType.java new file mode 100644 index 00000000000..8bd6add7ec1 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/EmptyType.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class EmptyType extends Type { + @NotNull + @Override + public String toKotlin() { + return "UNRESOLVED_TYPE"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Enum.java b/src/org/jetbrains/jet/j2k/ast/Enum.java new file mode 100644 index 00000000000..c390e79b8f2 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Enum.java @@ -0,0 +1,13 @@ +package org.jetbrains.jet.j2k.ast; + +import java.util.List; + +/** + * @author ignatov + */ +public class Enum extends Class { + public Enum(Identifier name, List innerClasses, List methods, List fields) { + super(name, innerClasses, methods, fields); + TYPE = "enum"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Expression.java b/src/org/jetbrains/jet/j2k/ast/Expression.java new file mode 100644 index 00000000000..e83a07becd0 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Expression.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.j2k.ast; + +/** + * @author ignatov + */ +public abstract class Expression extends Statement { +} diff --git a/src/org/jetbrains/jet/j2k/ast/ExpressionList.java b/src/org/jetbrains/jet/j2k/ast/ExpressionList.java new file mode 100644 index 00000000000..774d73b1573 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/ExpressionList.java @@ -0,0 +1,29 @@ +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 ExpressionList extends Expression { + private List myExpressions; + private List myTypes; // TODO: add types to toKotlin + + public ExpressionList(List expressions, List types) { + myExpressions = expressions; + myTypes = types; + } + + public ExpressionList(List expressions) { + myExpressions = expressions; + } + + @NotNull + @Override + public String toKotlin() { + return AstUtil.joinNodes(myExpressions, COMMA_WITH_SPACE); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Field.java b/src/org/jetbrains/jet/j2k/ast/Field.java new file mode 100644 index 00000000000..8d6090a2cd2 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Field.java @@ -0,0 +1,30 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class Field extends Node { + private Identifier myIdentifier; + private Type myType; + private Expression myInitializer; + + public Field(Identifier identifier, Type type, Expression initializer) { + myIdentifier = identifier; + myType = type; + myInitializer = initializer; + } + + @NotNull + @Override + public String toKotlin() { + String modifier = "var" + SPACE; + + if (myInitializer.toKotlin().isEmpty()) // TODO: remove + return modifier + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin(); + + return modifier + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + SPACE + + EQUAL + SPACE + myInitializer.toKotlin(); + } +} \ No newline at end of file diff --git a/src/org/jetbrains/jet/j2k/ast/File.java b/src/org/jetbrains/jet/j2k/ast/File.java new file mode 100644 index 00000000000..ba9c4952556 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/File.java @@ -0,0 +1,30 @@ +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 File extends Node { + private String myPackageName; + private List myImports; + private List myClasses; + + public File(String packageName, List imports, List classes) { + myPackageName = packageName; + myImports = imports; + myClasses = classes; + } + + @NotNull + @Override + public String toKotlin() { + return "namespace" + SPACE + myPackageName + SPACE + "{" + N + + AstUtil.joinNodes(myImports, N) + N2 + + AstUtil.joinNodes(myClasses, N) + N + + "}"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Function.java b/src/org/jetbrains/jet/j2k/ast/Function.java new file mode 100644 index 00000000000..3a5903a8165 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Function.java @@ -0,0 +1,25 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class Function extends Node { + private Identifier myName; + private Type myType; + private Block myBlock; + + public Function(Identifier name, Type type, Block block) { + myName = name; + myType = type; + myBlock = block; + } + + @NotNull + @Override + public String toKotlin() { + return "fun" + SPACE + myName.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 new file mode 100644 index 00000000000..57edb34a38c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/INode.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public interface INode { + @NotNull + public String toKotlin(); + + @NotNull + public Kind getKind(); + + public enum Kind { + UNDEFINED, TYPE, + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Identifier.java b/src/org/jetbrains/jet/j2k/ast/Identifier.java new file mode 100644 index 00000000000..777a842dc44 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Identifier.java @@ -0,0 +1,10 @@ +package org.jetbrains.jet.j2k.ast; + +/** + * @author ignatov + */ +public interface Identifier extends INode { + public String getName(); + + public boolean isEmpty(); +} diff --git a/src/org/jetbrains/jet/j2k/ast/IdentifierImpl.java b/src/org/jetbrains/jet/j2k/ast/IdentifierImpl.java new file mode 100644 index 00000000000..a17b486ed9b --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/IdentifierImpl.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class IdentifierImpl extends Expression implements Identifier { + private final String myName; + + public IdentifierImpl(String name) { + myName = name; + } + + @Override + public String getName() { + return myName; + } + + @Override + public boolean isEmpty() { + return myName.length() == 0; + } + + private String quote(String str) { + return BACKTICK + str + BACKTICK; + } + + @NotNull + @Override + public String toKotlin() { + if (ONLY_KOTLIN_KEYWORDS.contains(myName)) + return quote(myName); + return myName; + } +} \ No newline at end of file diff --git a/src/org/jetbrains/jet/j2k/ast/Import.java b/src/org/jetbrains/jet/j2k/ast/Import.java new file mode 100644 index 00000000000..973f2387f80 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Import.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class Import extends Node { + private String myName; + + public Import(String name) { + myName = name; + } + + @NotNull + @Override + public String toKotlin() { + return "import" + SPACE + myName; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/LiteralExpression.java b/src/org/jetbrains/jet/j2k/ast/LiteralExpression.java new file mode 100644 index 00000000000..2c46150f753 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/LiteralExpression.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class LiteralExpression extends Expression { + private Identifier myIdentifier; + + public LiteralExpression(Identifier identifier) { + myIdentifier = identifier; + } + + @NotNull + @Override + public String toKotlin() { + return myIdentifier.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/LocalVariable.java b/src/org/jetbrains/jet/j2k/ast/LocalVariable.java new file mode 100644 index 00000000000..572199b3cab --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/LocalVariable.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class LocalVariable extends Expression { + private Identifier myIdentifier; + private Type myType; + private Expression myInitializer; + + public LocalVariable(Identifier identifier, Type type, Expression initializer) { + myIdentifier = identifier; + myType = type; + myInitializer = initializer; + } + + @NotNull + @Override + public String toKotlin() { + if (myInitializer.toKotlin().isEmpty()) // TODO: remove + return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin(); + + return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + SPACE + + EQUAL + SPACE + myInitializer.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java b/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java new file mode 100644 index 00000000000..3153d6fb760 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java @@ -0,0 +1,22 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class MethodCallExpression extends Expression { + private Expression myMethodCall; + private Element myParamList; + + public MethodCallExpression(Expression methodCall, Element paramList) { + myMethodCall = methodCall; + myParamList = paramList; + } + + @NotNull + @Override + public String toKotlin() { + return myMethodCall.toKotlin() + "(" + myParamList.toKotlin() + ")"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Node.java b/src/org/jetbrains/jet/j2k/ast/Node.java new file mode 100644 index 00000000000..0c063354d7f --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Node.java @@ -0,0 +1,42 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author ignatov + */ +public abstract class Node implements INode { + @NotNull + @Override + public Kind getKind() { + return Kind.UNDEFINED; + } + + final static Set ONLY_KOTLIN_KEYWORDS = new HashSet(Arrays.asList( + "namespace", "in", "val", "var", "when", "object", + "out", "in", "is", "as", "ref", "override", + "open", "attribute", "lazy", "set", "get", + "fun", "where", "by", "trait", "type", "This" + )); + + public final static Set PRIMITIVE_TYPES = new HashSet(Arrays.asList( + "double", "float", "long", "int", "short", "byte", "boolean", "char" + )); + + static final String N = System.getProperty("line.separator"); + static final String N2 = N + N; + static final String SPACE = " "; + static final String EQUAL = "="; + static final String EMPTY = ""; + static final String DOT = "."; + static final String COLON = ":"; + static final String IN = "in"; + static final String AT = "@"; + static final String BACKTICK = "`"; + static final String QUESTION = "?"; + static final String COMMA_WITH_SPACE = "," + SPACE; +} diff --git a/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java b/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java new file mode 100644 index 00000000000..46af927081e --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/PrimitiveType.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class PrimitiveType extends Type { + private Identifier myType; + + public PrimitiveType(Identifier type) { + myType = type; + } + + @NotNull + @Override + public String toKotlin() { + return myType.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java b/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java new file mode 100644 index 00000000000..034c538e0f5 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java @@ -0,0 +1,20 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public class ReturnStatement extends Statement { + private Expression myExpression; + + public ReturnStatement(Expression expression) { + myExpression = expression; + } + + @NotNull + @Override + public String toKotlin() { + return "return" + SPACE + myExpression.toKotlin(); + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Statement.java b/src/org/jetbrains/jet/j2k/ast/Statement.java new file mode 100644 index 00000000000..1f6c667eb1b --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Statement.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.j2k.ast; + +/** + * @author ignatov + */ +public abstract class Statement extends Element { +} diff --git a/src/org/jetbrains/jet/j2k/ast/Trait.java b/src/org/jetbrains/jet/j2k/ast/Trait.java new file mode 100644 index 00000000000..90356dccda5 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Trait.java @@ -0,0 +1,13 @@ +package org.jetbrains.jet.j2k.ast; + +import java.util.List; + +/** + * @author ignatov + */ +public class Trait extends Class { + public Trait(Identifier name, List innerClasses, List methods, List fields) { + super(name, innerClasses, methods, fields); + TYPE = "trait"; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Type.java b/src/org/jetbrains/jet/j2k/ast/Type.java new file mode 100644 index 00000000000..7f040f92002 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Type.java @@ -0,0 +1,14 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public abstract class Type extends Element { + @NotNull + @Override + public Kind getKind() { + return Kind.TYPE; + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Visitor.java b/src/org/jetbrains/jet/j2k/ast/Visitor.java new file mode 100644 index 00000000000..fa1a2126af7 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Visitor.java @@ -0,0 +1,11 @@ +package org.jetbrains.jet.j2k.ast; + +import org.jetbrains.annotations.NotNull; + +/** + * @author ignatov + */ +public interface Visitor { + @NotNull + Element getResult(); +} diff --git a/src/org/jetbrains/jet/j2k/util/AstUtil.java b/src/org/jetbrains/jet/j2k/util/AstUtil.java new file mode 100644 index 00000000000..7b2c391fe3c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/util/AstUtil.java @@ -0,0 +1,44 @@ +package org.jetbrains.jet.j2k.util; + +import org.jetbrains.jet.j2k.ast.INode; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author ignatov + */ +public class AstUtil { + private static String join(final String array[], final String delimiter) { + StringBuilder buffer = new StringBuilder(); + boolean haveDelimiter = (delimiter != null); + + for (int i = 0; i < array.length; i++) { + buffer.append(array[i]); + + if (haveDelimiter && (i + 1) < array.length) + buffer.append(delimiter); + } + + return buffer.toString(); + } + + public static String joinNodes(final List nodes, final String delimiter) { + return join(nodesToKotlin(nodes), delimiter); + } + + public static String join(final List array, final String delimiter) { + return join(array.toArray(new String[array.size()]), delimiter); + } + + public static List nodesToKotlin(List nodes) { + List result = new LinkedList(); + for (INode n : nodes) + result.add(n.toKotlin()); + return result; + } + + public static String upperFirstCharacter(String string) { + return string.substring(0, 1).toUpperCase() + string.substring(1); + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java new file mode 100644 index 00000000000..044bd709f36 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.java @@ -0,0 +1,41 @@ +package org.jetbrains.jet.j2k.visitors; + +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.PsiExpressionList; +import com.intellij.psi.PsiLocalVariable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.ast.*; + +import static org.jetbrains.jet.j2k.Converter.*; + +/** + * @author ignatov + */ +public class ElementVisitor extends JavaElementVisitor implements Visitor { + private Element myResult = new EmptyElement(); + + @Override + public void visitLocalVariable(PsiLocalVariable variable) { + super.visitLocalVariable(variable); + myResult = new LocalVariable( + new IdentifierImpl(variable.getName()), // TODO + typeToType(variable.getType()), + expressionToExpression(variable.getInitializer()) + ); + } + + @Override + public void visitExpressionList(PsiExpressionList list) { + super.visitExpressionList(list); + myResult = new ExpressionList( + expressionsToExpressionList(list.getExpressions()), + typesToTypeList(list.getExpressionTypes()) + ); + + } + + @NotNull + public Element getResult() { + return myResult; + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java new file mode 100644 index 00000000000..14afb1ba126 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java @@ -0,0 +1,209 @@ +package org.jetbrains.jet.j2k.visitors; + +import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.ast.*; + +import static org.jetbrains.jet.j2k.Converter.elementToElement; +import static org.jetbrains.jet.j2k.Converter.expressionToExpression; + +/** + * @author ignatov + */ +public class ExpressionVisitor extends StatementVisitor implements Visitor { + private Expression myResult = new EmptyExpression(); + + @NotNull + public Expression getResult() { + return myResult; + } + + @Override + public void visitArrayAccessExpression(PsiArrayAccessExpression expression) { + super.visitArrayAccessExpression(expression); + } + + @Override + public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { + super.visitArrayInitializerExpression(expression); + } + + @Override + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + super.visitAssignmentExpression(expression); + + // TODO: simplify + + final IElementType tokenType = expression.getOperationSign().getTokenType(); + + if (tokenType == JavaTokenType.GTGTGTEQ) { // because it's transform to the method call + myResult = new AssignmentExpression( + expressionToExpression(expression.getLExpression()), + new DummyMethodCallExpression( + expressionToExpression(expression.getLExpression()), + "cyclicShiftRight", + expressionToExpression(expression.getRExpression()) + ), + "=" + ); + } else { + + String secondOp = ""; + if (tokenType == JavaTokenType.GTGTEQ) secondOp = "shr"; + if (tokenType == JavaTokenType.LTLTEQ) secondOp = "shl"; + if (tokenType == JavaTokenType.XOREQ) secondOp = "xor"; + if (tokenType == JavaTokenType.ANDEQ) secondOp = "and"; + if (tokenType == JavaTokenType.OREQ) secondOp = "or"; + + if (!secondOp.equals("")) // if not Kotlin operators + myResult = new AssignmentExpression( + expressionToExpression(expression.getLExpression()), + new BinaryExpression( + expressionToExpression(expression.getLExpression()), + expressionToExpression(expression.getRExpression()), + secondOp + ), + "=" + ); + else + myResult = new AssignmentExpression( + expressionToExpression(expression.getLExpression()), + expressionToExpression(expression.getRExpression()), + expression.getOperationSign().getText() // TODO + ); + } + } + + private String getOperatorString(PsiJavaToken op) { + if (op.getTokenType() == JavaTokenType.GTGT) return "shr"; + if (op.getTokenType() == JavaTokenType.LTLT) return "shl"; + if (op.getTokenType() == JavaTokenType.XOR) return "xor"; + if (op.getTokenType() == JavaTokenType.AND) return "and"; + if (op.getTokenType() == JavaTokenType.OR) return "or"; + if (op.getTokenType() == JavaTokenType.OR) return "or"; + + return op.getText(); + } + + @Override + public void visitBinaryExpression(PsiBinaryExpression expression) { + super.visitBinaryExpression(expression); + + if (expression.getOperationSign().getTokenType() == JavaTokenType.GTGTGT) + myResult = new DummyMethodCallExpression( + expressionToExpression(expression.getLOperand()), + "cyclicShiftRight", + expressionToExpression(expression.getROperand())); + else + myResult = + new BinaryExpression( + expressionToExpression(expression.getLOperand()), + expressionToExpression(expression.getROperand()), + getOperatorString(expression.getOperationSign()) + ); + } + + @Override + public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { + super.visitClassObjectAccessExpression(expression); + } + + @Override + public void visitConditionalExpression(PsiConditionalExpression expression) { + super.visitConditionalExpression(expression); + } + + @Override + public void visitExpressionListStatement(PsiExpressionListStatement statement) { + super.visitExpressionListStatement(statement); + } + + @Override + public void visitExpressionStatement(PsiExpressionStatement statement) { + super.visitExpressionStatement(statement); + } + + @Override + public void visitExpressionList(PsiExpressionList list) { + super.visitExpressionList(list); + } + + @Override + public void visitInstanceOfExpression(PsiInstanceOfExpression expression) { + super.visitInstanceOfExpression(expression); + } + + @Override + public void visitLiteralExpression(PsiLiteralExpression expression) { + super.visitLiteralExpression(expression); + myResult = new LiteralExpression( + new IdentifierImpl( + ((PsiLiteralExpressionImpl) expression).getCanonicalText() // TODO + ) + ); + } + + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + // TODO: not resolved + myResult = + new MethodCallExpression( + expressionToExpression(expression.getMethodExpression()), + elementToElement(expression.getArgumentList()) + ); + } + + @Override + public void visitCallExpression(PsiCallExpression callExpression) { + super.visitCallExpression(callExpression); + } + + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); + } + + @Override + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { + super.visitParenthesizedExpression(expression); + } + + @Override + public void visitPostfixExpression(PsiPostfixExpression expression) { + super.visitPostfixExpression(expression); + } + + @Override + public void visitPrefixExpression(PsiPrefixExpression expression) { + super.visitPrefixExpression(expression); + } + + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + myResult = new IdentifierImpl(expression.getQualifiedName()); // TODO + } + + @Override + public void visitSuperExpression(PsiSuperExpression expression) { + super.visitSuperExpression(expression); + } + + @Override + public void visitThisExpression(PsiThisExpression expression) { + super.visitThisExpression(expression); + } + + @Override + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + super.visitTypeCastExpression(expression); + } + + @Override + public void visitPolyadicExpression(PsiPolyadicExpression expression) { + super.visitPolyadicExpression(expression); + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java new file mode 100644 index 00000000000..96c3a3206c1 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java @@ -0,0 +1,141 @@ +package org.jetbrains.jet.j2k.visitors; + +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.Converter; +import org.jetbrains.jet.j2k.ast.*; + +/** + * @author ignatov + */ +public class StatementVisitor extends ElementVisitor implements Visitor { + private Statement myResult = new EmptyStatement(); + + @NotNull + public Statement getStatement() { + return myResult; + } + + @Override + public void visitAssertStatement(PsiAssertStatement statement) { + super.visitAssertStatement(statement); + } + + @Override + public void visitBlockStatement(PsiBlockStatement statement) { + super.visitBlockStatement(statement); + } + + @Override + public void visitBreakStatement(PsiBreakStatement statement) { + super.visitBreakStatement(statement); + } + + @Override + public void visitContinueStatement(PsiContinueStatement statement) { + super.visitContinueStatement(statement); + } + + @Override + public void visitDeclarationStatement(PsiDeclarationStatement statement) { + super.visitDeclarationStatement(statement); + myResult = new DeclarationStatement( + Converter.elementsToElementList(statement.getDeclaredElements()) + ); + } + + @Override + public void visitDoWhileStatement(PsiDoWhileStatement statement) { + super.visitDoWhileStatement(statement); + } + + @Override + public void visitEmptyStatement(PsiEmptyStatement statement) { + super.visitEmptyStatement(statement); + } + + @Override + public void visitExpressionStatement(PsiExpressionStatement statement) { + super.visitExpressionStatement(statement); + myResult = Converter.expressionToExpression(statement.getExpression()); + } + + @Override + public void visitExpressionListStatement(PsiExpressionListStatement statement) { + super.visitExpressionListStatement(statement); + } + + @Override + public void visitForStatement(PsiForStatement statement) { + super.visitForStatement(statement); + } + + @Override + public void visitForeachStatement(PsiForeachStatement statement) { + super.visitForeachStatement(statement); + } + + @Override + public void visitImportStatement(PsiImportStatement statement) { + super.visitImportStatement(statement); + } + + @Override + public void visitIfStatement(PsiIfStatement statement) { + super.visitIfStatement(statement); + } + + @Override + public void visitImportStaticStatement(PsiImportStaticStatement statement) { + super.visitImportStaticStatement(statement); + } + + @Override + public void visitLabeledStatement(PsiLabeledStatement statement) { + super.visitLabeledStatement(statement); + } + + @Override + public void visitPackageStatement(PsiPackageStatement statement) { + super.visitPackageStatement(statement); + } + + @Override + public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) { + super.visitSwitchLabelStatement(statement); + } + + @Override + public void visitSwitchStatement(PsiSwitchStatement statement) { + super.visitSwitchStatement(statement); + } + + @Override + public void visitSynchronizedStatement(PsiSynchronizedStatement statement) { + super.visitSynchronizedStatement(statement); + } + + @Override + public void visitThrowStatement(PsiThrowStatement statement) { + super.visitThrowStatement(statement); + } + + @Override + public void visitTryStatement(PsiTryStatement statement) { + super.visitTryStatement(statement); + } + + @Override + public void visitWhileStatement(PsiWhileStatement statement) { + super.visitWhileStatement(statement); + } + + @Override + public void visitReturnStatement(PsiReturnStatement statement) { + super.visitReturnStatement(statement); + + myResult = new ReturnStatement( + Converter.expressionToExpression(statement.getReturnValue()) + ); + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java new file mode 100644 index 00000000000..fbac51b6861 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java @@ -0,0 +1,67 @@ +package org.jetbrains.jet.j2k.visitors; + +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.ast.*; +import org.jetbrains.jet.j2k.util.AstUtil; + +/** + * @author ignatov + */ +public class TypeVisitor extends PsiTypeVisitor implements Visitor { + private Type myResult = new EmptyType(); + + @NotNull + public Type getResult() { + return myResult; + } + + @Override + public Type visitType(PsiType type) { + return super.visitType(type); + } + + @Override + public Type visitPrimitiveType(PsiPrimitiveType primitiveType) { + final String name = primitiveType.getCanonicalText(); + final IdentifierImpl identifier = new IdentifierImpl(name); + + if (name.equals("void")) + myResult = new PrimitiveType(new IdentifierImpl("Unit")); + else if (Node.PRIMITIVE_TYPES.contains(name)) + myResult = new PrimitiveType(new IdentifierImpl(AstUtil.upperFirstCharacter(name))); + else myResult = new PrimitiveType(identifier); + return super.visitPrimitiveType(primitiveType); + } + + @Override + public Type visitArrayType(PsiArrayType arrayType) { + return super.visitArrayType(arrayType); + } + + @Override + public Type visitClassType(PsiClassType classType) { + myResult = new ClassType(new IdentifierImpl(classType.getClassName())); + return super.visitClassType(classType); + } + + @Override + public Type visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) { + return super.visitCapturedWildcardType(capturedWildcardType); + } + + @Override + public Type visitWildcardType(PsiWildcardType wildcardType) { + return super.visitWildcardType(wildcardType); + } + + @Override + public Type visitEllipsisType(PsiEllipsisType ellipsisType) { + return super.visitEllipsisType(ellipsisType); + } + + @Override + public Type visitDisjunctionType(PsiDisjunctionType disjunctionType) { + return super.visitDisjunctionType(disjunctionType); + } +} diff --git a/test/org/jetbrains/jet/j2k/FileTest.java b/test/org/jetbrains/jet/j2k/FileTest.java new file mode 100644 index 00000000000..8d5a8f6a92c --- /dev/null +++ b/test/org/jetbrains/jet/j2k/FileTest.java @@ -0,0 +1,60 @@ +package org.jetbrains.jet.j2k; + +import junit.framework.Assert; + +/** + * @author ignatov + */ +public class FileTest extends JetTestCaseBase { + public void testPackageWithImports() throws Exception { + Assert.assertEquals( + fileToKotlin( + "package test;" + + "import ast;" + + "import ast2;"), + "namespace test {" + "\n" + + "import ast" + "\n" + + "import ast2" + "\n" + + "}" + ); + } + + public void testPackageWithMixedImports() throws Exception { + Assert.assertEquals( + fileToKotlin( + "package test;" + + "import static ast;" + + "import ast2;"), + "namespace test {" + "\n" + + "import ast" + "\n" + + "import ast2" + "\n" + + "}" + ); + } + + public void testPackageWithStaticImports() throws Exception { + Assert.assertEquals( + fileToKotlin( + "package test;" + + "import static ast;" + + "import static ast2;"), + "namespace test {" + "\n" + + "import ast" + "\n" + + "import ast2" + "\n" + + "}" + ); + } + + public void testPackageWithClass() throws Exception { + Assert.assertEquals( + toSingleLine(fileToKotlin("package test; class C {}")), + "namespace test { class C { } }" + ); + } + + public void testPackageWithClasses() throws Exception { + Assert.assertEquals( + toSingleLine(fileToKotlin("class A {} class B {}")), + "namespace { class A { } class B { } }"); + } +} diff --git a/test/org/jetbrains/jet/j2k/JetTestCaseBase.java b/test/org/jetbrains/jet/j2k/JetTestCaseBase.java new file mode 100644 index 00000000000..b210ee6fc36 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/JetTestCaseBase.java @@ -0,0 +1,200 @@ +package org.jetbrains.jet.j2k; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; +import com.intellij.psi.PsiJavaFile; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author abreslav + */ +public abstract class JetTestCaseBase extends LightDaemonAnalyzerTestCase { + private boolean checkInfos = false; + private String dataPath; + protected final String name; + + protected JetTestCaseBase() { + this("", ""); + } + + public JetTestCaseBase(String dataPath, String name) { + this.dataPath = dataPath; + this.name = name; + } + + public final JetTestCaseBase setCheckInfos(boolean checkInfos) { + this.checkInfos = checkInfos; + return this; + } + + public static Sdk jdkFromIdeaHome() { + return new JavaSdkImpl().createJdk("JDK", "compiler/testData/mockJDK-1.7/jre", true); + } + + @Override + protected String getTestDataPath() { + return getTestDataPathBase(); + } + + public static String getTestDataPathBase() { + return getHomeDirectory() + "/compiler/testData"; + } + + public static String getHomeDirectory() { + return new File(PathManager.getResourceRoot(JetTestCaseBase.class, "/org/jetbrains/jet/JetTestCaseBase.class")).getParentFile().getParentFile().getParent(); + } + + @Override + protected Sdk getProjectJDK() { + return jdkFromIdeaHome(); + } + +// @Override +// public String getName() { +// return "test" + name; +// } + +// @Override +// protected void runTest() throws Throwable { +// doTest(getTestFilePath(), true, checkInfos); +// } + + @NotNull + protected String getTestFilePath() { + return dataPath + File.separator + name + ".jet"; + } + + protected String getDataPath() { + return dataPath; + } + + protected void configureFromText(String text) throws IOException { + configureFromFileText("test.java", text); + } + + @NotNull + protected String classToKotlin(String text) throws IOException { + configureFromText(text); + + PsiJavaFile javaFile = (PsiJavaFile) myFile; + + String result = prettify(Converter.fileToFile(javaFile).toKotlin()).replaceAll("namespace \\{", ""); + result = result.substring(0, result.lastIndexOf("}")); + return prettify(result); + + } + + @NotNull + protected String classToSingleLineKotlin(String text) throws IOException { + return toSingleLine(classToKotlin(text)); + } + + protected String fileToKotlin(String text) throws IOException { + configureFromText(text); + return prettify(Converter.fileToFile((PsiJavaFile) myFile).toKotlin()); + } + + protected String methodToKotlin(String text) throws IOException { + String result = classToKotlin("class C {" + text + "}") + .replaceAll("class C \\{", ""); + result = result.substring(0, result.lastIndexOf("}")); + return prettify(result); + } + + protected String methodToSingleLineKotlin(String text) throws IOException { + return toSingleLine(methodToKotlin(text)); + } + + protected String statementToKotlin(String text) throws Exception { + String result = methodToKotlin("void main() {" + text + "}"); + int pos = result.lastIndexOf("}"); + result = result.substring(0, pos).replaceFirst("fun main\\(\\) : Unit \\{", ""); + return prettify(result); + } + + protected String statementToSingleLineKotlin(String code) throws Exception { + return toSingleLine(statementToKotlin(code)); + } + + protected String expressionToKotlin(String code) throws Exception { + String result = statementToKotlin("Object o =" + code + "}"); + result = result.replaceFirst("var o : Object\\? =", ""); + return prettify(result); + } + + protected String expressionToSingleLineKotlin(String code) throws Exception { + return toSingleLine(expressionToKotlin(code)); + } + + public interface NamedTestFactory { + @NotNull + Test createTest(@NotNull String dataPath, @NotNull String name); + } + + @NotNull + public static TestSuite suiteForDirectory(String baseDataDir, @NotNull final String dataPath, boolean recursive, @NotNull NamedTestFactory factory) { + TestSuite suite = new TestSuite(dataPath); + final String extension = ".jet"; + FilenameFilter extensionFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(extension); + } + }; + File dir = new File(baseDataDir + dataPath); + FileFilter dirFilter = new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.isDirectory(); + } + }; + if (recursive) { + File[] files = dir.listFiles(dirFilter); + assert files != null : dir; + List subdirs = Arrays.asList(files); + Collections.sort(subdirs); + for (File subdir : subdirs) { + suite.addTest(suiteForDirectory(baseDataDir, dataPath + "/" + subdir.getName(), recursive, factory)); + } + } + List files = Arrays.asList(dir.listFiles(extensionFilter)); + Collections.sort(files); + for (File file : files) { + String fileName = file.getName(); + assert fileName != null; + suite.addTest(factory.createTest(dataPath, fileName.substring(0, fileName.length() - extension.length()))); + } + return suite; + } + + @NotNull + protected static String prettify(String code) { + if (code == null) + return ""; + return code + .trim() + .replaceAll("\r\n", "\n") + .replaceAll("\n+", "\n") + .replaceAll("\n ", "\n") + .replaceAll(" +", " ") + .trim() + ; + } + + @NotNull + protected static String toSingleLine(String string) { + return prettify(string.replaceAll("\n", " ")); + } +} \ No newline at end of file diff --git a/test/org/jetbrains/jet/j2k/ast/AssignmentExpressionTest.java b/test/org/jetbrains/jet/j2k/ast/AssignmentExpressionTest.java new file mode 100644 index 00000000000..40e6470465a --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/AssignmentExpressionTest.java @@ -0,0 +1,61 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class AssignmentExpressionTest extends JetTestCaseBase { + public void testSimpleAssignment() throws Exception { + Assert.assertEquals(statementToSingleLineKotlin("i = 1;"), "i = 1"); + } + + public void testShiftRight() throws Exception { + Assert.assertEquals(expressionToKotlin("x >>= 2"), "x = (x shr 2)"); + } + + public void testShiftLeft() throws Exception { + Assert.assertEquals(expressionToKotlin("x <<= 2"), "x = (x shl 2)"); + } + + public void testUnsignedRightShift() throws Exception { + Assert.assertEquals(expressionToKotlin("x >>>= 2"), "x = x.cyclicShiftRight(2)"); + } + + public void testXor() throws Exception { + Assert.assertEquals(expressionToKotlin("x ^= 2"), "x = (x xor 2)"); + } + + public void testAnd() throws Exception { + Assert.assertEquals(expressionToKotlin("x &= 2"), "x = (x and 2)"); + } + + public void testOr() throws Exception { + Assert.assertEquals(expressionToKotlin("x |= 2"), "x = (x or 2)"); + } + + public void testMultiplyAssign() throws Exception { + Assert.assertEquals(expressionToKotlin("x *= 2"), "x *= 2"); + } + + public void testDivideAssign() throws Exception { + Assert.assertEquals(expressionToKotlin("x /= 2"), "x /= 2"); + } + + public void testPlusAssign() throws Exception { + Assert.assertEquals(expressionToKotlin("x += 2"), "x += 2"); + } + + public void testMinusAssign() throws Exception { + Assert.assertEquals(expressionToKotlin("x -= 2"), "x -= 2"); + } + + public void testReminder() throws Exception { + Assert.assertEquals(expressionToKotlin("x %= 2"), "x %= 2"); + } + + public void testAssignment() throws Exception { + Assert.assertEquals(expressionToKotlin("x = 2"), "x = 2"); + } +} \ No newline at end of file diff --git a/test/org/jetbrains/jet/j2k/ast/BinaryExpressionTest.java b/test/org/jetbrains/jet/j2k/ast/BinaryExpressionTest.java new file mode 100644 index 00000000000..d87c90c892a --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/BinaryExpressionTest.java @@ -0,0 +1,81 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class BinaryExpressionTest extends JetTestCaseBase { + public void testMultiply() throws Exception { + Assert.assertEquals(expressionToKotlin("1 * 2"), "(1 * 2)"); + } + + public void testDivide() throws Exception { + Assert.assertEquals(expressionToKotlin("1 / 2"), "(1 / 2)"); + } + + public void testRemainder() throws Exception { + Assert.assertEquals(expressionToKotlin("1 % 2"), "(1 % 2)"); + } + + public void testPlus() throws Exception { + Assert.assertEquals(expressionToKotlin("1 + 2"), "(1 + 2)"); + } + + public void testMinus() throws Exception { + Assert.assertEquals(expressionToKotlin("1 - 2"), "(1 - 2)"); + } + + public void testLessThan() throws Exception { + Assert.assertEquals(expressionToKotlin("1 < 2"), "(1 < 2)"); + } + + public void testGreaterThan() throws Exception { + Assert.assertEquals(expressionToKotlin("1 > 2"), "(1 > 2)"); + } + + public void testLessThanEqual() throws Exception { + Assert.assertEquals(expressionToKotlin("1 <= 2"), "(1 <= 2)"); + } + + public void testGreaterThanEqual() throws Exception { + Assert.assertEquals(expressionToKotlin("1 >= 2"), "(1 >= 2)"); + } + + public void testConditionalAnd() throws Exception { + Assert.assertEquals(expressionToKotlin("true && false"), "(true && false)"); + } + + public void testConditionalOr() throws Exception { + Assert.assertEquals(expressionToKotlin("true || false"), "(true || false)"); + } + + public void testShiftRight() throws Exception { + Assert.assertEquals(expressionToKotlin("x >> 2"), "(x shr 2)"); + } + + public void testShiftLeft() throws Exception { + Assert.assertEquals(expressionToKotlin("x << 2"), "(x shl 2)"); + } + + public void testUnsignedRightShift() throws Exception { + Assert.assertEquals(expressionToKotlin("x >>> 2"), "x.cyclicShiftRight(2)"); + } + + public void testXor() throws Exception { + Assert.assertEquals(expressionToKotlin("x ^ 2"), "(x xor 2)"); + } + + public void testAnd() throws Exception { + Assert.assertEquals(expressionToKotlin("x & 2"), "(x and 2)"); + } + + public void testOr() throws Exception { + Assert.assertEquals(expressionToKotlin("x | 2"), "(x or 2)"); + } + +// public void testNot() throws Exception { // TODO: move to prefix +// Assert.assertEquals(expressionToKotlin("~x"), "inv(x)"); +// } +} diff --git a/test/org/jetbrains/jet/j2k/ast/ClassTest.java b/test/org/jetbrains/jet/j2k/ast/ClassTest.java new file mode 100644 index 00000000000..67397afe71d --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/ClassTest.java @@ -0,0 +1,65 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class ClassTest extends JetTestCaseBase { + public void testEmptyClass() throws Exception { + Assert.assertEquals( + classToSingleLineKotlin("final class A {}"), + "class A { }" + ); + } + + public void testInnerEmptyClass() throws Exception { + Assert.assertEquals( + classToSingleLineKotlin("final class A { inner final class B {} }"), + "class A { class B { } }" + ); + } + + public void testClassWithFields() throws Exception { + Assert.assertEquals(classToKotlin( + "final class T {" + + "String a = \"abc\";" + + "int b = 10;" + + "}"), + "class T {\n" + + "var a : String? = \"abc\"\n" + + "var b : Int = 10\n" + + "}"); + } + + public void testClassWithMultiplyFields() throws Exception { + Assert.assertEquals(classToKotlin( + "final class T {" + + "String a, b, c = \"abc\";" + + "}"), + "class T {\n" + + "var a : String?\n" + + "var b : String?\n" + + "var c : String? = \"abc\"\n" + + "}"); + } + + public void testClassWithEmptyMethods() throws Exception { + Assert.assertEquals(classToKotlin( + "final class T {" + + "void main() {}" + + "int i() {}" + + "String s() {}" + + "}" + ), + "class T {\n" + + "fun main() : Unit {\n" + + "}\n" + + "fun i() : Int {\n" + + "}\n" + + "fun s() : String? {\n" + + "}\n" + + "}"); + } +} diff --git a/test/org/jetbrains/jet/j2k/ast/DeclarationStatementTest.java b/test/org/jetbrains/jet/j2k/ast/DeclarationStatementTest.java new file mode 100644 index 00000000000..f544399cf27 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/DeclarationStatementTest.java @@ -0,0 +1,33 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class DeclarationStatementTest extends JetTestCaseBase { + public void testSingleStringDeclaration() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("String s;"), + "var s : String?" + ); + } + + public void testSingleIntDeclaration() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("int s;"), + "var s : Int" + ); + } + + public void testMultiplyIntDeclaration() throws Exception { + Assert.assertEquals( + statementToKotlin("int k, l, m;"), + "var k : Int\n" + + "var l : Int\n" + + "var m : Int" + ); + } + +} diff --git a/test/org/jetbrains/jet/j2k/ast/EnumTest.java b/test/org/jetbrains/jet/j2k/ast/EnumTest.java new file mode 100644 index 00000000000..da270403b3c --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/EnumTest.java @@ -0,0 +1,28 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class EnumTest extends JetTestCaseBase { + public void testEmptyEnum() throws Exception { + Assert.assertEquals( + classToSingleLineKotlin("enum A {}"), + "enum A { }" + ); + } + +// 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" + +// "}" +// ); +// } +} diff --git a/test/org/jetbrains/jet/j2k/ast/FunctionTest.java b/test/org/jetbrains/jet/j2k/ast/FunctionTest.java new file mode 100644 index 00000000000..dd2297deb96 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/FunctionTest.java @@ -0,0 +1,44 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class FunctionTest extends JetTestCaseBase { + public void testEmptyVoidMethod() throws Exception { + Assert.assertEquals( + methodToSingleLineKotlin("void main() {}"), + "fun main() : Unit { }" + ); + } + + public void testMethodClassType() throws Exception { + Assert.assertEquals( + methodToSingleLineKotlin("String main() {}"), + "fun main() : String? { }" + ); + } + + public void testMethodPrimitiveType() throws Exception { + Assert.assertEquals( + methodToSingleLineKotlin("int main() {}"), + "fun main() : Int { }" + ); + } + + public void testMethodPrimitiveType2() throws Exception { + Assert.assertEquals( + methodToSingleLineKotlin("boolean main() {}"), + "fun main() : Boolean { }" + ); + } + + public void testMethodWithReturnStatement() throws Exception { + Assert.assertEquals( + methodToSingleLineKotlin("boolean isTrue() { return true; }"), + "fun isTrue() : Boolean { return true }" + ); + } +} \ No newline at end of file diff --git a/test/org/jetbrains/jet/j2k/ast/IdentifierImplTest.java b/test/org/jetbrains/jet/j2k/ast/IdentifierImplTest.java new file mode 100644 index 00000000000..9b5dd9aff52 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/IdentifierImplTest.java @@ -0,0 +1,11 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.TestCase; + +/** + * @author ignatov + */ +public class IdentifierImplTest extends TestCase { + public void testEmpty() throws Exception { // TODO: remove + } +} diff --git a/test/org/jetbrains/jet/j2k/ast/LocalVariableTest.java b/test/org/jetbrains/jet/j2k/ast/LocalVariableTest.java new file mode 100644 index 00000000000..fc056e3790e --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/LocalVariableTest.java @@ -0,0 +1,16 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class LocalVariableTest extends JetTestCaseBase { + public void testObject() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("int i;"), + "var i : Int" + ); + } +} diff --git a/test/org/jetbrains/jet/j2k/ast/MethodCallExpressionTest.java b/test/org/jetbrains/jet/j2k/ast/MethodCallExpressionTest.java new file mode 100644 index 00000000000..76d11053c28 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/MethodCallExpressionTest.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class MethodCallExpressionTest extends JetTestCaseBase { + public void testSimpleCall() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("method(param1, param2);"), "method(param1, param2)" + ); + } + + public void testEmptyCall() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("methodCall();"), "methodCall()" + ); + } + + public void testCallWithKeywords() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("when(open, trait);"), "`when`(`open`, `trait`)" + ); + } +} diff --git a/test/org/jetbrains/jet/j2k/ast/ReturnStatementTest.java b/test/org/jetbrains/jet/j2k/ast/ReturnStatementTest.java new file mode 100644 index 00000000000..92fce59b4e4 --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/ReturnStatementTest.java @@ -0,0 +1,37 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class ReturnStatementTest extends JetTestCaseBase { + public void testReturnLiteral() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("return true;"), + "return true" + ); + } + + public void testReturnString() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("return \"str\";"), + "return \"str\"" + ); + } + + public void testReturnNumber() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("return 1;"), + "return 1" + ); + } + + public void testReturnChar() throws Exception { + Assert.assertEquals( + statementToSingleLineKotlin("return 'c';"), + "return 'c'" + ); + } +} diff --git a/test/org/jetbrains/jet/j2k/ast/TraitTest.java b/test/org/jetbrains/jet/j2k/ast/TraitTest.java new file mode 100644 index 00000000000..f638681b49c --- /dev/null +++ b/test/org/jetbrains/jet/j2k/ast/TraitTest.java @@ -0,0 +1,45 @@ +package org.jetbrains.jet.j2k.ast; + +import junit.framework.Assert; +import org.jetbrains.jet.j2k.JetTestCaseBase; + +/** + * @author ignatov + */ +public class TraitTest extends JetTestCaseBase { + public void testEmptyInterface() throws Exception { + Assert.assertEquals( + classToSingleLineKotlin("interface A {}"), + "trait A { }" + ); + } + + public void testInterfaceWithMethodDeclaration() throws Exception { + Assert.assertEquals(classToKotlin( + "interface INode {" + + "Tag getTag();" + + "String toKotlin();" + + "}" + ), + "trait INode {\n" + + "fun getTag() : Tag? \n" + + "fun toKotlin() : String? \n" + + "}"); + } + + public void testInterfaceWithFields() throws Exception { + Assert.assertEquals(classToKotlin( + "interface INode {" + + "String IN = \"in\";" + + "String AT = \"@\";" + + "String COMMA_WITH_SPACE = COMMA + SPACE;" + + "}" + ), + "trait INode {\n" + + "var IN : String? = \"in\"\n" + + "var AT : String? = \"@\"\n" + + "var COMMA_WITH_SPACE : String? = (COMMA + SPACE)\n" + + "}" + ); + } +} \ No newline at end of file