예제 #1
0
 public void handle(
     final AccessLevel level,
     final Class<? extends java.lang.annotation.Annotation> annotationType) {
   LOMBOK_NODE_TYPE mayBeField = annotationNode.up();
   if (mayBeField == null) return;
   TYPE_TYPE type = typeOf(annotationNode, ast);
   List<FIELD_TYPE> fields = new ArrayList<FIELD_TYPE>();
   if (mayBeField.getKind() == Kind.FIELD) {
     for (LOMBOK_NODE_TYPE node : annotationNode.upFromAnnotationToFields()) {
       fields.add(fieldOf(node, ast));
     }
   } else if (mayBeField.getKind() == Kind.TYPE) {
     for (FIELD_TYPE field : type.fields()) {
       if (!field.annotations(SETTER_PATTERN).isEmpty()) continue;
       if (field.name().startsWith("$")) continue;
       if (field.isFinal()) continue;
       if (field.isStatic()) continue;
       fields.add(field);
     }
   } else {
     annotationNode.addError(canBeUsedOnClassAndFieldOnly(annotationType));
     return;
   }
   generateSetter(type, fields, level);
 }
 private void generateGetVetoableSupportMethod(final TYPE_TYPE type) {
   if (type.hasMethod(VETOABLE_CHANGE_SUPPORT_METHOD_NAME)) return;
   type.editor()
       .injectMethod(
           MethodDecl(Type(VetoableChangeSupport.class), VETOABLE_CHANGE_SUPPORT_METHOD_NAME)
               .makePrivate() //
               .withStatement(
                   If(Equal(Field(VETOABLE_CHANGE_SUPPORT_FIELD_NAME), Null()))
                       .Then(
                           Block() //
                               .withStatement(
                                   Synchronized(
                                           Field(VETOABLE_CHANGE_SUPPORT_FIELD_NAME + "Lock")) //
                                       .withStatement(
                                           If(Equal(
                                                   Field(VETOABLE_CHANGE_SUPPORT_FIELD_NAME),
                                                   Null()))
                                               .Then(
                                                   Block() //
                                                       .withStatement(
                                                           Assign(
                                                               Field(
                                                                   VETOABLE_CHANGE_SUPPORT_FIELD_NAME),
                                                               New(Type(
                                                                       VetoableChangeSupport
                                                                           .class))
                                                                   .withArgument(This())))))))) //
               .withStatement(Return(Field(VETOABLE_CHANGE_SUPPORT_FIELD_NAME))));
 }
예제 #3
0
 private void generateSetter(
     final TYPE_TYPE type,
     final FIELD_TYPE field,
     final AccessLevel level,
     final String propertyNameFieldName) {
   String fieldName = field.name();
   boolean isBoolean = field.isOfType("boolean");
   String setterName = TransformationsUtil.toSetterName(fieldName, isBoolean);
   if (type.hasMethod(setterName)) return;
   String oldValueName = OLD_VALUE_VARIABLE_NAME;
   List<lombok.ast.Annotation> nonNulls = field.annotations(TransformationsUtil.NON_NULL_PATTERN);
   MethodDecl methodDecl =
       MethodDecl(Type("void"), setterName)
           .withAccessLevel(level)
           .withArgument(Arg(field.type(), fieldName).withAnnotations(nonNulls));
   if (!nonNulls.isEmpty() && !field.isPrimitive()) {
     methodDecl.withStatement(
         If(Equal(Name(fieldName), Null()))
             .Then(Throw(New(Type(NullPointerException.class)).withArgument(String(fieldName)))));
   }
   methodDecl
       .withStatement(
           LocalDecl(field.type(), oldValueName)
               .makeFinal()
               .withInitialization(Field(fieldName))) //
       .withStatement(Assign(Field(fieldName), Name(fieldName))) //
       .withStatement(
           Call(Call(PROPERTY_CHANGE_SUPPORT_METHOD_NAME), FIRE_PROPERTY_CHANGE_METHOD_NAME) //
               .withArgument(Name(propertyNameFieldName))
               .withArgument(Name(oldValueName))
               .withArgument(Field(fieldName)));
   type.injectMethod(methodDecl);
 }
  private void generateSetter(
      final TYPE_TYPE type,
      final FIELD_TYPE field,
      final AccessLevel level,
      final boolean vetoable,
      final boolean throwVetoException,
      final String propertyNameFieldName) {
    String fieldName = field.filteredName();
    boolean isBoolean = field.isOfType("boolean");
    String setterName =
        toSetterName(field.getAnnotationValue(Accessors.class), field.name(), isBoolean);
    if (type.hasMethod(setterName, field.type())) return;
    String oldValueName = OLD_VALUE_VARIABLE_NAME;
    List<lombok.ast.Annotation> nonNulls = field.annotations(TransformationsUtil.NON_NULL_PATTERN);
    MethodDecl methodDecl =
        MethodDecl(Type("void"), setterName)
            .withAccessLevel(level)
            .withArgument(Arg(field.type(), fieldName).withAnnotations(nonNulls));
    if (!nonNulls.isEmpty() && !field.isPrimitive()) {
      methodDecl.withStatement(
          If(Equal(Name(fieldName), Null()))
              .Then(Throw(New(Type(NullPointerException.class)).withArgument(String(fieldName)))));
    }

    methodDecl.withStatement(
        LocalDecl(field.type(), oldValueName).makeFinal().withInitialization(Field(fieldName)));

    if (vetoable) {
      if (throwVetoException) {
        methodDecl.withThrownException(Type(PropertyVetoException.class));
        methodDecl.withStatement(
            Call(FIRE_VETOABLE_CHANGE_METHOD_NAME) //
                .withArgument(Name(propertyNameFieldName))
                .withArgument(Name(oldValueName))
                .withArgument(Name(fieldName)));
      } else {
        methodDecl.withStatement(
            Try(Block()
                    .withStatement(
                        Call(FIRE_VETOABLE_CHANGE_METHOD_NAME) //
                            .withArgument(Name(propertyNameFieldName))
                            .withArgument(Name(oldValueName))
                            .withArgument(Name(fieldName)))) //
                .Catch(
                    Arg(Type(PropertyVetoException.class), E_VALUE_VARIABLE_NAME),
                    Block().withStatement(Return())));
      }
    }

    methodDecl
        .withStatement(Assign(Field(fieldName), Name(fieldName))) //
        .withStatement(
            Call(FIRE_PROPERTY_CHANGE_METHOD_NAME) //
                .withArgument(Name(propertyNameFieldName))
                .withArgument(Name(oldValueName))
                .withArgument(Name(fieldName)));
    type.editor().injectMethod(methodDecl);
  }
예제 #5
0
 private void generatePropertyNameConstant(
     final TYPE_TYPE type, final FIELD_TYPE field, final String propertyNameFieldName) {
   String propertyName = field.name();
   if (type.hasField(propertyNameFieldName)) return;
   type.injectField(
       FieldDecl(Type(String.class), propertyNameFieldName)
           .makePublic()
           .makeStatic()
           .makeFinal() //
           .withInitialization(String(propertyName)));
 }
 private void generateVetoableChangeListenerMethod(final String methodName, final TYPE_TYPE type) {
   if (type.hasMethod(methodName, Type(VetoableChangeListener.class))) return;
   type.editor()
       .injectMethod(
           MethodDecl(Type("void"), methodName)
               .makePublic()
               .withArgument(Arg(Type(VetoableChangeListener.class), LISTENER_ARG_NAME)) //
               .withStatement(
                   Call(Call(VETOABLE_CHANGE_SUPPORT_METHOD_NAME), methodName)
                       .withArgument(Name(LISTENER_ARG_NAME))));
 }
예제 #7
0
 public FieldDecl addField(
     final TYPE_TYPE type, TypeRef fieldType, String fieldName, Expression<?> initialization) {
   final FieldDecl fieldDecl = FieldDecl(fieldType, fieldName).makePrivate();
   if (initialization != null) {
     fieldDecl.withInitialization(initialization);
   }
   type.editor().injectField(fieldDecl);
   return fieldDecl;
 }
예제 #8
0
 public FieldDecl addField(
     final TYPE_TYPE type,
     MethodDescriptor.Type fieldType,
     String fieldName,
     Expression<?> initialization) {
   final FieldDecl fieldDecl = FieldDecl(asTypeRef(fieldType), fieldName).makePrivate();
   if (initialization != null) fieldDecl.withInitialization(initialization);
   type.editor().injectField(fieldDecl);
   return fieldDecl;
 }
 private void generateVetoableChangeSupportFields(final TYPE_TYPE type) {
   if (!type.hasField(VETOABLE_CHANGE_SUPPORT_FIELD_NAME)) {
     type.editor()
         .injectField(
             FieldDecl(Type(VetoableChangeSupport.class), VETOABLE_CHANGE_SUPPORT_FIELD_NAME)
                 .makePrivate()
                 .makeTransient()
                 .makeVolatile());
   }
   if (!type.hasField(VETOABLE_CHANGE_SUPPORT_FIELD_NAME + "Lock")) {
     type.editor()
         .injectField(
             FieldDecl(
                     Type(Object.class).withDimensions(1),
                     VETOABLE_CHANGE_SUPPORT_FIELD_NAME + "Lock")
                 .makePrivate()
                 .makeFinal() //
                 .withInitialization(
                     NewArray(Type(Object.class)).withDimensionExpression(Number(0))));
   }
 }
 private void generateFirePropertyChangeMethod(final TYPE_TYPE type) {
   if (type.hasMethod(
       FIRE_PROPERTY_CHANGE_METHOD_NAME,
       Type(String.class),
       Type(Object.class),
       Type(Object.class))) return;
   type.editor()
       .injectMethod(
           MethodDecl(Type("void"), FIRE_PROPERTY_CHANGE_METHOD_NAME)
               .makePublic() //
               .withArgument(Arg(Type(String.class), PROPERTY_NAME_ARG_NAME))
               .withArgument(Arg(Type(Object.class), OLD_VALUE_ARG_NAME))
               .withArgument(Arg(Type(Object.class), NEW_VALUE_ARG_NAME)) //
               .withStatement(
                   Call(
                           Call(PROPERTY_CHANGE_SUPPORT_METHOD_NAME),
                           FIRE_PROPERTY_CHANGE_METHOD_NAME) //
                       .withArgument(Name(PROPERTY_NAME_ARG_NAME))
                       .withArgument(Name(OLD_VALUE_ARG_NAME))
                       .withArgument(Name(NEW_VALUE_ARG_NAME))));
 }
예제 #11
0
  public void delegateMethodsTo(
      TYPE_TYPE type,
      MethodDescriptor[] methodDescriptors,
      Expression<?> receiver,
      Map<String, String> methodMapper) {
    for (MethodDescriptor methodDesc : methodDescriptors) {
      List<TypeRef> argTypes = new ArrayList<>();
      List<Argument> methodArgs = new ArrayList<>();
      List<Expression<?>> callArgs = new ArrayList<>();
      int argCounter = 0;
      for (MethodDescriptor.Type argType : methodDesc.arguments) {
        String argName = "arg" + argCounter++;
        TypeRef argTypeRef = asTypeRef(argType);
        argTypes.add(argTypeRef);
        Argument arg = Arg(argTypeRef, argName);
        if (argType.annotations.length > 0) {
          List<Annotation> annotations = new ArrayList<>();
          for (int i = 0; i < argType.annotations.length; i++) {
            annotations.add(Annotation(asTypeRef(argType.annotations[i])));
          }
          arg.withAnnotations(annotations);
        }
        methodArgs.add(arg);
        callArgs.add(Name(argName));
      }

      if (type.hasMethodIncludingSupertypes(
          methodDesc.methodName, argTypes.toArray(new TypeRef[argTypes.size()]))) {
        continue;
      }

      String delegateMethodName = methodMapper.get(methodDesc.methodName);
      if (delegateMethodName == null) {
        delegateMethodName = methodDesc.methodName;
      }

      Call methodCall = Call(receiver, delegateMethodName).withArguments(callArgs);
      MethodDecl methodDecl =
          MethodDecl(asTypeRef(methodDesc.returnType), methodDesc.methodName)
              .makePublic()
              .withArguments(methodArgs);
      if (VOID.equals(methodDesc.returnType.type)) {
        methodDecl.withStatement(methodCall);
      } else {
        methodDecl.withStatement(Return(methodCall));
      }
      if (methodDesc.typeParameters.length > 0) {
        List<TypeParam> types = new ArrayList<>();
        for (int i = 0; i < methodDesc.typeParameters.length; i++) {
          types.add(asTypeParam(methodDesc.typeParameters[i]));
        }
        methodDecl.withTypeParameters(types);
      }
      if (methodDesc.exceptions.length > 0) {
        List<TypeRef> exceptions = new ArrayList<>();
        for (int i = 0; i < methodDesc.exceptions.length; i++) {
          exceptions.add(asTypeRef(methodDesc.exceptions[i]));
        }
        methodDecl.withThrownExceptions(exceptions);
      }
      if (methodDesc.annotations.length > 0) {
        List<Annotation> annotations = new ArrayList<>();
        for (int i = 0; i < methodDesc.annotations.length; i++) {
          annotations.add(Annotation(asTypeRef(methodDesc.annotations[i])));
        }
        methodDecl.withAnnotations(annotations);
      }

      type.editor().injectMethod(methodDecl);
    }
  }