Search in sources :

Example 56 with TypeMirror

use of javax.lang.model.type.TypeMirror in project auto by google.

the class AutoValueProcessor method getFieldOfClasses.

/**
   * Returns the contents of a {@code Class[]}-typed field in an annotation.
   *
   * <p>This method is needed because directly reading the value of such a field from an
   * AnnotationMirror throws: <pre>
   * javax.lang.model.type.MirroredTypeException: Attempt to access Class object for TypeMirror Foo.
   * </pre>
   *
   * @param element The element on which the annotation is present. e.g. the class being processed
   *     by AutoValue.
   * @param annotation The class of the annotation to read from., e.g. {@link
   *     AutoValue.CopyAnnotations}.
   * @param fieldName The name of the field to read, e.g. "exclude".
   * @return a set of fully-qualified names of classes appearing in 'fieldName' on 'annotation' on
   *     'element'.
   */
private ImmutableSet<String> getFieldOfClasses(Element element, Class<? extends Annotation> annotation, String fieldName, Elements elementUtils) {
    TypeElement annotationElement = elementUtils.getTypeElement(annotation.getCanonicalName());
    if (annotationElement == null) {
        // This can happen if the annotation is on the -processorpath but not on the -classpath.
        return ImmutableSet.of();
    }
    TypeMirror annotationMirror = annotationElement.asType();
    for (AnnotationMirror annot : element.getAnnotationMirrors()) {
        if (!typeUtils.isSameType(annot.getAnnotationType(), annotationMirror)) {
            continue;
        }
        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : annot.getElementValues().entrySet()) {
            if (fieldName.contentEquals(entry.getKey().getSimpleName())) {
                ImmutableSet.Builder<String> result = ImmutableSet.builder();
                @SuppressWarnings("unchecked") List<AnnotationValue> annotationsToCopy = (List<AnnotationValue>) entry.getValue().getValue();
                for (AnnotationValue annotationValue : annotationsToCopy) {
                    String qualifiedName = ((TypeElement) ((DeclaredType) annotationValue.getValue()).asElement()).getQualifiedName().toString();
                    result.add(qualifiedName);
                }
                return result.build();
            }
        }
    }
    return ImmutableSet.of();
}
Also used : TypeElement(javax.lang.model.element.TypeElement) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ImmutableSet(com.google.common.collect.ImmutableSet) TypeMirror(javax.lang.model.type.TypeMirror) AnnotationValue(javax.lang.model.element.AnnotationValue) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableBiMap(com.google.common.collect.ImmutableBiMap) DeclaredType(javax.lang.model.type.DeclaredType)

Example 57 with TypeMirror

use of javax.lang.model.type.TypeMirror in project auto by google.

the class AutoValueProcessor method defineVarsForType.

private TypeSimplifier defineVarsForType(TypeElement type, AutoValueTemplateVars vars, ImmutableSet<ExecutableElement> toBuilderMethods, ImmutableSet<ExecutableElement> propertyMethods, Optional<BuilderSpec.Builder> builder) {
    DeclaredType declaredType = MoreTypes.asDeclared(type.asType());
    Set<TypeMirror> types = new TypeMirrorSet();
    types.addAll(returnTypesOf(propertyMethods));
    if (builder.isPresent()) {
        types.addAll(builder.get().referencedTypes());
    }
    TypeElement generatedTypeElement = processingEnv.getElementUtils().getTypeElement("javax.annotation.Generated");
    if (generatedTypeElement != null) {
        types.add(generatedTypeElement.asType());
    }
    TypeMirror javaUtilArrays = getTypeMirror(Arrays.class);
    if (containsArrayType(types)) {
        // If there are array properties then we will be referencing java.util.Arrays.
        // Arrange to import it unless that would introduce ambiguity.
        types.add(javaUtilArrays);
    }
    vars.toBuilderMethods = FluentIterable.from(toBuilderMethods).transform(SimpleMethodFunction.INSTANCE).toList();
    ImmutableSetMultimap<ExecutableElement, String> excludedAnnotationsMap = allMethodExcludedAnnotations(propertyMethods);
    types.addAll(allMethodAnnotationTypes(propertyMethods, excludedAnnotationsMap));
    String pkg = TypeSimplifier.packageNameOf(type);
    TypeSimplifier typeSimplifier = new TypeSimplifier(typeUtils, pkg, types, declaredType);
    vars.imports = typeSimplifier.typesToImport();
    vars.generated = generatedTypeElement == null ? "" : typeSimplifier.simplify(generatedTypeElement.asType());
    vars.arrays = typeSimplifier.simplify(javaUtilArrays);
    ImmutableBiMap<ExecutableElement, String> methodToPropertyName = propertyNameToMethodMap(propertyMethods).inverse();
    Map<ExecutableElement, String> methodToIdentifier = Maps.newLinkedHashMap(methodToPropertyName);
    fixReservedIdentifiers(methodToIdentifier);
    List<Property> props = new ArrayList<Property>();
    EclipseHack eclipseHack = eclipseHack();
    ImmutableMap<ExecutableElement, TypeMirror> returnTypes = eclipseHack.methodReturnTypes(propertyMethods, declaredType);
    for (ExecutableElement method : propertyMethods) {
        TypeMirror returnType = returnTypes.get(method);
        String propertyType = typeSimplifier.simplify(returnType);
        String propertyName = methodToPropertyName.get(method);
        String identifier = methodToIdentifier.get(method);
        ImmutableSet<String> excludedAnnotations = ImmutableSet.<String>builder().addAll(excludedAnnotationsMap.get(method)).add(Override.class.getCanonicalName()).build();
        Property p = new Property(propertyName, identifier, method, propertyType, typeSimplifier, excludedAnnotations);
        props.add(p);
        if (p.isNullable() && returnType.getKind().isPrimitive()) {
            errorReporter.reportError("Primitive types cannot be @Nullable", method);
        }
    }
    // If we are running from Eclipse, undo the work of its compiler which sorts methods.
    eclipseHack.reorderProperties(props);
    vars.props = ImmutableSet.copyOf(props);
    vars.serialVersionUID = getSerialVersionUID(type);
    vars.formalTypes = typeSimplifier.formalTypeParametersString(type);
    vars.actualTypes = TypeSimplifier.actualTypeParametersString(type);
    vars.wildcardTypes = wildcardTypeParametersString(type);
    // Check for @AutoValue.Builder and add appropriate variables if it is present.
    if (builder.isPresent()) {
        builder.get().defineVars(vars, typeSimplifier, methodToPropertyName);
    }
    return typeSimplifier;
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) TypeMirror(javax.lang.model.type.TypeMirror) DeclaredType(javax.lang.model.type.DeclaredType)

Example 58 with TypeMirror

use of javax.lang.model.type.TypeMirror in project auto by google.

the class Key method create.

/**
   * Constructs a key based on the type {@code type} and any {@link Qualifier}s in {@code
   * annotations}.
   *
   * <p>If {@code type} is a {@code Provider<T>}, the returned {@link Key}'s {@link #type()} is
   * {@code T}. If {@code type} is a primitive, the returned {@link Key}'s {@link #type()} is the
   * corresponding {@linkplain Types#boxedClass(PrimitiveType) boxed type}.
   *
   * <p>For example:
   * <table>
   *   <tr><th>Input type                <th>{@code Key.type()}
   *   <tr><td>{@code String}            <td>{@code String}
   *   <tr><td>{@code Provider<String>}  <td>{@code String}
   *   <tr><td>{@code int}               <td>{@code Integer}
   * </table>
   */
static Key create(TypeMirror type, Iterable<? extends AnnotationMirror> annotations, Types types) {
    ImmutableSet.Builder<AnnotationMirror> qualifiers = ImmutableSet.builder();
    for (AnnotationMirror annotation : annotations) {
        if (isAnnotationPresent(annotation.getAnnotationType().asElement(), Qualifier.class)) {
            qualifiers.add(annotation);
        }
    }
    // TODO(gak): check for only one qualifier rather than using the first
    Optional<AnnotationMirror> qualifier = FluentIterable.from(qualifiers.build()).first();
    TypeMirror keyType = isProvider(type) ? MoreTypes.asDeclared(type).getTypeArguments().get(0) : boxedType(type, types);
    return new AutoValue_Key(keyType, wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), qualifier));
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) ImmutableSet(com.google.common.collect.ImmutableSet) TypeMirror(javax.lang.model.type.TypeMirror)

Example 59 with TypeMirror

use of javax.lang.model.type.TypeMirror in project auto by google.

the class TypeSimplifier method findImports.

/**
   * Given a set of referenced types, works out which of them should be imported and what the
   * resulting spelling of each one is.
   *
   * <p>This method operates on a {@code Set<TypeMirror>} rather than just a {@code Set<String>}
   * because it is not strictly possible to determine what part of a fully-qualified type name is
   * the package and what part is the top-level class. For example, {@code java.util.Map.Entry} is
   * a class called {@code Map.Entry} in a package called {@code java.util} assuming Java
   * conventions are being followed, but it could theoretically also be a class called {@code Entry}
   * in a package called {@code java.util.Map}. Since we are operating as part of the compiler, our
   * goal should be complete correctness, and the only way to achieve that is to operate on the real
   * representations of types.
   *
   * @param packageName The name of the package where the class containing these references is
   *     defined. Other classes within the same package do not need to be imported.
   * @param referenced The complete set of declared types (classes and interfaces) that will be
   *     referenced in the generated code.
   * @param defined The complete set of declared types (classes and interfaces) that are defined
   *     within the scope of the generated class (i.e. nested somewhere in its superclass chain,
   *     or in its interface set)
   * @return a map where the keys are fully-qualified types and the corresponding values indicate
   *     whether the type should be imported, and how the type should be spelled in the source code.
   */
private static Map<String, Spelling> findImports(Types typeUtils, String packageName, Set<TypeMirror> referenced, Set<TypeMirror> defined) {
    Map<String, Spelling> imports = new HashMap<String, Spelling>();
    Set<TypeMirror> typesInScope = new TypeMirrorSet();
    typesInScope.addAll(referenced);
    typesInScope.addAll(defined);
    Set<String> ambiguous = ambiguousNames(typeUtils, typesInScope);
    for (TypeMirror type : referenced) {
        TypeElement typeElement = (TypeElement) typeUtils.asElement(type);
        String fullName = typeElement.getQualifiedName().toString();
        String simpleName = typeElement.getSimpleName().toString();
        String pkg = packageNameOf(typeElement);
        boolean importIt;
        String spelling;
        if (ambiguous.contains(simpleName)) {
            importIt = false;
            spelling = fullName;
        } else if (pkg.equals(packageName) || pkg.equals("java.lang")) {
            importIt = false;
            spelling = fullName.substring(pkg.isEmpty() ? 0 : pkg.length() + 1);
        } else {
            importIt = true;
            spelling = simpleName;
        }
        imports.put(fullName, new Spelling(spelling, importIt));
    }
    return imports;
}
Also used : HashMap(java.util.HashMap) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement)

Example 60 with TypeMirror

use of javax.lang.model.type.TypeMirror in project auto by google.

the class TypeSimplifier method referencedClassTypes.

/**
   * Finds all declared types (classes and interfaces) that are referenced in the given
   * {@code Set<TypeMirror>}. This includes classes and interfaces that appear directly in the set,
   * but also ones that appear in type parameters and the like. For example, if the set contains
   * {@code java.util.List<? extends java.lang.Number>} then both {@code java.util.List} and
   * {@code java.lang.Number} will be in the resulting set.
   *
   * <p>The returned set contains only top-level types. If we reference {@code java.util.Map.Entry}
   * then the returned set will contain {@code java.util.Map}. This is because we want to write
   * {@code Map.Entry} everywhere rather than {@code Entry}.
   */
private static Set<TypeMirror> referencedClassTypes(Types typeUtil, Set<TypeMirror> types) {
    Set<TypeMirror> allReferenced = new TypeMirrorSet();
    ReferencedClassTypeVisitor referencedClassVisitor = new ReferencedClassTypeVisitor(typeUtil, allReferenced);
    for (TypeMirror type : types) {
        referencedClassVisitor.visit(type);
    }
    Set<TypeMirror> topLevelReferenced = new TypeMirrorSet();
    for (TypeMirror type : allReferenced) {
        TypeElement typeElement = MoreElements.asType(typeUtil.asElement(type));
        topLevelReferenced.add(topLevelType(typeElement).asType());
    }
    return topLevelReferenced;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement)

Aggregations

TypeMirror (javax.lang.model.type.TypeMirror)1086 TypeElement (javax.lang.model.element.TypeElement)419 ExecutableElement (javax.lang.model.element.ExecutableElement)259 VariableElement (javax.lang.model.element.VariableElement)237 Element (javax.lang.model.element.Element)196 DeclaredType (javax.lang.model.type.DeclaredType)177 ArrayList (java.util.ArrayList)154 Test (org.junit.Test)152 AnnotationMirror (javax.lang.model.element.AnnotationMirror)75 Types (javax.lang.model.util.Types)70 List (java.util.List)66 Elements (javax.lang.model.util.Elements)60 HashSet (java.util.HashSet)53 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)50 Map (java.util.Map)49 ExecutableType (javax.lang.model.type.ExecutableType)45 MethodSpec (com.squareup.javapoet.MethodSpec)44 PackageElement (javax.lang.model.element.PackageElement)41 ArrayType (javax.lang.model.type.ArrayType)41 Expression (com.google.devtools.j2objc.ast.Expression)39