Beispiel #1
0
  public boolean handle(
      AnnotationValues<Data> annotation, Annotation ast, EclipseNode annotationNode) {
    Data ann = annotation.getInstance();
    EclipseNode typeNode = annotationNode.up();

    TypeDeclaration typeDecl = null;
    if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
    int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
    boolean notAClass =
        (modifiers
                & (ClassFileConstants.AccInterface
                    | ClassFileConstants.AccAnnotation
                    | ClassFileConstants.AccEnum))
            != 0;

    if (typeDecl == null || notAClass) {
      annotationNode.addError("@Data is only supported on a class.");
      return false;
    }

    // Careful: Generate the public static constructor (if there is one) LAST, so that any attempt
    // to
    // 'find callers' on the annotation node will find callers of the constructor, which is by far
    // the
    // most useful of the many methods built by @Data. This trick won't work for the non-static
    // constructor,
    // for whatever reason, though you can find callers of that one by focusing on the class name
    // itself
    // and hitting 'find callers'.

    new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
    new HandleSetter().generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
    new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
    new HandleToString().generateToStringForType(typeNode, annotationNode);
    new HandleConstructor()
        .generateRequiredArgsConstructor(
            typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), true, ast);

    return false;
  }
Beispiel #2
0
  public boolean handle(
      AnnotationValues<Data> annotation, Annotation ast, EclipseNode annotationNode) {
    Data ann = annotation.getInstance();
    EclipseNode typeNode = annotationNode.up();

    TypeDeclaration typeDecl = null;
    if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
    int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
    boolean notAClass =
        (modifiers
                & (ClassFileConstants.AccInterface
                    | ClassFileConstants.AccAnnotation
                    | ClassFileConstants.AccEnum))
            != 0;

    if (typeDecl == null || notAClass) {
      annotationNode.addError("@Data is only supported on a class.");
      return false;
    }

    FieldNameMangler fieldNameMangler = null;
    try {
      Class<? extends FieldNameMangler> clazz = annotation.getInstance().fieldNameMangler();
      if (clazz != null) {
        fieldNameMangler = clazz.newInstance();
      }
    } catch (InstantiationException ie) {
      // Ignore this Exception (would log if there were a logger instance)
    } catch (IllegalAccessException iae) {
      // Ignore this Exception (would log if there were a logger instance)
    }
    boolean chainable = annotation.getInstance().chainableSetters();

    List<EclipseNode> nodesForConstructor = new ArrayList<EclipseNode>();
    for (EclipseNode child : typeNode.down()) {
      if (child.getKind() != Kind.FIELD) continue;
      FieldDeclaration fieldDecl = (FieldDeclaration) child.get();
      // Skip fields that start with $
      if (fieldDecl.name.length > 0 && fieldDecl.name[0] == '$') continue;
      // Skip static fields.
      if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) continue;
      boolean isFinal = (fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0;
      boolean isNonNull =
          findAnnotations(fieldDecl, TransformationsUtil.NON_NULL_PATTERN).length != 0;
      if ((isFinal || isNonNull) && fieldDecl.initialization == null)
        nodesForConstructor.add(child);
      new HandleGetter().generateGetterForField(child, annotationNode.get(), fieldNameMangler);
      if (!isFinal)
        new HandleSetter()
            .generateSetterForField(child, annotationNode.get(), chainable, fieldNameMangler);
    }

    new HandleToString().generateToStringForType(typeNode, annotationNode);
    new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);

    // Careful: Generate the public static constructor (if there is one) LAST, so that any attempt
    // to
    // 'find callers' on the annotation node will find callers of the constructor, which is by far
    // the
    // most useful of the many methods built by @Data. This trick won't work for the non-static
    // constructor,
    // for whatever reason, though you can find callers of that one by focusing on the class name
    // itself
    // and hitting 'find callers'.

    if (constructorExists(typeNode) == MemberExistsResult.NOT_EXISTS) {
      ConstructorDeclaration constructor =
          createConstructor(
              ann.staticConstructor().length() == 0, typeNode, nodesForConstructor, ast);
      injectMethod(typeNode, constructor);
    }

    if (ann.staticConstructor().length() > 0) {
      if (methodExists("of", typeNode) == MemberExistsResult.NOT_EXISTS) {
        MethodDeclaration staticConstructor =
            createStaticConstructor(ann.staticConstructor(), typeNode, nodesForConstructor, ast);
        injectMethod(typeNode, staticConstructor);
      }
    }

    return false;
  }