예제 #1
0
 @NotNull
 private static List<Parameter> createParametersFromFields(@NotNull List<? extends Field> fields) {
   List<Parameter> result = new LinkedList<Parameter>();
   for (Field f : fields)
     result.add(new Parameter(new IdentifierImpl("_" + f.getIdentifier().getName()), f.getType()));
   return result;
 }
예제 #2
0
 @NotNull
 private static List<Field> getFinalOrWithEmptyInitializer(@NotNull List<? extends Field> fields) {
   List<Field> result = new LinkedList<Field>();
   for (Field f : fields)
     if (f.isVal() || f.getInitializer().toKotlin().isEmpty()) {
       result.add(f);
     }
   return result;
 }
예제 #3
0
 @NotNull
 private static List<Statement> createInitStatementsFromFields(
     @NotNull List<? extends Field> fields) {
   List<Statement> result = new LinkedList<Statement>();
   for (Field f : fields) {
     String identifierToKotlin = f.getIdentifier().toKotlin();
     result.add(new DummyStringExpression(identifierToKotlin + " = " + "_" + identifierToKotlin));
   }
   return result;
 }
예제 #4
0
 @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, ", ") + ")";
 }
예제 #5
0
 @NotNull
 public static String getDefaultInitializer(@NotNull Field f) {
   if (f.getType().isNullable()) {
     return "null";
   } else {
     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";
   }
 }
예제 #6
0
  @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);
  }