diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java deleted file mode 100644 index 40aa89c7a0e..00000000000 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ /dev/null @@ -1,791 +0,0 @@ -/* - * 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.ImmutableMap; -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.ast.types.ClassType; -import org.jetbrains.jet.j2k.ast.types.EmptyType; -import org.jetbrains.jet.j2k.ast.types.Type; -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 com.intellij.psi.CommonClassNames.*; -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" - ); - - private static final Map PRIMITIVE_TYPE_CONVERSIONS = ImmutableMap.builder() - .put("byte", BYTE) - .put("short", SHORT) - .put("int", INT) - .put("long", LONG) - .put("float", FLOAT) - .put("double", DOUBLE) - .put("char", CHAR) - - .put(JAVA_LANG_BYTE, BYTE) - .put(JAVA_LANG_SHORT, SHORT) - .put(JAVA_LANG_INTEGER, INT) - .put(JAVA_LANG_LONG, LONG) - .put(JAVA_LANG_FLOAT, FLOAT) - .put(JAVA_LANG_DOUBLE, DOUBLE) - .put(JAVA_LANG_CHARACTER, CHAR) - .build(); - - @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 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 fields) { - List result = new LinkedList(); - for (Field f : fields) - result.add(new Parameter(new IdentifierImpl("_" + f.getIdentifier().getName()), f.getType(), true)); - return result; - } - - @NotNull - private static List createInitStatementsFromFields(@NotNull List 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 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).getIsPrimary()) { - 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(), false), - 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().getNullable()) { - 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()), - expressionToExpression(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 new EmptyType(); - 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) { - return result.convertedToNotNull(); - } - return result; - } - - @NotNull - private List typesToNotNullableTypeList(@NotNull PsiType[] types) { - List result = new ArrayList(); - for (PsiType type : types) { - result.add(typeToType(type).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())), - true - ); - } - - @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; - } - - public List argumentsToExpressionList(@NotNull PsiCallExpression expression) { - PsiExpressionList argumentList = expression.getArgumentList(); - PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : PsiExpression.EMPTY_ARRAY; - List result = new ArrayList(); - - PsiMethod resolved = expression.resolveMethod(); - List expectedTypes = new ArrayList(); - if (resolved != null) { - for (PsiParameter p : resolved.getParameterList().getParameters()) - expectedTypes.add(p.getType()); - } - - // TODO handle varargs correctly - if (arguments.length == expectedTypes.size()) { - for (int i = 0; i < expectedTypes.size(); i++) - result.add(expressionToExpression(arguments[i], expectedTypes.get(i))); - } - else { - for (PsiExpression argument : arguments) { - result.add(expressionToExpression(argument)); - } - } - - return result; - } - - public Expression expressionToExpression(PsiExpression argument, PsiType expectedType) { - if (argument == null) return (IdentifierImpl) Identifier.EMPTY_IDENTIFIER; - Expression expression = expressionToExpression(argument); - PsiType actualType = argument.getType(); - boolean isPrimitiveTypeOrNull = actualType == null || actualType instanceof PsiPrimitiveType; - boolean isRef = (argument instanceof PsiReferenceExpression && ((PsiReferenceExpression) argument).isQualified() || argument instanceof PsiMethodCallExpression); - - if (isPrimitiveTypeOrNull && isRef && expression.isNullable()) { - expression = new BangBangExpression(expression); - } - - if (actualType != null) { - if (isConversionNeeded(actualType, expectedType) && !(expression instanceof LiteralExpression)) { - String conversion = PRIMITIVE_TYPE_CONVERSIONS.get(expectedType.getCanonicalText()); - if (conversion != null) { - expression = new DummyMethodCallExpression(expression, conversion, (IdentifierImpl) Identifier.EMPTY_IDENTIFIER); - } - } - } - return expression; - } - - 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 applyConversion(Expression expression, String conversion) { -// if (conversion.isEmpty()) -// return expression.toKotlin(); -// return "(" + expression.toKotlin() + ")" + conversion; -// } - -} diff --git a/src/org/jetbrains/jet/j2k/Converter.kt b/src/org/jetbrains/jet/j2k/Converter.kt new file mode 100644 index 00000000000..09e5963194c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/Converter.kt @@ -0,0 +1,681 @@ +package org.jetbrains.jet.j2k + +import com.google.common.collect.ImmutableMap +import com.google.common.collect.ImmutableSet +import com.google.common.collect.Sets +import com.intellij.psi.* +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.ast.types.ClassType +import org.jetbrains.jet.j2k.ast.types.EmptyType +import org.jetbrains.jet.j2k.ast.types.Type +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 org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses +import org.jetbrains.jet.j2k.ConverterUtil.createMainFunction +import com.intellij.psi.CommonClassNames.* +import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* + +public open class Converter() { + private var classIdentifiers: Set = hashSet() + private val dispatcher: Dispatcher = Dispatcher(this) + private var methodReturnType: PsiType? = null + private val flags: Set? = Sets.newHashSet() + public open fun addFlag(flag: J2KConverterFlags): Boolean { + return flags?.add(flag)!! + } + public open fun hasFlag(flag: J2KConverterFlags): Boolean { + return flags?.contains(flag)!! + } + + public open fun setClassIdentifiers(identifiers: Set) { + classIdentifiers = identifiers + } + + public open fun getClassIdentifiers(): Set { + return Collections.unmodifiableSet(classIdentifiers)!! + } + + public open fun getMethodReturnType(): PsiType? { + return methodReturnType + } + + public open fun clearClassIdentifiers(): Unit { + classIdentifiers.clear() + } + + public open fun elementToKotlin(element: PsiElement): String = + when(element) { + is PsiJavaFile -> fileToFile(element).toKotlin() + is PsiClass -> classToClass(element).toKotlin() + is PsiMethod -> methodToFunction(element).toKotlin() + is PsiField -> fieldToField(element, element.getContainingClass()).toKotlin() + is PsiStatement -> statementToStatement(element).toKotlin() + is PsiExpression -> expressionToExpression(element).toKotlin() + else -> "" + + } + + public open fun fileToFile(javaFile: PsiJavaFile): File { + return fileToFile(javaFile, Collections.emptyList()!!) + } + + public open fun fileToFileWithCompatibilityImport(javaFile: PsiJavaFile): File { + return fileToFile(javaFile, Collections.singletonList("kotlin.compatibility.*")!!) + } + + private fun fileToFile(javaFile: PsiJavaFile, additionalImports: List): File { + val importList: PsiImportList? = javaFile.getImportList() + val imports: List = (if (importList == null) + arrayList() + else + importsToImportList(importList.getAllImportStatements())) + for (i : String in additionalImports) + imports.add(Import(i)) + return File(quoteKeywords(javaFile.getPackageName()), imports, classesToClassList(javaFile.getClasses()), createMainFunction(javaFile)) + } + + private fun classesToClassList(classes: Array): List = classes.map { classToClass(it!!) } + + public open fun anonymousClassToAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { + return AnonymousClass(this, getMembers(anonymousClass)) + } + + private fun getMembers(psiClass: PsiClass): List { + val members: List = arrayList() + for (e : PsiElement? in psiClass.getChildren()) { + val converted = memberToMember(e, psiClass) + if (converted != null) members.add(converted) + } + return members + } + + private fun memberToMember(e: PsiElement?, containingClass: PsiClass): Member? = when(e) { + is PsiMethod -> methodToFunction(e, true) + is PsiField -> fieldToField(e, containingClass) + is PsiClass -> classToClass(e) + is PsiClassInitializer -> initializerToInitializer(e) + else -> null + } + + private fun classToClass(psiClass: PsiClass): Class { + val modifiers: Set = modifiersListToModifiersSet(psiClass.getModifierList()) + val fields: List = fieldsToFieldList(psiClass.getFields(), psiClass) + val typeParameters: List = elementsToElementList(psiClass.getTypeParameters()) + val implementsTypes: List = typesToNotNullableTypeList(psiClass.getImplementsListTypes()) + val extendsTypes: List = typesToNotNullableTypeList(psiClass.getExtendsListTypes()) + val name: IdentifierImpl = IdentifierImpl(psiClass.getName()) + val baseClassParams: List = arrayList() + val members: List = getMembers(psiClass) + val visitor: SuperVisitor = SuperVisitor() + psiClass.accept(visitor) + val resolvedSuperCallParameters = visitor.resolvedSuperCallParameters + if (resolvedSuperCallParameters.size() == 1) { + val psiExpressionList = resolvedSuperCallParameters.iterator().next() + baseClassParams.addAll(expressionsToExpressionList(psiExpressionList.getExpressions())) + } + + if (!psiClass.isEnum() && !psiClass.isInterface() && psiClass.getConstructors().size > 1 && + getPrimaryConstructorForThisCase(psiClass) == null) { + val finalOrWithEmptyInitializer: List = getFinalOrWithEmptyInitializer(fields) + val initializers: Map = HashMap() + for (m in members) { + if (m is Constructor) { + if (!m.isPrimary) { + for (fo in finalOrWithEmptyInitializer){ + val init: String = getDefaultInitializer(fo) + initializers.put(fo.identifier.toKotlin(), init) + } + val newStatements: List = arrayList() + for (s : Statement? in m.block!!.statements) { + var isRemoved: Boolean = false + if (s is AssignmentExpression) { + if (s.left.getKind() == INode.Kind.CALL_CHAIN) { + for (fo : Field in finalOrWithEmptyInitializer) { + val id: String = fo.identifier.toKotlin() + if ((s.left as CallChainExpression).identifier.toKotlin().endsWith("." + id)) { + initializers.put(id, s.right.toKotlin()) + isRemoved = true + } + + } + } + + } + + if (!isRemoved) { + newStatements.add(s!!) + } + + } + newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializer, initializers))) + m.block = Block(newStatements) + } + } + } + members.add(Constructor(Identifier.EMPTY_IDENTIFIER, Collections.emptySet()!!, + ClassType(name, Collections.emptyList()!!, false), + Collections.emptyList()!!, + ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), + Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)), + true)) + } + + if (psiClass.isInterface()) { + return Trait(this, name, modifiers, typeParameters, extendsTypes, Collections.emptyList()!!, implementsTypes, members) + } + + if (psiClass.isEnum()) { + return Enum(this, name, modifiers, typeParameters, Collections.emptyList()!!, Collections.emptyList()!!, implementsTypes, members) + } + + return Class(this, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) + } + + private fun initializerToInitializer(i: PsiClassInitializer): Initializer { + return Initializer(blockToBlock(i.getBody(), true), modifiersListToModifiersSet(i.getModifierList())) + } + + private fun fieldsToFieldList(fields: Array, psiClass: PsiClass): List { + return fields.map { fieldToField(it!!, psiClass) } + } + + private fun fieldToField(field: PsiField, psiClass: PsiClass?): Field { + val modifiers: Set = modifiersListToModifiersSet(field.getModifierList()) + if (field is PsiEnumConstant?) { + return EnumConstant(IdentifierImpl(field.getName()), modifiers, typeToType(field.getType()), elementToElement(field.getArgumentList())) + } + + return Field(IdentifierImpl(field.getName()), + modifiers, + typeToType(field.getType()), + expressionToExpression(field.getInitializer(), field.getType()), + countWritingAccesses(field, psiClass)) + } + + private fun methodToFunction(method: PsiMethod): Function { + return methodToFunction(method, true) + } + + private fun methodToFunction(method: PsiMethod, notEmpty: Boolean): Function { + if (isOverrideObjectDirect(method)) { + dispatcher.expressionVisitor = ExpressionVisitorForDirectObjectInheritors(this) + } + else { + dispatcher.expressionVisitor = ExpressionVisitor(this) + } + methodReturnType = method.getReturnType() + val identifier: IdentifierImpl = IdentifierImpl(method.getName()) + val returnType: Type = typeToType(method.getReturnType(), ConverterUtil.isAnnotatedAsNotNull(method.getModifierList())) + val body: Block = (if (hasFlag(J2KConverterFlags.SKIP_BODIES)) + Block.EMPTY_BLOCK + else + blockToBlock(method.getBody(), notEmpty)) + + val params: Element = createFunctionParameters(method) + val typeParameters: List = elementsToElementList(method.getTypeParameters()) + val modifiers: Set = modifiersListToModifiersSet(method.getModifierList()) + if (isOverrideAnyMethodExceptMethodsFromObject(method)) { + modifiers.add(Modifier.OVERRIDE) + } + + val containingClass = method.getContainingClass() + if (containingClass != null && containingClass.isInterface()) { + modifiers.remove(Modifier.ABSTRACT) + } + + if (isNotOpenMethod(method)) { + modifiers.add(Modifier.NOT_OPEN) + } + + if (method.isConstructor()) { + val isPrimary: Boolean = isConstructorPrimary(method) + return Constructor(identifier, modifiers, returnType, typeParameters, params, Block(removeEmpty(body.statements), false), isPrimary) + } + + return Function(identifier, modifiers, returnType, typeParameters, params, body) + } + + private fun createFunctionParameters(method: PsiMethod): ParameterList { + val result: List = arrayList() + for (parameter : PsiParameter? in method.getParameterList().getParameters()) + { + result.add(Parameter(IdentifierImpl(parameter?.getName()), + typeToType(parameter?.getType(), + ConverterUtil.isAnnotatedAsNotNull(parameter?.getModifierList())), + ConverterUtil.isReadOnly(parameter, method.getBody()))) + } + return ParameterList(result) + } + + private fun isOverrideAnyMethodExceptMethodsFromObject(method: PsiMethod): Boolean { + var counter: Boolean = normalCase(method) + if (counter) + { + return true + } + + if (isInheritFromObject(method)) + { + return caseForObject(method) + } + + return false + } + + private fun caseForObject(method: PsiMethod): Boolean { + var containing: PsiClass? = method.getContainingClass() + if (containing != null) { + for (s : PsiClassType? in containing?.getSuperTypes()) { + val canonicalText: String? = s?.getCanonicalText() + if (canonicalText != JAVA_LANG_OBJECT && !getClassIdentifiers().contains(canonicalText)) { + return true + } + } + } + + return false + } + public open fun blockToBlock(block: PsiCodeBlock?, notEmpty: Boolean): Block { + if (block == null) + return Block.EMPTY_BLOCK + + return Block(statementsToStatementList(block.getStatements()), notEmpty) + } + + public open fun blockToBlock(block: PsiCodeBlock?): Block { + return blockToBlock(block, true) + } + + public open fun statementsToStatementList(statements: Array): List { + return statements.map { statementToStatement(it) } + } + + public open fun statementsToStatementList(statements: List): List { + return statements.map { statementToStatement(it) } + } + + public open fun statementToStatement(s: PsiStatement?): Statement { + if (s == null) + return Statement.EMPTY_STATEMENT + + val statementVisitor: StatementVisitor = StatementVisitor(this) + s.accept(statementVisitor) + return statementVisitor.getResult() + } + + public open fun expressionsToExpressionList(expressions: Array): List { + val result: List = arrayList() + for (e : PsiExpression? in expressions) + result.add(expressionToExpression(e)) + return result + } + + public open fun expressionToExpression(e: PsiExpression?): Expression { + if (e == null) + return Expression.EMPTY_EXPRESSION + + val expressionVisitor: ExpressionVisitor = dispatcher.expressionVisitor + e.accept(expressionVisitor) + return expressionVisitor.getResult() + } + + public open fun elementToElement(e: PsiElement?): Element { + if (e == null) + return Element.EMPTY_ELEMENT + + val elementVisitor: ElementVisitor = ElementVisitor(this) + e.accept(elementVisitor) + return elementVisitor.getResult() + } + + public open fun elementsToElementList(elements: Array): List { + val result: List = arrayList() + for(element in elements) { + result.add(elementToElement(element)) + } + return result + } + + public open fun typeToType(`type`: PsiType?): Type { + if (`type` == null) + return EmptyType() + + val typeVisitor: TypeVisitor = TypeVisitor(this) + `type`.accept(typeVisitor) + return typeVisitor.getResult() + } + + public open fun typesToTypeList(types: Array): List { + return types.map { typeToType(it) } + } + + public open fun typeToType(`type`: PsiType?, notNull: Boolean): Type { + val result: Type = typeToType(`type`) + if (notNull) { + return result.convertedToNotNull() + } + + return result + } + + private fun typesToNotNullableTypeList(types: Array): List { + val result: List = arrayList() + for(aType in types) { + result.add(typeToType(aType).convertedToNotNull()) + } + return result + } + + public open fun parametersToParameterList(parameters: Array): List { + return parameters.map { parameterToParameter(it!!) } + } + + public open fun parameterToParameter(parameter: PsiParameter): Parameter { + return Parameter(IdentifierImpl(parameter.getName()), + typeToType(parameter.getType(), + ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())), true) + } + + public open fun argumentsToExpressionList(expression: PsiCallExpression): List { + val argumentList: PsiExpressionList? = expression.getArgumentList() + val arguments: Array = (if (argumentList != null) + argumentList.getExpressions() + else + PsiExpression.EMPTY_ARRAY) + val result: List = ArrayList() + val resolved: PsiMethod? = expression.resolveMethod() + val expectedTypes: List = ArrayList() + if (resolved != null) { + for (p : PsiParameter? in resolved.getParameterList().getParameters()) + expectedTypes.add(p?.getType()) + } + + if (arguments.size == expectedTypes.size()) { + for (i in 0..expectedTypes.size() - 1) result.add(expressionToExpression(arguments[i], expectedTypes.get(i))) + } + else { + for (argument : PsiExpression? in arguments) { + result.add(expressionToExpression(argument)) + } + } + return result + } + + public open fun expressionToExpression(argument: PsiExpression?, expectedType: PsiType?): Expression { + if (argument == null) + return (Identifier.EMPTY_IDENTIFIER as IdentifierImpl) + + var expression: Expression = expressionToExpression(argument) + val actualType: PsiType? = argument.getType() + val isPrimitiveTypeOrNull: Boolean = actualType == null || actualType is PsiPrimitiveType + var isRef: Boolean = ((argument is PsiReferenceExpression && argument.isQualified()) || argument is PsiMethodCallExpression) + if (isPrimitiveTypeOrNull && isRef && expression.isNullable()) { + expression = BangBangExpression(expression) + } + + if (actualType != null) { + if (isConversionNeeded(actualType, expectedType) && !(expression is LiteralExpression)) + { + var conversion: String? = PRIMITIVE_TYPE_CONVERSIONS?.get(expectedType?.getCanonicalText()) + if (conversion != null) + { + expression = DummyMethodCallExpression(expression, conversion, (Identifier.EMPTY_IDENTIFIER as IdentifierImpl?)) + } + + } + + } + + return expression + } + + class object { + public val NOT_NULL_ANNOTATIONS: Set = ImmutableSet.of("org.jetbrains.annotations.NotNull", "com.sun.istack.internal.NotNull", "javax.annotation.Nonnull")!! + private val PRIMITIVE_TYPE_CONVERSIONS: Map = ImmutableMap.builder() + ?.put("byte", BYTE) + ?.put("short", SHORT) + ?.put("int", INT) + ?.put("long", LONG) + ?.put("float", FLOAT) + ?.put("double", DOUBLE) + ?.put("char", CHAR) + ?.put(JAVA_LANG_BYTE, BYTE) + ?.put(JAVA_LANG_SHORT, SHORT) + ?.put(JAVA_LANG_INTEGER, INT) + ?.put(JAVA_LANG_LONG, LONG) + ?.put(JAVA_LANG_FLOAT, FLOAT) + ?.put(JAVA_LANG_DOUBLE, DOUBLE) + ?.put(JAVA_LANG_CHARACTER, CHAR) + ?.build()!! + + private fun quoteKeywords(packageName: String): String { + return packageName.split("\\.").map { IdentifierImpl(it).toKotlin() }.makeString(".") + } + + private fun getFinalOrWithEmptyInitializer(fields: List): List { + val result: List = arrayList() + for (f : Field in fields) + if (f.isVal() || f.initializer.toKotlin().isEmpty()) { + result.add(f) + } + + return result + } + + private fun createParametersFromFields(fields: List): List { + return fields.map { Parameter(IdentifierImpl("_" + it.identifier.getName()), it.`type`, true) } + } + + private fun createInitStatementsFromFields(fields: List): List { + val result: List = arrayList() + for (f : Field in fields) { + val identifierToKotlin: String? = f.identifier.toKotlin() + result.add(DummyStringExpression(identifierToKotlin + " = " + "_" + identifierToKotlin)) + } + return result + } + + private fun createPrimaryConstructorInvocation(s: String, fields: List, initializers: Map): String { + return s + "(" + fields.map { initializers[it.identifier.toKotlin()] }.makeString(", ") + ")" + } + + public open fun getDefaultInitializer(f: Field): String { + if (f.`type`.nullable) { + return "null" + } + else { + val typeToKotlin: String = f.`type`.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" + } + } + + private fun getPrimaryConstructorForThisCase(psiClass: PsiClass): PsiMethod? { + val tv = ThisVisitor() + psiClass.accept(tv) + return tv.getPrimaryConstructor() + } + + public open fun isConstructorPrimary(constructor: PsiMethod): Boolean { + val parent = constructor.getParent() + if (parent is PsiClass) { + if (parent.getConstructors().size == 1) { + return true + } + else { + val c: PsiMethod? = getPrimaryConstructorForThisCase(parent) + if (c != null && c.hashCode() == constructor.hashCode()) { + return true + } + + } + } + + return false + } + private fun removeEmpty(statements: List): List { + return statements.filterNot { it == Statement.EMPTY_STATEMENT || it == Expression.EMPTY_EXPRESSION } + } + + private fun isNotOpenMethod(method: PsiMethod): Boolean { + val parent = method.getParent() + if (parent is PsiClass) { + val parentModifierList: PsiModifierList? = parent.getModifierList() + if ((parentModifierList != null && parentModifierList.hasExplicitModifier(Modifier.FINAL)) || parent.isEnum()) { + return true + } + + } + + return false + } + + private fun normalCase(method: PsiMethod): Boolean { + var counter: Int = 0 + for (s : HierarchicalMethodSignature? in method.getHierarchicalMethodSignature()?.getSuperSignatures()) + { + var containingClass: PsiClass? = s?.getMethod()?.getContainingClass() + var qualifiedName: String? = (if (containingClass != null) + containingClass?.getQualifiedName() + else + "") + if (qualifiedName != null && !qualifiedName.equals(JAVA_LANG_OBJECT)) + { + counter++ + } + + } + return counter > 0 + } + + private fun isInheritFromObject(method: PsiMethod): Boolean { + var superSignatures: List? = method.getHierarchicalMethodSignature().getSuperSignatures() + for (s : HierarchicalMethodSignature? in superSignatures) { + var containingClass: PsiClass? = s?.getMethod()?.getContainingClass() + var qualifiedName: String? = (if (containingClass != null) + containingClass?.getQualifiedName() + else + "") + if (qualifiedName == JAVA_LANG_OBJECT) { + return true + } + + } + return false + } + + private fun isOverrideObjectDirect(method: PsiMethod): Boolean { + var superSignatures: List? = method?.getHierarchicalMethodSignature()?.getSuperSignatures() + if (superSignatures?.size()!! == 1) + { + val containingClass: PsiClass? = superSignatures?.get(0)?.getMethod()?.getContainingClass() + val qualifiedName: String? = (if (containingClass != null) + containingClass?.getQualifiedName() + else + "") + if (qualifiedName != null && qualifiedName?.equals(JAVA_LANG_OBJECT)!!) + { + return true + } + + } + + return false + } + private fun importsToImportList(imports: Array): List { + val result: List = arrayList() + for (i : PsiImportStatementBase? in imports) { + if (i == null) continue + val anImport: Import = importToImport(i) + val name: String = anImport.name + if (!name.isEmpty() && !NOT_NULL_ANNOTATIONS.contains(name)) { + result.add(anImport) + } + + } + return result + } + + private fun importToImport(i: PsiImportStatementBase): Import { + val reference: PsiJavaCodeReferenceElement? = i.getImportReference() + if (reference != null) { + return Import(quoteKeywords(reference.getQualifiedName()!!) + ((if (i.isOnDemand()) + ".*" + else + ""))) + } + + return Import("") + } + + public open fun identifierToIdentifier(identifier: PsiIdentifier?): Identifier { + if (identifier == null) + return Identifier.EMPTY_IDENTIFIER + + return IdentifierImpl(identifier?.getText()) + } + + public open fun modifiersListToModifiersSet(modifierList: PsiModifierList?): Set { + val modifiersSet: HashSet = 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 + } + private fun isConversionNeeded(actual: PsiType?, expected: PsiType?): Boolean { + if (actual == null || expected == null) { + return false + } + + var typeMap: Map = 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") + var expectedStr: String? = expected.getCanonicalText() + var actualStr: String? = actual.getCanonicalText() + var o1: Boolean = AstUtil.getOrElse(typeMap, actualStr, "")?.equals(expectedStr)!! + var o2: Boolean = AstUtil.getOrElse(typeMap, expectedStr, "")?.equals(actualStr)!! + return actualStr != expectedStr && (!(o1 xor o2)) + } + } +} diff --git a/src/org/jetbrains/jet/j2k/ConverterUtil.java b/src/org/jetbrains/jet/j2k/ConverterUtil.java index d4f536c78d8..c92c9a34b4c 100644 --- a/src/org/jetbrains/jet/j2k/ConverterUtil.java +++ b/src/org/jetbrains/jet/j2k/ConverterUtil.java @@ -26,8 +26,6 @@ import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; -import static org.jetbrains.jet.j2k.Converter.NOT_NULL_ANNOTATIONS; - /** * @author ignatov */ @@ -101,7 +99,7 @@ public class ConverterUtil { return counter; } - static boolean isReadOnly(PsiElement element, PsiElement container) { + public static boolean isReadOnly(PsiElement element, PsiElement container) { return countWritingAccesses(element, container) == 0; } @@ -110,7 +108,7 @@ public class ConverterUtil { PsiAnnotation[] annotations = modifierList.getAnnotations(); for (PsiAnnotation a : annotations) { String qualifiedName = a.getQualifiedName(); - if (qualifiedName != null && NOT_NULL_ANNOTATIONS.contains(qualifiedName)) { + if (qualifiedName != null && Converter.$classobj.NOT_NULL_ANNOTATIONS.contains(qualifiedName)) { return true; } } diff --git a/src/org/jetbrains/jet/j2k/ast/Block.java b/src/org/jetbrains/jet/j2k/ast/Block.java deleted file mode 100644 index 1aeb1172d9f..00000000000 --- a/src/org/jetbrains/jet/j2k/ast/Block.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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/Block.kt b/src/org/jetbrains/jet/j2k/ast/Block.kt new file mode 100644 index 00000000000..28127e014da --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Block.kt @@ -0,0 +1,23 @@ +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.util.AstUtil +import java.util.LinkedList +import java.util.List + +public open class Block(val statements: List, val notEmpty: Boolean = false): Statement() { + public override fun isEmpty(): Boolean { + return !notEmpty && statements.size() == 0 + } + + public override fun toKotlin(): String { + if (!isEmpty()) { + return "{\n" + AstUtil.joinNodes(statements, "\n") + "\n}" + } + + return "" + } + + class object { + public val EMPTY_BLOCK: Block = Block(arrayList()) + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/CaseContainer.java b/src/org/jetbrains/jet/j2k/ast/CaseContainer.java index 4e58dabaf24..8ea01bfced7 100644 --- a/src/org/jetbrains/jet/j2k/ast/CaseContainer.java +++ b/src/org/jetbrains/jet/j2k/ast/CaseContainer.java @@ -36,7 +36,7 @@ public class CaseContainer extends Statement { if (s.getKind() != Kind.BREAK && s.getKind() != Kind.CONTINUE) { newStatements.add(s); } - myBlock = new Block(newStatements); + myBlock = new Block(newStatements, false); } @NotNull diff --git a/src/org/jetbrains/jet/j2k/ast/Class.kt b/src/org/jetbrains/jet/j2k/ast/Class.kt index 2c802fe9908..7db90c23184 100644 --- a/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -65,7 +65,7 @@ public open class Class(converter : Converter, private fun constructorToInit(f: Function): Function { val modifiers : Set = HashSet(f.getModifiers()) modifiers.add(Modifier.STATIC) - val statements : List = f.block?.getStatements() ?: arrayList() + val statements : List = f.block?.statements ?: arrayList() statements.add(ReturnStatement(IdentifierImpl("__"))) val block : Block = Block(statements) val constructorTypeParameters : List = arrayList() diff --git a/src/org/jetbrains/jet/j2k/ast/ExpressionList.java b/src/org/jetbrains/jet/j2k/ast/ExpressionList.java deleted file mode 100644 index 4387b065e43..00000000000 --- a/src/org/jetbrains/jet/j2k/ast/ExpressionList.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.ast.types.Type; -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/ExpressionList.kt b/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt new file mode 100644 index 00000000000..4404319d2e2 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/ExpressionList.kt @@ -0,0 +1,9 @@ +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.ast.types.Type +import org.jetbrains.jet.j2k.util.AstUtil +import java.util.List + +public open class ExpressionList(val expressions: List): Expression() { + public override fun toKotlin(): String = expressions.map { it.toKotlin() }.makeString(", ") +} diff --git a/src/org/jetbrains/jet/j2k/ast/Field.kt b/src/org/jetbrains/jet/j2k/ast/Field.kt index c676c1ea1af..3bcee833104 100644 --- a/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -5,7 +5,7 @@ import org.jetbrains.jet.j2k.util.AstUtil import java.util.LinkedList import java.util.List import java.util.Set -import org.jetbrains.jet.j2k.Converter.getDefaultInitializer +import org.jetbrains.jet.j2k.Converter public open class Field(val identifier : Identifier, modifiers : Set, @@ -43,7 +43,7 @@ public open class Field(val identifier : Identifier, return declaration + ((if (isVal() && !isStatic() && writingAccesses == 1) "" else - " = " + getDefaultInitializer(this))) + " = " + Converter.getDefaultInitializer(this))) } return declaration + " = " + initializer.toKotlin() diff --git a/src/org/jetbrains/jet/j2k/ast/File.java b/src/org/jetbrains/jet/j2k/ast/File.java deleted file mode 100644 index eb1be6a22ef..00000000000 --- a/src/org/jetbrains/jet/j2k/ast/File.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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/File.kt b/src/org/jetbrains/jet/j2k/ast/File.kt new file mode 100644 index 00000000000..52b9bfff84c --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/File.kt @@ -0,0 +1,19 @@ +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.util.AstUtil +import java.util.List + +public open class File(val packageName: String, + val imports: List, + val classes: List, + val mainFunction: String): Node() { + + public override fun toKotlin(): String { + val common: String = AstUtil.joinNodes(imports, "\n") + "\n\n" + AstUtil.joinNodes(classes, "\n") + "\n" + mainFunction + if (packageName.isEmpty()) { + return common + } + + return "package " + packageName + "\n" + common + } +} diff --git a/src/org/jetbrains/jet/j2k/ast/Import.java b/src/org/jetbrains/jet/j2k/ast/Import.java deleted file mode 100644 index 4d81911c01d..00000000000 --- a/src/org/jetbrains/jet/j2k/ast/Import.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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/Import.kt b/src/org/jetbrains/jet/j2k/ast/Import.kt new file mode 100644 index 00000000000..1d3ca5854b3 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/Import.kt @@ -0,0 +1,6 @@ +package org.jetbrains.jet.j2k.ast + + +public open class Import(val name: String): Node() { + public override fun toKotlin() = "import " + name +} diff --git a/src/org/jetbrains/jet/j2k/ast/LocalVariable.java b/src/org/jetbrains/jet/j2k/ast/LocalVariable.java deleted file mode 100644 index e2925caf0e2..00000000000 --- a/src/org/jetbrains/jet/j2k/ast/LocalVariable.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.ast.types.Type; - -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/LocalVariable.kt b/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt new file mode 100644 index 00000000000..5a6ad3ad367 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt @@ -0,0 +1,22 @@ +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.ast.types.Type +import java.util.Set + +public open class LocalVariable(val identifier: Identifier, + val modifiersSet: Set, + val `type`: Type, + val initializer: Expression): Expression() { + + public open fun hasModifier(modifier: String): Boolean { + return modifiersSet.contains(modifier) + } + + public override fun toKotlin(): String { + if (initializer.isEmpty()) { + return identifier.toKotlin() + " : " + `type`.toKotlin() + } + + return identifier.toKotlin() + " : " + `type`.toKotlin() + " = " + initializer.toKotlin() + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/Dispatcher.java b/src/org/jetbrains/jet/j2k/visitors/Dispatcher.java deleted file mode 100644 index 063c5e81daf..00000000000 --- a/src/org/jetbrains/jet/j2k/visitors/Dispatcher.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.visitors; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.j2k.Converter; - -/** - * @author ignatov - */ -public class Dispatcher { - private ExpressionVisitor myExpressionVisitor; - - public void setExpressionVisitor(final ExpressionVisitor expressionVisitor) { - this.myExpressionVisitor = expressionVisitor; - } - - public Dispatcher(@NotNull Converter converter) { - myExpressionVisitor = new ExpressionVisitor(converter); - } - - public ExpressionVisitor getExpressionVisitor() { - return myExpressionVisitor; - } -} diff --git a/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt b/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt new file mode 100644 index 00000000000..709baecb077 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt @@ -0,0 +1,7 @@ +package org.jetbrains.jet.j2k.visitors + +import org.jetbrains.jet.j2k.Converter + +public open class Dispatcher(converter: Converter) { + public var expressionVisitor: ExpressionVisitor = ExpressionVisitor(converter) +} diff --git a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt index c9396544801..02cd86edfc9 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt +++ b/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt @@ -5,7 +5,6 @@ import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.types.Type import java.util.List -import org.jetbrains.jet.j2k.Converter.modifiersListToModifiersSet import org.jetbrains.jet.j2k.ConverterUtil.isAnnotatedAsNotNull public open class ElementVisitor(val myConverter : Converter) : JavaElementVisitor(), J2KVisitor { @@ -22,14 +21,13 @@ public open class ElementVisitor(val myConverter : Converter) : JavaElementVisit public override fun visitLocalVariable(variable : PsiLocalVariable?) : Unit { val theVariable = variable!! myResult = LocalVariable(IdentifierImpl(theVariable.getName()), - modifiersListToModifiersSet(theVariable.getModifierList()), + Converter.modifiersListToModifiersSet(theVariable.getModifierList()), myConverter.typeToType(theVariable.getType(), isAnnotatedAsNotNull(theVariable.getModifierList())), myConverter.expressionToExpression(theVariable.getInitializer(), theVariable.getType())) } public override fun visitExpressionList(list : PsiExpressionList?) : Unit { - myResult = ExpressionList(myConverter.expressionsToExpressionList(list!!.getExpressions()), - myConverter.typesToTypeList(list!!.getExpressionTypes())) + myResult = ExpressionList(myConverter.expressionsToExpressionList(list!!.getExpressions())) } public override fun visitReferenceElement(reference : PsiJavaCodeReferenceElement?) : Unit { diff --git a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java index 0bdfd16c20f..2494e56d499 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import static org.jetbrains.jet.j2k.Converter.isConstructorPrimary; import static com.intellij.psi.CommonClassNames.*; /** @@ -236,7 +235,7 @@ public class ExpressionVisitor extends StatementVisitor { @Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { super.visitMethodCallExpression(expression); - if (!SuperVisitor.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) { + if (!SuperVisitor.$classobj.isSuper(expression.getMethodExpression()) || !isInsidePrimaryConstructor(expression)) { myResult = // TODO: not resolved new MethodCallExpression( getConverter().expressionToExpression(expression.getMethodExpression()), @@ -274,7 +273,7 @@ public class ExpressionVisitor extends StatementVisitor { final boolean isNotConvertedClass = classReference != null && !getConverter().getClassIdentifiers().contains(classReference.getQualifiedName()); PsiExpressionList argumentList = expression.getArgumentList(); PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[]{}; - if (constructor == null || isConstructorPrimary(constructor) || isNotConvertedClass) { + if (constructor == null || Converter.$classobj.isConstructorPrimary(constructor) || isNotConvertedClass) { return new NewClassExpression( getConverter().expressionToExpression(expression.getQualifier()), getConverter().elementToElement(classReference), @@ -419,7 +418,7 @@ public class ExpressionVisitor extends StatementVisitor { PsiElement context = expression.getContext(); while (context != null) { if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) { - return !isConstructorPrimary((PsiMethod) context); + return !Converter.$classobj.isConstructorPrimary((PsiMethod) context); } context = context.getContext(); } @@ -430,7 +429,7 @@ public class ExpressionVisitor extends StatementVisitor { PsiElement context = expression.getContext(); while (context != null) { if (context instanceof PsiMethod && ((PsiMethod) context).isConstructor()) { - return isConstructorPrimary((PsiMethod) context); + return Converter.$classobj.isConstructorPrimary((PsiMethod) context); } context = context.getContext(); } diff --git a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java index 8dfaede8fdd..bbc4446eb91 100644 --- a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java @@ -28,7 +28,6 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import static org.jetbrains.jet.j2k.Converter.identifierToIdentifier; import static org.jetbrains.jet.j2k.ConverterUtil.countWritingAccesses; /** @@ -73,7 +72,7 @@ public class StatementVisitor extends ElementVisitor { } else { myResult = new BreakStatement( - identifierToIdentifier(statement.getLabelIdentifier()) + Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier()) ); } } @@ -86,7 +85,7 @@ public class StatementVisitor extends ElementVisitor { } else { myResult = new ContinueStatement( - identifierToIdentifier(statement.getLabelIdentifier()) + Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier()) ); } } @@ -181,8 +180,8 @@ public class StatementVisitor extends ElementVisitor { getConverter().expressionToExpression(condition), new Block( Arrays.asList(getConverter().statementToStatement(body), - new Block(Arrays.asList(getConverter().statementToStatement(update))))))); - myResult = new Block(forStatements); + new Block(Arrays.asList(getConverter().statementToStatement(update)), false)), false))); + myResult = new Block(forStatements, false); } } @@ -220,7 +219,7 @@ public class StatementVisitor extends ElementVisitor { public void visitLabeledStatement(@NotNull PsiLabeledStatement statement) { super.visitLabeledStatement(statement); myResult = new LabelStatement( - identifierToIdentifier(statement.getLabelIdentifier()), + Converter.$classobj.identifierToIdentifier(statement.getLabelIdentifier()), getConverter().statementToStatement(statement.getStatement()) ); } diff --git a/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.java b/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.java deleted file mode 100644 index 1e72832b2f4..00000000000 --- a/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.visitors; - -import com.intellij.psi.*; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; - - -/** - * @author ignatov - */ -public class SuperVisitor extends JavaRecursiveElementVisitor { - @NotNull - private final HashSet myResolvedSuperCallParameters; - - public SuperVisitor() { - myResolvedSuperCallParameters = new HashSet(); - } - - @NotNull - public HashSet getResolvedSuperCallParameters() { - return myResolvedSuperCallParameters; - } - - @Override - public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) { - super.visitMethodCallExpression(expression); - if (isSuper(expression.getMethodExpression())) { - myResolvedSuperCallParameters.add(expression.getArgumentList()); - } - } - - static boolean isSuper(@NotNull PsiReference r) { - if (r.getCanonicalText().equals("super")) { - final PsiElement baseConstructor = r.resolve(); - if (baseConstructor != null && baseConstructor instanceof PsiMethod && ((PsiMethod) baseConstructor).isConstructor()) { - return true; - } - } - return false; - } -} diff --git a/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt b/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt new file mode 100644 index 00000000000..7cb4e1853f7 --- /dev/null +++ b/src/org/jetbrains/jet/j2k/visitors/SuperVisitor.kt @@ -0,0 +1,26 @@ +package org.jetbrains.jet.j2k.visitors + +import com.intellij.psi.* +import java.util.HashSet + +public open class SuperVisitor(): JavaRecursiveElementVisitor() { + public val resolvedSuperCallParameters: HashSet = hashSet() + + public override fun visitMethodCallExpression(expression: PsiMethodCallExpression?): Unit { + if (expression != null && isSuper(expression.getMethodExpression())) { + resolvedSuperCallParameters.add(expression.getArgumentList()) + } + } + class object { + open fun isSuper(r: PsiReference): Boolean { + if (r.getCanonicalText().equals("super")) { + val baseConstructor: PsiElement? = r.resolve() + if (baseConstructor != null && baseConstructor is PsiMethod && baseConstructor.isConstructor()) { + return true + } + } + + return false + } + } +} diff --git a/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt index 4cb6c3d68c7..26b1f864f49 100644 --- a/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt +++ b/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt @@ -10,13 +10,13 @@ import org.jetbrains.jet.j2k.util.AstUtil import java.util.LinkedList import java.util.List -public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisitor(), J2KVisitor { +public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisitor(), J2KVisitor { private var myResult : Type = EmptyType() public open fun getResult() : Type { return myResult } - public override fun visitPrimitiveType(primitiveType: PsiPrimitiveType?) : Type? { + public override fun visitPrimitiveType(primitiveType: PsiPrimitiveType?) : Type { val name : String = primitiveType?.getCanonicalText()!! val identifier : IdentifierImpl = IdentifierImpl(name) if (name == "void") { @@ -28,19 +28,19 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi else { myResult = PrimitiveType(identifier) } - return null + return myResult } - public override fun visitArrayType(arrayType: PsiArrayType?) : Type? { + public override fun visitArrayType(arrayType: PsiArrayType?) : Type { if (myResult is EmptyType) { myResult = ArrayType(myConverter.typeToType(arrayType?.getComponentType()), true) } - return null + return myResult } - public override fun visitClassType(classType : PsiClassType?) : Type? { - if (classType == null) return null + public override fun visitClassType(classType : PsiClassType?) : Type { + if (classType == null) return myResult val identifier : IdentifierImpl = constructClassTypeIdentifier(classType) val resolvedClassTypeParams : List = createRawTypesForResolvedReference(classType) if (classType.getParameterCount() == 0 && resolvedClassTypeParams.size() > 0) { @@ -49,7 +49,7 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi else { myResult = ClassType(identifier, myConverter.typesToTypeList(classType.getParameters()).requireNoNulls(), true) } - return null + return myResult } private fun constructClassTypeIdentifier(classType : PsiClassType) : IdentifierImpl { @@ -102,7 +102,7 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi return typeParams } - public override fun visitWildcardType(wildcardType : PsiWildcardType?) : Type? { + public override fun visitWildcardType(wildcardType : PsiWildcardType?) : Type { if (wildcardType!!.isExtends()) { myResult = OutProjectionType(myConverter.typeToType(wildcardType!!.getExtendsBound())) } @@ -113,12 +113,12 @@ public open class TypeVisitor(private val myConverter : Converter) : PsiTypeVisi else { myResult = StarProjectionType() } - return null + return myResult } - public override fun visitEllipsisType(ellipsisType : PsiEllipsisType?) : Type? { + public override fun visitEllipsisType(ellipsisType : PsiEllipsisType?) : Type { myResult = VarArg(myConverter.typeToType(ellipsisType?.getComponentType())) - return null + return myResult } public override fun getConverter() : Converter = myConverter