Class BuilderMethodClassifier


  • class BuilderMethodClassifier
    extends java.lang.Object
    Classifies methods inside builder types, based on their names and parameter and return types.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private BuilderMethodClassifier​(ErrorReporter errorReporter, javax.annotation.processing.ProcessingEnvironment processingEnv, javax.lang.model.element.TypeElement autoValueClass, javax.lang.model.element.TypeElement builderType, com.google.common.collect.ImmutableBiMap<javax.lang.model.element.ExecutableElement,​java.lang.String> getterToPropertyName)  
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) com.google.common.collect.ImmutableMap<java.lang.String,​BuilderSpec.PropertyGetter> builderGetters()
      Returns the set of properties that have getters in the builder.
      (package private) javax.lang.model.type.TypeMirror builderMethodReturnType​(javax.lang.model.element.ExecutableElement builderMethod)
      Returns the return type of the given method from the builder.
      (package private) java.util.Set<javax.lang.model.element.ExecutableElement> buildMethods()
      Returns the methods that were identified as build() methods.
      private boolean canMakeCopyUsing​(com.google.common.collect.ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods, javax.lang.model.element.ExecutableElement valueGetter, javax.lang.model.element.ExecutableElement setter)
      Checks that the given setter method has a parameter type that can be copied to the return type of the given getter using one of the given copyOf methods.
      private boolean canMakeCopyUsing​(javax.lang.model.element.ExecutableElement copyOfMethod, javax.lang.model.type.TypeMirror targetType, javax.lang.model.type.TypeMirror parameterType)
      Returns true if copyOfMethod can be used to copy the parameterType to the targetType.
      private void checkForFailedJavaBean​(javax.lang.model.element.ExecutableElement rejectedSetter)  
      private boolean checkSetterParameter​(javax.lang.model.element.ExecutableElement valueGetter, javax.lang.model.element.ExecutableElement setter)
      Checks that the given setter method has a parameter type that is compatible with the return type of the given getter.
      (package private) static java.util.Optional<BuilderMethodClassifier> classify​(java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods, ErrorReporter errorReporter, javax.annotation.processing.ProcessingEnvironment processingEnv, javax.lang.model.element.TypeElement autoValueClass, javax.lang.model.element.TypeElement builderType, com.google.common.collect.ImmutableBiMap<javax.lang.model.element.ExecutableElement,​java.lang.String> getterToPropertyName, boolean autoValueHasToBuilder)
      Classifies the given methods from a builder type and its ancestors.
      private boolean classifyGetter​(javax.lang.model.element.ExecutableElement builderGetter, javax.lang.model.element.ExecutableElement originalGetter)  
      private boolean classifyMethod​(javax.lang.model.element.ExecutableElement method)
      Classifies a method and update the state of this object based on what is found.
      private boolean classifyMethodNoArgs​(javax.lang.model.element.ExecutableElement method)
      Classifies a method given that it has no arguments.
      private boolean classifyMethodOneArg​(javax.lang.model.element.ExecutableElement method)
      Classifies a method given that it has one argument.
      private boolean classifyMethods​(java.lang.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 com.google.common.collect.ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods​(javax.lang.model.type.TypeMirror targetType)
      Returns copyOf methods from the given type.
      private static java.lang.String decapitalize​(java.lang.String propertyName)  
      private static java.lang.String prefixWithSet​(java.lang.String propertyName)  
      (package private) java.util.Map<java.lang.String,​PropertyBuilderClassifier.PropertyBuilder> propertyNameToPropertyBuilder()  
      (package private) com.google.common.collect.ImmutableMultimap<java.lang.String,​javax.lang.model.element.ExecutableElement> propertyNameToSetters()
      Returns a multimap from the name of a property to the methods that set it.
      private java.lang.String typeParamsString()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • TYPE_EQUIVALENCE

        private static final com.google.common.base.Equivalence<javax.lang.model.type.TypeMirror> TYPE_EQUIVALENCE
      • typeUtils

        private final javax.lang.model.util.Types typeUtils
      • elementUtils

        private final javax.lang.model.util.Elements elementUtils
      • autoValueClass

        private final javax.lang.model.element.TypeElement autoValueClass
      • builderType

        private final javax.lang.model.element.TypeElement builderType
      • getterToPropertyName

        private final com.google.common.collect.ImmutableBiMap<javax.lang.model.element.ExecutableElement,​java.lang.String> getterToPropertyName
      • getterNameToGetter

        private final com.google.common.collect.ImmutableMap<java.lang.String,​javax.lang.model.element.ExecutableElement> getterNameToGetter
      • buildMethods

        private final java.util.Set<javax.lang.model.element.ExecutableElement> buildMethods
      • propertyNameToPrefixedSetters

        private final com.google.common.collect.Multimap<java.lang.String,​javax.lang.model.element.ExecutableElement> propertyNameToPrefixedSetters
      • propertyNameToUnprefixedSetters

        private final com.google.common.collect.Multimap<java.lang.String,​javax.lang.model.element.ExecutableElement> propertyNameToUnprefixedSetters
      • settersPrefixed

        private boolean settersPrefixed
    • Constructor Detail

      • BuilderMethodClassifier

        private BuilderMethodClassifier​(ErrorReporter errorReporter,
                                        javax.annotation.processing.ProcessingEnvironment processingEnv,
                                        javax.lang.model.element.TypeElement autoValueClass,
                                        javax.lang.model.element.TypeElement builderType,
                                        com.google.common.collect.ImmutableBiMap<javax.lang.model.element.ExecutableElement,​java.lang.String> getterToPropertyName)
    • Method Detail

      • classify

        static java.util.Optional<BuilderMethodClassifier> classify​(java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods,
                                                                    ErrorReporter errorReporter,
                                                                    javax.annotation.processing.ProcessingEnvironment processingEnv,
                                                                    javax.lang.model.element.TypeElement autoValueClass,
                                                                    javax.lang.model.element.TypeElement builderType,
                                                                    com.google.common.collect.ImmutableBiMap<javax.lang.model.element.ExecutableElement,​java.lang.String> getterToPropertyName,
                                                                    boolean autoValueHasToBuilder)
        Classifies the given methods from a builder type and its ancestors.
        Parameters:
        methods - the methods in builderType and its ancestors.
        errorReporter - where to report errors.
        processingEnv - the ProcessingEnvironment for annotation processing.
        autoValueClass - the AutoValue class containing the builder.
        builderType - the builder class or interface within autoValueClass.
        getterToPropertyName - a map from getter methods to the properties they get.
        autoValueHasToBuilder - true if the containing @AutoValue class has a toBuilder() method.
        Returns:
        an Optional that contains the results of the classification if it was successful or nothing if it was not.
      • propertyNameToSetters

        com.google.common.collect.ImmutableMultimap<java.lang.String,​javax.lang.model.element.ExecutableElement> 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 is a method in the builder called foo or setFoo.
      • builderGetters

        com.google.common.collect.ImmutableMap<java.lang.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.
      • buildMethods

        java.util.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().
      • classifyMethods

        private boolean classifyMethods​(java.lang.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.
      • classifyMethod

        private boolean classifyMethod​(javax.lang.model.element.ExecutableElement method)
        Classifies a method and update the state of this object based on what is found.
        Returns:
        true if the method was successfully classified, false if an error has been reported.
      • classifyMethodNoArgs

        private boolean 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().
        Returns:
        true if the method was successfully classified, false if an error has been reported.
      • classifyGetter

        private boolean classifyGetter​(javax.lang.model.element.ExecutableElement builderGetter,
                                       javax.lang.model.element.ExecutableElement originalGetter)
      • classifyMethodOneArg

        private boolean classifyMethodOneArg​(javax.lang.model.element.ExecutableElement method)
        Classifies a method given that it has one argument. Currently, a method with one argument can only be a setter, meaning that it must look like foo(T) or setFoo(T), where the AutoValue class has a property called foo of type T.
        Returns:
        true if the method was successfully classified, false if an error has been reported.
      • checkForFailedJavaBean

        private void checkForFailedJavaBean​(javax.lang.model.element.ExecutableElement rejectedSetter)
      • checkSetterParameter

        private boolean checkSetterParameter​(javax.lang.model.element.ExecutableElement valueGetter,
                                             javax.lang.model.element.ExecutableElement setter)
        Checks that the given setter method has a parameter type that is compatible with the return type of the given getter. Compatible means either that it is the same, or that it is a type that can be copied using a method like ImmutableList.copyOf or Optional.of.
        Returns:
        true if the types correspond, false if an error has been reported.
      • canMakeCopyUsing

        private boolean canMakeCopyUsing​(com.google.common.collect.ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods,
                                         javax.lang.model.element.ExecutableElement valueGetter,
                                         javax.lang.model.element.ExecutableElement setter)
        Checks that the given setter method has a parameter type that can be copied to the return type of the given getter using one of the given copyOf methods.
        Returns:
        true if the copy can be made, false if an error has been reported.
      • canMakeCopyUsing

        private boolean canMakeCopyUsing​(javax.lang.model.element.ExecutableElement copyOfMethod,
                                         javax.lang.model.type.TypeMirror targetType,
                                         javax.lang.model.type.TypeMirror parameterType)
        Returns true if copyOfMethod can be used to copy the parameterType to the targetType.
      • copyOfMethods

        private com.google.common.collect.ImmutableList<javax.lang.model.element.ExecutableElement> copyOfMethods​(javax.lang.model.type.TypeMirror targetType)
        Returns copyOf methods from the given type. These are static methods called 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 EnumSet.
      • builderMethodReturnType

        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(java.util.Set<javax.lang.model.element.ExecutableElement>, javax.lang.model.type.DeclaredType) 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.

      • prefixWithSet

        private static java.lang.String prefixWithSet​(java.lang.String propertyName)
      • decapitalize

        private static java.lang.String decapitalize​(java.lang.String propertyName)
      • typeParamsString

        private java.lang.String typeParamsString()