예제 #1
0
 private static void verifyNamesUnique(TypeSystemData typeSystem) {
   Set<String> usedNames = new HashSet<>();
   for (TypeMirror type : typeSystem.getLegacyTypes()) {
     String boxedName = ElementUtils.getSimpleName(typeSystem.boxType(type));
     String primitiveName = ElementUtils.getSimpleName(type);
     if (usedNames.contains(boxedName)) {
       typeSystem.addError("Two types result in the same boxed name: %s.", boxedName);
     } else if (usedNames.contains(primitiveName)) {
       typeSystem.addError("Two types result in the same primitive name: %s.", primitiveName);
     }
     usedNames.add(boxedName);
     usedNames.add(primitiveName);
   }
 }
예제 #2
0
  private static void verifyTypeOrder(TypeSystemData typeSystem) {
    Map<String, List<String>> invalidTypes = new HashMap<>();

    for (int i = typeSystem.getLegacyTypes().size() - 1; i >= 0; i--) {
      TypeMirror typeData = typeSystem.getLegacyTypes().get(i);
      TypeMirror type = typeSystem.boxType(typeData);
      if (invalidTypes.containsKey(ElementUtils.getQualifiedName(type))) {
        typeSystem.addError(
            "Invalid type order. The type(s) %s are inherited from a earlier defined type %s.",
            invalidTypes.get(ElementUtils.getQualifiedName(type)),
            ElementUtils.getQualifiedName(type));
      }
      TypeElement element = ElementUtils.fromTypeMirror(type);
      List<String> nextInvalidTypes = new ArrayList<>();
      if (element != null) {
        nextInvalidTypes.addAll(ElementUtils.getQualifiedSuperTypeNames(element));
      }
      nextInvalidTypes.add(ElementUtils.getQualifiedName(type));

      for (String qualifiedName : nextInvalidTypes) {
        List<String> inheritedTypes = invalidTypes.get(qualifiedName);
        if (inheritedTypes == null) {
          inheritedTypes = new ArrayList<>();
          invalidTypes.put(qualifiedName, inheritedTypes);
        }
        inheritedTypes.add(ElementUtils.getQualifiedName(typeSystem.boxType(typeData)));
      }
    }
  }
예제 #3
0
 private boolean isPrimitiveWrapper(TypeMirror type) {
   Types types = context.getEnvironment().getTypeUtils();
   for (TypeKind kind : TypeKind.values()) {
     if (!kind.isPrimitive()) {
       continue;
     }
     if (ElementUtils.typeEquals(type, types.boxedClass(types.getPrimitiveType(kind)).asType())) {
       return true;
     }
   }
   return false;
 }
예제 #4
0
 protected final TypeMirror resolveCastOrCheck(TemplateMethod method) {
   Class<?> annotationType = getAnnotationType();
   TypeMirror targetTypeMirror =
       ElementUtils.getAnnotationValue(TypeMirror.class, method.getMessageAnnotation(), "value");
   if (!method.getMethod().getModifiers().contains(Modifier.PUBLIC)
       || !method.getMethod().getModifiers().contains(Modifier.STATIC)) {
     method.addError(
         "@%s annotated method %s must be public and static.",
         annotationType.getSimpleName(), method.getMethodName());
   }
   return targetTypeMirror;
 }
예제 #5
0
  private void verifyTypes(TypeSystemData typeSystem) {
    for (TypeMirror type : typeSystem.getLegacyTypes()) {
      if (isPrimitiveWrapper(type)) {
        typeSystem.addError("Types must not contain primitive wrapper types.");
      }

      if (ElementUtils.typeEquals(type, context.getType(Object.class))) {
        typeSystem.addError("Types must not contain the generic type java.lang.Object.");
      }
    }

    verifyTypeOrder(typeSystem);
  }
예제 #6
0
  private void verifyExclusiveMethodAnnotation(Template template, Class<?>... annotationTypes) {
    List<ExecutableElement> methods =
        ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements());
    for (ExecutableElement method : methods) {
      List<AnnotationMirror> foundAnnotations = new ArrayList<>();
      for (int i = 0; i < annotationTypes.length; i++) {
        Class<?> annotationType = annotationTypes[i];
        AnnotationMirror mirror =
            ElementUtils.findAnnotationMirror(context.getEnvironment(), method, annotationType);
        if (mirror != null) {
          foundAnnotations.add(mirror);
        }
      }
      if (foundAnnotations.size() > 1) {
        List<String> annotationNames = new ArrayList<>();
        for (AnnotationMirror mirror : foundAnnotations) {
          annotationNames.add("@" + ElementUtils.getSimpleName(mirror.getAnnotationType()));
        }

        template.addError("Non exclusive usage of annotations %s.", annotationNames);
      }
    }
  }
예제 #7
0
  @Override
  protected TypeSystemData parse(Element element, AnnotationMirror mirror) {
    TypeElement templateType = (TypeElement) element;
    AnnotationMirror templateTypeAnnotation = mirror;
    DSLOptions options = element.getAnnotation(DSLOptions.class);
    if (options == null) {
      options = TypeSystemParser.class.getAnnotation(DSLOptions.class);
    }
    assert options != null;

    TypeSystemData typeSystem =
        new TypeSystemData(context, templateType, templateTypeAnnotation, options, false);

    // annotation type on class path!?
    TypeElement annotationTypeElement =
        processingEnv.getElementUtils().getTypeElement(getAnnotationType().getCanonicalName());
    if (annotationTypeElement == null) {
      typeSystem.addError(
          "Required class %s is not on the classpath.", getAnnotationType().getName());
    }
    if (templateType.getModifiers().contains(Modifier.PRIVATE)) {
      typeSystem.addError(
          "A @%s must have at least package protected visibility.", getAnnotationType().getName());
    }

    if (templateType.getModifiers().contains(Modifier.FINAL)) {
      typeSystem.addError("The @%s must not be final.", getAnnotationType().getName());
    }
    if (typeSystem.hasErrors()) {
      return typeSystem;
    }

    if (typeSystem.hasErrors()) {
      return typeSystem;
    }

    verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class);

    List<Element> elements =
        newElementList(context.getEnvironment().getElementUtils().getAllMembers(templateType));
    List<ImplicitCastData> implicitCasts =
        new ImplicitCastParser(context, typeSystem).parse(elements);
    List<TypeCastData> casts = new TypeCastParser(context, typeSystem).parse(elements);
    List<TypeCheckData> checks = new TypeCheckParser(context, typeSystem).parse(elements);

    if (casts == null || checks == null || implicitCasts == null) {
      return typeSystem;
    }

    List<TypeMirror> legacyTypes =
        ElementUtils.getAnnotationValueList(
            TypeMirror.class, typeSystem.getTemplateTypeAnnotation(), "value");
    for (int i = 0; i < legacyTypes.size(); i++) {
      legacyTypes.set(i, ElementUtils.fillInGenericWildcards(legacyTypes.get(i)));
    }

    typeSystem.getLegacyTypes().addAll(legacyTypes);
    verifyTypes(typeSystem);
    typeSystem.getLegacyTypes().add(context.getType(Object.class));
    typeSystem.getLegacyTypes().add(context.getType(void.class));
    verifyNamesUnique(typeSystem);

    typeSystem.getImplicitCasts().addAll(implicitCasts);
    typeSystem.getCasts().addAll(casts);
    typeSystem.getChecks().addAll(checks);

    if (typeSystem.hasErrors()) {
      return typeSystem;
    }
    return typeSystem;
  }
예제 #8
0
 @Override
 public AnnotationValue getMessageAnnotationValue() {
   return ElementUtils.getAnnotationValue(getMessageAnnotation(), "value");
 }
예제 #9
0
 public Modifier getVisibility() {
   return ElementUtils.getVisibility(getModifiers());
 }
예제 #10
0
 public void setVisibility(Modifier visibility) {
   ElementUtils.setVisibility(getModifiers(), visibility);
 }
예제 #11
0
 public CodeExecutableElement(TypeMirror returnType, String name) {
   super(ElementUtils.modifiers());
   this.returnType = returnType;
   this.name = CodeNames.of(name);
 }
예제 #12
0
 @Override
 public final boolean isParsable(ExecutableElement method) {
   return ElementUtils.findAnnotationMirror(
           getContext().getEnvironment(), method, getAnnotationType())
       != null;
 }