@NotNull private static String createPrimaryConstructorInvocation( @NotNull String s, @NotNull List<? extends Field> fields, @NotNull Map<String, String> initializers) { List<String> result = new LinkedList<String>(); for (Field f : fields) { String id = f.getIdentifier().toKotlin(); result.add(initializers.get(id)); } return s + "(" + AstUtil.join(result, ", ") + ")"; }
private static boolean isConversionNeeded(@Nullable PsiType actual, @Nullable PsiType expected) { if (actual == null || expected == null) { return false; } Map<String, String> typeMap = new HashMap<String, String>(); typeMap.put(JAVA_LANG_BYTE, "byte"); typeMap.put(JAVA_LANG_SHORT, "short"); typeMap.put(JAVA_LANG_INTEGER, "int"); typeMap.put(JAVA_LANG_LONG, "long"); typeMap.put(JAVA_LANG_FLOAT, "float"); typeMap.put(JAVA_LANG_DOUBLE, "double"); typeMap.put(JAVA_LANG_CHARACTER, "char"); String expectedStr = expected.getCanonicalText(); String actualStr = actual.getCanonicalText(); boolean o1 = AstUtil.getOrElse(typeMap, actualStr, "").equals(expectedStr); boolean o2 = AstUtil.getOrElse(typeMap, expectedStr, "").equals(actualStr); return !actualStr.equals(expectedStr) && (!(o1 ^ o2)); }
@NotNull private static String getPrimitiveTypeConversion(@NotNull String type) { Map<String, Name> conversions = new HashMap<String, Name>(); conversions.put("byte", BYTE); conversions.put("short", SHORT); conversions.put("int", INT); conversions.put("long", LONG); conversions.put("float", FLOAT); conversions.put("double", DOUBLE); conversions.put("char", CHAR); conversions.put(JAVA_LANG_BYTE, BYTE); conversions.put(JAVA_LANG_SHORT, SHORT); conversions.put(JAVA_LANG_INTEGER, INT); conversions.put(JAVA_LANG_LONG, LONG); conversions.put(JAVA_LANG_FLOAT, FLOAT); conversions.put(JAVA_LANG_DOUBLE, DOUBLE); conversions.put(JAVA_LANG_CHARACTER, CHAR); if (conversions.containsKey(type)) { return "." + conversions.get(type) + "()"; } return ""; }
@NotNull public Class classToClass(@NotNull PsiClass psiClass) { Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList()); List<Field> fields = fieldsToFieldList(psiClass.getFields(), psiClass); List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters()); List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes()); List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes()); IdentifierImpl name = new IdentifierImpl(psiClass.getName()); 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) SuperVisitor visitor = new SuperVisitor(); psiClass.accept(visitor); Collection<PsiExpressionList> 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) { List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields); Map<String, String> initializers = new HashMap<String, String>(); for (Member m : members) { // and modify secondaries if (m.getKind() == INode.Kind.CONSTRUCTOR) { Function f = (Function) m; if (!((Constructor) f).isPrimary()) { for (Field fo : finalOrWithEmptyInitializer) { String init = getDefaultInitializer(fo); initializers.put(fo.getIdentifier().toKotlin(), init); } List<Statement> newStatements = new LinkedList<Statement>(); for (Statement s : f.getBlock().getStatements()) { boolean isRemoved = false; if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) { AssignmentExpression assignmentExpression = (AssignmentExpression) s; if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) { for (Field fo : finalOrWithEmptyInitializer) { 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.<String>emptySet(), new ClassType(name), Collections.<Element>emptyList(), new ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)), new Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)), true)); } if (psiClass.isInterface()) { return new Trait( this, name, modifiers, typeParameters, extendsTypes, Collections.<Expression>emptyList(), implementsTypes, members); } if (psiClass.isEnum()) { return new Enum( this, name, modifiers, typeParameters, Collections.<Type>emptyList(), Collections.<Expression>emptyList(), implementsTypes, members); } return new Class( this, name, modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members); }