Class Analyser
- java.lang.Object
-
- org.inferred.freebuilder.processor.Analyser
-
class Analyser extends java.lang.ObjectAnalyses aFreeBuilderdatatype type, returning aGeneratedTypefor a Builder superclass derived from its API.Any deviations from the FreeBuilder spec in the user's class will result in errors being issued, but unless code generation is totally impossible, a type will still be returned. This allows the user to extend an existing type without worrying that a mistake will cause compiler errors in all dependent code—which would make it very hard to find the real error.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classAnalyser.CannotGenerateCodeExceptionThrown when a FreeBuilder type cannot have a Builder type generated, for instance if it is private.private classAnalyser.ConfigImplprivate static classAnalyser.IsSubclassOfGeneratedTypeVisitorVisitor that returns true if the visited type extends a generatedsuperclassin the same package.
-
Field Summary
Fields Modifier and Type Field Description private static java.lang.StringBUILDER_SIMPLE_NAME_TEMPLATEprivate static javax.lang.model.util.SimpleTypeVisitor8<java.lang.Boolean,?>CAST_IS_FULLY_CHECKEDVisitor that returns true if a cast to the visited type is guaranteed to be fully checked at runtime.private javax.lang.model.util.Elementselementsprivate javax.annotation.processing.ProcessingEnvironmentenvprivate static javax.lang.model.util.SimpleTypeVisitor8<java.lang.Boolean,?>IS_UNBOUNDED_WILDCARDVisitor that returns true if the visited type is an unbounded wildcard, i.e.private javax.annotation.processing.Messagermessagerprivate javax.lang.model.util.Typestypesprivate static java.lang.StringUSER_BUILDER_NAME
-
Constructor Summary
Constructors Constructor Description Analyser(javax.annotation.processing.ProcessingEnvironment env, javax.annotation.processing.Messager messager)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private voidaddPropertyData(Property.Builder propertyBuilder, javax.lang.model.element.TypeElement valueType, javax.lang.model.element.ExecutableElement method, java.util.Optional<JacksonSupport> jacksonSupport)Introspectsmethod, as found onvalueType.(package private) GeneratedTypeanalyse(javax.lang.model.element.TypeElement type)Returns a BuilderGeneratedTypefortype.private static java.lang.StringcamelCaseToAllCaps(java.lang.String camelCase)Converts camelCaseConvention to ALL_CAPS_CONVENTION.private Datatype.BuilderconstructionAndExtension(javax.lang.model.type.DeclaredType builder)private static PropertyCodeGeneratorcreateCodeGenerator(PropertyCodeGenerator.Config config)private java.util.Map<Datatype.StandardMethod,Datatype.UnderrideLevel>findUnderriddenMethods(java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)Find any standard methods the user has 'underridden' in their type.private java.lang.StringgeneratedBuilderSimpleName(javax.lang.model.element.TypeElement type)Returns the simple name of the builder class that should be generated for the given type.private java.util.Set<java.lang.String>getMethodsInvokedInBuilderConstructor(javax.lang.model.element.TypeElement builder)private booleanhasToBuilderMethod(javax.lang.model.type.DeclaredType builder, boolean isExtensible, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)Find a toBuilder method, if the user has provided one.private java.util.function.Predicate<javax.lang.model.type.TypeMirror>isEqualTo(java.lang.Class<?> cls)private booleanisToBuilderMethod(javax.lang.model.type.DeclaredType declaredType, javax.lang.model.element.ExecutableElement method)private static booleanisUnderride(javax.lang.model.element.ExecutableElement method)private static java.util.Optional<Datatype.StandardMethod>maybeStandardMethod(javax.lang.model.element.ExecutableElement method)Returns whether a method is one of theDatatype.StandardMethods, and if so, which.private java.util.Map<Property,PropertyCodeGenerator>pickPropertyGenerators(javax.lang.model.element.TypeElement type, Datatype datatype, javax.lang.model.type.DeclaredType builder, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)private java.util.Set<javax.lang.model.element.ExecutableElement>removeNonGetterMethods(javax.lang.model.type.DeclaredType builder, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)private booleanshouldBuilderBeSerializable(javax.lang.model.type.DeclaredType builder)private java.util.Optional<javax.lang.model.type.DeclaredType>tryFindBuilder(QualifiedName superclass, javax.lang.model.element.TypeElement valueType)Looks for a nested type invalueTypecalled Builder, and verifies it extends the autogeneratedsuperclass.private voidverifyType(javax.lang.model.element.TypeElement type, javax.lang.model.element.PackageElement pkg)Basic sanity-checking to ensure we can fulfil the @FreeBuilder contract for this type.private voidverifyTypeIsConstructible(javax.lang.model.element.TypeElement type)Issues an error iftypedoes not have a package-visible no-args constructor.
-
-
-
Field Detail
-
BUILDER_SIMPLE_NAME_TEMPLATE
private static final java.lang.String BUILDER_SIMPLE_NAME_TEMPLATE
- See Also:
- Constant Field Values
-
USER_BUILDER_NAME
private static final java.lang.String USER_BUILDER_NAME
- See Also:
- Constant Field Values
-
env
private final javax.annotation.processing.ProcessingEnvironment env
-
elements
private final javax.lang.model.util.Elements elements
-
messager
private final javax.annotation.processing.Messager messager
-
types
private final javax.lang.model.util.Types types
-
CAST_IS_FULLY_CHECKED
private static final javax.lang.model.util.SimpleTypeVisitor8<java.lang.Boolean,?> CAST_IS_FULLY_CHECKED
Visitor that returns true if a cast to the visited type is guaranteed to be fully checked at runtime. This is true for any type that is non-generic, raw, or parameterized with unbounded wildcards, such asInteger,ListorMap<?, ?>.
-
IS_UNBOUNDED_WILDCARD
private static final javax.lang.model.util.SimpleTypeVisitor8<java.lang.Boolean,?> IS_UNBOUNDED_WILDCARD
Visitor that returns true if the visited type is an unbounded wildcard, i.e.<?>.
-
-
Method Detail
-
analyse
GeneratedType analyse(javax.lang.model.element.TypeElement type) throws Analyser.CannotGenerateCodeException
Returns a BuilderGeneratedTypefortype.- Throws:
Analyser.CannotGenerateCodeException- if code cannot be generated, e.g. if the type is private
-
verifyType
private void verifyType(javax.lang.model.element.TypeElement type, javax.lang.model.element.PackageElement pkg) throws Analyser.CannotGenerateCodeExceptionBasic sanity-checking to ensure we can fulfil the @FreeBuilder contract for this type.
-
verifyTypeIsConstructible
private void verifyTypeIsConstructible(javax.lang.model.element.TypeElement type) throws Analyser.CannotGenerateCodeExceptionIssues an error iftypedoes not have a package-visible no-args constructor.
-
findUnderriddenMethods
private java.util.Map<Datatype.StandardMethod,Datatype.UnderrideLevel> findUnderriddenMethods(java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)
Find any standard methods the user has 'underridden' in their type.
-
hasToBuilderMethod
private boolean hasToBuilderMethod(javax.lang.model.type.DeclaredType builder, boolean isExtensible, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)Find a toBuilder method, if the user has provided one.
-
isToBuilderMethod
private boolean isToBuilderMethod(javax.lang.model.type.DeclaredType declaredType, javax.lang.model.element.ExecutableElement method)
-
removeNonGetterMethods
private java.util.Set<javax.lang.model.element.ExecutableElement> removeNonGetterMethods(javax.lang.model.type.DeclaredType builder, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)
-
isUnderride
private static boolean isUnderride(javax.lang.model.element.ExecutableElement method)
-
tryFindBuilder
private java.util.Optional<javax.lang.model.type.DeclaredType> tryFindBuilder(QualifiedName superclass, javax.lang.model.element.TypeElement valueType)
Looks for a nested type invalueTypecalled Builder, and verifies it extends the autogeneratedsuperclass.If the value type is generic, the builder type must match, and the returned DeclaredType will be parameterized with the type variables from the value type, not the builder. (This makes type checking massively easier.)
Issues an error if the wrong type is being subclassed—a typical copy-and-paste error when renaming an existing @FreeBuilder type, or using one as a template.
-
constructionAndExtension
private Datatype.Builder constructionAndExtension(javax.lang.model.type.DeclaredType builder)
-
pickPropertyGenerators
private java.util.Map<Property,PropertyCodeGenerator> pickPropertyGenerators(javax.lang.model.element.TypeElement type, Datatype datatype, javax.lang.model.type.DeclaredType builder, java.lang.Iterable<javax.lang.model.element.ExecutableElement> methods)
-
getMethodsInvokedInBuilderConstructor
private java.util.Set<java.lang.String> getMethodsInvokedInBuilderConstructor(javax.lang.model.element.TypeElement builder)
-
addPropertyData
private void addPropertyData(Property.Builder propertyBuilder, javax.lang.model.element.TypeElement valueType, javax.lang.model.element.ExecutableElement method, java.util.Optional<JacksonSupport> jacksonSupport)
Introspectsmethod, as found onvalueType.
-
createCodeGenerator
private static PropertyCodeGenerator createCodeGenerator(PropertyCodeGenerator.Config config)
-
generatedBuilderSimpleName
private java.lang.String generatedBuilderSimpleName(javax.lang.model.element.TypeElement type)
Returns the simple name of the builder class that should be generated for the given type.This is simply the
BUILDER_SIMPLE_NAME_TEMPLATEwith the original type name substituted in. (If the original type is nested, its enclosing classes will be included, separated with underscores, to ensure uniqueness.)
-
shouldBuilderBeSerializable
private boolean shouldBuilderBeSerializable(javax.lang.model.type.DeclaredType builder)
-
maybeStandardMethod
private static java.util.Optional<Datatype.StandardMethod> maybeStandardMethod(javax.lang.model.element.ExecutableElement method)
Returns whether a method is one of theDatatype.StandardMethods, and if so, which.
-
camelCaseToAllCaps
private static java.lang.String camelCaseToAllCaps(java.lang.String camelCase)
Converts camelCaseConvention to ALL_CAPS_CONVENTION.
-
isEqualTo
private java.util.function.Predicate<javax.lang.model.type.TypeMirror> isEqualTo(java.lang.Class<?> cls)
-
-