Class TypeSimplifier

java.lang.Object
com.google.auto.value.processor.TypeSimplifier

final class TypeSimplifier extends Object
Takes a set of types and a package and determines which of those types can be imported, and how to spell any of the types in the set given those imports.
  • Field Details

  • Constructor Details

    • TypeSimplifier

      TypeSimplifier(Elements elementUtils, Types typeUtils, String packageName, Set<TypeMirror> types, TypeMirror base)
      Makes a new simplifier for the given package and set of types.
      Parameters:
      elementUtils - the result of ProcessingEnvironment.getElementUtils() for the current annotation processing environment.
      typeUtils - the result of ProcessingEnvironment.getTypeUtils() for the current annotation processing environment.
      packageName - the name of the package from which classes will be referenced. Classes that are in the same package do not need to be imported.
      types - the types that will be referenced.
      base - a base class that the class containing the references will extend. This is needed because nested classes in that class or one of its ancestors are in scope in the generated subclass, so a reference to another class with the same name as one of them is ambiguous.
      Throws:
      MissingTypeException - if one of the input types contains an error (typically, is undefined).
  • Method Details

    • typesToImport

      com.google.common.collect.ImmutableSortedSet<String> typesToImport()
      Returns the set of types to import. We import every type that is neither in java.lang nor in the package containing the AutoValue class, provided that the result refers to the type unambiguously. For example, if there is a property of type java.util.Map.Entry then we will import java.util.Map.Entry and refer to the property as Entry. We could also import just java.util.Map in this case and refer to Map.Entry, but currently we never do that.
    • simplifiedClassName

      String simplifiedClassName(DeclaredType type)
    • actualTypeParametersString

      static String actualTypeParametersString(TypeElement type)
    • classNameOf

      static String classNameOf(TypeElement type)
      Returns the name of the given type, including any enclosing types but not the package.
    • topLevelType

      private static TypeElement topLevelType(TypeElement type)
    • packageNameOf

      static String packageNameOf(TypeElement type)
      Returns the name of the package that the given type is in. If the type is in the default (unnamed) package then the name is the empty string.
    • simpleNameOf

      static String simpleNameOf(String s)
    • findImports

      private static Map<String,TypeSimplifier.Spelling> findImports(Elements elementUtils, Types typeUtils, String codePackageName, Set<TypeMirror> referenced, Set<TypeMirror> defined)
      Given a set of referenced types, works out which of them should be imported and what the resulting spelling of each one is.

      This method operates on a Set<TypeMirror> rather than just a 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, java.util.Map.Entry is a class called Map.Entry in a package called java.util assuming Java conventions are being followed, but it could theoretically also be a class called Entry in a package called 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.

      Parameters:
      codePackageName - 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.
      referenced - The complete set of declared types (classes and interfaces) that will be referenced in the generated code.
      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)
      Returns:
      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.
    • javaLangSpelling

      private static String javaLangSpelling(Elements elementUtils, String codePackageName, TypeElement typeElement)
      Handles the tricky case where the class being referred to is in java.lang, but the package of the referring code contains another class of the same name. For example, if the current package is foo.bar and there is a foo.bar.Compiler, then we will refer to java.lang.Compiler by its full name. The plain name Compiler would reference foo.bar.Compiler in this case. We need to write java.lang.Compiler even if the other Compiler class is not being considered here, so the ambiguousNames(javax.lang.model.util.Types, java.util.Set<javax.lang.model.type.TypeMirror>) logic is not enough. We have to look to see if the class exists.
    • topLevelTypes

      private static Set<TypeMirror> topLevelTypes(Types typeUtil, Set<TypeMirror> types)
      Finds the top-level types for all the declared types (classes and interfaces) in the given Set<TypeMirror>.

      The returned set contains only top-level types. If we reference java.util.Map.Entry then the returned set will contain java.util.Map. This is because we want to write Map.Entry everywhere rather than Entry.

    • nonPrivateDeclaredTypes

      private static Set<TypeMirror> nonPrivateDeclaredTypes(Types typeUtils, TypeMirror type)
      Finds all types that are declared with non private visibility by the given TypeMirror, any class in its superclass chain, or any interface it implements.
    • ambiguousNames

      private static Set<String> ambiguousNames(Types typeUtils, Set<TypeMirror> types)
    • isCastingUnchecked

      static boolean isCastingUnchecked(TypeMirror type)
      Returns true if casting to the given type will elicit an unchecked warning from the compiler. Only generic types such as List<String> produce such warnings. There will be no warning if the type's only generic parameters are simple wildcards, as in Map<?, ?>.