+
+
+
+
+ kotlin
+ nullable
+ ushr
+
+
+
+
+
+
+
+
+
+ http://www.w3.org/1999/xhtml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..84f4c3093d1
--- /dev/null
+++ b/src/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: org.jetbrains.jet.j2k.JavaToKotlinCli
+
diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java
new file mode 100644
index 00000000000..e5d952e5ada
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/Converter.java
@@ -0,0 +1,823 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+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.util.AstUtil;
+import org.jetbrains.jet.j2k.visitors.*;
+import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
+
+import java.util.*;
+
+import static org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses;
+import static org.jetbrains.jet.j2k.ConverterUtil.createMainFunction;
+import static org.jetbrains.jet.j2k.visitors.TypeVisitor.*;
+import static org.jetbrains.jet.lang.types.expressions.OperatorConventions.*;
+
+/**
+ * @author ignatov
+ */
+public class Converter {
+ @NotNull
+ public static final Set NOT_NULL_ANNOTATIONS = ImmutableSet.of(
+ "org.jetbrains.annotations.NotNull",
+ "com.sun.istack.internal.NotNull",
+ "javax.annotation.Nonnull"
+ );
+
+ @NotNull
+ private Set classIdentifiers = Sets.newHashSet();
+
+ @NotNull
+ private final Dispatcher dispatcher = new Dispatcher(this);
+
+ @Nullable
+ private PsiType methodReturnType = null;
+
+ @NotNull
+ private final Set flags = Sets.newHashSet();
+
+ public Converter() {
+ }
+
+ public boolean addFlag(@NotNull J2KConverterFlags flag) {
+ return flags.add(flag);
+ }
+
+ public boolean hasFlag(@NotNull J2KConverterFlags flag) {
+ return flags.contains(flag);
+ }
+
+ public void setClassIdentifiers(@NotNull Set identifiers) {
+ classIdentifiers = identifiers;
+ }
+
+ @NotNull
+ public Set getClassIdentifiers() {
+ return Collections.unmodifiableSet(classIdentifiers);
+ }
+
+ @Nullable
+ public PsiType getMethodReturnType() {
+ return methodReturnType;
+ }
+
+ public void clearClassIdentifiers() {
+ classIdentifiers.clear();
+ }
+
+ @NotNull
+ public String elementToKotlin(@NotNull PsiElement element) {
+ if (element instanceof PsiJavaFile) {
+ return fileToFile((PsiJavaFile) element).toKotlin();
+ }
+
+ if (element instanceof PsiClass) {
+ return classToClass((PsiClass) element).toKotlin();
+ }
+
+ if (element instanceof PsiMethod) {
+ return methodToFunction((PsiMethod) element).toKotlin();
+ }
+
+ if (element instanceof PsiField) {
+ PsiField field = (PsiField) element;
+ return fieldToField(field, field.getContainingClass()).toKotlin();
+ }
+
+ if (element instanceof PsiStatement) {
+ return statementToStatement((PsiStatement) element).toKotlin();
+ }
+
+ if (element instanceof PsiExpression) {
+ return expressionToExpression((PsiExpression) element).toKotlin();
+ }
+
+ return "";
+ }
+
+ @NotNull
+ public File fileToFile(@NotNull PsiJavaFile javaFile) {
+ return fileToFile(javaFile, Collections.emptyList());
+ }
+
+ @NotNull
+ public File fileToFileWithCompatibilityImport(@NotNull PsiJavaFile javaFile) {
+ return fileToFile(javaFile, Collections.singletonList("kotlin.compatibility.*"));
+ }
+
+ @NotNull
+ private File fileToFile(PsiJavaFile javaFile, List additionalImports) {
+ final PsiImportList importList = javaFile.getImportList();
+ List imports = importList == null
+ ? Collections.emptyList()
+ : importsToImportList(importList.getAllImportStatements());
+ for (String i : additionalImports)
+ imports.add(new Import(i));
+ return new File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses()), createMainFunction(javaFile));
+ }
+
+ @NotNull
+ private static String quoteKeywords(@NotNull String packageName) {
+ List result = new LinkedList();
+ for (String part : packageName.split("\\."))
+ result.add(new IdentifierImpl(part).toKotlin());
+ return AstUtil.join(result, ".");
+ }
+
+ @NotNull
+ private List classesToClassList(@NotNull PsiClass[] classes) {
+ List result = new LinkedList();
+ for (PsiClass t : classes) result.add(classToClass(t));
+ return result;
+ }
+
+ @NotNull
+ public AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
+ return new AnonymousClass(this, getMembers(anonymousClass));
+ }
+
+ @NotNull
+ private List getMembers(@NotNull PsiClass psiClass) {
+ List members = new LinkedList();
+ for (PsiElement e : psiClass.getChildren()) {
+ if (e instanceof PsiMethod) {
+ members.add(methodToFunction((PsiMethod) e, true));
+ }
+ else if (e instanceof PsiField) {
+ members.add(fieldToField((PsiField) e, psiClass));
+ }
+ else if (e instanceof PsiClass) {
+ members.add(classToClass((PsiClass) e));
+ }
+ else if (e instanceof PsiClassInitializer) {
+ members.add(initializerToInitializer((PsiClassInitializer) e));
+ }
+ else if (e instanceof PsiMember) System.out.println(e.getClass() + " " + e.getText());
+ }
+ return members;
+ }
+
+ @NotNull
+ private static List getFinalOrWithEmptyInitializer(@NotNull List extends Field> fields) {
+ List result = new LinkedList();
+ for (Field f : fields)
+ if (f.isVal() || f.getInitializer().toKotlin().isEmpty()) {
+ result.add(f);
+ }
+ return result;
+ }
+
+ @NotNull
+ private static List createParametersFromFields(@NotNull List extends Field> fields) {
+ List result = new LinkedList();
+ for (Field f : fields)
+ result.add(new Parameter(new IdentifierImpl("_" + f.getIdentifier().getName()), f.getType()));
+ return result;
+ }
+
+ @NotNull
+ private static List createInitStatementsFromFields(@NotNull List extends Field> fields) {
+ List result = new LinkedList();
+ for (Field f : fields) {
+ final String identifierToKotlin = f.getIdentifier().toKotlin();
+ result.add(new DummyStringExpression(identifierToKotlin + " = " + "_" + identifierToKotlin));
+ }
+ return result;
+ }
+
+ @NotNull
+ private static String createPrimaryConstructorInvocation(@NotNull String s, @NotNull List extends Field> fields, @NotNull Map initializers) {
+ List result = new LinkedList();
+ for (Field f : fields) {
+ final String id = f.getIdentifier().toKotlin();
+ result.add(initializers.get(id));
+ }
+ return s + "(" + AstUtil.join(result, ", ") + ")";
+ }
+
+ @NotNull
+ private Class classToClass(@NotNull PsiClass psiClass) {
+ final Set modifiers = modifiersListToModifiersSet(psiClass.getModifierList());
+ final List fields = fieldsToFieldList(psiClass.getFields(), psiClass);
+ final List typeParameters = elementsToElementList(psiClass.getTypeParameters());
+ final List implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes());
+ final List extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes());
+ final IdentifierImpl name = new IdentifierImpl(psiClass.getName());
+ final List baseClassParams = new LinkedList();
+
+ List members = getMembers(psiClass);
+
+ // we try to find super() call and generate class declaration like that: class A(name: String, i : Int) : Base(name)
+ final SuperVisitor visitor = new SuperVisitor();
+ psiClass.accept(visitor);
+ final HashSet resolvedSuperCallParameters = visitor.getResolvedSuperCallParameters();
+ if (resolvedSuperCallParameters.size() == 1) {
+ baseClassParams.addAll(
+ expressionsToExpressionList(
+ resolvedSuperCallParameters.toArray(new PsiExpressionList[1])[0].getExpressions()
+ )
+ );
+ }
+
+ // we create primary constructor from all non final fields and fields without initializers
+ if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().length > 1 && getPrimaryConstructorForThisCase(psiClass) == null) {
+ final List finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields);
+ final Map initializers = new HashMap();
+
+ for (final Member m : members) {
+ // and modify secondaries
+ if (m.getKind() == INode.Kind.CONSTRUCTOR) {
+ Function f = (Function) m;
+ if (!((Constructor) f).isPrimary()) {
+ for (Field fo : finalOrWithEmptyInitializer) {
+ String init = getDefaultInitializer(fo);
+ initializers.put(fo.getIdentifier().toKotlin(), init);
+ }
+
+ final List newStatements = new LinkedList();
+
+ for (Statement s : f.getBlock().getStatements()) {
+ boolean isRemoved = false;
+
+ if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) {
+ final AssignmentExpression assignmentExpression = (AssignmentExpression) s;
+ if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
+ for (Field fo : finalOrWithEmptyInitializer) {
+ final String id = fo.getIdentifier().toKotlin();
+ if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) {
+ initializers.put(id, assignmentExpression.getRight().toKotlin());
+ isRemoved = true;
+ }
+ }
+ }
+ }
+ if (!isRemoved) {
+ newStatements.add(s);
+ }
+ }
+
+ newStatements.add(
+ 0,
+ new DummyStringExpression(
+ "val __ = " + createPrimaryConstructorInvocation(
+ name.toKotlin(),
+ finalOrWithEmptyInitializer,
+ initializers)));
+
+ f.setBlock(new Block(newStatements));
+ }
+ }
+ }
+
+ members.add(
+ new Constructor(
+ Identifier.EMPTY_IDENTIFIER,
+ Collections.emptySet(),
+ new ClassType(name),
+ Collections.emptyList(),
+ new ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
+ new Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
+ true
+ )
+ );
+ }
+
+ if (psiClass.isInterface()) {
+ return new Trait(this, name, modifiers, typeParameters, extendsTypes, Collections.emptyList(), implementsTypes, members);
+ }
+ if (psiClass.isEnum()) {
+ return new Enum(this, name, modifiers, typeParameters, Collections.emptyList(), Collections.emptyList(), implementsTypes, members);
+ }
+ return new Class(this, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
+ }
+
+ @NotNull
+ private Initializer initializerToInitializer(@NotNull PsiClassInitializer i) {
+ return new Initializer(
+ blockToBlock(i.getBody(), true),
+ modifiersListToModifiersSet(i.getModifierList())
+ );
+ }
+
+ @NotNull
+ public static String getDefaultInitializer(@NotNull Field f) {
+ if (f.getType().isNullable()) {
+ return "null";
+ }
+ else {
+ final String typeToKotlin = f.getType().toKotlin();
+ if (typeToKotlin.equals("Boolean")) return "false";
+ if (typeToKotlin.equals("Char")) return "' '";
+ if (typeToKotlin.equals("Double")) return "0." + OperatorConventions.DOUBLE + "()";
+ if (typeToKotlin.equals("Float")) return "0." + OperatorConventions.FLOAT + "()";
+ return "0";
+ }
+ }
+
+ @NotNull
+ private List fieldsToFieldList(@NotNull PsiField[] fields, PsiClass psiClass) {
+ List result = new LinkedList();
+ for (PsiField f : fields) result.add(fieldToField(f, psiClass));
+ return result;
+ }
+
+ @NotNull
+ private Field fieldToField(@NotNull PsiField field, PsiClass psiClass) {
+ Set modifiers = modifiersListToModifiersSet(field.getModifierList());
+ if (field instanceof PsiEnumConstant) // TODO: remove instanceof
+ {
+ return new EnumConstant(
+ new IdentifierImpl(field.getName()), // TODO
+ modifiers,
+ typeToType(field.getType()),
+ elementToElement(((PsiEnumConstant) field).getArgumentList())
+ );
+ }
+ return new Field(
+ new IdentifierImpl(field.getName()), // TODO
+ modifiers,
+ typeToType(field.getType()),
+ createSureCallOnlyForChain(field.getInitializer(), field.getType()), // TODO: add modifiers
+ countWritingAccesses(field, psiClass)
+ );
+ }
+
+ @Nullable
+ private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) {
+ ThisVisitor tv = new ThisVisitor();
+ psiClass.accept(tv);
+ return tv.getPrimaryConstructor();
+ }
+
+ public static boolean isConstructorPrimary(@NotNull PsiMethod constructor) {
+ if (constructor.getParent() instanceof PsiClass) {
+ final PsiClass parent = (PsiClass) constructor.getParent();
+ if (parent.getConstructors().length == 1) {
+ return true;
+ }
+ else {
+ PsiMethod c = getPrimaryConstructorForThisCase(parent); // TODO: move up to classToClass() method
+ if (c != null && c.hashCode() == constructor.hashCode()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @NotNull
+ private static List removeEmpty(@NotNull List statements) {
+ List result = new LinkedList();
+ for (Statement s : statements)
+ if (s != Statement.EMPTY_STATEMENT && s != Expression.EMPTY_EXPRESSION) {
+ result.add(s);
+ }
+ return result;
+ }
+
+ @NotNull
+ private Function methodToFunction(@NotNull PsiMethod method) {
+ return methodToFunction(method, true);
+ }
+
+ @NotNull
+ private Function methodToFunction(@NotNull PsiMethod method, boolean notEmpty) {
+ if (isOverrideObjectDirect(method)) {
+ dispatcher.setExpressionVisitor(new ExpressionVisitorForDirectObjectInheritors(this));
+ }
+ else {
+ dispatcher.setExpressionVisitor(new ExpressionVisitor(this));
+ }
+
+ methodReturnType = method.getReturnType();
+
+ final IdentifierImpl identifier = new IdentifierImpl(method.getName());
+ final Type returnType = typeToType(method.getReturnType(), ConverterUtil.isAnnotatedAsNotNull(method.getModifierList()));
+ final Block body = hasFlag(J2KConverterFlags.SKIP_BODIES)
+ ? Block.EMPTY_BLOCK
+ : blockToBlock(method.getBody(), notEmpty); // #TODO
+ final Element params = createFunctionParameters(method);
+ final List typeParameters = elementsToElementList(method.getTypeParameters());
+
+ final Set modifiers = modifiersListToModifiersSet(method.getModifierList());
+ if (isOverrideAnyMethodExceptMethodsFromObject(method)) {
+ modifiers.add(Modifier.OVERRIDE);
+ }
+ if (method.getParent() instanceof PsiClass && ((PsiClass) method.getParent()).isInterface()) {
+ modifiers.remove(Modifier.ABSTRACT);
+ }
+ if (isNotOpenMethod(method)) {
+ modifiers.add(Modifier.NOT_OPEN);
+ }
+
+ if (method.isConstructor()) { // TODO: simplify
+ boolean isPrimary = isConstructorPrimary(method);
+ return new Constructor(
+ identifier,
+ modifiers,
+ returnType,
+ typeParameters,
+ params,
+ new Block(removeEmpty(body.getStatements()), false),
+ isPrimary
+ );
+ }
+ return new Function(
+ identifier,
+ modifiers,
+ returnType,
+ typeParameters,
+ params,
+ body
+ );
+ }
+
+ @NotNull
+ private ParameterList createFunctionParameters(@NotNull PsiMethod method) {
+ List result = new LinkedList();
+ for (PsiParameter parameter : method.getParameterList().getParameters()) {
+ result.add(new Parameter(
+ new IdentifierImpl(parameter.getName()),
+ typeToType(parameter.getType(), ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())),
+ ConverterUtil.isReadOnly(parameter, method.getBody())
+ ));
+ }
+ return new ParameterList(result);
+ }
+
+ private static boolean isNotOpenMethod(@NotNull final PsiMethod method) {
+ if (method.getParent() instanceof PsiClass) {
+ final PsiModifierList parentModifierList = ((PsiClass) method.getParent()).getModifierList();
+ if ((parentModifierList != null && parentModifierList.hasExplicitModifier(Modifier.FINAL)) || ((PsiClass) method.getParent()).isEnum()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isOverrideAnyMethodExceptMethodsFromObject(@NotNull PsiMethod method) {
+ boolean counter = normalCase(method);
+ if (counter) {
+ return true;
+ }
+ if (isInheritFromObject(method)) {
+ return caseForObject(method);
+ }
+ return false;
+ }
+
+ private boolean caseForObject(@NotNull PsiMethod method) {
+ PsiClass containing = method.getContainingClass();
+ if (containing != null) {
+ for (PsiClassType s : containing.getSuperTypes()) {
+ String canonicalText = s.getCanonicalText();
+ if (!canonicalText.equals(JAVA_LANG_OBJECT) && !getClassIdentifiers().contains(canonicalText)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean normalCase(@NotNull PsiMethod method) {
+ int counter = 0;
+ for (HierarchicalMethodSignature s : method.getHierarchicalMethodSignature().getSuperSignatures()) {
+ PsiClass containingClass = s.getMethod().getContainingClass();
+ String qualifiedName = containingClass != null ? containingClass.getQualifiedName() : "";
+ if (qualifiedName != null && !qualifiedName.equals(JAVA_LANG_OBJECT)) {
+ counter++;
+ }
+ }
+ return counter > 0;
+ }
+
+ private static boolean isInheritFromObject(@NotNull PsiMethod method) {
+ List superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
+ for (HierarchicalMethodSignature s : superSignatures) {
+ PsiClass containingClass = s.getMethod().getContainingClass();
+ String qualifiedName = containingClass != null ? containingClass.getQualifiedName() : "";
+ if (qualifiedName != null && qualifiedName.equals(JAVA_LANG_OBJECT)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean isOverrideObjectDirect(@NotNull final PsiMethod method) {
+ List superSignatures = method.getHierarchicalMethodSignature().getSuperSignatures();
+ if (superSignatures.size() == 1) {
+ final PsiClass containingClass = superSignatures.get(0).getMethod().getContainingClass();
+ final String qualifiedName = containingClass != null ? containingClass.getQualifiedName() : "";
+ if (qualifiedName != null && qualifiedName.equals(JAVA_LANG_OBJECT)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @NotNull
+ public Block blockToBlock(@Nullable PsiCodeBlock block, boolean notEmpty) {
+ if (block == null) return Block.EMPTY_BLOCK;
+ return new Block(statementsToStatementList(block.getStatements()), notEmpty);
+ }
+
+ @NotNull
+ public Block blockToBlock(@Nullable PsiCodeBlock block) {
+ return blockToBlock(block, true);
+ }
+
+ @NotNull
+ public List statementsToStatementList(@NotNull PsiStatement[] statements) {
+ List result = new LinkedList();
+ for (PsiStatement t : statements) result.add(statementToStatement(t));
+ return result;
+ }
+
+ @NotNull
+ public List statementsToStatementList(@NotNull List statements) {
+ List result = new LinkedList();
+ for (PsiStatement t : statements) result.add(statementToStatement(t));
+ return result;
+ }
+
+ @NotNull
+ public Statement statementToStatement(@Nullable PsiStatement s) {
+ if (s == null) return Statement.EMPTY_STATEMENT;
+ final StatementVisitor statementVisitor = new StatementVisitor(this);
+ s.accept(statementVisitor);
+ return statementVisitor.getResult();
+ }
+
+ @NotNull
+ public List expressionsToExpressionList(@NotNull PsiExpression[] expressions) {
+ List result = new LinkedList();
+ for (PsiExpression e : expressions) result.add(expressionToExpression(e));
+ return result;
+ }
+
+ @NotNull
+ public Expression expressionToExpression(@Nullable PsiExpression e) {
+ if (e == null) return Expression.EMPTY_EXPRESSION;
+ final ExpressionVisitor expressionVisitor = dispatcher.getExpressionVisitor();
+ e.accept(expressionVisitor);
+ return expressionVisitor.getResult();
+ }
+
+ @NotNull
+ public Element elementToElement(@Nullable PsiElement e) {
+ if (e == null) return Element.EMPTY_ELEMENT;
+ final ElementVisitor elementVisitor = new ElementVisitor(this);
+ e.accept(elementVisitor);
+ return elementVisitor.getResult();
+ }
+
+ @NotNull
+ public List elementsToElementList(@NotNull PsiElement[] elements) {
+ List result = new LinkedList();
+ for (PsiElement e : elements) result.add(elementToElement(e));
+ return result;
+ }
+
+ @NotNull
+ public Type typeToType(@Nullable PsiType type) {
+ if (type == null) return Type.EMPTY_TYPE;
+ TypeVisitor typeVisitor = new TypeVisitor(this);
+ type.accept(typeVisitor);
+ return typeVisitor.getResult();
+ }
+
+ @NotNull
+ public List typesToTypeList(@NotNull PsiType[] types) {
+ List result = new LinkedList();
+ for (PsiType t : types) result.add(typeToType(t));
+ return result;
+ }
+
+ @NotNull
+ public Type typeToType(PsiType type, boolean notNull) {
+ Type result = typeToType(type);
+ if (notNull) {
+ result.convertedToNotNull();
+ }
+ return result;
+ }
+
+ @NotNull
+ private List typesToNotNullableTypeList(@NotNull PsiType[] types) {
+ List result = new LinkedList(typesToTypeList(types));
+ for (Type p : result) p.convertedToNotNull();
+ return result;
+ }
+
+ @NotNull
+ private static List importsToImportList(@NotNull PsiImportStatementBase[] imports) {
+ List result = new LinkedList();
+ for (PsiImportStatementBase i : imports) {
+ Import anImport = importToImport(i);
+ String name = anImport.getName();
+ if (!name.isEmpty() && !NOT_NULL_ANNOTATIONS.contains(name)) {
+ result.add(anImport);
+ }
+ }
+ return result;
+ }
+
+ @NotNull
+ private static Import importToImport(@NotNull PsiImportStatementBase i) {
+ final PsiJavaCodeReferenceElement reference = i.getImportReference();
+ if (reference != null) {
+ return new Import(quoteKeywords(reference.getQualifiedName()) + (i.isOnDemand() ? ".*" : ""));
+ }
+ return new Import("");
+ }
+
+ @NotNull
+ public List parametersToParameterList(@NotNull PsiParameter[] parameters) {
+ List result = new LinkedList();
+ for (PsiParameter t : parameters) result.add(parameterToParameter(t));
+ return result;
+ }
+
+ @NotNull
+ public Parameter parameterToParameter(@NotNull PsiParameter parameter) {
+ return new Parameter(
+ new IdentifierImpl(parameter.getName()),
+ typeToType(parameter.getType(), ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList()))
+ );
+ }
+
+ @NotNull
+ public static Identifier identifierToIdentifier(@Nullable PsiIdentifier identifier) {
+ if (identifier == null) return Identifier.EMPTY_IDENTIFIER;
+ return new IdentifierImpl(identifier.getText());
+ }
+
+ @NotNull
+ public static Set modifiersListToModifiersSet(@Nullable PsiModifierList modifierList) {
+ HashSet modifiersSet = new HashSet();
+ if (modifierList != null) {
+ if (modifierList.hasExplicitModifier(PsiModifier.ABSTRACT)) modifiersSet.add(Modifier.ABSTRACT);
+ if (modifierList.hasModifierProperty(PsiModifier.FINAL)) modifiersSet.add(Modifier.FINAL);
+ if (modifierList.hasModifierProperty(PsiModifier.STATIC)) modifiersSet.add(Modifier.STATIC);
+ if (modifierList.hasExplicitModifier(PsiModifier.PUBLIC)) modifiersSet.add(Modifier.PUBLIC);
+ if (modifierList.hasExplicitModifier(PsiModifier.PROTECTED)) modifiersSet.add(Modifier.PROTECTED);
+ if (modifierList.hasExplicitModifier(PsiModifier.PACKAGE_LOCAL)) modifiersSet.add(Modifier.INTERNAL);
+ if (modifierList.hasExplicitModifier(PsiModifier.PRIVATE)) modifiersSet.add(Modifier.PRIVATE);
+ }
+ return modifiersSet;
+ }
+
+ @NotNull
+ public List createConversions(@NotNull PsiCallExpression expression) {
+ PsiExpressionList argumentList = expression.getArgumentList();
+ PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[]{};
+ List conversions = new LinkedList();
+ //noinspection UnusedDeclaration
+ for (final PsiExpression a : arguments) {
+ conversions.add("");
+ }
+
+ PsiMethod resolve = expression.resolveMethod();
+ if (resolve != null) {
+ List expectedTypes = new LinkedList();
+ List actualTypes = new LinkedList();
+
+ for (PsiParameter p : resolve.getParameterList().getParameters())
+ expectedTypes.add(p.getType());
+
+ for (PsiExpression e : arguments)
+ actualTypes.add(e.getType());
+
+ if (conversions.size() == actualTypes.size() && actualTypes.size() == expectedTypes.size()) {
+ for (int i = 0; i < actualTypes.size(); i++)
+ conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));
+ }
+ }
+ return conversions;
+ }
+
+ @NotNull
+ public List createConversions(@NotNull PsiPolyadicExpression expression, PsiType expectedType) {
+ PsiExpression[] arguments = expression.getOperands();
+ int length = arguments.length;
+ List conversions = new LinkedList();
+
+ List expectedTypes = Collections.nCopies(length, expectedType);
+ List actualTypes = new LinkedList();
+
+ for (PsiExpression e : arguments)
+ actualTypes.add(e.getType());
+
+ assert actualTypes.size() == expectedTypes.size() : "The type list must have the same length";
+
+ for (int i = 0; i < actualTypes.size(); i++)
+ conversions.add(i, createConversionForExpression(arguments[i], expectedTypes.get(i)));
+
+ return conversions;
+ }
+
+ @NotNull
+ private String createConversionForExpression(@Nullable PsiExpression expression, @NotNull PsiType expectedType) {
+ String conversion = "";
+ if (expression != null) {
+ PsiType actualType = expression.getType();
+ boolean isPrimitiveTypeOrNull = actualType == null || Node.PRIMITIVE_TYPES.contains(actualType.getCanonicalText());
+ boolean isRef = (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression) expression).isQualified() || expression instanceof PsiMethodCallExpression);
+ boolean containsQuestDot = expressionToExpression(expression).toKotlin().contains("?.");
+
+ if (isPrimitiveTypeOrNull && isRef && containsQuestDot) {
+ conversion += ".sure()";
+ }
+
+ if (actualType != null) {
+ if (isConversionNeeded(actualType, expectedType)) {
+ conversion += getPrimitiveTypeConversion(expectedType.getCanonicalText());
+ }
+ }
+ }
+ return conversion;
+ }
+
+ private static boolean isConversionNeeded(@Nullable final PsiType actual, @Nullable final PsiType expected) {
+ if (actual == null || expected == null) {
+ return false;
+ }
+ Map typeMap = new HashMap();
+ typeMap.put(JAVA_LANG_BYTE, "byte");
+ typeMap.put(JAVA_LANG_SHORT, "short");
+ typeMap.put(JAVA_LANG_INTEGER, "int");
+ typeMap.put(JAVA_LANG_LONG, "long");
+ typeMap.put(JAVA_LANG_FLOAT, "float");
+ typeMap.put(JAVA_LANG_DOUBLE, "double");
+ typeMap.put(JAVA_LANG_CHARACTER, "char");
+ String expectedStr = expected.getCanonicalText();
+ String actualStr = actual.getCanonicalText();
+ boolean o1 = AstUtil.getOrElse(typeMap, actualStr, "").equals(expectedStr);
+ boolean o2 = AstUtil.getOrElse(typeMap, expectedStr, "").equals(actualStr);
+ return !actualStr.equals(expectedStr) && (!(o1 ^ o2));
+ }
+
+ @NotNull
+ private static String getPrimitiveTypeConversion(@NotNull String type) {
+ Map conversions = new HashMap();
+ conversions.put("byte", BYTE);
+ conversions.put("short", SHORT);
+ conversions.put("int", INT);
+ conversions.put("long", LONG);
+ conversions.put("float", FLOAT);
+ conversions.put("double", DOUBLE);
+ conversions.put("char", CHAR);
+
+ conversions.put(JAVA_LANG_BYTE, BYTE);
+ conversions.put(JAVA_LANG_SHORT, SHORT);
+ conversions.put(JAVA_LANG_INTEGER, INT);
+ conversions.put(JAVA_LANG_LONG, LONG);
+ conversions.put(JAVA_LANG_FLOAT, FLOAT);
+ conversions.put(JAVA_LANG_DOUBLE, DOUBLE);
+ conversions.put(JAVA_LANG_CHARACTER, CHAR);
+
+ if (conversions.containsKey(type)) {
+ return "." + conversions.get(type) + "()";
+ }
+ return "";
+ }
+
+// @NotNull
+// private static String applyConversion(Expression expression, String conversion) {
+// if (conversion.isEmpty())
+// return expression.toKotlin();
+// return "(" + expression.toKotlin() + ")" + conversion;
+// }
+
+ @NotNull
+ public SureCallChainExpression createSureCallOnlyForChain(@Nullable PsiExpression expression, @NotNull PsiType type) {
+ String conversion = (expression != null && (expression instanceof PsiReferenceExpression || expression instanceof PsiMethodCallExpression))
+ ?
+ createConversionForExpression(expression, type)
+ : "";
+ return new SureCallChainExpression(expressionToExpression(expression), conversion);
+ }
+
+}
diff --git a/src/org/jetbrains/jet/j2k/ConverterUtil.java b/src/org/jetbrains/jet/j2k/ConverterUtil.java
new file mode 100644
index 00000000000..d4f536c78d8
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ConverterUtil.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.MessageFormat;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.jetbrains.jet.j2k.Converter.NOT_NULL_ANNOTATIONS;
+
+/**
+ * @author ignatov
+ */
+public class ConverterUtil {
+ private ConverterUtil() {
+ }
+
+ @NotNull
+ public static String createMainFunction(@NotNull PsiFile file) {
+ List> classNamesWithMains = new LinkedList>();
+
+ for (PsiClass c : ((PsiJavaFile) file).getClasses()) {
+ PsiMethod main = findMainMethod(c);
+ if (main != null) {
+ classNamesWithMains.add(new Pair(c.getName(), main));
+ }
+ }
+ if (classNamesWithMains.size() > 0) {
+ String className = classNamesWithMains.get(0).getFirst();
+ return MessageFormat.format("fun main(args : Array?) = {0}.main(args)", className);
+ }
+ return "";
+ }
+
+ @Nullable
+ private static PsiMethod findMainMethod(@NotNull PsiClass aClass) {
+ if (isMainClass(aClass)) {
+ final PsiMethod[] mainMethods = aClass.findMethodsByName("main", false);
+ return findMainMethod(mainMethods);
+ }
+ return null;
+ }
+
+ @Nullable
+ private static PsiMethod findMainMethod(@NotNull PsiMethod[] mainMethods) {
+ for (PsiMethod mainMethod : mainMethods) {
+ if (isMainMethod(mainMethod)) return mainMethod;
+ }
+ return null;
+ }
+
+ private static boolean isMainClass(@NotNull PsiClass psiClass) {
+ if (psiClass instanceof PsiAnonymousClass) return false;
+ if (psiClass.isInterface()) return false;
+ return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC);
+ }
+
+ public static boolean isMainMethod(@Nullable PsiMethod method) {
+ if (method == null || method.getContainingClass() == null) return false;
+ if (PsiType.VOID != method.getReturnType()) return false;
+ if (!method.hasModifierProperty(PsiModifier.STATIC)) return false;
+ if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return false;
+ final PsiParameter[] parameters = method.getParameterList().getParameters();
+ if (parameters.length != 1) return false;
+ final PsiType type = parameters[0].getType();
+ if (!(type instanceof PsiArrayType)) return false;
+ final PsiType componentType = ((PsiArrayType) type).getComponentType();
+ return componentType.equalsToText("java.lang.String");
+ }
+
+ public static int countWritingAccesses(@Nullable PsiElement element, @Nullable PsiElement container) {
+ int counter = 0;
+ if (container != null) {
+ ReferenceCollector visitor = new ReferenceCollector();
+ container.accept(visitor);
+ for (PsiReferenceExpression e : visitor.getCollectedReferences())
+ if (e.isReferenceTo(element) && PsiUtil.isAccessedForWriting(e)) {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ static boolean isReadOnly(PsiElement element, PsiElement container) {
+ return countWritingAccesses(element, container) == 0;
+ }
+
+ public static boolean isAnnotatedAsNotNull(@Nullable PsiModifierList modifierList) {
+ if (modifierList != null) {
+ PsiAnnotation[] annotations = modifierList.getAnnotations();
+ for (PsiAnnotation a : annotations) {
+ String qualifiedName = a.getQualifiedName();
+ if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ static class ReferenceCollector extends JavaRecursiveElementVisitor {
+ public List getCollectedReferences() {
+ return myCollectedReferences;
+ }
+
+ private List myCollectedReferences = new LinkedList();
+
+ @Override
+ public void visitReferenceExpression(PsiReferenceExpression expression) {
+ super.visitReferenceExpression(expression);
+ myCollectedReferences.add(expression);
+ }
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/J2KConverterFlags.java b/src/org/jetbrains/jet/j2k/J2KConverterFlags.java
new file mode 100644
index 00000000000..8a812ac664b
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/J2KConverterFlags.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k;
+
+/**
+ * @author abreslav
+ */
+public enum J2KConverterFlags {
+ FULLY_QUALIFIED_TYPE_NAMES,
+ SKIP_BODIES,
+ SKIP_NON_PUBLIC_MEMBERS
+}
diff --git a/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java b/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java
new file mode 100644
index 00000000000..f65d30a9b31
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/JavaToKotlinCli.java
@@ -0,0 +1,147 @@
+//package org.jetbrains.jet.j2k;
+//
+//import com.intellij.psi.PsiFile;
+//import com.intellij.psi.PsiJavaFile;
+//import org.apache.commons.cli.*;
+//import org.jetbrains.annotations.NotNull;
+//import org.jetbrains.annotations.Nullable;
+//
+//import java.io.File;
+//import java.io.FileNotFoundException;
+//import java.io.IOException;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.List;
+//import java.util.logging.Logger;
+//import java.util.regex.Pattern;
+//
+//import static org.apache.commons.io.FileUtils.readFileToString;
+//import static org.apache.commons.io.FileUtils.writeStringToFile;
+//
+///**
+// * @author ignatov
+// */
+//@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"})
+//public class JavaToKotlinCli {
+// private static final Logger myLogger = Logger.getAnonymousLogger();
+//
+// private JavaToKotlinCli() {
+// }
+//
+// public static void main(String[] args) {
+// CommandLineParser parser = new BasicParser();
+// Options options = new Options()
+// .addOption("h", "help", false, "Print usage information")
+// .addOption("f", "from", true, "Directory with Java sources")
+// .addOption("t", "to", true, "Directory with Kotlin sources")
+// .addOption("p", "public-only", false, "Only public and protected members")
+// .addOption("fqn", "fqn", false, "Full qualified names")
+// .addOption("d", "declarations-only", false, "Declarations only")
+// ;
+//
+// try {
+// CommandLine commandLine = parser.parse(options, args);
+//
+// if (commandLine.hasOption("help"))
+// showHelpAndExit();
+//
+// if (commandLine.hasOption("from") && commandLine.hasOption("to")) {
+// String from = commandLine.getOptionValue("from");
+// String to = commandLine.getOptionValue("to");
+//
+// for (Option o : commandLine.getOptions()) {
+// Converter.addFlag(o.getLongOpt());
+// }
+//
+// if (!from.isEmpty() && !to.isEmpty())
+// convertSourceTree(from, to);
+// else
+// showHelpAndExit();
+// } else
+// showHelpAndExit();
+// } catch (ParseException e) {
+// e.printStackTrace();
+// }
+// }
+//
+// @SuppressWarnings("ResultOfMethodCallIgnored")
+// private static void convertSourceTree(String javaPath, String kotlinPath) {
+// try {
+// File javaDir = new File(javaPath);
+// File kotlinDir = new File(kotlinPath);
+//
+// if (kotlinDir.exists())
+// kotlinDir.delete();
+//
+// if (!kotlinDir.exists() && !kotlinDir.mkdir())
+// myLogger.warning("Creation failed: " + kotlinDir.getAbsolutePath());
+//
+// for (File f : getJavaFiles(javaDir.getAbsolutePath())) {
+// String relative = javaDir.toURI().relativize(f.toURI()).getPath().replace(".java", ".kt");
+// File file = new File(kotlinPath, relative);
+//
+// if (file.exists())
+// file.delete();
+//
+// if (f.isDirectory())
+// if (!file.exists() && !file.mkdir())
+// myLogger.warning("Creation failed: " + file.getAbsolutePath());
+//
+// if (f.isFile()) {
+// writeStringToFile(file, fileToKotlin(f));
+// }
+// }
+// } catch (FileNotFoundException e) {
+// e.printStackTrace();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// }
+//
+// @NotNull
+// private static String fileToKotlin(File f) throws IOException {
+// final String javaCode = readJavaFileToString(f);
+// return generateKotlinCode(JavaToKotlinTranslator.createFile(JavaToKotlinTranslator.setUpJavaCoreEnvironment(), javaCode));
+// }
+//
+// @NotNull
+// private static String generateKotlinCode(@Nullable PsiFile file) {
+// if (file != null && file instanceof PsiJavaFile) {
+// JavaToKotlinTranslator.setClassIdentifiers(file);
+// return JavaToKotlinTranslator.prettify(Converter.fileToFile((PsiJavaFile) file).toKotlin());
+// }
+// return "";
+// }
+//
+// @NotNull
+// private static String readJavaFileToString(@NotNull File javaFile) throws IOException {
+// return Pattern.compile("\\s*/\\*.*\\*/", Pattern.DOTALL).matcher(readFileToString(javaFile)).replaceAll("");
+// }
+//
+// private static void showHelpAndExit() {
+// System.err.println("Usage: java -jar java2kotlin.jar -f -t ");
+// System.exit(1);
+// }
+//
+// static public List getJavaFiles(String startDirName) throws FileNotFoundException {
+// return getJavaFiles(new File(startDirName));
+// }
+//
+// private static List getJavaFiles(File start) throws FileNotFoundException {
+// List result = new ArrayList();
+//
+// if (start.isFile())
+// return Arrays.asList(start);
+//
+// for (File file : Arrays.asList(start.listFiles())) {
+// if ((file.isFile() && file.getName().endsWith(".java")) || file.isDirectory())
+// result.add(file);
+//
+// if (file.isDirectory()) {
+// List deeperList = getJavaFiles(file);
+// result.addAll(deeperList);
+// }
+// }
+// return result;
+// }
+//}
\ No newline at end of file
diff --git a/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java b/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java
new file mode 100644
index 00000000000..c5c95a11a6b
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.jet.j2k;
+
+import com.intellij.core.JavaCoreEnvironment;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileFactory;
+import com.intellij.psi.PsiJavaFile;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.j2k.visitors.ClassVisitor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * @author ignatov
+ */
+public class JavaToKotlinTranslator {
+ private JavaToKotlinTranslator() {
+ }
+
+ private static final Converter CONVERTER = new Converter();
+
+ @Nullable
+ private static PsiFile createFile(@NotNull String text) {
+ JavaCoreEnvironment javaCoreEnvironment = setUpJavaCoreEnvironment();
+ return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
+ "test.java", JavaLanguage.INSTANCE, text
+ );
+ }
+
+ @Nullable
+ static PsiFile createFile(@NotNull JavaCoreEnvironment javaCoreEnvironment, @NotNull String text) {
+ return PsiFileFactory.getInstance(javaCoreEnvironment.getProject()).createFileFromText(
+ "test.java", JavaLanguage.INSTANCE, text
+ );
+ }
+
+ @NotNull
+ static JavaCoreEnvironment setUpJavaCoreEnvironment() {
+ JavaCoreEnvironment javaCoreEnvironment = new JavaCoreEnvironment(new Disposable() {
+ @Override
+ public void dispose() {
+ }
+ });
+
+ javaCoreEnvironment.addToClasspath(findRtJar());
+ File annotations = findAnnotations();
+ if (annotations != null && annotations.exists()) {
+ javaCoreEnvironment.addToClasspath(annotations);
+ }
+ return javaCoreEnvironment;
+ }
+
+ @NotNull
+ static String prettify(@Nullable String code) {
+ if (code == null) {
+ return "";
+ }
+ return code
+ .trim()
+ .replaceAll("\r\n", "\n")
+ .replaceAll(" \n", "\n")
+ .replaceAll("\n ", "\n")
+ .replaceAll("\n+", "\n")
+ .replaceAll(" +", " ")
+ .trim()
+ ;
+ }
+
+ @Nullable
+ private static File findRtJar() {
+ String javaHome = System.getenv("JAVA_HOME");
+ File rtJar;
+ if (javaHome == null) {
+ rtJar = findActiveRtJar(true);
+
+ if (rtJar == null) {
+ throw new SetupJavaCoreEnvironmentException("JAVA_HOME environment variable needs to be defined");
+ }
+ }
+ else {
+ rtJar = findRtJar(javaHome);
+ }
+
+ if (rtJar == null || !rtJar.exists()) {
+ rtJar = findActiveRtJar(true);
+
+ if ((rtJar == null || !rtJar.exists())) {
+ throw new SetupJavaCoreEnvironmentException("No rt.jar found under JAVA_HOME=" + javaHome);
+ }
+ }
+ return rtJar;
+ }
+
+ @Nullable
+ private static File findRtJar(String javaHome) {
+ File rtJar = new File(javaHome, "jre/lib/rt.jar");
+ if (rtJar.exists()) {
+ return rtJar;
+ }
+
+ File classesJar = new File(new File(javaHome).getParentFile().getAbsolutePath(), "Classes/classes.jar");
+ if (classesJar.exists()) {
+ return classesJar;
+ }
+ return null;
+ }
+
+ @Nullable
+ private static File findAnnotations() {
+ ClassLoader classLoader = JavaToKotlinTranslator.class.getClassLoader();
+ while (classLoader != null) {
+ if (classLoader instanceof URLClassLoader) {
+ URLClassLoader loader = (URLClassLoader) classLoader;
+ for (URL url : loader.getURLs())
+ if ("file".equals(url.getProtocol()) && url.getFile().endsWith("/annotations.jar")) {
+ return new File(url.getFile());
+ }
+ }
+ classLoader = classLoader.getParent();
+ }
+ return null;
+ }
+
+ @Nullable
+ private static File findActiveRtJar(boolean failOnError) {
+ ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+ if (systemClassLoader instanceof URLClassLoader) {
+ URLClassLoader loader = (URLClassLoader) systemClassLoader;
+ for (URL url : loader.getURLs()) {
+ if ("file".equals(url.getProtocol())) {
+ if (url.getFile().endsWith("/lib/rt.jar")) {
+ return new File(url.getFile());
+ }
+ if (url.getFile().endsWith("/Classes/classes.jar")) {
+ return new File(url.getFile()).getAbsoluteFile();
+ }
+ }
+ }
+ if (failOnError) {
+ throw new SetupJavaCoreEnvironmentException("Could not find rt.jar in system class loader: " + StringUtil.join(loader.getURLs(), new Function() {
+ @NotNull
+ @Override
+ public String fun(@NotNull URL url) {
+ return url.toString() + "\n";
+ }
+ }, ", "));
+ }
+ }
+ else if (failOnError) {
+ throw new SetupJavaCoreEnvironmentException("System class loader is not an URLClassLoader: " + systemClassLoader);
+ }
+ return null;
+ }
+
+ static void setClassIdentifiers(@NotNull Converter converter, @NotNull PsiElement psiFile) {
+ ClassVisitor c = new ClassVisitor();
+ psiFile.accept(c);
+ converter.clearClassIdentifiers();
+ converter.setClassIdentifiers(c.getClassIdentifiers());
+ }
+
+ @NotNull
+ static String generateKotlinCode(@NotNull String javaCode) {
+ PsiFile file = createFile(javaCode);
+ if (file != null && file instanceof PsiJavaFile) {
+ setClassIdentifiers(CONVERTER, file);
+ return prettify(CONVERTER.fileToFile((PsiJavaFile) file).toKotlin());
+ }
+ return "";
+ }
+
+ @NotNull
+ static String generateKotlinCodeWithCompatibilityImport(@NotNull String javaCode) {
+ PsiFile file = createFile(javaCode);
+ if (file != null && file instanceof PsiJavaFile) {
+ setClassIdentifiers(CONVERTER, file);
+ return prettify(CONVERTER.fileToFileWithCompatibilityImport((PsiJavaFile) file).toKotlin());
+ }
+ return "";
+ }
+
+ public static void main(@NotNull String[] args) throws IOException {
+ //noinspection UseOfSystemOutOrSystemErr
+ final PrintStream out = System.out;
+ if (args.length == 1) {
+ String kotlinCode = "";
+ try {
+ kotlinCode = generateKotlinCode(args[0]);
+ } catch (Exception e) {
+ out.println("EXCEPTION: " + e.getMessage());
+ }
+ if (kotlinCode.isEmpty()) {
+ out.println("EXCEPTION: generated code is empty.");
+ }
+ else {
+ out.println(kotlinCode);
+ }
+ }
+ else {
+ out.println("EXCEPTION: wrong number of arguments (should be 1).");
+ }
+ }
+
+ public static String translateToKotlin(String code) {
+ return generateKotlinCode(code);
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/SetupJavaCoreEnvironmentException.java b/src/org/jetbrains/jet/j2k/SetupJavaCoreEnvironmentException.java
new file mode 100644
index 00000000000..af20ad4d7fd
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/SetupJavaCoreEnvironmentException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k;
+
+/**
+ * @author ignatov
+ */
+public class SetupJavaCoreEnvironmentException extends RuntimeException {
+ public SetupJavaCoreEnvironmentException(String s) {
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java
new file mode 100644
index 00000000000..8a547b26aab
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/AnonymousClass.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.j2k.Converter;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author ignatov
+ */
+public class AnonymousClass extends Class {
+ public AnonymousClass(Converter converter, List members) {
+ super(converter,
+ new IdentifierImpl("anonClass"),
+ Collections.emptySet(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ getMembers(members, converter)
+ );
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return bodyToKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ArrayAccessExpression.kt b/src/org/jetbrains/jet/j2k/ast/ArrayAccessExpression.kt
new file mode 100644
index 00000000000..ae5913a512a
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ArrayAccessExpression.kt
@@ -0,0 +1,7 @@
+package org.jetbrains.jet.j2k.ast
+
+public open class ArrayAccessExpression(val expression : Expression, val index : Expression) : Expression() {
+ public override fun toKotlin() : String {
+ return expression.toKotlin() + "[" + index.toKotlin() + "]"
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt b/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt
new file mode 100644
index 00000000000..bc0b6ed98a5
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt
@@ -0,0 +1,62 @@
+package org.jetbrains.jet.j2k.ast
+
+import org.jetbrains.jet.j2k.util.AstUtil
+import org.jetbrains.jet.lang.types.expressions.OperatorConventions
+import java.util.*
+
+public open class ArrayInitializerExpression(val `type` : Type, val initializers : List) : Expression() {
+ public override fun toKotlin() : String {
+ return createArrayFunction() + "(" + createInitializers() + ")"
+ }
+
+ private fun createInitializers(): String {
+ return initializers.map { explicitConvertIfNeeded(it) }.makeString(", ")
+ }
+
+ private fun createArrayFunction() : String {
+ var sType : String? = innerTypeStr()
+ if (Node.PRIMITIVE_TYPES.contains(sType))
+ {
+ return sType + "Array"
+ }
+
+ return AstUtil.lowerFirstCharacter(`type`.convertedToNotNull().toKotlin())
+ }
+
+ private fun innerTypeStr() : String {
+ return `type`.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase()
+ }
+
+ private fun explicitConvertIfNeeded(i : Expression) : String {
+ val doubleOrFloatTypes = hashSet("double", "float", "java.lang.double", "java.lang.float")
+ val afterReplace : String = innerTypeStr().replace(">", "").replace("<", "").replace("?", "")
+ if (doubleOrFloatTypes.contains(afterReplace))
+ {
+ if (i.getKind() == INode.Kind.LITERAL)
+ {
+ if (i.toKotlin().contains("."))
+ {
+ return i.toKotlin()
+ }
+
+ return i.toKotlin() + ".0"
+ }
+
+ return "(" + i.toKotlin() + ")" + getConversion(afterReplace)
+ }
+
+ return i.toKotlin()
+ }
+
+ class object {
+ private open fun getConversion(afterReplace : String) : String {
+ if (afterReplace.contains("double").sure())
+ return "." + OperatorConventions.DOUBLE + "()"
+
+ if (afterReplace.contains("float").sure())
+ return "." + OperatorConventions.FLOAT + "()"
+
+ return ""
+ }
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ArrayType.java b/src/org/jetbrains/jet/j2k/ast/ArrayType.java
new file mode 100644
index 00000000000..6c651bd39aa
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ArrayType.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ArrayType extends Type {
+ private final Type myType;
+
+ public ArrayType(Type type) {
+ myType = type;
+ }
+
+ public Type getInnerType() {
+ return myType;
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.ARRAY_TYPE;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (PRIMITIVE_TYPES.contains(myType.toKotlin().toLowerCase())) {
+ return myType.toKotlin() + "Array" + isNullableStr(); // returns IntArray, BooleanArray, etc.
+ }
+ return "Array" + "<" + myType.toKotlin() + ">" + isNullableStr();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt b/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt
new file mode 100644
index 00000000000..db384ab56b9
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt
@@ -0,0 +1,48 @@
+package org.jetbrains.jet.j2k.ast
+
+import org.jetbrains.jet.j2k.util.AstUtil
+import java.util.List
+
+public open class ArrayWithoutInitializationExpression(val `type` : Type, val expressions : List) : Expression() {
+ public override fun toKotlin() : String {
+ if (`type`.getKind() == INode.Kind.ARRAY_TYPE)
+ {
+ return constructInnerType(`type` as ArrayType, expressions)
+ }
+
+ return getConstructorName(`type`)
+ }
+
+ private fun constructInnerType(hostType : ArrayType, expressions: List) : String {
+ if (expressions.size() == 1)
+ {
+ return oneDim(hostType, expressions[0])
+ }
+
+ var innerType : Type? = hostType.getInnerType()
+ if (expressions.size() > 1 && innerType?.getKind() == INode.Kind.ARRAY_TYPE)
+ {
+ return oneDim(hostType, expressions[0], "{" + constructInnerType(innerType as ArrayType, expressions.subList(1, expressions.size())) + "}")
+ }
+
+ return getConstructorName(hostType)
+ }
+
+ class object {
+ private open fun oneDim(`type` : Type, size : Expression) : String {
+ return oneDim(`type`, size, "")
+ }
+
+ private open fun oneDim(`type` : Type, size : Expression, init : String) : String {
+ var commaWithInit : String? = (if (init.isEmpty())
+ ""
+ else
+ ", " + init)
+ return getConstructorName(`type`) + "(" + size.toKotlin() + commaWithInit + ")"
+ }
+
+ private open fun getConstructorName(`type` : Type) : String {
+ return AstUtil.replaceLastQuest(`type`.toKotlin())
+ }
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/AssertStatement.kt b/src/org/jetbrains/jet/j2k/ast/AssertStatement.kt
new file mode 100644
index 00000000000..bc6df0f6986
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/AssertStatement.kt
@@ -0,0 +1,12 @@
+package org.jetbrains.jet.j2k.ast
+
+
+public open class AssertStatement(val condition : Expression, val detail : Expression) : Statement() {
+ public override fun toKotlin() : String {
+ var detail : String? = (if (detail != Expression.EMPTY_EXPRESSION)
+ "(" + detail.toKotlin() + ")"
+ else
+ "")
+ return "assert" + detail + " {" + condition.toKotlin() + "}"
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.kt b/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.kt
new file mode 100644
index 00000000000..62edeb5b35b
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/AssignmentExpression.kt
@@ -0,0 +1,12 @@
+package org.jetbrains.jet.j2k.ast
+
+
+public open class AssignmentExpression(val left : Expression, val right : Expression, val op : String) : Expression() {
+ public override fun toKotlin() : String {
+ return left.toKotlin() + " "+ op + " "+ right.toKotlin()
+ }
+
+ public override fun getKind() : INode.Kind {
+ return INode.Kind.ASSIGNMENT_EXPRESSION
+ }
+}
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..42c7f8773cf
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/BinaryExpression.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.j2k.util.AstUtil;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author ignatov
+ */
+public class BinaryExpression extends Expression {
+ private final Expression myLeft;
+ private final Expression myRight;
+ private final String myOp;
+ private final List myConversions;
+
+ public BinaryExpression(Expression left, Expression right, String op) {
+ this(left, right, op, Arrays.asList("", ""));
+ }
+
+ public BinaryExpression(Expression left, Expression right, String op, List conversions) {
+ myLeft = left;
+ myRight = right;
+ myOp = op;
+ myConversions = conversions;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ List expressionsWithConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(Arrays.asList(myLeft, myRight)), myConversions);
+ return AstUtil.join(expressionsWithConversions, SPACE + myOp + SPACE);
+ }
+}
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..1aeb1172d9f
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Block.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 Block extends Statement {
+ @NotNull
+ public final static Block EMPTY_BLOCK = new Block();
+
+ private List myStatements;
+ private boolean myNotEmpty = false;
+
+ private Block() {
+ myStatements = new LinkedList();
+ }
+
+ public Block(List statements) {
+ myStatements = new LinkedList();
+ myStatements = statements;
+ }
+
+ public Block(List statements, boolean notEmpty) {
+ myStatements = new LinkedList();
+ myStatements = statements;
+ myNotEmpty = notEmpty;
+ }
+
+ public boolean isEmpty() {
+ return !myNotEmpty && myStatements.size() == 0;
+ }
+
+ public List getStatements() {
+ return myStatements;
+ }
+
+ @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/BreakStatement.java b/src/org/jetbrains/jet/j2k/ast/BreakStatement.java
new file mode 100644
index 00000000000..c07b2fc6db8
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/BreakStatement.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class BreakStatement extends Statement {
+ private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
+
+ public BreakStatement(Identifier label) {
+ myLabel = label;
+ }
+
+ public BreakStatement() {
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.BREAK;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (myLabel.isEmpty()) {
+ return "break";
+ }
+ return "break" + AT + myLabel.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/CallChainExpression.java b/src/org/jetbrains/jet/j2k/ast/CallChainExpression.java
new file mode 100644
index 00000000000..bd9fca6e9ba
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/CallChainExpression.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class CallChainExpression extends Expression {
+ private final Expression myExpression;
+ private final Expression myIdentifier;
+
+ public Expression getIdentifier() {
+ return myIdentifier;
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.CALL_CHAIN;
+ }
+
+ public CallChainExpression(Expression expression, Expression identifier) {
+ myExpression = expression;
+ myIdentifier = identifier;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return myIdentifier.isNullable();
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (!myExpression.isEmpty()) {
+ if (myExpression.isNullable()) {
+ return myExpression.toKotlin() + QUESTDOT + myIdentifier.toKotlin();
+ }
+ else {
+ return myExpression.toKotlin() + DOT + myIdentifier.toKotlin();
+ }
+ }
+ return myIdentifier.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/CaseContainer.java b/src/org/jetbrains/jet/j2k/ast/CaseContainer.java
new file mode 100644
index 00000000000..4e58dabaf24
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/CaseContainer.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 CaseContainer extends Statement {
+ private final List myCaseStatement;
+ private final Block myBlock;
+
+ public CaseContainer(final List caseStatement, @NotNull final List statements) {
+ myCaseStatement = caseStatement;
+ List newStatements = new LinkedList();
+ for (Statement s : statements)
+ if (s.getKind() != Kind.BREAK && s.getKind() != Kind.CONTINUE) {
+ newStatements.add(s);
+ }
+ myBlock = new Block(newStatements);
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return AstUtil.joinNodes(myCaseStatement, COMMA_WITH_SPACE) + SPACE + "->" + SPACE + myBlock.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/CatchStatement.java b/src/org/jetbrains/jet/j2k/ast/CatchStatement.java
new file mode 100644
index 00000000000..044d4808b6e
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/CatchStatement.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class CatchStatement extends Statement {
+ private final Parameter myVariable;
+ private final Block myBlock;
+
+ public CatchStatement(Parameter variable, Block block) {
+ myVariable = variable;
+ myBlock = block;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "catch" + SPACE + "(" + myVariable.toKotlin() + ")" + SPACE + myBlock.toKotlin();
+ }
+}
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..af7b37e3cf6
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Class.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.j2k.Converter;
+import org.jetbrains.jet.j2k.J2KConverterFlags;
+import org.jetbrains.jet.j2k.util.AstUtil;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.jetbrains.jet.j2k.util.AstUtil.*;
+
+/**
+ * @author ignatov
+ */
+public class Class extends Member {
+ @NotNull
+ String TYPE = "class";
+ final Identifier myName;
+ private final List myBaseClassParams;
+ private final List myMembers;
+ private final List myTypeParameters;
+ private final List myExtendsTypes;
+ private final List myImplementsTypes;
+
+ public Class(Converter converter, Identifier name, Set modifiers, List typeParameters, List extendsTypes,
+ List baseClassParams, List implementsTypes, List members) {
+ myName = name;
+ myBaseClassParams = baseClassParams;
+ myModifiers = modifiers;
+ myTypeParameters = typeParameters;
+ myExtendsTypes = extendsTypes;
+ myImplementsTypes = implementsTypes;
+ myMembers = getMembers(members, converter);
+ }
+
+ /*package*/ static List getMembers(List members, Converter converter) {
+ List withoutPrivate = new LinkedList();
+ if (converter.hasFlag(J2KConverterFlags.SKIP_NON_PUBLIC_MEMBERS)) {
+ for (Member m : members) {
+ if (m.accessModifier().equals("public") || m.accessModifier().equals("protected")) {
+ withoutPrivate.add(m);
+ }
+ }
+ }
+ else {
+ withoutPrivate = members;
+ }
+ return withoutPrivate;
+ }
+
+
+ @Nullable
+ private Constructor getPrimaryConstructor() {
+ for (Member m : myMembers)
+ if (m.getKind() == Kind.CONSTRUCTOR) {
+ if (((Constructor) m).isPrimary()) {
+ return (Constructor) m;
+ }
+ }
+ return null;
+ }
+
+ String primaryConstructorSignatureToKotlin() {
+ Constructor maybeConstructor = getPrimaryConstructor();
+ if (maybeConstructor != null) {
+ return maybeConstructor.primarySignatureToKotlin();
+ }
+ return "(" + ")";
+ }
+
+ String primaryConstructorBodyToKotlin() {
+ Constructor maybeConstructor = getPrimaryConstructor();
+ if (maybeConstructor != null && !maybeConstructor.getBlock().isEmpty()) {
+ return maybeConstructor.primaryBodyToKotlin();
+ }
+ return EMPTY;
+ }
+
+ private boolean hasWhere() {
+ for (Element t : myTypeParameters)
+ if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere()) {
+ return true;
+ }
+ return false;
+ }
+
+ @NotNull
+ String typeParameterWhereToKotlin() {
+ if (hasWhere()) {
+ List wheres = new LinkedList();
+ for (Element t : myTypeParameters)
+ if (t instanceof TypeParameter) {
+ wheres.add(((TypeParameter) t).getWhereToKotlin());
+ }
+ return SPACE + "where" + SPACE + join(wheres, COMMA_WITH_SPACE) + SPACE;
+ }
+ return EMPTY;
+ }
+
+ @NotNull
+ LinkedList membersExceptConstructors() {
+ final LinkedList result = new LinkedList();
+ for (Member m : myMembers)
+ if (m.getKind() != Kind.CONSTRUCTOR) {
+ result.add(m);
+ }
+ return result;
+ }
+
+ @NotNull
+ List secondaryConstructorsAsStaticInitFunction() {
+ final LinkedList result = new LinkedList();
+ for (Member m : myMembers)
+ if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) {
+ Function f = (Function) m;
+ Set modifiers = new HashSet(m.myModifiers);
+ modifiers.add(Modifier.STATIC);
+
+ final List statements = f.getBlock().getStatements();
+ statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages
+ final Block block = new Block(statements);
+
+ final List typeParameters = new LinkedList();
+ if (f.getTypeParameters().size() == 0) {
+ typeParameters.addAll(myTypeParameters);
+ }
+ else {
+ typeParameters.addAll(myTypeParameters);
+ typeParameters.addAll(f.getTypeParameters());
+ }
+
+ result.add(new Function(
+ new IdentifierImpl("init"),
+ modifiers,
+ new ClassType(myName, typeParameters, false),
+ typeParameters,
+ f.getParams(),
+ block
+ ));
+ }
+ return result;
+ }
+
+ @NotNull
+ String typeParametersToKotlin() {
+ return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
+ }
+
+ List baseClassSignatureWithParams() {
+ if (TYPE.equals("class") && myExtendsTypes.size() == 1) {
+ LinkedList result = new LinkedList();
+ result.add(myExtendsTypes.get(0).toKotlin() + "(" + joinNodes(myBaseClassParams, COMMA_WITH_SPACE) + ")");
+ return result;
+ }
+ else {
+ return nodesToKotlin(myExtendsTypes);
+ }
+ }
+
+ @NotNull
+ String implementTypesToKotlin() {
+ List allTypes = new LinkedList() {
+ {
+ addAll(baseClassSignatureWithParams());
+ addAll(nodesToKotlin(myImplementsTypes));
+ }
+ };
+ return allTypes.size() == 0 ? EMPTY : SPACE + COLON + SPACE + join(allTypes, COMMA_WITH_SPACE);
+ }
+
+ @NotNull
+ String modifiersToKotlin() {
+ List modifierList = new LinkedList();
+
+ modifierList.add(accessModifier());
+
+ if (needAbstractModifier()) {
+ modifierList.add(Modifier.ABSTRACT);
+ }
+
+ if (needOpenModifier()) {
+ modifierList.add(Modifier.OPEN);
+ }
+
+ if (modifierList.size() > 0) {
+ return join(modifierList, SPACE) + SPACE;
+ }
+
+ return EMPTY;
+ }
+
+ boolean needOpenModifier() {
+ return !myModifiers.contains(Modifier.FINAL) && !myModifiers.contains(Modifier.ABSTRACT);
+ }
+
+ boolean needAbstractModifier() {
+ return isAbstract();
+ }
+
+ @NotNull
+ String bodyToKotlin() {
+ return SPACE + "{" + N +
+ AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N +
+ primaryConstructorBodyToKotlin() + N +
+ classObjectToKotlin() + N +
+ "}";
+ }
+
+ @NotNull
+ private static List getStatic(@NotNull List extends Member> members) {
+ List result = new LinkedList();
+ for (Member m : members)
+ if (m.isStatic()) {
+ result.add(m);
+ }
+ return result;
+ }
+
+ @NotNull
+ private static List getNonStatic(@NotNull List extends Member> members) {
+ List result = new LinkedList();
+ for (Member m : members)
+ if (!m.isStatic()) {
+ result.add(m);
+ }
+ return result;
+ }
+
+ @NotNull
+ private String classObjectToKotlin() {
+ final List staticMembers = new LinkedList(secondaryConstructorsAsStaticInitFunction());
+ staticMembers.addAll(getStatic(membersExceptConstructors()));
+ if (staticMembers.size() > 0) {
+ return "class" + SPACE + "object" + SPACE + "{" + N +
+ AstUtil.joinNodes(staticMembers, N) + N +
+ "}";
+ }
+ return EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return modifiersToKotlin() + TYPE + SPACE + myName.toKotlin() + typeParametersToKotlin() + primaryConstructorSignatureToKotlin() +
+ implementTypesToKotlin() +
+ typeParameterWhereToKotlin() +
+ bodyToKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ClassObjectAccessExpression.java b/src/org/jetbrains/jet/j2k/ast/ClassObjectAccessExpression.java
new file mode 100644
index 00000000000..78aefcb3f3e
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ClassObjectAccessExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ClassObjectAccessExpression extends Expression {
+ private final Element myTypeElement;
+
+ public ClassObjectAccessExpression(Element typeElement) {
+ myTypeElement = typeElement;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "getJavaClass" + "<" + myTypeElement.toKotlin() + ">";
+ }
+}
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..860c73cf0e3
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ClassType.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.j2k.util.AstUtil;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author ignatov
+ */
+public class ClassType extends Type {
+ private final Identifier myType;
+ private final List extends Element> myParameters;
+
+ public ClassType(Identifier type, List extends Element> parameters, boolean nullable) {
+ myType = type;
+ myParameters = parameters;
+ myNullable = nullable;
+ }
+
+ public ClassType(Identifier type, List extends Element> parameters) {
+ myType = type;
+ myParameters = parameters;
+ }
+
+ public ClassType(Identifier type) {
+ myType = type;
+ myNullable = false;
+ myParameters = Collections.emptyList();
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ String params = myParameters.size() == 0
+ ? EMPTY
+ : "<" + AstUtil.joinNodes(myParameters, COMMA_WITH_SPACE) + ">";
+ return myType.toKotlin() + params + isNullableStr();
+ }
+}
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..e0a3d4b8628
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Constructor.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class Constructor extends Function {
+ private final boolean myIsPrimary;
+
+ public Constructor(Identifier identifier, Set modifiers, Type type, List typeParameters, Element params, Block block, boolean isPrimary) {
+ super(identifier, modifiers, type, typeParameters, params, block);
+ myIsPrimary = isPrimary;
+ }
+
+ @NotNull
+ public String primarySignatureToKotlin() {
+ return "(" + myParams.toKotlin() + ")";
+ }
+
+ @NotNull
+ public String primaryBodyToKotlin() {
+ return myBlock.toKotlin();
+ }
+
+ public boolean isPrimary() {
+ return myIsPrimary;
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.CONSTRUCTOR;
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ContinueStatement.java b/src/org/jetbrains/jet/j2k/ast/ContinueStatement.java
new file mode 100644
index 00000000000..1defbd27651
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ContinueStatement.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ContinueStatement extends Statement {
+ private Identifier myLabel = Identifier.EMPTY_IDENTIFIER;
+
+ public ContinueStatement(Identifier label) {
+ myLabel = label;
+ }
+
+ public ContinueStatement() {
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.CONTINUE;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (myLabel.isEmpty()) {
+ return "continue";
+ }
+ return "continue" + AT + myLabel.toKotlin();
+ }
+}
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..165babb208c
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/DeclarationStatement.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 final List myElements;
+
+ public DeclarationStatement(List elements) {
+ myElements = elements;
+ }
+
+ @NotNull
+ private static List toStringList(@NotNull List elements) {
+ List result = new LinkedList();
+ for (Element e : elements) {
+ if (e instanceof LocalVariable) {
+ LocalVariable v = (LocalVariable) e;
+
+ final String varKeyword = v.hasModifier(Modifier.FINAL) ? "val" : "var";
+ result.add(
+ varKeyword + SPACE + e.toKotlin()
+ );
+ }
+ }
+ return result;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return AstUtil.join(toStringList(myElements), N);
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/DefaultSwitchLabelStatement.java b/src/org/jetbrains/jet/j2k/ast/DefaultSwitchLabelStatement.java
new file mode 100644
index 00000000000..a7d71d772cd
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/DefaultSwitchLabelStatement.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class DefaultSwitchLabelStatement extends Statement {
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "else";
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/DoWhileStatement.java b/src/org/jetbrains/jet/j2k/ast/DoWhileStatement.java
new file mode 100644
index 00000000000..9592d8c8883
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/DoWhileStatement.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class DoWhileStatement extends WhileStatement {
+ public DoWhileStatement(Expression condition, Statement statement) {
+ super(condition, statement);
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "do" + N +
+ myStatement.toKotlin() + N +
+ "while" + SPACE + "(" + myCondition.toKotlin() + ")";
+ }
+}
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..afada0ea95a
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/DummyMethodCallExpression.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class DummyMethodCallExpression extends Expression {
+ private final Element myWho;
+ private final String myMethodName;
+ private final Element myWhat;
+
+ public DummyMethodCallExpression(Element who, String methodName, Element 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/DummyStringExpression.java b/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.java
new file mode 100644
index 00000000000..d8456d9033c
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/DummyStringExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class DummyStringExpression extends Expression {
+ private final String myString;
+
+ public DummyStringExpression(String string) {
+ myString = string;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return myString;
+ }
+}
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..18047306a23
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Element.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public abstract class Element extends Node {
+ @NotNull
+ public static final Element EMPTY_ELEMENT = new EmptyElement();
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * @author ignatov
+ */
+ private static class EmptyElement extends Element {
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return EMPTY;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+ }
+}
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..2310a273db0
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Enum.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.j2k.Converter;
+import org.jetbrains.jet.j2k.util.AstUtil;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class Enum extends Class {
+ public Enum(Converter converter, Identifier name, Set modifiers, List typeParameters, List extendsTypes,
+ List baseClassParams, List implementsTypes, List members) {
+ super(converter, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, getMembers(members, converter));
+ }
+
+ String primaryConstructorSignatureToKotlin() {
+ String s = super.primaryConstructorSignatureToKotlin();
+ return s.equals("()") ? EMPTY : s;
+ }
+
+ @Override
+ boolean needOpenModifier() {
+ return false;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return modifiersToKotlin() + "enum class" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() +
+ typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N +
+ AstUtil.joinNodes(membersExceptConstructors(), N) + N +
+ primaryConstructorBodyToKotlin() + N +
+ "public fun name() : String { return \"\" }" + N + // TODO : remove hack
+ "public fun order() : Int { return 0 }" + 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..990a56501a0
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/EnumConstant.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class EnumConstant extends Field {
+ public EnumConstant(Identifier identifier, Set modifiers, @NotNull Type type, Element params) {
+ super(identifier, modifiers, type.convertedToNotNull(), params, 0);
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (myInitializer.toKotlin().isEmpty()) {
+ return myIdentifier.toKotlin();
+ }
+ return myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin() + "(" + myInitializer.toKotlin() + ")";
+ }
+}
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..28c9a6143f0
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Expression.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public abstract class Expression extends Statement {
+ @NotNull
+ public static final Expression EMPTY_EXPRESSION = new EmptyExpression();
+
+ /**
+ * @author ignatov
+ */
+ private static class EmptyExpression extends Expression {
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return EMPTY;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+ }
+
+ boolean isNullable() {
+ return false;
+ }
+}
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..5d26a57c56c
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ExpressionList.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 final List myExpressions;
+
+ public ExpressionList(List expressions, List types) {
+ myExpressions = expressions;
+ }
+
+ 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/ExpressionListStatement.java b/src/org/jetbrains/jet/j2k/ast/ExpressionListStatement.java
new file mode 100644
index 00000000000..810dbd14f6b
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ExpressionListStatement.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 ExpressionListStatement extends Expression {
+ private final List myExpressions;
+
+ public ExpressionListStatement(List expressions) {
+ myExpressions = expressions;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return AstUtil.joinNodes(myExpressions, N);
+ }
+}
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..4e35538fd3d
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Field.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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;
+import java.util.Set;
+
+import static org.jetbrains.jet.j2k.Converter.getDefaultInitializer;
+
+/**
+ * @author ignatov
+ */
+public class Field extends Member {
+ final Identifier myIdentifier;
+ private final int myWritingAccesses;
+ final Type myType;
+ final Element myInitializer;
+
+ public Field(Identifier identifier, Set modifiers, Type type, Element initializer, int writingAccesses) {
+ myIdentifier = identifier;
+ myWritingAccesses = writingAccesses;
+ myModifiers = modifiers;
+ myType = type;
+ myInitializer = initializer;
+ }
+
+ public Element getInitializer() {
+ return myInitializer;
+ }
+
+ public Identifier getIdentifier() {
+ return myIdentifier;
+ }
+
+ public Type getType() {
+ return myType;
+ }
+
+ @NotNull
+ String modifiersToKotlin() {
+ List modifierList = new LinkedList();
+
+ if (isAbstract()) {
+ modifierList.add(Modifier.ABSTRACT);
+ }
+
+ modifierList.add(accessModifier());
+
+ modifierList.add(isVal() ? "val" : "var");
+
+ if (modifierList.size() > 0) {
+ return AstUtil.join(modifierList, SPACE) + SPACE;
+ }
+
+ return EMPTY;
+ }
+
+ public boolean isVal() {
+ return myModifiers.contains(Modifier.FINAL);
+ }
+
+ @Override
+ public boolean isStatic() {
+ return myModifiers.contains(Modifier.STATIC);
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ final String declaration = modifiersToKotlin() + myIdentifier.toKotlin() + SPACE + COLON + SPACE + myType.toKotlin();
+
+ if (myInitializer.isEmpty()) {
+ return declaration + (isVal() && !isStatic() && myWritingAccesses == 1
+ ? EMPTY
+ : SPACE + EQUAL + SPACE + getDefaultInitializer(this));
+ }
+
+ return declaration + SPACE + EQUAL + SPACE + myInitializer.toKotlin();
+ }
+}
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..eb1be6a22ef
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/File.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 final String myPackageName;
+ private final List myImports;
+ private final List myClasses;
+ private final String myMainFunction;
+
+ public File(String packageName, List imports, List classes, String mainFunction) {
+ myPackageName = packageName;
+ myImports = imports;
+ myClasses = classes;
+ myMainFunction = mainFunction;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N + myMainFunction;
+ if (myPackageName.isEmpty()) {
+ return common;
+ }
+ return "package" + SPACE + myPackageName + N +
+ common;
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ForeachStatement.java b/src/org/jetbrains/jet/j2k/ast/ForeachStatement.java
new file mode 100644
index 00000000000..431dcf4168e
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ForeachStatement.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ForeachStatement extends Statement {
+ private final Parameter myVariable;
+ private final Expression myExpression;
+ private final Statement myStatement;
+
+ public ForeachStatement(Parameter variable, Expression expression, Statement statement) {
+ myVariable = variable;
+ myExpression = expression;
+ myStatement = statement;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "for" + SPACE + "(" + myVariable.toKotlin() + SPACE + IN + SPACE + myExpression.toKotlin() + ")" + N +
+ myStatement.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/ForeachWithRangeStatement.java b/src/org/jetbrains/jet/j2k/ast/ForeachWithRangeStatement.java
new file mode 100644
index 00000000000..ed9a5712a3a
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ForeachWithRangeStatement.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ForeachWithRangeStatement extends Statement {
+ private final Expression myStart;
+ private final IdentifierImpl myIdentifier;
+ private final Expression myEnd;
+ private final Statement myBody;
+
+ public ForeachWithRangeStatement(IdentifierImpl identifier, Expression start, Expression end, Statement body) {
+ myStart = start;
+ myIdentifier = identifier;
+ myEnd = end;
+ myBody = body;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "for" + SPACE + "(" +
+ myIdentifier.toKotlin() + SPACE + "in" + SPACE + myStart.toKotlin() + ".." + myEnd.toKotlin() +
+ ")" + SPACE +
+ myBody.toKotlin();
+ }
+}
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..0844e177a9d
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Function.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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;
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class Function extends Member {
+ private final Identifier myName;
+ private final Type myType;
+ private final List myTypeParameters;
+ final Element myParams;
+
+ // TODO: maybe remove it?
+ public void setBlock(Block block) {
+ myBlock = block;
+ }
+
+ Block myBlock;
+
+ public Function(Identifier name, Set modifiers, Type type, List typeParameters, Element params, Block block) {
+ myName = name;
+ myModifiers = modifiers;
+ myType = type;
+ myTypeParameters = typeParameters;
+ myParams = params;
+ myBlock = block;
+ }
+
+ public List getTypeParameters() {
+ return myTypeParameters;
+ }
+
+ public Element getParams() {
+ return myParams;
+ }
+
+ public Block getBlock() {
+ return myBlock;
+ }
+
+ @NotNull
+ private String typeParametersToKotlin() {
+ return myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
+ }
+
+ private boolean hasWhere() {
+ for (Element t : myTypeParameters)
+ if (t instanceof TypeParameter && ((TypeParameter) t).hasWhere()) {
+ return true;
+ }
+ return false;
+ }
+
+ private String typeParameterWhereToKotlin() {
+ if (hasWhere()) {
+ List wheres = new LinkedList();
+ for (Element t : myTypeParameters)
+ if (t instanceof TypeParameter) {
+ wheres.add(((TypeParameter) t).getWhereToKotlin());
+ }
+ return SPACE + "where" + SPACE + AstUtil.join(wheres, COMMA_WITH_SPACE) + SPACE;
+ }
+ return EMPTY;
+ }
+
+ String modifiersToKotlin() {
+ List modifierList = new LinkedList();
+
+ String accessModifier = accessModifier();
+ if (!accessModifier.isEmpty()) {
+ modifierList.add(accessModifier);
+ }
+
+ if (isAbstract()) {
+ modifierList.add(Modifier.ABSTRACT);
+ }
+
+ if (myModifiers.contains(Modifier.OVERRIDE)) {
+ modifierList.add(Modifier.OVERRIDE);
+ }
+
+ if (!myModifiers.contains(Modifier.ABSTRACT) && !myModifiers.contains(Modifier.OVERRIDE) && !myModifiers.contains(Modifier.FINAL)) {
+ modifierList.add(Modifier.OPEN);
+ }
+
+ if (myModifiers.contains(Modifier.NOT_OPEN)) {
+ modifierList.remove(Modifier.OPEN);
+ }
+
+ if (modifierList.size() > 0) {
+ return AstUtil.join(modifierList, SPACE) + SPACE;
+ }
+
+ return EMPTY;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return modifiersToKotlin() + "fun" + SPACE + myName.toKotlin() + typeParametersToKotlin() + "(" + myParams.toKotlin() + ")" + SPACE + COLON +
+ SPACE + myType.toKotlin() + SPACE +
+ typeParameterWhereToKotlin() +
+ myBlock.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/IMember.java b/src/org/jetbrains/jet/j2k/ast/IMember.java
new file mode 100644
index 00000000000..3e0bdf5e7fb
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/IMember.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+/**
+ * @author ignatov
+ */
+public interface IMember extends INode {
+ boolean isStatic();
+
+ boolean isAbstract();
+}
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..aa60b6ed1bb
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/INode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public interface INode {
+ @NotNull
+ String toKotlin();
+
+ @NotNull
+ Kind getKind();
+
+ enum Kind {
+ UNDEFINED, TYPE, CONSTRUCTOR, BREAK, CONTINUE, VARARG, TRAIT, ASSIGNMENT_EXPRESSION, CALL_CHAIN, LITERAL, ARRAY_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..f94be742be2
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Identifier.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public interface Identifier extends INode {
+ @NotNull
+ Identifier EMPTY_IDENTIFIER = new IdentifierImpl("");
+
+ boolean isEmpty();
+
+ String getName();
+}
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..fd543f23f91
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/IdentifierImpl.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class IdentifierImpl extends Expression implements Identifier {
+ private final String myName;
+ private boolean myIsNullable = true;
+ private boolean myQuotingNeeded = true;
+
+ public IdentifierImpl(String name) {
+ myName = name;
+ }
+
+ public IdentifierImpl(String name, boolean isNullable) {
+ myName = name;
+ myIsNullable = isNullable;
+ }
+
+ public IdentifierImpl(String name, boolean isNullable, boolean quotingNeeded) {
+ myName = name;
+ myIsNullable = isNullable;
+ myQuotingNeeded = quotingNeeded;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return myName.length() == 0;
+ }
+
+ @Override
+ public String getName() {
+ return myName;
+ }
+
+ @NotNull
+ private static String quote(String str) {
+ return BACKTICK + str + BACKTICK;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return myIsNullable;
+ }
+
+ private String ifNeedQuote() {
+ if (myQuotingNeeded && (ONLY_KOTLIN_KEYWORDS.contains(myName) || myName.contains("$"))) {
+ return quote(myName);
+ }
+ return myName;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return ifNeedQuote();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/IfStatement.java b/src/org/jetbrains/jet/j2k/ast/IfStatement.java
new file mode 100644
index 00000000000..1efa8311a56
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/IfStatement.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class IfStatement extends Expression {
+ private final Expression myCondition;
+ private final Statement myThenStatement;
+ private final Statement myElseStatement;
+
+ public IfStatement(Expression condition, Statement thenStatement, Statement elseStatement) {
+ myCondition = condition;
+ myThenStatement = thenStatement;
+ myElseStatement = elseStatement;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ String result = "if" + SPACE + "(" + myCondition.toKotlin() + ")" + N + myThenStatement.toKotlin() + N;
+
+ if (myElseStatement != Statement.EMPTY_STATEMENT) {
+ return result +
+ "else" + N +
+ myElseStatement.toKotlin();
+ }
+
+ return result;
+ }
+}
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..4d81911c01d
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Import.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class Import extends Node {
+ private final String myName;
+
+ public String getName() {
+ return 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/InProjectionType.java b/src/org/jetbrains/jet/j2k/ast/InProjectionType.java
new file mode 100644
index 00000000000..9849ee47d58
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/InProjectionType.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class InProjectionType extends Type {
+ private final Type myBound;
+
+ public InProjectionType(Type bound) {
+ myBound = bound;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "in" + SPACE + myBound.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/Initializer.java b/src/org/jetbrains/jet/j2k/ast/Initializer.java
new file mode 100644
index 00000000000..056f8424d09
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Initializer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class Initializer extends Member {
+ private final Block myBlock;
+
+ public Initializer(Block block, Set modifiers) {
+ myBlock = block;
+ myModifiers = modifiers;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return myBlock.toKotlin();
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/IsOperator.java b/src/org/jetbrains/jet/j2k/ast/IsOperator.java
new file mode 100644
index 00000000000..79262f14871
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/IsOperator.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class IsOperator extends Expression {
+ private final Expression myExpression;
+ private final Element myTypeElement;
+
+ public IsOperator(Expression expression, Element typeElement) {
+ myExpression = expression;
+ myTypeElement = typeElement;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "(" + myExpression.toKotlin() + SPACE + "is" + SPACE + myTypeElement.toKotlin() + ")";
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/LabelStatement.java b/src/org/jetbrains/jet/j2k/ast/LabelStatement.java
new file mode 100644
index 00000000000..0d0c7ebdfa9
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/LabelStatement.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class LabelStatement extends Statement {
+ private final Identifier myName;
+ private final Statement myStatement;
+
+ public LabelStatement(Identifier name, Statement statement) {
+ myName = name;
+ myStatement = statement;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return AT + myName.toKotlin() + SPACE + myStatement.toKotlin();
+ }
+}
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..06162ae412b
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/LiteralExpression.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class LiteralExpression extends Expression {
+ private final Identifier myIdentifier;
+
+ public LiteralExpression(Identifier identifier) {
+ myIdentifier = identifier;
+ }
+
+ @NotNull
+ @Override
+ public Kind getKind() {
+ return Kind.LITERAL;
+ }
+
+ @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..6d3d411ba13
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/LocalVariable.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public class LocalVariable extends Expression {
+ private final Identifier myIdentifier;
+ private final Set myModifiersSet;
+ private final Type myType;
+ private final Expression myInitializer;
+
+ public LocalVariable(Identifier identifier, Set modifiersSet, Type type, Expression initializer) {
+ myIdentifier = identifier;
+ myModifiersSet = modifiersSet;
+ myType = type;
+ myInitializer = initializer;
+ }
+
+ public boolean hasModifier(String modifier) {
+ return myModifiersSet.contains(modifier);
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ if (myInitializer.isEmpty()) {
+ 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/Member.java b/src/org/jetbrains/jet/j2k/ast/Member.java
new file mode 100644
index 00000000000..dca9a33cf2f
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Member.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author ignatov
+ */
+public abstract class Member extends Node implements IMember {
+ Set myModifiers;
+
+ @NotNull
+ String accessModifier() {
+ for (String m : myModifiers)
+ if (m.equals(Modifier.PUBLIC) || m.equals(Modifier.PROTECTED) || m.equals(Modifier.PRIVATE)) {
+ return m;
+ }
+ return EMPTY; // package local converted to internal, but we use internal by default
+ }
+
+ @Override
+ public boolean isAbstract() {
+ return myModifiers.contains(Modifier.ABSTRACT);
+ }
+
+ @Override
+ public boolean isStatic() {
+ return myModifiers.contains(Modifier.STATIC);
+ }
+}
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..481b8fad792
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 MethodCallExpression extends Expression {
+ private final Expression myMethodCall;
+ private final List myArguments;
+ private final List myConversions;
+ private final boolean myIsResultNullable;
+ private final List myTypeParameters;
+
+ public MethodCallExpression(Expression methodCall, List arguments, List typeParameters) {
+ this(methodCall, arguments, AstUtil.createListWithEmptyString(arguments), false, typeParameters);
+ }
+
+ public MethodCallExpression(Expression methodCall, List arguments, List conversions, boolean nullable, List typeParameters) {
+ myMethodCall = methodCall;
+ myArguments = arguments;
+ myConversions = conversions;
+ myIsResultNullable = nullable;
+ myTypeParameters = typeParameters;
+ }
+
+ @Override
+ public boolean isNullable() {
+ return myIsResultNullable;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ String typeParamsToKotlin = myTypeParameters.size() > 0
+ ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">"
+ : EMPTY;
+ List applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
+ return myMethodCall.toKotlin() + typeParamsToKotlin + "(" + AstUtil.join(applyConversions, COMMA_WITH_SPACE) + ")";
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/Modifier.java b/src/org/jetbrains/jet/j2k/ast/Modifier.java
new file mode 100644
index 00000000000..9e666fe5090
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Modifier.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public abstract class Modifier {
+ @NotNull
+ public static final String PUBLIC = "public";
+ @NotNull
+ public static final String PROTECTED = "protected";
+ @NotNull
+ public static final String PRIVATE = "private";
+ @NotNull
+ public static final String INTERNAL = "internal";
+ @NotNull
+ public static final String STATIC = "static";
+ @NotNull
+ public static final String ABSTRACT = "abstract";
+ @NotNull
+ public static final String FINAL = "final";
+ @NotNull
+ public static final String OPEN = "open";
+ @NotNull
+ public static final String NOT_OPEN = "not open";
+ @NotNull
+ public static final String OVERRIDE = "override";
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/NewClassExpression.java b/src/org/jetbrains/jet/j2k/ast/NewClassExpression.java
new file mode 100644
index 00000000000..7bbf906dff0
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/NewClassExpression.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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;
+
+/**
+ * @author ignatov
+ */
+public class NewClassExpression extends Expression {
+ private final Element myName;
+ private final List myArguments;
+ private Expression myQualifier;
+ private List myConversions;
+ @Nullable
+ private AnonymousClass myAnonymousClass = null;
+
+ private NewClassExpression(Element name, List arguments) {
+ myName = name;
+ myQualifier = EMPTY_EXPRESSION;
+ myArguments = arguments;
+ myConversions = AstUtil.createListWithEmptyString(arguments);
+ }
+
+ public NewClassExpression(@NotNull Expression qualifier, @NotNull Element name, @NotNull List arguments,
+ @NotNull List conversions, @Nullable AnonymousClass anonymousClass) {
+ this(name, arguments);
+ myQualifier = qualifier;
+ myConversions = conversions;
+ myAnonymousClass = anonymousClass;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
+ final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
+ List applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
+ String appliedArguments = AstUtil.join(applyConversions, COMMA_WITH_SPACE);
+ return myAnonymousClass != null ?
+ "object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
+ :
+ qualifier + myName.toKotlin() + "(" + appliedArguments + ")";
+ }
+}
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..e1d580d6cd7
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Node.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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;
+ }
+
+ @NotNull
+ final static Set ONLY_KOTLIN_KEYWORDS = new HashSet(Arrays.asList(
+ "package", "as", "type", "val", "var", "fun", "is", "in", "object", "when", "trait", "This"
+ ));
+
+ @NotNull
+ public final static Set PRIMITIVE_TYPES = new HashSet(Arrays.asList(
+ "double", "float", "long", "int", "short", "byte", "boolean", "char"
+ ));
+
+ static final String N = "\n";
+ @NotNull
+ static final String N2 = N + N;
+ @NotNull
+ static final String SPACE = " ";
+ @NotNull
+ static final String EQUAL = "=";
+ @NotNull
+ static final String EMPTY = "";
+ @NotNull
+ static final String DOT = ".";
+ @NotNull
+ static final String QUESTDOT = "?.";
+ @NotNull
+ static final String COLON = ":";
+ @NotNull
+ static final String IN = "in";
+ @NotNull
+ static final String AT = "@";
+ @NotNull
+ static final String BACKTICK = "`";
+ @NotNull
+ static final String QUEST = "?";
+ @NotNull
+ public static final String COMMA_WITH_SPACE = "," + SPACE;
+ @NotNull
+ static final String STAR = "*";
+ @NotNull
+ protected static final String ZERO = "0";
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/OutProjectionType.java b/src/org/jetbrains/jet/j2k/ast/OutProjectionType.java
new file mode 100644
index 00000000000..0d91c4b9e5d
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/OutProjectionType.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class OutProjectionType extends Type {
+ private final Type myBound;
+
+ public OutProjectionType(Type bound) {
+ myBound = bound;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "out" + SPACE + myBound.toKotlin();
+ }
+}
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..b20caf83fd0
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/Parameter.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class Parameter extends Expression {
+ private final Identifier myIdentifier;
+ private final Type myType;
+ private boolean myReadOnly;
+
+ public Parameter(Identifier identifier, Type type) {
+ myIdentifier = identifier;
+ myType = type;
+ myReadOnly = true;
+ }
+
+ public Parameter(IdentifierImpl identifier, Type type, boolean readOnly) {
+ this(identifier, type);
+ myReadOnly = readOnly;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ String vararg = myType.getKind() == Kind.VARARG ? "vararg" + SPACE : EMPTY;
+ String var = myReadOnly ? EMPTY : "var" + SPACE;
+ return vararg + var + 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..7f26c4414eb
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ParameterList.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 final 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/ast/ParenthesizedExpression.java b/src/org/jetbrains/jet/j2k/ast/ParenthesizedExpression.java
new file mode 100644
index 00000000000..4f73f4ee719
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/ParenthesizedExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.j2k.ast;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author ignatov
+ */
+public class ParenthesizedExpression extends Expression {
+ private final Expression myExpression;
+
+ public ParenthesizedExpression(Expression expression) {
+ myExpression = expression;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ return "(" + myExpression.toKotlin() + ")";
+ }
+}
diff --git a/src/org/jetbrains/jet/j2k/ast/PolyadicExpression.java b/src/org/jetbrains/jet/j2k/ast/PolyadicExpression.java
new file mode 100644
index 00000000000..1523ed864c7
--- /dev/null
+++ b/src/org/jetbrains/jet/j2k/ast/PolyadicExpression.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2010-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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 PolyadicExpression extends Expression {
+ private final List myExpressions;
+ private final String myToken;
+ private final List myConversions;
+
+ public PolyadicExpression(List expressions, String token, List conversions) {
+ super();
+ myExpressions = expressions;
+ myToken = token;
+ myConversions = conversions;
+ }
+
+ @NotNull
+ @Override
+ public String toKotlin() {
+ List