コード例 #1
0
  private void assertMembersNamesAreUnique() {
    Map<String, FieldNode> allDslCollectionFieldNodesOfHierarchy = new HashMap<String, FieldNode>();

    for (ClassNode level : ASTHelper.getHierarchyOfDSLObjectAncestors(annotatedClass)) {
      for (FieldNode field : level.getFields()) {
        if (!ASTHelper.isListOrMap(field.getType())) continue;

        String memberName = getElementNameForCollectionField(field);

        FieldNode conflictingField = allDslCollectionFieldNodesOfHierarchy.get(memberName);

        if (conflictingField != null) {
          addCompileError(
              String.format(
                  "Member name %s is used more than once: %s:%s and %s:%s",
                  memberName,
                  field.getOwner().getName(),
                  field.getName(),
                  conflictingField.getOwner().getName(),
                  conflictingField.getName()),
              field);
          return;
        }

        allDslCollectionFieldNodesOfHierarchy.put(memberName, field);
      }
    }
  }
コード例 #2
0
 private Statement createConstructorStatementMapSpecial(FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   Expression namedArgs = findArg(fNode.getName());
   Expression baseArgs = new VariableExpression("args");
   return new IfStatement(
       equalsNullExpr(baseArgs),
       new IfStatement(
           equalsNullExpr(initExpr),
           new EmptyStatement(),
           assignStatement(fieldExpr, cloneCollectionExpr(initExpr))),
       new IfStatement(
           equalsNullExpr(namedArgs),
           new IfStatement(
               isTrueExpr(
                   new MethodCallExpression(
                       baseArgs, "containsKey", new ConstantExpression(fNode.getName()))),
               assignStatement(fieldExpr, namedArgs),
               assignStatement(fieldExpr, cloneCollectionExpr(baseArgs))),
           new IfStatement(
               isOneExpr(
                   new MethodCallExpression(baseArgs, "size", MethodCallExpression.NO_ARGUMENTS)),
               assignStatement(fieldExpr, cloneCollectionExpr(namedArgs)),
               assignStatement(fieldExpr, cloneCollectionExpr(baseArgs)))));
 }
コード例 #3
0
 private static void initializeFields(List<FieldNode> fields, BlockStatement body) {
   for (FieldNode field : fields) {
     body.addStatement(
         stmt(
             assignX(
                 propX(varX("this"), field.getName()),
                 varX(param(field.getType(), field.getName())))));
   }
 }
コード例 #4
0
  private void preventOwnerOverride() {

    MethodBuilder.createPublicMethod(setterName(ownerField))
        .param(OBJECT_TYPE, "value")
        .statement(
            ifS(
                andX(
                    isInstanceOfX(varX("value"), ownerField.getType()),
                    notX(propX(varX("this"), ownerField.getName()))),
                assignX(propX(varX("this"), ownerField.getName()), varX("value"))))
        .addTo(annotatedClass);
  }
コード例 #5
0
  private void createSingleFieldSetterMethod(FieldNode fieldNode) {
    MethodBuilder.createPublicMethod(fieldNode.getName())
        .param(fieldNode.getType(), "value")
        .assignToProperty(fieldNode.getName(), varX("value"))
        .addTo(annotatedClass);

    if (fieldNode.getType().equals(ClassHelper.boolean_TYPE)) {
      MethodBuilder.createPublicMethod(fieldNode.getName())
          .callThis(fieldNode.getName(), constX(true))
          .addTo(annotatedClass);
    }
  }
コード例 #6
0
 private static FieldNode createFieldCopy(ClassNode buildee, FieldNode fNode) {
   Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
   extractSuperClassGenerics(fNode.getType(), buildee, genericsSpec);
   ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
   return new FieldNode(
       fNode.getName(), fNode.getModifiers(), correctedType, buildee, DEFAULT_INITIAL_VALUE);
 }
コード例 #7
0
 private Statement createConstructorStatement(
     ClassNode cNode,
     PropertyNode pNode,
     List<String> knownImmutableClasses,
     List<String> knownImmutables) {
   FieldNode fNode = pNode.getField();
   final ClassNode fieldType = fNode.getType();
   Statement statement = null;
   if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) {
     statement = createConstructorStatementArrayOrCloneable(fNode);
   } else if (isKnownImmutableClass(fieldType, knownImmutableClasses)
       || isKnownImmutable(pNode.getName(), knownImmutables)) {
     statement = createConstructorStatementDefault(fNode);
   } else if (fieldType.isDerivedFrom(DATE_TYPE)) {
     statement = createConstructorStatementDate(fNode);
   } else if (isOrImplements(fieldType, COLLECTION_TYPE)
       || fieldType.isDerivedFrom(COLLECTION_TYPE)
       || isOrImplements(fieldType, MAP_TYPE)
       || fieldType.isDerivedFrom(MAP_TYPE)) {
     statement = createConstructorStatementCollection(fNode);
   } else if (fieldType.isResolved()) {
     addError(
         createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"),
         fNode);
     statement = EmptyStatement.INSTANCE;
   } else {
     statement = createConstructorStatementGuarded(cNode, fNode);
   }
   return statement;
 }
コード例 #8
0
  private void createListOfSimpleElementsMethods(FieldNode fieldNode, ClassNode elementType) {

    MethodBuilder.createPublicMethod(fieldNode.getName())
        .arrayParam(elementType, "values")
        .statement(callX(propX(varX("this"), fieldNode.getName()), "addAll", varX("values")))
        .addTo(annotatedClass);

    MethodBuilder.createPublicMethod(fieldNode.getName())
        .param(fieldNode.getType(), "values")
        .statement(callX(propX(varX("this"), fieldNode.getName()), "addAll", varX("values")))
        .addTo(annotatedClass);

    MethodBuilder.createPublicMethod(getElementNameForCollectionField(fieldNode))
        .param(elementType, "value")
        .statement(callX(propX(varX("this"), fieldNode.getName()), "add", varX("value")))
        .addTo(annotatedClass);
  }
コード例 #9
0
  private void createMapOfSimpleElementsMethods(
      FieldNode fieldNode, ClassNode keyType, ClassNode valueType) {
    String methodName = fieldNode.getName();

    MethodBuilder.createPublicMethod(methodName)
        .param(fieldNode.getType(), "values")
        .callMethod(propX(varX("this"), fieldNode.getName()), "putAll", varX("values"))
        .addTo(annotatedClass);

    String singleElementMethod = getElementNameForCollectionField(fieldNode);

    MethodBuilder.createPublicMethod(singleElementMethod)
        .param(keyType, "key")
        .param(valueType, "value")
        .callMethod(propX(varX("this"), fieldNode.getName()), "put", args("key", "value"))
        .addTo(annotatedClass);
  }
コード例 #10
0
 public void visitField(FieldNode node) {
   if (currentClass.getDeclaredField(node.getName()) != node) {
     addError("The " + getDescription(node) + " is declared multiple times.", node);
   }
   checkInterfaceFieldModifiers(node);
   checkGenericsUsage(node, node.getType());
   super.visitField(node);
 }
コード例 #11
0
 public static List<String> getInstanceNonPropertyFieldNames(ClassNode cNode) {
   List<FieldNode> fList = getInstanceNonPropertyFields(cNode);
   List<String> result = new ArrayList<String>(fList.size());
   for (FieldNode fNode : fList) {
     result.add(fNode.getName());
   }
   return result;
 }
コード例 #12
0
 private static Expression initializeInstance(
     ClassNode buildee, List<FieldNode> fields, BlockStatement body) {
   Expression instance = varX("_the" + buildee.getNameWithoutPackage(), buildee);
   body.addStatement(declS(instance, ctorX(buildee)));
   for (FieldNode field : fields) {
     body.addStatement(stmt(assignX(propX(instance, field.getName()), varX(field))));
   }
   return instance;
 }
コード例 #13
0
 private static List<FieldNode> selectFieldsFromExistingClass(
     List<FieldNode> fieldNodes, List<String> includes, List<String> excludes) {
   List<FieldNode> fields = new ArrayList<FieldNode>();
   for (FieldNode fNode : fieldNodes) {
     if (shouldSkip(fNode.getName(), excludes, includes)) continue;
     fields.add(fNode);
   }
   return fields;
 }
コード例 #14
0
 private static List<FieldNode> filterFields(
     List<FieldNode> fieldNodes, List<String> includes, List<String> excludes) {
   List<FieldNode> fields = new ArrayList<FieldNode>();
   for (FieldNode fNode : fieldNodes) {
     if (AbstractASTTransformation.shouldSkip(fNode.getName(), excludes, includes)) continue;
     fields.add(fNode);
   }
   return fields;
 }
コード例 #15
0
 public static List<FieldNode> getInstanceNonPropertyFields(ClassNode cNode) {
   final List<FieldNode> result = new ArrayList<FieldNode>();
   for (FieldNode fNode : cNode.getFields()) {
     if (!fNode.isStatic() && cNode.getProperty(fNode.getName()) == null) {
       result.add(fNode);
     }
   }
   return result;
 }
コード例 #16
0
 private String createFieldLabel(FieldNode node) {
   StringBuilder sb = new StringBuilder();
   sb.append(createClassLabel(node.getType()));
   sb.append(" ");
   sb.append(createClassLabel(node.getDeclaringClass()));
   sb.append(".");
   sb.append(node.getName());
   return sb.toString();
 }
コード例 #17
0
 private Expression checkUnresolved(ClassNode cNode, FieldNode fNode, Expression value) {
   Expression args =
       new TupleExpression(
           new MethodCallExpression(
               new VariableExpression("this"), "getClass", ArgumentListExpression.EMPTY_ARGUMENTS),
           new ConstantExpression(fNode.getName()),
           value);
   return new StaticMethodCallExpression(SELF_TYPE, "checkImmutable", args);
 }
コード例 #18
0
  public void visitField(FieldNode fieldNode) {

    cv.visitField(
        fieldNode.getModifiers(),
        fieldNode.getName(),
        BytecodeHelper.getTypeDescription(fieldNode.getType()),
        null, // fieldValue,  //br  all the sudden that one cannot init the field here. init is done
        // in static initializer and instance initializer.
        null);
  }
コード例 #19
0
  private FieldNode getKeyField(ClassNode target) {

    List<FieldNode> annotatedFields = getAnnotatedFieldsOfHierarchy(target, KEY_ANNOTATION);

    if (annotatedFields.isEmpty()) return null;

    if (annotatedFields.size() > 1) {
      addCompileError(
          String.format(
              "Found more than one key fields, only one is allowed in hierarchy (%s, %s)",
              getQualifiedName(annotatedFields.get(0)), getQualifiedName(annotatedFields.get(1))),
          annotatedFields.get(0));
      return null;
    }

    FieldNode result = annotatedFields.get(0);

    if (!result.getType().equals(ClassHelper.STRING_TYPE)) {
      addCompileError(
          String.format(
              "Key field '%s' must be of type String, but is '%s' instead",
              result.getName(), result.getType().getName()),
          result);
      return null;
    }

    ClassNode ancestor = ASTHelper.getHighestAncestorDSLObject(target);

    if (target.equals(ancestor)) return result;

    FieldNode firstKey = getKeyField(ancestor);

    if (firstKey == null) {
      addCompileError(
          String.format(
              "Inconsistent hierarchy: Toplevel class %s has no key, but child class %s defines '%s'.",
              ancestor.getName(), target.getName(), result.getName()),
          result);
      return null;
    }

    return result;
  }
コード例 #20
0
 @SuppressWarnings("RedundantIfStatement")
 boolean shouldFieldBeIgnored(FieldNode fieldNode) {
   if (fieldNode == keyField) return true;
   if (fieldNode == ownerField) return true;
   if (getAnnotation(fieldNode, IGNORE_ANNOTATION) != null) return true;
   if (fieldNode.isFinal()) return true;
   if (fieldNode.getName().startsWith("$")) return true;
   if ((fieldNode.getModifiers() & ACC_TRANSIENT) != 0) return true;
   return false;
 }
コード例 #21
0
  private void validateFields(BlockStatement block) {
    Validation.Option mode =
        getEnumMemberValue(
            getAnnotation(annotatedClass, VALIDATION_ANNOTATION),
            "option",
            Validation.Option.class,
            Validation.Option.IGNORE_UNMARKED);
    for (FieldNode fieldNode : annotatedClass.getFields()) {
      if (shouldFieldBeIgnoredForValidation(fieldNode)) continue;

      ClosureExpression validationClosure =
          createGroovyTruthClosureExpression(block.getVariableScope());
      String message = null;

      AnnotationNode validateAnnotation = getAnnotation(fieldNode, VALIDATE_ANNOTATION);
      if (validateAnnotation != null) {
        message =
            getMemberStringValue(
                validateAnnotation, "message", "'" + fieldNode.getName() + "' must be set!");
        Expression member = validateAnnotation.getMember("value");
        if (member instanceof ClassExpression) {
          ClassNode memberType = member.getType();
          if (memberType.equals(ClassHelper.make(Validate.Ignore.class))) continue;
          else if (!memberType.equals(ClassHelper.make(Validate.GroovyTruth.class))) {
            addError(
                "value of Validate must be either Validate.GroovyTruth, Validate.Ignore or a closure.",
                fieldNode);
          }
        } else if (member instanceof ClosureExpression) {
          validationClosure = (ClosureExpression) member;
        }
      }

      if (validateAnnotation != null || mode == Validation.Option.VALIDATE_UNMARKED) {
        block.addStatement(
            new AssertStatement(
                new BooleanExpression(
                    callX(validationClosure, "call", args(varX(fieldNode.getName())))),
                message == null ? ConstantExpression.NULL : new ConstantExpression(message)));
      }
    }
  }
コード例 #22
0
 private static Parameter[] getParams(List<FieldNode> fields, ClassNode cNode) {
   Parameter[] parameters = new Parameter[fields.size()];
   for (int i = 0; i < parameters.length; i++) {
     FieldNode fNode = fields.get(i);
     Map<String, ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass());
     extractSuperClassGenerics(fNode.getType(), cNode, genericsSpec);
     ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType());
     parameters[i] = new Parameter(correctedType, fNode.getName());
   }
   return parameters;
 }
コード例 #23
0
 private void createKeyConstructor() {
   annotatedClass.addConstructor(
       ACC_PUBLIC,
       params(param(STRING_TYPE, "key")),
       NO_EXCEPTIONS,
       block(
           ASTHelper.isDSLObject(annotatedClass.getSuperClass())
               ? ctorSuperS(args("key"))
               : ctorSuperS(),
           assignS(propX(varX("this"), keyField.getName()), varX("key"))));
 }
コード例 #24
0
 private Statement checkFinalArgNotOverridden(ClassNode cNode, FieldNode fNode) {
   final String name = fNode.getName();
   Expression value = findArg(name);
   return new IfStatement(
       equalsNullExpr(value),
       new EmptyStatement(),
       new ThrowStatement(
           new ConstructorCallExpression(
               READONLYEXCEPTION_TYPE,
               new ArgumentListExpression(
                   new ConstantExpression(name), new ConstantExpression(cNode.getName())))));
 }
コード例 #25
0
 private void createConstructorMapCommon(ClassNode cNode, BlockStatement body) {
   final List<FieldNode> fList = cNode.getFields();
   for (FieldNode fNode : fList) {
     if (fNode.isPublic()) continue; // public fields will be rejected elsewhere
     if (cNode.getProperty(fNode.getName()) != null) continue; // a property
     if (fNode.isFinal() && fNode.isStatic()) continue;
     if (fNode.getName().contains("$")) continue; // internal field
     if (fNode.isFinal() && fNode.getInitialExpression() != null)
       body.addStatement(checkFinalArgNotOverridden(cNode, fNode));
     body.addStatement(createConstructorStatementDefault(fNode));
   }
   final Parameter[] params = new Parameter[] {new Parameter(HASHMAP_TYPE, "args")};
   doAddConstructor(
       cNode,
       new ConstructorNode(
           ACC_PUBLIC,
           params,
           ClassNode.EMPTY_ARRAY,
           new IfStatement(
               equalsNullExpr(new VariableExpression("args")), new EmptyStatement(), body)));
 }
コード例 #26
0
 private boolean shouldFieldBeInWhiteList(
     final FieldNode fieldNode, final Set<String> fieldsInTransientsList) {
   boolean shouldInclude = true;
   final int modifiers = fieldNode.getModifiers();
   if ((modifiers & Modifier.STATIC) != 0
       || (modifiers & Modifier.TRANSIENT) != 0
       || fieldsInTransientsList.contains(fieldNode.getName())
       || fieldNode.getType().equals(new ClassNode(Object.class))) {
     shouldInclude = false;
   }
   return shouldInclude;
 }
コード例 #27
0
 private Statement createConstructorStatementDate(FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   final Expression date = findArg(fNode.getName());
   return new IfStatement(
       equalsNullExpr(date),
       new IfStatement(
           equalsNullExpr(initExpr),
           assignStatement(fieldExpr, new ConstantExpression(null)),
           assignStatement(fieldExpr, cloneDateExpr(initExpr))),
       assignStatement(fieldExpr, cloneDateExpr(date)));
 }
コード例 #28
0
 private Statement createConstructorStatementGuarded(ClassNode cNode, FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   Expression unknown = findArg(fNode.getName());
   return new IfStatement(
       equalsNullExpr(unknown),
       new IfStatement(
           equalsNullExpr(initExpr),
           new EmptyStatement(),
           assignStatement(fieldExpr, checkUnresolved(cNode, fNode, initExpr))),
       assignStatement(fieldExpr, checkUnresolved(cNode, fNode, unknown)));
 }
コード例 #29
0
 private void printEnumFields(PrintWriter out, List<FieldNode> fields) {
   if (fields.size() == 0) return;
   boolean first = true;
   for (FieldNode field : fields) {
     if (!first) {
       out.print(", ");
     } else {
       first = false;
     }
     out.print(field.getName());
   }
   out.println(";");
 }
コード例 #30
0
 private Statement createConstructorStatementArrayOrCloneable(FieldNode fNode) {
   final Expression fieldExpr = new VariableExpression(fNode);
   Expression initExpr = fNode.getInitialValueExpression();
   ClassNode fieldType = fNode.getType();
   if (initExpr == null) initExpr = new ConstantExpression(null);
   final Expression array = findArg(fNode.getName());
   return new IfStatement(
       equalsNullExpr(array),
       new IfStatement(
           equalsNullExpr(initExpr),
           assignStatement(fieldExpr, new ConstantExpression(null)),
           assignStatement(fieldExpr, cloneArrayOrCloneableExpr(initExpr, fieldType))),
       assignStatement(fieldExpr, cloneArrayOrCloneableExpr(array, fieldType)));
 }