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:
}
}
}
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;
}
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();
}
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;
}
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;
}
Aggregations