Class TypeEncoder
The idea is that types that appear in generated source code use encode(javax.lang.model.type.TypeMirror)
, which will
spell out a type like java.util.List<? extends java.lang.Number>
, except that wherever a
class name appears it is replaced by a special token. So the spelling might actually be
`java.util.List`<? extends `java.lang.Number`>
. Then once the entire class has been generated,
#decode
scans for these tokens to determine what classes need to be imported, and
replaces the tokens with the correct spelling given the imports. So here, java.util.List
would be imported, and the final spelling would be List<? extends Number>
(knowing that
Number
is implicitly imported). The special token `import`
marks where the
imports should be, and decode(java.lang.String, javax.annotation.processing.ProcessingEnvironment, java.lang.String, javax.lang.model.type.TypeMirror)
replaces it with the correct list of imports.
The funky syntax for type annotations on qualified type names requires an adjustment to this
scheme. `«java.util.Map`
stands for java.util.
and `»java.util.Map`
stands for Map
. If java.util.Map
is imported, then `«java.util.Map`
will
eventually be empty, but if java.util.Map
is not imported (perhaps because there is
another Map
in scope) then `«java.util.Map`
will be java.util.
. The end
result is that the code can contain `«java.util.Map`@`javax.annotation.Nullable`
`»java.util.Map`
. That might decode to @Nullable Map
or to java.util.@Nullable
Map
or even to java.util.@javax.annotation.Nullable Map
.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static class
LikeTypeEncoder.EncodingTypeVisitor
except that annotations on the visited type are also included in the resultant string.private static class
Converts a type into a string, using standard Java syntax, except that every class name is wrapped in backquotes, like`java.util.List`
.private static class
LikeTypeEncoder.EncodingTypeVisitor
except that type parameters are omitted from the result.private static class
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final TypeEncoder.AnnotatedEncodingTypeVisitor
private static final TypeEncoder.EncodingTypeVisitor
private static final TypeEncoder.RawEncodingTypeVisitor
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static void
appendAnnotations
(List<? extends AnnotationMirror> annotationMirrors, StringBuilder sb) private static void
appendTypeParameterWithBounds
(TypeParameterElement typeParameter, StringBuilder sb) private static String
className
(DeclaredType declaredType) (package private) static String
decode
(String text, ProcessingEnvironment processingEnv, String packageName, TypeMirror baseType) Decodes the given string, respelling class names appropriately.(package private) static String
(package private) static String
encode
(TypeMirror type) Returns the encoding for the given type, where class names are marked by special tokens.(package private) static String
encodeRaw
(TypeMirror type) Likeencode(javax.lang.model.type.TypeMirror)
, except that only the raw type is encoded.(package private) static String
Encodes the given type and its type annotations.(package private) static String
Returns the formal type parameters of the given type.
-
Field Details
-
ENCODING_TYPE_VISITOR
-
RAW_ENCODING_TYPE_VISITOR
-
ANNOTATED_ENCODING_TYPE_VISITOR
-
-
Constructor Details
-
TypeEncoder
private TypeEncoder()
-
-
Method Details
-
encode
Returns the encoding for the given type, where class names are marked by special tokens. The encoding forint
will beint
, but the encoding forjava.util.List<java.lang.Integer>
will be`java.util.List`<`java.lang.Integer`>
. -
encodeRaw
Likeencode(javax.lang.model.type.TypeMirror)
, except that only the raw type is encoded. So if the given type isjava.util.List<java.lang.Integer>
the result will be`java.util.List`
. -
encodeWithAnnotations
Encodes the given type and its type annotations. The class comment forTypeEncoder
covers the details of annotation encoding. -
decode
static String decode(String text, ProcessingEnvironment processingEnv, String packageName, TypeMirror baseType) Decodes the given string, respelling class names appropriately. The text is scanned for tokens like`java.util.Locale`
or`«java.util.Locale`
to determine which classes are referenced. An appropriate set of imports is computed based on the set of those types. If the special token`import`
appears intext
then it will be replaced by this set of import statements. Then all of the tokens are replaced by the class names they represent, spelled appropriately given the import statements.- Parameters:
text
- the text to be decoded.packageName
- the package of the generated class. Other classes in the same package do not need to be imported.baseType
- a class or interface that the generated class inherits from. Nested classes in that type do not need to be imported, and if another class has the same name as one of those nested classes then it will need to be qualified.
-
decode
-
className
-
formalTypeParametersString
Returns the formal type parameters of the given type. If we have@AutoValue abstract class Foo<T extends SomeClass>
then this method will return an encoding of<T extends SomeClass>
forFoo
. Likewise it will return an encoding of the angle-bracket part of:
Foo<SomeClass>
Foo<T extends Number>
Foo<E extends Enum<E>>
Foo<K, V extends Comparable<? extends K>>
.The encoding is simply that classes in the "extends" part are marked, so the examples will actually look something like this:
<`bar.baz.SomeClass`>
<T extends `java.lang.Number`>
<E extends `java.lang.Enum`<E>>
<K, V extends `java.lang.Comparable`<? extends K>>
. -
appendTypeParameterWithBounds
private static void appendTypeParameterWithBounds(TypeParameterElement typeParameter, StringBuilder sb) -
appendAnnotations
private static void appendAnnotations(List<? extends AnnotationMirror> annotationMirrors, StringBuilder sb)
-