Search in sources :

Example 16 with TypeElement

use of javax.lang.model.element.TypeElement in project epoxy by airbnb.

the class HashCodeValidator method hasHashCodeInClassHierarchy.

private boolean hasHashCodeInClassHierarchy(TypeElement clazz) {
    ExecutableElement methodOnClass = getMethodOnClass(clazz, HASH_CODE_METHOD, typeUtils);
    if (methodOnClass == null) {
        return false;
    }
    Element implementingClass = methodOnClass.getEnclosingElement();
    if (implementingClass.getSimpleName().toString().equals("Object")) {
        // Don't count default implementation on Object class
        return false;
    }
    // correctly :P)
    return true;
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement)

Example 17 with TypeElement

use of javax.lang.model.element.TypeElement in project epoxy by airbnb.

the class HashCodeValidator method validateImplementsHashCode.

private void validateImplementsHashCode(TypeMirror mirror) throws EpoxyProcessorException {
    if (TypeName.get(mirror).isPrimitive()) {
        return;
    }
    if (mirror.getKind() == TypeKind.ARRAY) {
        validateArrayType((ArrayType) mirror);
        return;
    }
    if (!(mirror instanceof DeclaredType)) {
        return;
    }
    DeclaredType declaredType = (DeclaredType) mirror;
    Element element = typeUtils.asElement(mirror);
    TypeElement clazz = (TypeElement) element;
    if (isIterableType(clazz)) {
        validateIterableType(declaredType);
        return;
    }
    if (isAutoValueType(element)) {
        return;
    }
    if (isWhiteListedType(element)) {
        return;
    }
    if (!hasHashCodeInClassHierarchy(clazz)) {
        throwError("Attribute does not implement hashCode");
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) DeclaredType(javax.lang.model.type.DeclaredType)

Example 18 with TypeElement

use of javax.lang.model.element.TypeElement in project epoxy by airbnb.

the class ProcessorUtils method isSubtypeOfType.

static boolean isSubtypeOfType(TypeMirror typeMirror, String otherType) {
    if (otherType.equals(typeMirror.toString())) {
        return true;
    }
    if (typeMirror.getKind() != TypeKind.DECLARED) {
        return false;
    }
    DeclaredType declaredType = (DeclaredType) typeMirror;
    List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
    if (typeArguments.size() > 0) {
        StringBuilder typeString = new StringBuilder(declaredType.asElement().toString());
        typeString.append('<');
        for (int i = 0; i < typeArguments.size(); i++) {
            if (i > 0) {
                typeString.append(',');
            }
            typeString.append('?');
        }
        typeString.append('>');
        if (typeString.toString().equals(otherType)) {
            return true;
        }
    }
    Element element = declaredType.asElement();
    if (!(element instanceof TypeElement)) {
        return false;
    }
    TypeElement typeElement = (TypeElement) element;
    TypeMirror superType = typeElement.getSuperclass();
    if (isSubtypeOfType(superType, otherType)) {
        return true;
    }
    for (TypeMirror interfaceType : typeElement.getInterfaces()) {
        if (isSubtypeOfType(interfaceType, otherType)) {
            return true;
        }
    }
    return false;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableElement(javax.lang.model.element.VariableElement) Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) DeclaredType(javax.lang.model.type.DeclaredType)

Example 19 with TypeElement

use of javax.lang.model.element.TypeElement in project epoxy by airbnb.

the class EpoxyProcessor method findClassAnnotationWithLayout.

/**
   * Looks for {@link EpoxyModelClass} annotation in the original class and his parents.
   */
private EpoxyModelClass findClassAnnotationWithLayout(TypeElement classElement) {
    if (!isEpoxyModel(classElement)) {
        return null;
    }
    EpoxyModelClass annotation = classElement.getAnnotation(EpoxyModelClass.class);
    if (annotation == null) {
        return null;
    }
    try {
        int layoutRes = annotation.layout();
        if (layoutRes != 0) {
            return annotation;
        }
    } catch (AnnotationTypeMismatchException e) {
        logError("Invalid layout value in %s annotation. (class: %s). %s: %s", EpoxyModelClass.class, classElement.getSimpleName(), e.getClass().getSimpleName(), e.getMessage());
        return null;
    }
    TypeElement superclassElement = (TypeElement) typeUtils.asElement(classElement.getSuperclass());
    EpoxyModelClass annotationOnSuperClass = findClassAnnotationWithLayout(superclassElement);
    // Return the last annotation value we have so the proper error can be thrown if needed
    return annotationOnSuperClass != null ? annotationOnSuperClass : annotation;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) AnnotationTypeMismatchException(java.lang.annotation.AnnotationTypeMismatchException)

Example 20 with TypeElement

use of javax.lang.model.element.TypeElement in project epoxy by airbnb.

the class EpoxyProcessor method validateAccessibleViaGeneratedCode.

private void validateAccessibleViaGeneratedCode(Element attribute) {
    TypeElement enclosingElement = (TypeElement) attribute.getEnclosingElement();
    // Verify method modifiers.
    Set<Modifier> modifiers = attribute.getModifiers();
    if (modifiers.contains(PRIVATE) || modifiers.contains(STATIC)) {
        logError("%s annotations must not be on private or static fields. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
    }
    // Nested classes must be static
    if (enclosingElement.getNestingKind().isNested()) {
        if (!enclosingElement.getModifiers().contains(STATIC)) {
            logError("Nested classes with %s annotations must be static. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
        }
    }
    // Verify containing type.
    if (enclosingElement.getKind() != CLASS) {
        logError("%s annotations may only be contained in classes. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
    }
    // Verify containing class visibility is not private.
    if (enclosingElement.getModifiers().contains(PRIVATE)) {
        logError("%s annotations may not be contained in private classes. (class: %s, field: %s)", EpoxyAttribute.class.getSimpleName(), enclosingElement.getSimpleName(), attribute.getSimpleName());
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) Modifier(javax.lang.model.element.Modifier)

Aggregations

TypeElement (javax.lang.model.element.TypeElement)1564 ExecutableElement (javax.lang.model.element.ExecutableElement)517 Element (javax.lang.model.element.Element)504 TypeMirror (javax.lang.model.type.TypeMirror)421 VariableElement (javax.lang.model.element.VariableElement)333 DeclaredType (javax.lang.model.type.DeclaredType)202 ArrayList (java.util.ArrayList)177 PackageElement (javax.lang.model.element.PackageElement)159 AnnotationMirror (javax.lang.model.element.AnnotationMirror)151 Test (org.junit.Test)136 HashMap (java.util.HashMap)118 HashSet (java.util.HashSet)109 Elements (javax.lang.model.util.Elements)101 Map (java.util.Map)98 IOException (java.io.IOException)97 List (java.util.List)97 ClassName (com.squareup.javapoet.ClassName)88 Test (org.junit.jupiter.api.Test)80 MethodSpec (com.squareup.javapoet.MethodSpec)72 TypeSpec (com.squareup.javapoet.TypeSpec)63