Search in sources :

Example 91 with TypeElement

use of javax.lang.model.element.TypeElement in project auto by google.

the class AutoValueProcessor method determineObjectMethodsToGenerate.

/**
   * Given a list of all methods defined in or inherited by a class, sets the equals, hashCode, and
   * toString fields of vars according as the corresponding methods should be generated.
   */
private static void determineObjectMethodsToGenerate(Set<ExecutableElement> methods, AutoValueTemplateVars vars) {
    // The defaults here only come into play when an ancestor class doesn't exist.
    // Compilation will fail in that case, but we don't want it to crash the compiler with
    // an exception before it does. If all ancestors do exist then we will definitely find
    // definitions of these three methods (perhaps the ones in Object) so we will overwrite these:
    vars.equals = false;
    vars.hashCode = false;
    vars.toString = false;
    for (ExecutableElement method : methods) {
        ObjectMethodToOverride override = objectMethodToOverride(method);
        boolean canGenerate = method.getModifiers().contains(Modifier.ABSTRACT) || isJavaLangObject((TypeElement) method.getEnclosingElement());
        switch(override) {
            case EQUALS:
                vars.equals = canGenerate;
                break;
            case HASH_CODE:
                vars.hashCode = canGenerate;
                break;
            case TO_STRING:
                vars.toString = canGenerate;
                break;
            default:
        }
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 92 with TypeElement

use of javax.lang.model.element.TypeElement 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 93 with TypeElement

use of javax.lang.model.element.TypeElement in project auto by google.

the class BuilderMethodClassifier method copyOfMethods.

/**
   * Returns {@code copyOf} methods from the given type. These are static methods called
   * {@code copyOf} with a single parameter. All of Guava's concrete immutable collection types have
   * at least one such method, but we will also accept other classes with an appropriate method,
   * such as {@link java.util.EnumSet}.
   */
private ImmutableList<ExecutableElement> copyOfMethods(TypeMirror targetType) {
    if (!targetType.getKind().equals(TypeKind.DECLARED)) {
        return ImmutableList.of();
    }
    String copyOf = Optionalish.isOptional(targetType) ? "of" : "copyOf";
    TypeElement immutableTargetType = MoreElements.asType(typeUtils.asElement(targetType));
    ImmutableList.Builder<ExecutableElement> copyOfMethods = ImmutableList.builder();
    for (ExecutableElement method : ElementFilter.methodsIn(immutableTargetType.getEnclosedElements())) {
        if (method.getSimpleName().contentEquals(copyOf) && method.getParameters().size() == 1 && method.getModifiers().contains(Modifier.STATIC)) {
            copyOfMethods.add(method);
        }
    }
    return copyOfMethods.build();
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ImmutableList(com.google.common.collect.ImmutableList) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 94 with TypeElement

use of javax.lang.model.element.TypeElement 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 95 with TypeElement

use of javax.lang.model.element.TypeElement 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

TypeElement (javax.lang.model.element.TypeElement)1562 ExecutableElement (javax.lang.model.element.ExecutableElement)517 Element (javax.lang.model.element.Element)502 TypeMirror (javax.lang.model.type.TypeMirror)420 VariableElement (javax.lang.model.element.VariableElement)333 DeclaredType (javax.lang.model.type.DeclaredType)201 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