Help at rigth part

This commit is contained in:
Natalia.Ukhorskaya
2011-11-23 14:55:42 +04:00
parent 773bc1ced2
commit 01025a07c6
99 changed files with 799 additions and 299 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="commons-io-2.1" level="project" /> <orderEntry type="library" scope="TEST" name="commons-io-2.1" level="project" />
</component> </component>
</module> </module>
+1 -1
View File
@@ -168,7 +168,7 @@
<component name="ProjectResources"> <component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype> <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA IC-110.203" project-jdk-type="IDEA JDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA 10.x" project-jdk-type="IDEA JDK">
<output url="file://$PROJECT_DIR$/out" /> <output url="file://$PROJECT_DIR$/out" />
</component> </component>
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
+58 -85
View File
@@ -40,13 +40,19 @@ public class Converter {
@NotNull @NotNull
public static AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) { public static AnonymousClass anonymousClassToAnonymousClass(@NotNull PsiAnonymousClass anonymousClass) {
// TODO: replace by Block, use class.getChild() method return new AnonymousClass(getMembers(anonymousClass));
return new AnonymousClass( }
classesToClassList(anonymousClass.getAllInnerClasses()),
methodsToFunctionList(anonymousClass.getMethods()), private static List<Member> getMembers(PsiClass psiClass) {
fieldsToFieldList(anonymousClass.getAllFields()), List<Member> members = new LinkedList<Member>();
initializersToInitializerList(anonymousClass.getInitializers()) for (PsiElement e : psiClass.getChildren()) {
); if (e instanceof PsiMethod) members.add(methodToFunction((PsiMethod) e, true));
else if (e instanceof PsiField) members.add(fieldToField((PsiField) e));
else if (e instanceof PsiClass) members.add(classToClass((PsiClass) e));
else if (e instanceof PsiClassInitializer) members.add(initializerToInitializer((PsiClassInitializer) e));
else if (e instanceof PsiMember) System.out.println(e.getClass() + " " + e.getText());
}
return members;
} }
@NotNull @NotNull
@@ -88,16 +94,15 @@ public class Converter {
@NotNull @NotNull
private static Class classToClass(@NotNull PsiClass psiClass) { private static Class classToClass(@NotNull PsiClass psiClass) {
final Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList()); final Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList());
final List<Class> innerClasses = classesToClassList(psiClass.getAllInnerClasses());
final List<Function> methods = methodsToFunctionList(psiClass.getMethods());
final List<Field> fields = fieldsToFieldList(psiClass.getFields()); final List<Field> fields = fieldsToFieldList(psiClass.getFields());
final List<Initializer> anonymousInitializers = initializersToInitializerList(psiClass.getInitializers());
final List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters()); final List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters());
final List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes()); final List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes());
final List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes()); final List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes());
final IdentifierImpl name = new IdentifierImpl(psiClass.getName()); final IdentifierImpl name = new IdentifierImpl(psiClass.getName());
final List<Expression> baseClassParams = new LinkedList<Expression>(); final List<Expression> baseClassParams = new LinkedList<Expression>();
List<Member> members = getMembers(psiClass);
// we try to find super() call and generate class declaration like that: class A(name: String, i : Int) : Base(name) // we try to find super() call and generate class declaration like that: class A(name: String, i : Int) : Base(name)
final SuperVisitor visitor = new SuperVisitor(); final SuperVisitor visitor = new SuperVisitor();
psiClass.accept(visitor); psiClass.accept(visitor);
@@ -114,49 +119,52 @@ public class Converter {
final List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields); final List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields);
final Map<String, String> initializers = new HashMap<String, String>(); final Map<String, String> initializers = new HashMap<String, String>();
for (final Function f : methods) { for (final Member m : members) {
for (Field fo : finalOrWithEmptyInitializer) {
String init = getDefaultInitializer(fo);
initializers.put(fo.getIdentifier().toKotlin(), init);
}
// and modify secondaries // and modify secondaries
if (f.getKind() == INode.Kind.CONSTRUCTOR && !((Constructor) f).isPrimary()) { if (m.getKind() == INode.Kind.CONSTRUCTOR) {
final List<Statement> newStatements = new LinkedList<Statement>(); Function f = (Function)m;
if (!((Constructor) f).isPrimary()) {
for (Field fo : finalOrWithEmptyInitializer) {
String init = getDefaultInitializer(fo);
initializers.put(fo.getIdentifier().toKotlin(), init);
}
for (Statement s : f.getBlock().getStatements()) { final List<Statement> newStatements = new LinkedList<Statement>();
boolean isRemoved = false;
if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { for (Statement s : f.getBlock().getStatements()) {
final AssignmentExpression assignmentExpression = (AssignmentExpression) s; boolean isRemoved = false;
if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
for (Field fo : finalOrWithEmptyInitializer) { if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) {
final String id = fo.getIdentifier().toKotlin(); final AssignmentExpression assignmentExpression = (AssignmentExpression) s;
if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) { if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
initializers.put(id, assignmentExpression.getRight().toKotlin()); for (Field fo : finalOrWithEmptyInitializer) {
isRemoved = true; final String id = fo.getIdentifier().toKotlin();
if (((CallChainExpression) assignmentExpression.getLeft()).getIdentifier().toKotlin().endsWith("." + id)) {
initializers.put(id, assignmentExpression.getRight().toKotlin());
isRemoved = true;
}
} }
} }
} }
if (!isRemoved) {
newStatements.add(s);
}
} }
if (!isRemoved) {
newStatements.add(s); newStatements.add(
} 0,
new DummyStringStatement(
"val __ = " + createPrimaryConstructorInvocation(
name.toKotlin(),
finalOrWithEmptyInitializer,
initializers)));
f.setBlock(new Block(newStatements));
} }
newStatements.add(
0,
new DummyStringStatement(
"val __ = " + createPrimaryConstructorInvocation(
name.toKotlin(),
finalOrWithEmptyInitializer,
initializers)));
f.setBlock(new Block(newStatements));
} }
} }
methods.add( members.add(
new Constructor( new Constructor(
Identifier.EMPTY_IDENTIFIER, Identifier.EMPTY_IDENTIFIER,
Collections.<String>emptySet(), Collections.<String>emptySet(),
@@ -170,18 +178,10 @@ public class Converter {
} }
if (psiClass.isInterface()) if (psiClass.isInterface())
return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, innerClasses, methods, fields, anonymousInitializers); return new Trait(name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, members);
if (psiClass.isEnum()) if (psiClass.isEnum())
return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, return new Enum(name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, members);
innerClasses, methods, fieldsToFieldListForEnums(psiClass.getAllFields()), anonymousInitializers); return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
return new Class(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, anonymousInitializers);
}
@NotNull
private static List<Initializer> initializersToInitializerList(@NotNull PsiClassInitializer[] initializers) {
List<Initializer> result = new LinkedList<Initializer>();
for (PsiClassInitializer i : initializers) result.add(initializerToInitializer(i));
return result;
} }
@NotNull @NotNull
@@ -206,31 +206,6 @@ public class Converter {
} }
} }
// hack for enums, we remove methods:
// private int ordinal() { ... }
// private String name() { ... }
// those methods any enum class inherits from java.lang.Enum
@NotNull
private static List<Field> fieldsToFieldListForEnums(@NotNull PsiField[] fields) {
List<Field> result = new LinkedList<Field>();
for (PsiField f : fields) {
if ((f.getName().equals("ordinal")
&& f.getType().getCanonicalText().equals("int")
&& f.hasModifierProperty(PsiModifier.PRIVATE)
&& f.hasModifierProperty(PsiModifier.FINAL)
) ||
(f.getName().equals("name")
&& f.getType().getCanonicalText().equals("java.lang.String")
&& f.hasModifierProperty(PsiModifier.PRIVATE)
&& f.hasModifierProperty(PsiModifier.FINAL)
))
continue;
result.add(fieldToField(f));
}
return result;
}
@NotNull @NotNull
private static List<Field> fieldsToFieldList(@NotNull PsiField[] fields) { private static List<Field> fieldsToFieldList(@NotNull PsiField[] fields) {
List<Field> result = new LinkedList<Field>(); List<Field> result = new LinkedList<Field>();
@@ -256,13 +231,6 @@ public class Converter {
); );
} }
@NotNull
private static List<Function> methodsToFunctionList(@NotNull PsiMethod[] methods) {
List<Function> result = new LinkedList<Function>();
for (PsiMethod t : methods) result.add(methodToFunction(t, true));
return result;
}
@Nullable @Nullable
private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) { private static PsiMethod getPrimaryConstructorForThisCase(@NotNull PsiClass psiClass) {
ThisVisitor tv = new ThisVisitor(); ThisVisitor tv = new ThisVisitor();
@@ -306,6 +274,11 @@ public class Converter {
modifiers.add(Modifier.OVERRIDE); modifiers.add(Modifier.OVERRIDE);
if (method.getParent() instanceof PsiClass && ((PsiClass) method.getParent()).isInterface()) if (method.getParent() instanceof PsiClass && ((PsiClass) method.getParent()).isInterface())
modifiers.remove(Modifier.ABSTRACT); modifiers.remove(Modifier.ABSTRACT);
if (method.getParent() instanceof PsiClass) {
final PsiModifierList parentModifierList = ((PsiClass) method.getParent()).getModifierList();
if (parentModifierList != null && parentModifierList.hasExplicitModifier(Modifier.FINAL))
modifiers.add(Modifier.NOT_OPEN);
}
if (method.isConstructor()) { // TODO: simplify if (method.isConstructor()) { // TODO: simplify
boolean isPrimary = isConstructorPrimary(method); boolean isPrimary = isConstructorPrimary(method);
@@ -9,17 +9,15 @@ import java.util.List;
* @author ignatov * @author ignatov
*/ */
public class AnonymousClass extends Class { public class AnonymousClass extends Class {
public AnonymousClass(List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public AnonymousClass(List<Member> members) {
super(new IdentifierImpl("anonClass"), super(new IdentifierImpl("anonClass"),
Collections.<String>emptySet(), Collections.<String>emptySet(),
Collections.<Element>emptyList(), Collections.<Element>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
Collections.<Expression>emptyList(), Collections.<Expression>emptyList(),
Collections.<Type>emptyList(), Collections.<Type>emptyList(),
innerClasses, members
methods, );
fields,
initializers);
} }
@NotNull @NotNull
+28 -33
View File
@@ -18,31 +18,26 @@ public class Class extends Member {
String TYPE = "class"; String TYPE = "class";
final Identifier myName; final Identifier myName;
private final List<Expression> myBaseClassParams; private final List<Expression> myBaseClassParams;
private final List<Initializer> myInitializers; private final List<? extends Member> myMembers;
private final List<Element> myTypeParameters; private final List<Element> myTypeParameters;
private final List<Type> myExtendsTypes; private final List<Type> myExtendsTypes;
private final List<Type> myImplementsTypes; private final List<Type> myImplementsTypes;
final List<Class> myInnerClasses;
private final List<Function> myMethods;
final List<Field> myFields;
public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, public Class(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { List<Expression> baseClassParams, List<Type> implementsTypes, List<? extends Member> members) {
myName = name; myName = name;
myBaseClassParams = baseClassParams; myBaseClassParams = baseClassParams;
myModifiers = modifiers; myModifiers = modifiers;
myTypeParameters = typeParameters; myTypeParameters = typeParameters;
myExtendsTypes = extendsTypes; myExtendsTypes = extendsTypes;
myImplementsTypes = implementsTypes; myImplementsTypes = implementsTypes;
myInnerClasses = innerClasses; myMembers = members;
myMethods = methods;
myFields = fields;
myInitializers = initializers;
} }
@Nullable @Nullable
private Constructor getPrimaryConstructor() { private Constructor getPrimaryConstructor() {
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() == Kind.CONSTRUCTOR) if (m.getKind() == Kind.CONSTRUCTOR)
if (((Constructor) m).isPrimary()) if (((Constructor) m).isPrimary())
return (Constructor) m; return (Constructor) m;
@@ -82,9 +77,9 @@ public class Class extends Member {
} }
@NotNull @NotNull
List<Function> methodsExceptConstructors() { LinkedList<Member> membersExceptConstructors() {
final LinkedList<Function> result = new LinkedList<Function>(); final LinkedList<Member> result = new LinkedList<Member>();
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() != Kind.CONSTRUCTOR) if (m.getKind() != Kind.CONSTRUCTOR)
result.add(m); result.add(m);
return result; return result;
@@ -93,21 +88,30 @@ public class Class extends Member {
@NotNull @NotNull
List<Function> secondaryConstructorsAsStaticInitFunction() { List<Function> secondaryConstructorsAsStaticInitFunction() {
final LinkedList<Function> result = new LinkedList<Function>(); final LinkedList<Function> result = new LinkedList<Function>();
for (Function m : myMethods) for (Member m : myMembers)
if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) { if (m.getKind() == Kind.CONSTRUCTOR && !((Constructor) m).isPrimary()) {
Function f = (Function) m;
Set<String> modifiers = new HashSet<String>(m.myModifiers); Set<String> modifiers = new HashSet<String>(m.myModifiers);
modifiers.add(Modifier.STATIC); modifiers.add(Modifier.STATIC);
final List<Statement> statements = m.getBlock().getStatements(); final List<Statement> statements = f.getBlock().getStatements();
statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages statements.add(new ReturnStatement(new IdentifierImpl("__"))); // TODO: move to one place, find other __ usages
final Block block = new Block(statements); final Block block = new Block(statements);
final List<Element> typeParameters = new LinkedList<Element>();
if (f.getTypeParameters().size() == 0)
typeParameters.addAll(myTypeParameters);
else {
typeParameters.addAll(myTypeParameters);
typeParameters.addAll(f.getTypeParameters());
}
result.add(new Function( result.add(new Function(
new IdentifierImpl("init"), new IdentifierImpl("init"),
modifiers, modifiers,
new ClassType(myName), new ClassType(myName),
m.getTypeParameters(), typeParameters,
m.getParams(), f.getParams(),
block block
)); ));
} }
@@ -164,16 +168,13 @@ public class Class extends Member {
String bodyToKotlin() { String bodyToKotlin() {
return SPACE + "{" + N + return SPACE + "{" + N +
AstUtil.joinNodes(getNonStatic(myFields), N) + N + AstUtil.joinNodes(getNonStatic(membersExceptConstructors()), N) + N +
AstUtil.joinNodes(getNonStatic(myInitializers), N) + N +
classObjectToKotlin() + N + classObjectToKotlin() + N +
AstUtil.joinNodes(getNonStatic(methodsExceptConstructors()), N) + N +
AstUtil.joinNodes(getNonStatic(myInnerClasses), N) + N +
primaryConstructorBodyToKotlin() + N + primaryConstructorBodyToKotlin() + N +
"}"; "}";
} }
private List<Member> getStatic(List<? extends Member> members) { private static List<Member> getStatic(List<? extends Member> members) {
List<Member> result = new LinkedList<Member>(); List<Member> result = new LinkedList<Member>();
for (Member m : members) for (Member m : members)
if (m.isStatic()) if (m.isStatic())
@@ -181,7 +182,7 @@ public class Class extends Member {
return result; return result;
} }
private List<Member> getNonStatic(List<? extends Member> members) { private static List<Member> getNonStatic(List<? extends Member> members) {
List<Member> result = new LinkedList<Member>(); List<Member> result = new LinkedList<Member>();
for (Member m : members) for (Member m : members)
if (!m.isStatic()) if (!m.isStatic())
@@ -190,17 +191,11 @@ public class Class extends Member {
} }
private String classObjectToKotlin() { private String classObjectToKotlin() {
final List<Member> staticMethods = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction()); final List<Member> staticMembers = new LinkedList<Member>(secondaryConstructorsAsStaticInitFunction());
staticMethods.addAll(getStatic(methodsExceptConstructors())); staticMembers.addAll(getStatic(membersExceptConstructors()));
final List<Member> staticFields = getStatic(myFields); if (staticMembers.size() > 0) {
final List<Member> staticInitializers = getStatic(myInitializers);
final List<Member> staticInnerClasses = getStatic(myInnerClasses);
if (staticFields.size() + staticMethods.size() + staticInnerClasses.size() + staticInitializers.size() > 0) {
return "class" + SPACE + "object" + SPACE + "{" + N + return "class" + SPACE + "object" + SPACE + "{" + N +
AstUtil.joinNodes(staticFields, N) + N + AstUtil.joinNodes(staticMembers, N) + N +
AstUtil.joinNodes(staticInitializers, N) + N +
AstUtil.joinNodes(staticMethods, N) + N +
AstUtil.joinNodes(staticInnerClasses, N) + N +
"}"; "}";
} }
return EMPTY; return EMPTY;
@@ -16,7 +16,7 @@ public class DeclarationStatement extends Statement {
myElements = elements; myElements = elements;
} }
private List<String> toStringList(List<Element> elements) { private static List<String> toStringList(List<Element> elements) {
List<String> result = new LinkedList<String>(); List<String> result = new LinkedList<String>();
for (Element e : elements) { for (Element e : elements) {
if (e instanceof LocalVariable) { if (e instanceof LocalVariable) {
+7 -7
View File
@@ -10,11 +10,12 @@ import java.util.Set;
* @author ignatov * @author ignatov
*/ */
public class Enum extends Class { public class Enum extends Class {
public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public Enum(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
} }
String primaryConstructorSignatureToKotlin() { String primaryConstructorSignatureToKotlin() {
String s = super.primaryConstructorSignatureToKotlin(); String s = super.primaryConstructorSignatureToKotlin();
return s.equals("()") ? EMPTY : s; return s.equals("()") ? EMPTY : s;
} }
@@ -27,10 +28,9 @@ public class Enum extends Class {
@NotNull @NotNull
@Override @Override
public String toKotlin() { public String toKotlin() {
return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N + return modifiersToKotlin() + "enum" + SPACE + myName.toKotlin() + primaryConstructorSignatureToKotlin() +
AstUtil.joinNodes(myFields, N) + N + typeParametersToKotlin() + implementTypesToKotlin() + SPACE + "{" + N +
AstUtil.joinNodes(methodsExceptConstructors(), N) + N + AstUtil.joinNodes(membersExceptConstructors(), N) + N +
AstUtil.joinNodes(myInnerClasses, N) + N +
primaryConstructorBodyToKotlin() + N + primaryConstructorBodyToKotlin() + N +
"}"; "}";
} }
+2 -3
View File
@@ -25,8 +25,7 @@ public class File extends Node {
final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N; final String common = AstUtil.joinNodes(myImports, N) + N2 + AstUtil.joinNodes(myClasses, N) + N;
if (myPackageName.isEmpty()) if (myPackageName.isEmpty())
return common; return common;
return "namespace" + SPACE + myPackageName + SPACE + "{" + N + return "namespace" + SPACE + myPackageName + N +
common + common;
"}";
} }
} }
@@ -0,0 +1,29 @@
package org.jetbrains.jet.j2k.ast;
import org.jetbrains.annotations.NotNull;
/**
* @author ignatov
*/
public class ForeachWithRangeStatement extends Statement {
private Expression myStart;
private IdentifierImpl myIdentifier;
private Expression myEnd;
private 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();
}
}
@@ -78,6 +78,9 @@ public class Function extends Member {
if (!myModifiers.contains(Modifier.OVERRIDE) && !myModifiers.contains(Modifier.FINAL)) if (!myModifiers.contains(Modifier.OVERRIDE) && !myModifiers.contains(Modifier.FINAL))
modifierList.add(Modifier.OPEN); modifierList.add(Modifier.OPEN);
if (myModifiers.contains(Modifier.NOT_OPEN))
modifierList.remove(Modifier.OPEN);
modifierList.add(accessModifier()); modifierList.add(accessModifier());
if (modifierList.size() > 0) if (modifierList.size() > 0)
@@ -30,7 +30,7 @@ public class IdentifierImpl extends Expression implements Identifier {
return myName.length() == 0; return myName.length() == 0;
} }
private String quote(String str) { private static String quote(String str) {
return BACKTICK + str + BACKTICK; return BACKTICK + str + BACKTICK;
} }
@@ -1,6 +1,9 @@
package org.jetbrains.jet.j2k.ast; package org.jetbrains.jet.j2k.ast;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.util.AstUtil;
import java.util.List;
/** /**
* @author ignatov * @author ignatov
@@ -9,11 +12,13 @@ public class MethodCallExpression extends Expression {
private final Expression myMethodCall; private final Expression myMethodCall;
private final Element myParamList; private final Element myParamList;
private final boolean myIsResultNullable; private final boolean myIsResultNullable;
private final List<Type> myTypeParameters;
public MethodCallExpression(Expression methodCall, Element paramList, boolean nullable) { public MethodCallExpression(Expression methodCall, Element paramList, boolean nullable, List<Type> typeParameters) {
myMethodCall = methodCall; myMethodCall = methodCall;
myParamList = paramList; myParamList = paramList;
myIsResultNullable = nullable; myIsResultNullable = nullable;
myTypeParameters = typeParameters;
} }
@Override @Override
@@ -24,6 +29,7 @@ public class MethodCallExpression extends Expression {
@NotNull @NotNull
@Override @Override
public String toKotlin() { public String toKotlin() {
return myMethodCall.toKotlin() + "(" + myParamList.toKotlin() + ")"; String typeParamsToKotlin = myTypeParameters.size() > 0 ? "<" + AstUtil.joinNodes(myTypeParameters, COMMA_WITH_SPACE) + ">" : EMPTY;
return myMethodCall.toKotlin() + typeParamsToKotlin + "(" + myParamList.toKotlin() + ")";
} }
} }
@@ -12,5 +12,6 @@ public abstract class Modifier {
public static final String ABSTRACT = "abstract"; public static final String ABSTRACT = "abstract";
public static final String FINAL = "final"; public static final String FINAL = "final";
public static final String OPEN = "open"; public static final String OPEN = "open";
public static final String NOT_OPEN = "not open";
public static final String OVERRIDE = "override"; public static final String OVERRIDE = "override";
} }
@@ -9,23 +9,28 @@ import org.jetbrains.annotations.Nullable;
public class NewClassExpression extends Expression { public class NewClassExpression extends Expression {
private final Element myName; private final Element myName;
private final Element myArguments; private final Element myArguments;
private Expression myQualifier;
private AnonymousClass myAnonymousClass = null; private AnonymousClass myAnonymousClass = null;
public NewClassExpression(Element name, Element arguments) { public NewClassExpression(Element name, Element arguments) {
myName = name; myName = name;
myQualifier = EMPTY_EXPRESSION;
myArguments = arguments; myArguments = arguments;
} }
public NewClassExpression(Element name, Element arguments, @Nullable AnonymousClass anonymousClass) { public NewClassExpression(Expression qualifier, Element name, Element arguments, @Nullable AnonymousClass anonymousClass) {
this(name, arguments); this(name, arguments);
myQualifier = qualifier;
myAnonymousClass = anonymousClass; myAnonymousClass = anonymousClass;
} }
@NotNull @NotNull
@Override @Override
public String toKotlin() { public String toKotlin() {
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
return myAnonymousClass != null ? return myAnonymousClass != null ?
myName.toKotlin() + "(" + myArguments.toKotlin() + ")" + myAnonymousClass.toKotlin() : "object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + myArguments.toKotlin() + ")" + myAnonymousClass.toKotlin() :
myName.toKotlin() + "(" + myArguments.toKotlin() + ")"; qualifier + myName.toKotlin() + "(" + myArguments.toKotlin() + ")";
} }
} }
@@ -0,0 +1,26 @@
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 ReferenceElement extends Element {
private final Identifier myReference;
private final List<Type> myTypes;
public ReferenceElement(@NotNull Identifier reference, @NotNull List<Type> types) {
myReference = reference;
myTypes = types;
}
@NotNull
@Override
public String toKotlin() {
String typesIfNeeded = myTypes.size() > 0 ? "<" + AstUtil.joinNodes(myTypes, COMMA_WITH_SPACE) + ">" : EMPTY;
return myReference.toKotlin() + typesIfNeeded;
}
}
+3 -2
View File
@@ -7,8 +7,9 @@ import java.util.Set;
* @author ignatov * @author ignatov
*/ */
public class Trait extends Class { public class Trait extends Class {
public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes, List<Expression> baseClassParams, List<Type> implementsTypes, List<Class> innerClasses, List<Function> methods, List<Field> fields, List<Initializer> initializers) { public Trait(Identifier name, Set<String> modifiers, List<Element> typeParameters, List<Type> extendsTypes,
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, innerClasses, methods, fields, initializers); List<Expression> baseClassParams, List<Type> implementsTypes, List<Member> members) {
super(name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members);
TYPE = "trait"; TYPE = "trait";
} }
@@ -5,6 +5,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.Converter; import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.ast.*; import org.jetbrains.jet.j2k.ast.*;
import java.util.List;
import static org.jetbrains.jet.j2k.Converter.*; import static org.jetbrains.jet.j2k.Converter.*;
/** /**
@@ -42,7 +44,26 @@ public class ElementVisitor extends JavaElementVisitor {
@Override @Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) { public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
super.visitReferenceElement(reference); super.visitReferenceElement(reference);
myResult = new IdentifierImpl(reference.getQualifiedName()); // TODO
final List<Type> types = typesToTypeList(reference.getTypeParameters());
if (!reference.isQualified()) {
myResult = new ReferenceElement(
new IdentifierImpl(reference.getReferenceName()),
types
);
} else {
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
PsiElement qualifier = reference.getQualifier();
while (qualifier != null) {
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
qualifier = p.getQualifier();
}
myResult = new ReferenceElement(
new IdentifierImpl(result),
types
);
}
} }
@Override @Override
@@ -4,9 +4,11 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl; import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.j2k.Converter; import org.jetbrains.jet.j2k.Converter;
import org.jetbrains.jet.j2k.ast.*; import org.jetbrains.jet.j2k.ast.*;
import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.j2k.Converter.*; import static org.jetbrains.jet.j2k.Converter.*;
@@ -56,7 +58,7 @@ public class ExpressionVisitor extends StatementVisitor {
if (tokenType == JavaTokenType.OREQ) secondOp = "or"; if (tokenType == JavaTokenType.OREQ) secondOp = "or";
if (tokenType == JavaTokenType.GTGTGTEQ) secondOp = "cyclicShiftRight"; if (tokenType == JavaTokenType.GTGTGTEQ) secondOp = "cyclicShiftRight";
if (!secondOp.equals("")) // if not Kotlin operators if (!secondOp.isEmpty()) // if not Kotlin operators
myResult = new AssignmentExpression( myResult = new AssignmentExpression(
expressionToExpression(expression.getLExpression()), expressionToExpression(expression.getLExpression()),
new BinaryExpression( new BinaryExpression(
@@ -75,7 +77,7 @@ public class ExpressionVisitor extends StatementVisitor {
} }
@NotNull @NotNull
private String getOperatorString(@NotNull IElementType tokenType) { private static String getOperatorString(@NotNull IElementType tokenType) {
if (tokenType == JavaTokenType.PLUS) return "+"; if (tokenType == JavaTokenType.PLUS) return "+";
if (tokenType == JavaTokenType.MINUS) return "-"; if (tokenType == JavaTokenType.MINUS) return "-";
if (tokenType == JavaTokenType.ASTERISK) return "*"; if (tokenType == JavaTokenType.ASTERISK) return "*";
@@ -97,6 +99,7 @@ public class ExpressionVisitor extends StatementVisitor {
if (tokenType == JavaTokenType.OROR) return "||"; if (tokenType == JavaTokenType.OROR) return "||";
if (tokenType == JavaTokenType.PLUSPLUS) return "++"; if (tokenType == JavaTokenType.PLUSPLUS) return "++";
if (tokenType == JavaTokenType.MINUSMINUS) return "--"; if (tokenType == JavaTokenType.MINUSMINUS) return "--";
if (tokenType == JavaTokenType.EXCL) return "!";
System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType.toString()); System.out.println("UNSUPPORTED TOKEN TYPE: " + tokenType.toString());
return ""; return "";
@@ -170,7 +173,8 @@ public class ExpressionVisitor extends StatementVisitor {
new MethodCallExpression( new MethodCallExpression(
expressionToExpression(expression.getMethodExpression()), expressionToExpression(expression.getMethodExpression()),
elementToElement(expression.getArgumentList()), elementToElement(expression.getArgumentList()),
typeToType(expression.getType()).isNullable() typeToType(expression.getType()).isNullable(),
typesToTypeList(expression.getTypeArguments())
); );
} }
@@ -184,30 +188,51 @@ public class ExpressionVisitor extends StatementVisitor {
super.visitNewExpression(expression); super.visitNewExpression(expression);
if (expression.getArrayInitializer() != null) // new Foo[] {} if (expression.getArrayInitializer() != null) // new Foo[] {}
myResult = expressionToExpression(expression.getArrayInitializer()); myResult = createNewEmptyArray(expression);
else if (expression.getArrayDimensions().length > 0) { // new Foo[5] else if (expression.getArrayDimensions().length > 0) { // new Foo[5]
final List<Expression> callExpression = expressionsToExpressionList(expression.getArrayDimensions()); myResult = createNewNonEmptyArray(expression);
callExpression.add(new IdentifierImpl("{null}")); // TODO: remove
myResult = new NewClassExpression(
typeToType(expression.getType()), // TODO: remove
new ExpressionList(callExpression)
);
} else { // new Class(): common case } else { // new Class(): common case
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass(); myResult = createNewClassExpression(expression);
myResult = new NewClassExpression( }
}
@NotNull
private static Expression createNewClassExpression(@NotNull PsiNewExpression expression) {
final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
final PsiMethod constructor = expression.resolveMethod();
if (constructor == null || isConstructorPrimary(constructor)) {
return new NewClassExpression(
expressionToExpression(expression.getQualifier()),
elementToElement(expression.getClassOrAnonymousClassReference()), elementToElement(expression.getClassOrAnonymousClassReference()),
elementToElement(expression.getArgumentList()), elementToElement(expression.getArgumentList()),
anonymousClass != null ? anonymousClassToAnonymousClass(anonymousClass) : null anonymousClass != null ? anonymousClassToAnonymousClass(anonymousClass) : null
); );
// is constructor secondary
final PsiMethod constructor = expression.resolveMethod();
if (constructor != null && !isConstructorPrimary(constructor)) {
myResult = new CallChainExpression(
new IdentifierImpl(constructor.getName(), false),
new MethodCallExpression(new IdentifierImpl("init"), elementToElement(expression.getArgumentList()), false));
}
} }
// is constructor secondary
final PsiJavaCodeReferenceElement reference = expression.getClassReference();
final List<Type> typeParameters = reference != null ? typesToTypeList(reference.getTypeParameters()) : Collections.<Type>emptyList();
return new CallChainExpression(
new IdentifierImpl(constructor.getName(), false),
new MethodCallExpression(
new IdentifierImpl("init"),
elementToElement(expression.getArgumentList()),
false,
typeParameters));
}
@NotNull
private static NewClassExpression createNewNonEmptyArray(@NotNull PsiNewExpression expression) {
final List<Expression> callExpression = expressionsToExpressionList(expression.getArrayDimensions());
callExpression.add(new IdentifierImpl("{null}")); // TODO: remove
return new NewClassExpression(
typeToType(expression.getType()),
new ExpressionList(callExpression)
);
}
@NotNull
private static Expression createNewEmptyArray(@NotNull PsiNewExpression expression) {
return expressionToExpression(expression.getArrayInitializer());
} }
@Override @Override
@@ -240,7 +265,7 @@ public class ExpressionVisitor extends StatementVisitor {
public void visitReferenceExpression(PsiReferenceExpression expression) { public void visitReferenceExpression(PsiReferenceExpression expression) {
super.visitReferenceExpression(expression); super.visitReferenceExpression(expression);
final boolean isFieldReference = isFieldReference(expression); final boolean isFieldReference = isFieldReference(expression, getContainingClass(expression));
final boolean hasDollar = isFieldReference && isInsidePrimaryConstructor(expression); final boolean hasDollar = isFieldReference && isInsidePrimaryConstructor(expression);
final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression); final boolean insideSecondaryConstructor = isInsideSecondaryConstructor(expression);
final boolean hasReceiver = isFieldReference && insideSecondaryConstructor; final boolean hasReceiver = isFieldReference && insideSecondaryConstructor;
@@ -267,7 +292,7 @@ public class ExpressionVisitor extends StatementVisitor {
} }
@NotNull @NotNull
private String getClassName(PsiReferenceExpression expression) { private static String getClassName(@NotNull PsiReferenceExpression expression) {
PsiElement context = expression.getContext(); PsiElement context = expression.getContext();
while (context != null) { while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) { if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) {
@@ -283,20 +308,20 @@ public class ExpressionVisitor extends StatementVisitor {
return ""; return "";
} }
private boolean isFieldReference(PsiReferenceExpression expression) { private static boolean isFieldReference(@NotNull PsiReferenceExpression expression, PsiClass currentClass) {
final PsiReference reference = expression.getReference(); final PsiReference reference = expression.getReference();
if (reference != null) { if (reference != null) {
final PsiElement resolvedReference = reference.resolve(); final PsiElement resolvedReference = reference.resolve();
if (resolvedReference != null) { if (resolvedReference != null) {
if (resolvedReference instanceof PsiField) { if (resolvedReference instanceof PsiField) {
return true; return ((PsiField) resolvedReference).getContainingClass() == currentClass;
} }
} }
} }
return false; return false;
} }
private boolean isInsideSecondaryConstructor(PsiReferenceExpression expression) { private static boolean isInsideSecondaryConstructor(PsiReferenceExpression expression) {
PsiElement context = expression.getContext(); PsiElement context = expression.getContext();
while (context != null) { while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
@@ -306,7 +331,7 @@ public class ExpressionVisitor extends StatementVisitor {
return false; return false;
} }
private boolean isInsidePrimaryConstructor(PsiExpression expression) { private static boolean isInsidePrimaryConstructor(PsiExpression expression) {
PsiElement context = expression.getContext(); PsiElement context = expression.getContext();
while (context != null) { while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
@@ -316,7 +341,18 @@ public class ExpressionVisitor extends StatementVisitor {
return false; return false;
} }
private boolean isThisExpression(PsiReferenceExpression expression) { @Nullable
private static PsiClass getContainingClass(@NotNull PsiExpression expression) {
PsiElement context = expression.getContext();
while (context != null) {
if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor())
return ((PsiMethod) context).getContainingClass();
context = context.getContext();
}
return null;
}
private static boolean isThisExpression(PsiReferenceExpression expression) {
for (PsiReference r : expression.getReferences()) for (PsiReference r : expression.getReferences())
if (r.getCanonicalText().equals("this")) { if (r.getCanonicalText().equals("this")) {
final PsiElement res = r.resolve(); final PsiElement res = r.resolve();
@@ -1,6 +1,9 @@
package org.jetbrains.jet.j2k.visitors; package org.jetbrains.jet.j2k.visitors;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.ast.*; import org.jetbrains.jet.j2k.ast.*;
@@ -93,17 +96,66 @@ public class StatementVisitor extends ElementVisitor {
} }
@Override @Override
public void visitForStatement(PsiForStatement statement) { public void visitForStatement(@NotNull PsiForStatement statement) {
super.visitForStatement(statement); super.visitForStatement(statement);
List<Statement> forStatements = new LinkedList<Statement>(); final PsiStatement initialization = statement.getInitialization();
forStatements.add(statementToStatement(statement.getInitialization())); final PsiStatement update = statement.getUpdate();
forStatements.add(new WhileStatement( final PsiExpression condition = statement.getCondition();
expressionToExpression(statement.getCondition()), final PsiLocalVariable firstChild = initialization != null && initialization.getFirstChild() instanceof PsiLocalVariable ?
new Block( (PsiLocalVariable) initialization.getFirstChild() : null;
Arrays.asList(statementToStatement(statement.getBody()),
new Block(Arrays.asList(statementToStatement(statement.getUpdate()))))))); final IElementType operationTokenType = condition != null && condition instanceof PsiBinaryExpression ?
myResult = new Block(forStatements); ((PsiBinaryExpression) condition).getOperationTokenType() : null;
if (
initialization != null &&
initialization instanceof PsiDeclarationStatement
&& initialization.getFirstChild() == initialization.getLastChild()
&& condition != null
&& update != null
&& update.getChildren().length == 1
&& update.getChildren()[0] instanceof PsiPostfixExpression
&& ((PsiPostfixExpression) update.getChildren()[0]).getOperationTokenType() == JavaTokenType.PLUSPLUS
&& operationTokenType != null
&& (operationTokenType == JavaTokenType.LT || operationTokenType == JavaTokenType.LE)
&& initialization.getFirstChild() != null
&& initialization.getFirstChild() instanceof PsiLocalVariable
&& firstChild != null
&& firstChild.getNameIdentifier() != null
&& isOnceWritableIterator(firstChild)
) {
final Expression end = expressionToExpression(((PsiBinaryExpression) condition).getROperand());
final Expression endExpression = operationTokenType == JavaTokenType.LT ?
new BinaryExpression(end, new IdentifierImpl("1"), "-"):
end;
myResult = new ForeachWithRangeStatement(
new IdentifierImpl(firstChild.getName()),
expressionToExpression(firstChild.getInitializer()),
endExpression,
statementToStatement(statement.getBody())
);
} else { // common case: while loop instead of for loop
List<Statement> forStatements = new LinkedList<Statement>();
forStatements.add(statementToStatement(initialization));
forStatements.add(new WhileStatement(
expressionToExpression(condition),
new Block(
Arrays.asList(statementToStatement(statement.getBody()),
new Block(Arrays.asList(statementToStatement(update)))))));
myResult = new Block(forStatements);
}
}
private static boolean isOnceWritableIterator(PsiLocalVariable firstChild) {
int counter = 0;
if (firstChild != null)
for (PsiReference r : (ReferencesSearch.search(firstChild))) {
if (r instanceof PsiExpression) {
if (PsiUtil.isAccessedForWriting((PsiExpression) r))
counter++;
}
}
return counter == 1; // only increment usage
} }
@Override @Override
@@ -1,10 +1,14 @@
package org.jetbrains.jet.j2k.visitors; package org.jetbrains.jet.j2k.visitors;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.j2k.ast.*; import org.jetbrains.jet.j2k.ast.*;
import org.jetbrains.jet.j2k.util.AstUtil; import org.jetbrains.jet.j2k.util.AstUtil;
import java.util.LinkedList;
import java.util.List;
import static org.jetbrains.jet.j2k.Converter.typeToType; import static org.jetbrains.jet.j2k.Converter.typeToType;
import static org.jetbrains.jet.j2k.Converter.typesToTypeList; import static org.jetbrains.jet.j2k.Converter.typesToTypeList;
@@ -42,15 +46,56 @@ public class TypeVisitor extends PsiTypeVisitor<Type> {
@Override @Override
public Type visitClassType(PsiClassType classType) { public Type visitClassType(PsiClassType classType) {
myResult = new ClassType( String classTypeName = createQualifiedName(classType);
new IdentifierImpl(getClassTypeName(classType)), if (classTypeName.isEmpty())
typesToTypeList(classType.getParameters()) classTypeName = getClassTypeName(classType);
); List<Type> resolvedClassTypeParams = createRawTypesForResolvedReference(classType);
final IdentifierImpl identifier = new IdentifierImpl(classTypeName);
if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0)
myResult = new ClassType(identifier, resolvedClassTypeParams);
else
myResult = new ClassType(identifier, typesToTypeList(classType.getParameters()));
return super.visitClassType(classType); return super.visitClassType(classType);
} }
@NotNull @NotNull
private String getClassTypeName(@NotNull PsiClassType classType) { private static String createQualifiedName(@NotNull PsiClassType classType) {
String classTypeName = "";
if (classType instanceof PsiClassReferenceType) {
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
if (reference.isQualified()) {
String result = new IdentifierImpl(reference.getReferenceName()).toKotlin();
PsiElement qualifier = reference.getQualifier();
while (qualifier != null) {
final PsiJavaCodeReferenceElement p = (PsiJavaCodeReferenceElement) qualifier;
result = new IdentifierImpl(p.getReferenceName()).toKotlin() + "." + result; // TODO: maybe need to replace by safe call?
qualifier = p.getQualifier();
}
classTypeName = result;
}
}
return classTypeName;
}
@NotNull
private static List<Type> createRawTypesForResolvedReference(@NotNull PsiClassType classType) {
final List<Type> typeParams = new LinkedList<Type>();
if (classType instanceof PsiClassReferenceType) {
final PsiJavaCodeReferenceElement reference = ((PsiClassReferenceType) classType).getReference();
final PsiElement resolve = reference.resolve();
if (resolve != null) {
if (resolve instanceof PsiClass)
//noinspection UnusedDeclaration
for (PsiTypeParameter p : ((PsiClass) resolve).getTypeParameters())
typeParams.add(new StarProjectionType());
}
}
return typeParams;
}
@NotNull
private static String getClassTypeName(@NotNull PsiClassType classType) {
String canonicalTypeStr = classType.getCanonicalText(); String canonicalTypeStr = classType.getCanonicalText();
if (canonicalTypeStr.equals("java.lang.Object")) return "Any"; if (canonicalTypeStr.equals("java.lang.Object")) return "Any";
if (canonicalTypeStr.equals("java.lang.Byte")) return "Byte"; if (canonicalTypeStr.equals("java.lang.Byte")) return "Byte";
@@ -61,7 +106,7 @@ public class TypeVisitor extends PsiTypeVisitor<Type> {
if (canonicalTypeStr.equals("java.lang.Long")) return "Long"; if (canonicalTypeStr.equals("java.lang.Long")) return "Long";
if (canonicalTypeStr.equals("java.lang.Short")) return "Short"; if (canonicalTypeStr.equals("java.lang.Short")) return "Short";
if (canonicalTypeStr.equals("java.lang.Boolean")) return "Boolean"; if (canonicalTypeStr.equals("java.lang.Boolean")) return "Boolean";
return classType.getClassName(); return classType.getClassName() != null ? classType.getClassName() : classType.getCanonicalText();
} }
@Override @Override
@@ -47,7 +47,7 @@ public class JavaToKotlinConverterTest extends LightDaemonAnalyzerTestCase {
else if (javaFile.getParent().endsWith("/class")) actual = fileToKotlin(javaCode); else if (javaFile.getParent().endsWith("/class")) actual = fileToKotlin(javaCode);
else if (javaFile.getParent().endsWith("/file")) actual = fileToKotlin(javaCode); else if (javaFile.getParent().endsWith("/file")) actual = fileToKotlin(javaCode);
assert !actual.equals("") : "Specify what is it: file, class, method, statement or expression"; assert !actual.isEmpty() : "Specify what is it: file, class, method, statement or expression";
final File tmp = new File(kotlinPath + ".tmp"); final File tmp = new File(kotlinPath + ".tmp");
if (!expected.equals(actual)) writeStringToFile(tmp, actual); if (!expected.equals(actual)) writeStringToFile(tmp, actual);
@@ -92,18 +92,18 @@ public class JavaToKotlinConverterTest extends LightDaemonAnalyzerTestCase {
return suite; return suite;
} }
void configureFromText(String text) throws IOException { static void configureFromText(String text) throws IOException {
configureFromFileText("test.java", text); configureFromFileText("test.java", text);
} }
@NotNull @NotNull
String fileToKotlin(String text) throws IOException { static String fileToKotlin(String text) throws IOException {
configureFromText(text); configureFromText(text);
return prettify(Converter.fileToFile((PsiJavaFile) myFile).toKotlin()); return prettify(Converter.fileToFile((PsiJavaFile) myFile).toKotlin());
} }
@NotNull @NotNull
String methodToKotlin(String text) throws IOException { static String methodToKotlin(String text) throws IOException {
String result = fileToKotlin("final class C {" + text + "}") String result = fileToKotlin("final class C {" + text + "}")
.replaceAll("class C\\(\\) \\{", ""); .replaceAll("class C\\(\\) \\{", "");
result = result.substring(0, result.lastIndexOf("}")); result = result.substring(0, result.lastIndexOf("}"));
@@ -111,15 +111,15 @@ public class JavaToKotlinConverterTest extends LightDaemonAnalyzerTestCase {
} }
@NotNull @NotNull
String statementToKotlin(String text) throws Exception { static String statementToKotlin(String text) throws Exception {
String result = methodToKotlin("void main() {" + text + "}"); String result = methodToKotlin("void main() {" + text + "}");
int pos = result.lastIndexOf("}"); int pos = result.lastIndexOf("}");
result = result.substring(0, pos).replaceFirst("open fun main\\(\\) : Unit \\{", ""); result = result.substring(0, pos).replaceFirst("fun main\\(\\) : Unit \\{", "");
return prettify(result); return prettify(result);
} }
@NotNull @NotNull
String expressionToKotlin(String code) throws Exception { static String expressionToKotlin(String code) throws Exception {
String result = statementToKotlin("Object o =" + code + "}"); String result = statementToKotlin("Object o =" + code + "}");
result = result.replaceFirst("var o : Any\\? =", ""); result = result.replaceFirst("var o : Any\\? =", "");
return prettify(result); return prettify(result);
@@ -1,2 +1,2 @@
open fun fromArrayToCollection(a : Array<Foo?>?) : Unit { fun fromArrayToCollection(a : Array<Foo?>?) : Unit {
} }
@@ -1,6 +1,6 @@
open class Library() { open class Library() {
class object { class object {
val ourOut : PrintStream? val ourOut : java.io.PrintStream?
} }
} }
open class User() { open class User() {
@@ -1,8 +1,8 @@
class T() { class T() {
open fun main() : Unit { fun main() : Unit {
} }
open fun i() : Int { fun i() : Int {
} }
open fun s() : String? { fun s() : String? {
} }
} }
@@ -1,8 +1,8 @@
class S() { class S() {
fun sB() : Boolean {
return true
}
class object { class object {
var myI : Int = 10 var myI : Int = 10
} }
open fun sB() : Boolean {
return true
}
} }
+1 -1
View File
@@ -1,6 +1,6 @@
class S() { class S() {
class object { class object {
open fun staticF() : Boolean { fun staticF() : Boolean {
return true return true
} }
} }
@@ -1,10 +1,10 @@
class S() { class S() {
fun sB() : Boolean {
return true
}
class object { class object {
open fun sI() : Int { fun sI() : Int {
return 1 return 1
} }
} }
open fun sB() : Boolean {
return true
}
} }
+2 -2
View File
@@ -1,9 +1,9 @@
class S() { class S() {
class object { class object {
open fun sB() : Boolean { fun sB() : Boolean {
return true return true
} }
open fun sI() : Int { fun sI() : Int {
return 1 return 1
} }
} }
@@ -1,4 +1,4 @@
namespace org.test.customer { namespace org.test.customer
open class Customer(first : String?, last : String?) { open class Customer(first : String?, last : String?) {
public val _firstName : String? public val _firstName : String?
public val _lastName : String? public val _lastName : String?
@@ -31,16 +31,15 @@ _lastName = lastName
return this return this
} }
open public fun Build() : Customer? { open public fun Build() : Customer? {
return org.test.customer.Customer(_firstName, _lastName) return Customer(_firstName, _lastName)
} }
} }
public open class User() { public open class User() {
class object { class object {
open public fun main() : Unit { open public fun main() : Unit {
var customer : Customer? = org.test.customer.CustomerBuilder().WithFirstName("Homer")?.WithLastName("Simpson")?.Build() var customer : Customer? = CustomerBuilder().WithFirstName("Homer")?.WithLastName("Simpson")?.Build()
System.out?.println(customer?.getFirstName()) System.out?.println(customer?.getFirstName())
System.out?.println(customer?.getLastName()) System.out?.println(customer?.getLastName())
} }
} }
} }
}
@@ -0,0 +1,33 @@
public class Identifier<T> {
private final T myName;
private boolean myHasDollar;
private boolean myNullable = true;
public Identifier(T name) {
myName = name;
}
public Identifier(T name, boolean isNullable) {
myName = name;
myNullable = isNullable;
}
public Identifier(T name, boolean hasDollar, boolean isNullable) {
myName = name;
myHasDollar = hasDollar;
myNullable = isNullable;
}
@Override
public T getName() {
return myName;
}
}
public class User {
public static void main() {
Identifier<?> i1 = new Identifier<String>("name", false, true);
Identifier i2 = new Identifier<String>("name", false);
Identifier i3 = new Identifier<String>("name");
}
}
@@ -0,0 +1,37 @@
public open class Identifier<T>(myName : T?, myHasDollar : Boolean) {
private val myName : T?
private var myHasDollar : Boolean
private var myNullable : Boolean = true
open public fun getName() : T? {
return myName
}
class object {
open public fun init<T>(name : T?) : Identifier {
val __ = Identifier(name, false)
return __
}
open public fun init<T>(name : T?, isNullable : Boolean) : Identifier {
val __ = Identifier(name, false)
__.myNullable = isNullable
return __
}
open public fun init<T>(name : T?, hasDollar : Boolean, isNullable : Boolean) : Identifier {
val __ = Identifier(name, hasDollar)
__.myNullable = isNullable
return __
}
}
{
$myName = myName
$myHasDollar = myHasDollar
}
}
public open class User() {
class object {
open public fun main() : Unit {
var i1 : Identifier<*>? = Identifier.init<String?>("name", false, true)
var i2 : Identifier<*>? = Identifier.init<String?>("name", false)
var i3 : Identifier<*>? = Identifier.init<String?>("name")
}
}
}
+3 -3
View File
@@ -2,6 +2,9 @@ public open class Identifier(myName : String?, myHasDollar : Boolean) {
private val myName : String? private val myName : String?
private var myHasDollar : Boolean private var myHasDollar : Boolean
private var myNullable : Boolean = true private var myNullable : Boolean = true
open public fun getName() : String? {
return myName
}
class object { class object {
open public fun init(name : String?) : Identifier { open public fun init(name : String?) : Identifier {
val __ = Identifier(name, false) val __ = Identifier(name, false)
@@ -18,9 +21,6 @@ __.myNullable = isNullable
return __ return __
} }
} }
open public fun getName() : String? {
return myName
}
{ {
$myName = myName $myName = myName
$myHasDollar = myHasDollar $myHasDollar = myHasDollar
+1 -2
View File
@@ -1,4 +1,3 @@
namespace test { namespace test
class C() { class C() {
} }
}
+1 -2
View File
@@ -1,4 +1,3 @@
namespace test { namespace test
import ast import ast
import ast2 import ast2
}
@@ -1,4 +1,3 @@
namespace test { namespace test
import ast import ast
import ast2 import ast2
}
@@ -1,4 +1,3 @@
namespace test { namespace test
open class C() { open class C() {
} }
}
@@ -1,4 +1,3 @@
namespace test { namespace test
import ast import ast
import ast2 import ast2
}
@@ -0,0 +1,2 @@
int[] array = new int[10];
for (int i = 0; i <= 10; i++) {array[i] = i;}
@@ -0,0 +1,4 @@
var array : IntArray? = IntArray?(10, {null})
for (i in 0..10) {
array[i] = i
}
@@ -0,0 +1,2 @@
int[] array = new int[10];
for (int i = 0; i < 10; i++) {array[i] = i;}
@@ -0,0 +1,4 @@
var array : IntArray? = IntArray?(10, {null})
for (i in 0..(10 - 1)) {
array[i] = i
}
+2 -1
View File
@@ -1 +1,2 @@
for (int i = 0; i < 0; i++) {int i = 1; i++;} int[] array = new int[10];
for (int i = 0; i < 10; i++) {array[i] = i;}
+3 -12
View File
@@ -1,13 +1,4 @@
{ var array : IntArray? = IntArray?(10, {null})
var i : Int = 0 for (i in 0..(10 - 1)) {
while ((i < 0)) array[i] = i
{
{
var i : Int = 1
(i++)
}
{
(i++)
}
}
} }
@@ -1,10 +1 @@
{ for (i in 0..(0 - 1)) (t++)
var i : Int = 0
while ((i < 0))
{
(t++)
{
(i++)
}
}
}
@@ -0,0 +1,5 @@
package demo;
final class Final {
void test() {}
}
@@ -0,0 +1,5 @@
namespace demo
class Final() {
fun test() : Unit {
}
}
@@ -1 +1 @@
abstract open fun getNoofGears() : Int abstract fun getNoofGears() : Int
@@ -1,2 +1,2 @@
open fun getT() : T? { fun getT() : T? {
} }
@@ -1,2 +1,2 @@
open fun main() : Unit { fun main() : Unit {
} }
+1 -1
View File
@@ -1,2 +1,2 @@
open fun test() : Unit { fun test() : Unit {
} }
+1 -1
View File
@@ -1,4 +1,4 @@
class object { class object {
open public fun main(args : Array<String?>?) : Unit { public fun main(args : Array<String?>?) : Unit {
} }
} }
@@ -1,2 +1,2 @@
open fun main() : String? { fun main() : String? {
} }
@@ -1,2 +1,2 @@
open fun main() : Int { fun main() : Int {
} }
@@ -1,2 +1,2 @@
open fun main() : Boolean { fun main() : Boolean {
} }
@@ -1,3 +1,3 @@
open fun isTrue() : Boolean { fun isTrue() : Boolean {
return true return true
} }
+1 -1
View File
@@ -1,3 +1,3 @@
open fun getString() : String? { fun getString() : String? {
return "" return ""
} }
@@ -1,2 +1,2 @@
open fun putU<U>(u : U?) : Unit { fun putU<U>(u : U?) : Unit {
} }
@@ -1,2 +1,2 @@
open fun putUVW<U, V, W>(u : U?, v : V?, w : W?) : Unit { fun putUVW<U, V, W>(u : U?, v : V?, w : W?) : Unit {
} }
+1 -1
View File
@@ -1,2 +1,2 @@
open private fun test() : Unit { private fun test() : Unit {
} }
+1 -1
View File
@@ -1,2 +1,2 @@
open protected fun test() : Unit { protected fun test() : Unit {
} }
+1 -1
View File
@@ -1,2 +1,2 @@
open public fun test() : Unit { public fun test() : Unit {
} }
@@ -1,5 +1,4 @@
namespace test { namespace test
import `namespace`.`as`.`type`.`val`.`var`.`fun`.`is`.`in`.`object`.`when`.`trait`.`This` import `namespace`.`as`.`type`.`val`.`var`.`fun`.`is`.`in`.`object`.`when`.`trait`.`This`
open class Test() { open class Test() {
} }
}
@@ -1,5 +1,4 @@
namespace org.jetbrains.jet.j2k { namespace org.jetbrains.jet.j2k
import org.jetbrains.annotations.* import org.jetbrains.annotations.*
public open class Converter() { public open class Converter() {
} }
}
@@ -1,5 +1,4 @@
namespace org.jetbrains.jet.j2k { namespace org.jetbrains.jet.j2k
import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.NotNull
public open class Converter() { public open class Converter() {
} }
}
@@ -1,2 +1,2 @@
open fun popAll(dst : Collection<in E?>?) : Unit { fun popAll(dst : Collection<in E?>?) : Unit {
} }
@@ -1,8 +1,4 @@
@test { @test for (i in 0..max) {
var i : Int = 0
while ((i <= max))
{
{
var n : Int = substring.length() var n : Int = substring.length()
var j : Int = i var j : Int = i
var k : Int = 0 var k : Int = 0
@@ -16,11 +12,6 @@ continue@test
foundIt = true foundIt = true
break@test break@test
} }
{
(i++)
}
}
}
System.out?.println((if (foundIt) System.out?.println((if (foundIt)
"Found it" "Found it"
else else
@@ -0,0 +1,12 @@
package demo;
class Map {
<K, V> void put(K k, V v) {}
}
class U {
void test() {
Map m = new Map();
m.<String, int>put("10", 10);
}
}
@@ -0,0 +1,11 @@
namespace demo
open class Map() {
open fun put<K, V>(k : K?, v : V?) : Unit {
}
}
open class U() {
open fun test() : Unit {
var m : Map? = Map()
m?.put<String?, Int>("10", 10)
}
}
@@ -1 +0,0 @@
new myApp.Foo();
@@ -1 +0,0 @@
myApp.Foo()
@@ -1,4 +1,4 @@
java.lang.Runnable() { object : Runnable() {
override public fun run() : Unit { override public fun run() : Unit {
System.out?.println("Run") System.out?.println("Run")
} }
@@ -0,0 +1,9 @@
package test;
import java.util.List;
class User {
void main() {
List list = new java.util.LinkedList();
}
}
@@ -0,0 +1,7 @@
namespace test
import java.util.List
open class User() {
open fun main() : Unit {
var list : List<*>? = java.util.LinkedList()
}
}
@@ -0,0 +1,7 @@
package test;
class User {
void main() {
java.util.List list = new java.util.LinkedList();
}
}
@@ -0,0 +1,6 @@
namespace test
open class User() {
open fun main() : Unit {
var list : java.util.List<*>? = java.util.LinkedList()
}
}
@@ -0,0 +1,8 @@
import java.util.List;
import java.util.LinkedList;
class User {
void main() {
List<String> list = new LinkedList<String>();
}
}
@@ -0,0 +1,7 @@
import java.util.List
import java.util.LinkedList
open class User() {
open fun main() : Unit {
var list : List<String?>? = LinkedList<String?>()
}
}
@@ -1,9 +1,8 @@
namespace org.test { namespace org.test
open class Library() { open class Library() {
} }
open class User() { open class User() {
open fun main() : Unit { open fun main() : Unit {
var lib : Library? = org.test.Library() var lib : Library? = Library()
}
} }
} }
@@ -0,0 +1,13 @@
package org.test;
class OuterClass {
class InnerClass {
}
}
class User {
void main() {
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
}
}
@@ -0,0 +1,11 @@
namespace org.test
open class OuterClass() {
open class InnerClass() {
}
}
open class User() {
open fun main() : Unit {
var outerObject : OuterClass? = OuterClass()
var innerObject : OuterClass.InnerClass? = outerObject?.InnerClass()
}
}
@@ -0,0 +1,13 @@
package org.test;
import java.util.List;
import java.util.LinkedList;
class Member {}
class User {
void main() {
List<Member> members = new LinkedList<Member>();
members.add(new Member());
}
}
@@ -0,0 +1,11 @@
namespace org.test
import java.util.List
import java.util.LinkedList
open class Member() {
}
open class User() {
open fun main() : Unit {
var members : List<Member?>? = LinkedList<Member?>()
members?.add(Member())
}
}
@@ -0,0 +1,11 @@
package demo;
class Foo {
static class Bar {}
}
class User {
void main() {
Foo.Bar boo = new Foo.Bar();
}
}
@@ -0,0 +1,12 @@
namespace demo
open class Foo() {
class object {
open class Bar() {
}
}
}
open class User() {
open fun main() : Unit {
var boo : Foo.Bar? = Foo.Bar()
}
}
@@ -0,0 +1,24 @@
package demo;
class WindowAdapter {
public void windowClosing () {
}
}
public final class Client extends Frame {
Client() {
WindowAdapter a = new WindowAdapter() {
@Override
public void windowClosing () {
}
}
addWindowListener(a);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing () {
}
});
}
}
@@ -0,0 +1,18 @@
namespace demo
open class WindowAdapter() {
open public fun windowClosing() : Unit {
}
}
public class Client() : Frame() {
{
var a : WindowAdapter? = object : WindowAdapter() {
override public fun windowClosing() : Unit {
}
}
addWindowListener(a)
addWindowListener(object : WindowAdapter() {
override public fun windowClosing() : Unit {
}
})
}
}
@@ -1,2 +1,2 @@
open fun pushAll(src : Collection<out E?>?) : Unit { fun pushAll(src : Collection<out E?>?) : Unit {
} }
@@ -1,6 +1,5 @@
namespace org.jetbrains.jet.j2k.`in` { namespace org.jetbrains.jet.j2k.`in`
import org.jetbrains.annotations.NotNull import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable import org.jetbrains.annotations.Nullable
public open class Converter() { public open class Converter() {
} }
}
@@ -0,0 +1,15 @@
package demo;
class Collection<E> {
Collection(E e) {
System.out.println(e);
}
}
class Test {
void main() {
Collection raw1 = new Collection(1);
Collection raw2 = new Collection<Integer>(1);
Collection raw3 = new Collection<String>("1");
}
}
@@ -0,0 +1,13 @@
namespace demo
open class Collection<E>(e : E?) {
{
System.out?.println(e)
}
}
open class Test() {
open fun main() : Unit {
var raw1 : Collection<*>? = Collection(1)
var raw2 : Collection<*>? = Collection<Int?>(1)
var raw3 : Collection<*>? = Collection<String?>("1")
}
}
+12
View File
@@ -0,0 +1,12 @@
package demo;
import java.util.List;
import java.util.LinkedList;
class Test {
void main() {
List<String> common = new LinkedList<String>();
List raw = new LinkedList<String>();
List superRaw = new LinkedList();
}
}
+10
View File
@@ -0,0 +1,10 @@
namespace demo
import java.util.List
import java.util.LinkedList
open class Test() {
open fun main() : Unit {
var common : List<String?>? = LinkedList<String?>()
var raw : List<*>? = LinkedList<String?>()
var superRaw : List<*>? = LinkedList()
}
}
@@ -0,0 +1,14 @@
package demo;
class TestT {
<T> void getT() { }
}
class U {
void main() {
TestT t = new TestT();
t.<String>getT();
t.<Integer>getT();
t.getT();
}
}
@@ -0,0 +1,13 @@
namespace demo
open class TestT() {
open fun getT<T>() : Unit {
}
}
open class U() {
open fun main() : Unit {
var t : TestT? = TestT()
t?.getT<String?>()
t?.getT<Int?>()
t?.getT()
}
}
@@ -1,2 +1,2 @@
open fun wtf(w : Collection<*>?) : Unit { fun wtf(w : Collection<*>?) : Unit {
} }
@@ -1,2 +1,2 @@
open fun max<T : Any?, K : Node?>(coll : Collection<out T?>?) : T? where T : Comparable<in T?>?, K : Collection<in K?>? { fun max<T : Any?, K : Node?>(coll : Collection<out T?>?) : T? where T : Comparable<in T?>?, K : Collection<in K?>? {
} }
+1 -1
View File
@@ -1,2 +1,2 @@
open fun max<T : Any?>(coll : Collection<out T?>?) : T? where T : Comparable<in T?>? { fun max<T : Any?>(coll : Collection<out T?>?) : T? where T : Comparable<in T?>? {
} }
@@ -1 +1 @@
open fun format(pattern : String?, vararg arguments : Any?) : String? fun format(pattern : String?, vararg arguments : Any?) : String?
@@ -1,2 +1,2 @@
open fun pushAll(vararg objs : Any?) : Unit { fun pushAll(vararg objs : Any?) : Unit {
} }