Top Description Fields Constructors Methods
com.google.auto.value.processor

pack-priv abstract Class BuilderMethodClassifier<E extends javax.lang.model.element.Element>

extends Object
Class Inheritance
Known Direct Subclasses
com.google.auto.value.processor.BuilderMethodClassifierForAutoBuilder, com.google.auto.value.processor.BuilderMethodClassifierForAutoValue
Type Parameters
<E>
the kind of Element that the corresponding properties are defined by. This is ExecutableElement for AutoValue, where properties are defined by abstract methods, and VariableElement for AutoBuilder, where they are defined by constructor or method parameters.
Static Imports
com.google.auto.value.processor.AutoValueishProcessor.nullableAnnotationFor

Classifies methods inside builder types, based on their names and parameter and return types.
Author
Éamonn McManus

Field Summary

Modifier and TypeField and Description
private final Map<String, BuilderSpec.PropertyGetter>
private final javax.lang.model.element.TypeElement
private final Set<javax.lang.model.element.ExecutableElement>
private final javax.lang.model.type.TypeMirror
private final EclipseHack
private final javax.lang.model.util.Elements
private final ErrorReporter
private final Nullables
private final ImmutableSet<String>
private final Multimap<String, BuilderSpec.PropertySetter>
private final Map<String, PropertyBuilderClassifier.PropertyBuilder>
private final Multimap<String, BuilderSpec.PropertySetter>
private final ImmutableMap<String, javax.lang.model.type.TypeMirror>
rewrittenPropertyTypes

Property types, rewritten to refer to type variables in the builder.

private boolean
private static final Equivalence<javax.lang.model.type.TypeMirror>
private final javax.lang.model.util.Types

Constructor Summary

AccessConstructor and Description
pack-priv
BuilderMethodClassifier(ErrorReporter errorReporter, javax.annotation.processing.ProcessingEnvironment processingEnv, javax.lang.model.type.TypeMirror builtType, javax.lang.model.element.TypeElement builderType, ImmutableMap<String, javax.lang.model.type.TypeMirror> rewrittenPropertyTypes, ImmutableSet<String> propertiesWithDefaults, Nullables nullables)

Method Summary

Modifier and TypeMethod and Description
pack-priv abstract String
autoWhat()

A string describing what sort of Auto this is, "AutoValue" or "AutoBuilder".

pack-priv ImmutableMap<String, BuilderSpec.PropertyGetter>
builderGetters()

Returns the set of properties that have getters in the builder.

pack-priv javax.lang.model.type.TypeMirror
builderMethodReturnType(javax.lang.model.element.ExecutableElement builderMethod)

Returns the return type of the given method from the builder.

pack-priv Set<javax.lang.model.element.ExecutableElement>
buildMethods()

Returns the methods that were identified as build() methods.

pack-priv abstract void
checkForFailedJavaBean(javax.lang.model.element.ExecutableElement rejectedSetter)

Checks for failed JavaBean usage when a method that looks like a setter doesn't actually match anything, and emits a compiler Note if detected.

private void
classifyGetter(javax.lang.model.element.ExecutableElement builderGetter, String propertyName)

private void
classifyMethod(javax.lang.model.element.ExecutableElement method)

Classifies a method and update the state of this object based on what is found.

private void
classifyMethodNoArgs(javax.lang.model.element.ExecutableElement method)

Classifies a method given that it has no arguments.

private void
classifyMethodOneArg(javax.lang.model.element.ExecutableElement method)

Classifies a method given that it has one argument.

pack-priv boolean
classifyMethods(Iterable<javax.lang.model.element.ExecutableElement> methods, boolean autoValueHasToBuilder)

Classifies the given methods and sets the state of this object based on what is found.

private boolean

Returns:

true if method has been classified successfully
classifyPropertyBuilderOneArg
(javax.lang.model.element.ExecutableElement
A method to classify
method
)

Classifies a method given that it has one argument and is a property builder with a parameter, like ImmutableSortedSet.Builder<String> foosBuilder(Comparator<String>).

private ImmutableList<javax.lang.model.element.ExecutableElement>
copyOfMethods(javax.lang.model.type.TypeMirror targetType, boolean nullableParameter)

Returns copyOf methods from the given type.

pack-priv abstract String
fooBuilderMustMatch()

A string describing what a property builder for property foo must match, foo() or getFoo() for AutoValue, foo for AutoBuilder.

private Optional<BuilderSpec.Copier>
getConvertingSetterFunction(ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods, E propertyElement, javax.lang.model.element.ExecutableElement setter, javax.lang.model.type.TypeMirror parameterType)

Returns an Optional describing how to convert a value from the setter's parameter type to the getter's return type using one of the given methods, or Optional.empty() if the conversion isn't possible.

private Optional<BuilderSpec.Copier>

Returns:

a function that maps a string parameter to a method call using that parameter. For example it might map foo to ImmutableList.copyOf(foo).
getConvertingSetterFunction
(javax.lang.model.element.ExecutableElement
the candidate method to do the copy, ImmutableSet.copyOf(Collection<? extends E>) or ImmutableSet.copyOf(E[]) in the examples.
copyOfMethod
,
javax.lang.model.type.DeclaredType
the type of the property to be set, ImmutableSet<T> in the example.
targetType
,
javax.lang.model.type.TypeMirror
the type of the setter parameter, Set<? extends T> in the example.
parameterType
)

Returns an Optional containing a function to use copyOfMethod to copy the parameterType to the targetType, or Optional.empty() if the method can't be used.

private Optional<BuilderSpec.Copier>
getSetterFunction(E propertyElement, javax.lang.model.element.ExecutableElement setter)

Returns an Optional describing how to convert a value from the setter's parameter type to the getter's return type, or Optional.empty() if the conversion isn't possible.

pack-priv abstract String
getterMustMatch()

A string describing what a builder getter must match: a property method for AutoValue, a parameter for AutoBuilder.

pack-priv abstract javax.lang.model.type.TypeMirror
originalPropertyType(E propertyElement)

Returns the property type as it appears on the original source program element.

private static String
prefixWithSet(String propertyName)

pack-priv abstract ImmutableBiMap<String, E>
propertyElements()

Returns a map from property names to the corresponding source program elements.

pack-priv abstract Optional<String>
propertyForBuilderGetter(javax.lang.model.element.ExecutableElement method)

Returns the name of the property that the given no-arg builder method queries, if any.

private boolean
propertyIsNullable(String property)

True if the given property is nullable, either because its type has a @Nullable type annotation, or because its getter method has a @Nullable method annotation.

pack-priv Map<String, PropertyBuilderClassifier.PropertyBuilder>
pack-priv ImmutableMultimap<String, BuilderSpec.PropertySetter>
propertyNameToSetters()

Returns a multimap from the name of a property to the methods that set it.

pack-priv abstract String
propertyString(E propertyElement)

A string identifying the given property element, which is a method for AutoValue or a parameter for AutoBuilder.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

builderGettersback to summary
private final Map<String, BuilderSpec.PropertyGetter> builderGetters
builderTypeback to summary
private final javax.lang.model.element.TypeElement builderType
buildMethodsback to summary
private final Set<javax.lang.model.element.ExecutableElement> buildMethods
builtTypeback to summary
private final javax.lang.model.type.TypeMirror builtType
eclipseHackback to summary
private final EclipseHack eclipseHack
elementUtilsback to summary
private final javax.lang.model.util.Elements elementUtils
errorReporterback to summary
private final ErrorReporter errorReporter
nullablesback to summary
private final Nullables nullables
propertiesWithDefaultsback to summary
private final ImmutableSet<String> propertiesWithDefaults
propertyNameToPrefixedSettersback to summary
private final Multimap<String, BuilderSpec.PropertySetter> propertyNameToPrefixedSetters
propertyNameToPropertyBuilderback to summary
private final Map<String, PropertyBuilderClassifier.PropertyBuilder> propertyNameToPropertyBuilder
propertyNameToUnprefixedSettersback to summary
private final Multimap<String, BuilderSpec.PropertySetter> propertyNameToUnprefixedSetters
rewrittenPropertyTypesback to summary
private final ImmutableMap<String, javax.lang.model.type.TypeMirror> rewrittenPropertyTypes

Property types, rewritten to refer to type variables in the builder. For example, suppose you have @AutoValue abstract class Foo<T> with a getter abstract T bar() and a builder @AutoValue.Builder interface Builder<T> with a setter abstract Builder<T> setBar(T t). Then the T of Foo<T> and the T of Foo.Builder<T> are two separate variables. Originally bar() returned the T of Foo<T>, but in this map we have rewritten it to be the T of Foo.Builder<T>.

Importantly, this rewrite loses type annotations, so when those are important we must be careful to look at the original type as reported by the originalPropertyType method.

settersPrefixedback to summary
private boolean settersPrefixed
TYPE_EQUIVALENCEback to summary
private static final Equivalence<javax.lang.model.type.TypeMirror> TYPE_EQUIVALENCE
typeUtilsback to summary
private final javax.lang.model.util.Types typeUtils

Constructor Detail

BuilderMethodClassifierback to summary
pack-priv BuilderMethodClassifier(ErrorReporter errorReporter, javax.annotation.processing.ProcessingEnvironment processingEnv, javax.lang.model.type.TypeMirror builtType, javax.lang.model.element.TypeElement builderType, ImmutableMap<String, javax.lang.model.type.TypeMirror> rewrittenPropertyTypes, ImmutableSet<String> propertiesWithDefaults, Nullables nullables)

Method Detail

autoWhatback to summary
pack-priv abstract String autoWhat()

A string describing what sort of Auto this is, "AutoValue" or "AutoBuilder".

builderGettersback to summary
pack-priv ImmutableMap<String, BuilderSpec.PropertyGetter> builderGetters()

Returns the set of properties that have getters in the builder. If a property is defined by an abstract method in the @AutoValue class called foo() or getFoo() then the name of the property is foo, If the builder also has a method of the same name (foo() or getFoo()) then the set returned here will contain foo.

builderMethodReturnTypeback to summary
pack-priv javax.lang.model.type.TypeMirror builderMethodReturnType(javax.lang.model.element.ExecutableElement builderMethod)

Returns the return type of the given method from the builder. This should be the final type of the method when any bound type variables are substituted. Consider this example:

abstract static class ParentBuilder<B extends ParentBuilder> {
  B setFoo(String s);
}
abstract static class ChildBuilder extends ParentBuilder<ChildBuilder> {
  ...
}
If the builder is ChildBuilder then the return type of setFoo is also ChildBuilder, and not B as its getReturnType() method would claim.

If the caller is in a version of Eclipse with this bug then the asMemberOf call will fail if the method is inherited from an interface. We work around that for methods in the @AutoValue class using EclipseHack#methodReturnTypes but we don't try to do so here because it should be much less likely. You might need to change ParentBuilder from an interface to an abstract class to make it work, but you'll often need to do that anyway.

buildMethodsback to summary
pack-priv Set<javax.lang.model.element.ExecutableElement> buildMethods()

Returns the methods that were identified as build() methods. These are methods that have no parameters and return the @AutoValue type, conventionally called build().

checkForFailedJavaBeanback to summary
pack-priv abstract void checkForFailedJavaBean(javax.lang.model.element.ExecutableElement rejectedSetter)

Checks for failed JavaBean usage when a method that looks like a setter doesn't actually match anything, and emits a compiler Note if detected. A frequent source of problems is where the JavaBeans conventions have been followed for most but not all getters. Then AutoValue considers that they haven't been followed at all, so you might have a property called getFoo where you thought it was called just foo, and you might not understand why your setter called setFoo is rejected (it would have to be called setGetFoo).

This is not relevant for AutoBuilder, which uses parameter names rather than getters. The parameter names are unambiguously the same as the property names.

classifyGetterback to summary
private void classifyGetter(javax.lang.model.element.ExecutableElement builderGetter, String propertyName)
classifyMethodback to summary
private void classifyMethod(javax.lang.model.element.ExecutableElement method)

Classifies a method and update the state of this object based on what is found.

classifyMethodNoArgsback to summary
private void classifyMethodNoArgs(javax.lang.model.element.ExecutableElement method)

Classifies a method given that it has no arguments. Currently a method with no arguments can be a build() method, meaning that its return type must be the @AutoValue class; it can be a getter, with the same signature as one of the property getters in the @AutoValue class; or it can be a property builder, like ImmutableList.Builder<String> foosBuilder() for the property defined by ImmutableList<String> foos() or getFoos().

classifyMethodOneArgback to summary
private void classifyMethodOneArg(javax.lang.model.element.ExecutableElement method)

Classifies a method given that it has one argument. A method with one argument can be:

  • a setter, meaning that it looks like foo(T) or setFoo(T), where the AutoValue class has a property called foo of type T;
  • a property builder with one argument, meaning it looks like ImmutableSortedSet.Builder<V> foosBuilder(Comparator<V>), where the AutoValue class has a property called foos with a type whose builder can be made with an argument of the given type.
classifyMethodsback to summary
pack-priv boolean classifyMethods(Iterable<javax.lang.model.element.ExecutableElement> methods, boolean autoValueHasToBuilder)

Classifies the given methods and sets the state of this object based on what is found.

classifyPropertyBuilderOneArgback to summary
private boolean classifyPropertyBuilderOneArg(javax.lang.model.element.ExecutableElement method)

Classifies a method given that it has one argument and is a property builder with a parameter, like ImmutableSortedSet.Builder<String> foosBuilder(Comparator<String>).

Parameters
method:javax.lang.model.element.ExecutableElement

A method to classify

Returns:boolean

true if method has been classified successfully

copyOfMethodsback to summary
private ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods(javax.lang.model.type.TypeMirror targetType, boolean nullableParameter)

Returns copyOf methods from the given type. These are static methods with a single parameter, called copyOf or copyOfSorted for Guava collection types, and called of or ofNullable for Optional. All of Guava's concrete immutable collection types have at least one such method, but we will also accept other classes with an appropriate copyOf method, such as java.util.EnumSet.

fooBuilderMustMatchback to summary
pack-priv abstract String fooBuilderMustMatch()

A string describing what a property builder for property foo must match, foo() or getFoo() for AutoValue, foo for AutoBuilder.

getConvertingSetterFunctionback to summary
private Optional<BuilderSpec.Copier> getConvertingSetterFunction(ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods, E propertyElement, javax.lang.model.element.ExecutableElement setter, javax.lang.model.type.TypeMirror parameterType)

Returns an Optional describing how to convert a value from the setter's parameter type to the getter's return type using one of the given methods, or Optional.empty() if the conversion isn't possible. An error will have been reported in the latter case.

getConvertingSetterFunctionback to summary
private Optional<BuilderSpec.Copier> getConvertingSetterFunction(javax.lang.model.element.ExecutableElement copyOfMethod, javax.lang.model.type.DeclaredType targetType, javax.lang.model.type.TypeMirror parameterType)

Returns an Optional containing a function to use copyOfMethod to copy the parameterType to the targetType, or Optional.empty() if the method can't be used. For example, we might have a property of type ImmutableSet<T> and our setter has a parameter of type Set<? extends T>. Can we use ImmutableSet<E> ImmutableSet.copyOf(Collection<? extends E>) to set the property? What about ImmutableSet<E> ImmutableSet.copyOf(E[])?

The example here is deliberately complicated, in that it has a type parameter of its own, presumably because the @AutoValue class is Foo<T>. One subtle point is that the builder will then be Builder<T> where this T is a different type variable. However, we've used TypeVariables to ensure that the T in ImmutableSet<T> is actually the one from Builder<T> instead of the original one from Foo<T>.}

Parameters
copyOfMethod:javax.lang.model.element.ExecutableElement

the candidate method to do the copy, ImmutableSet.copyOf(Collection<? extends E>) or ImmutableSet.copyOf(E[]) in the examples.

targetType:javax.lang.model.type.DeclaredType

the type of the property to be set, ImmutableSet<T> in the example.

parameterType:javax.lang.model.type.TypeMirror

the type of the setter parameter, Set<? extends T> in the example.

Returns:Optional<BuilderSpec.Copier>

a function that maps a string parameter to a method call using that parameter. For example it might map foo to ImmutableList.copyOf(foo).

getSetterFunctionback to summary
private Optional<BuilderSpec.Copier> getSetterFunction(E propertyElement, javax.lang.model.element.ExecutableElement setter)

Returns an Optional describing how to convert a value from the setter's parameter type to the getter's return type, or Optional.empty() if the conversion isn't possible. An error will have been reported in the latter case. We can convert if they are already the same type, when the returned function will be the identity; or if the setter type can be copied using a method like ImmutableList.copyOf or Optional.of, when the returned function will be something like s -> "Optional.of(" + s + ")".

getterMustMatchback to summary
pack-priv abstract String getterMustMatch()

A string describing what a builder getter must match: a property method for AutoValue, a parameter for AutoBuilder.

originalPropertyTypeback to summary
pack-priv abstract javax.lang.model.type.TypeMirror originalPropertyType(E propertyElement)

Returns the property type as it appears on the original source program element. This can be different from the type stored in rewrittenPropertyTypes since that one will refer to type variables in the builder rather than in the original class. Also, rewrittenPropertyTypes will not have type annotations even if they were present on the original element, so originalPropertyType is the right thing to use for those.

prefixWithSetback to summary
private static String prefixWithSet(String propertyName)
propertyElementsback to summary
pack-priv abstract ImmutableBiMap<String, E> propertyElements()

Returns a map from property names to the corresponding source program elements. For AutoValue, these elements are the abstract getter methods in the @AutoValue class. For AutoBuilder, they are the parameters of the constructor or method that the generated builder will call.

propertyForBuilderGetterback to summary
pack-priv abstract Optional<String> propertyForBuilderGetter(javax.lang.model.element.ExecutableElement method)

Returns the name of the property that the given no-arg builder method queries, if any. For example, if your @AutoValue class has a method abstract String getBar() then an abstract method in its builder with the same signature will query the bar property.

propertyIsNullableback to summary
private boolean propertyIsNullable(String property)

True if the given property is nullable, either because its type has a @Nullable type annotation, or because its getter method has a @Nullable method annotation.

propertyNameToPropertyBuilderback to summary
pack-priv Map<String, PropertyBuilderClassifier.PropertyBuilder> propertyNameToPropertyBuilder()
propertyNameToSettersback to summary
pack-priv ImmutableMultimap<String, BuilderSpec.PropertySetter> propertyNameToSetters()

Returns a multimap from the name of a property to the methods that set it. If the property is defined by an abstract method in the @AutoValue class called foo() or getFoo() then the name of the property is foo and there will be an entry in the map where the key is "foo" and the value describes a method in the builder called foo or setFoo.

propertyStringback to summary
pack-priv abstract String propertyString(E propertyElement)

A string identifying the given property element, which is a method for AutoValue or a parameter for AutoBuilder.