下面列出了com.google.common.base.Equivalence.Wrapper#com.google.auto.common.MoreTypes 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void validateActionCreator(ExecutableElement element,
String actionName,
TypeMirror actionCreator,
ArrayList<VariableElement> args,
Map<String, ActionCreatorElement> knownActionCreators,
Env env) throws ValidationException {
Element actionCreatorElement = MoreTypes.asElement(actionCreator);
if (!MoreElements.isAnnotationPresent(actionCreatorElement, ActionCreator.class)) {
throw new ValidationException(element, "Action creator %s should be annotated with @%s", actionCreator, ActionCreator.class.getSimpleName());
}
ActionCreatorElement creatorElement = knownActionCreators.get(env.getElements().getBinaryName((TypeElement) actionCreatorElement).toString());
if (creatorElement == null) {
throw new ElementNotReadyException();
}
if (!creatorElement.hasAction(actionName, args)) {
throw new ValidationException(element, "Cannot find action creator for action \"%s\" and args %s in interface %s", actionName, toString(args), creatorElement.getName(env));
}
}
public static DeclaredType getReducerSuperInterface(DeclaredType reducerType) {
List<? extends TypeMirror> supertypes = MoreTypes.asTypeElement(reducerType).getInterfaces();
for (TypeMirror supertype : supertypes) {
boolean isReducer = MoreTypes.isTypeOf(Reducer.class, supertype);
if (isReducer) {
return MoreTypes.asDeclared(supertype);
}
}
TypeMirror superclass = MoreTypes.asTypeElement(reducerType).getSuperclass();
if (!MoreTypes.isTypeOf(Object.class, superclass)) {
return getReducerSuperInterface(MoreTypes.asDeclared(superclass));
}
return null;
}
private static boolean needsContentDescriptor(Context context) {
ProcessingEnvironment env = context.processingEnvironment();
TypeElement autoValueTypeElement = context.autoValueClass();
Elements elements = env.getElementUtils();
@SuppressWarnings("deprecation") // Support for kapt2
ImmutableSet<ExecutableElement> methods =
MoreElements.getLocalAndInheritedMethods(autoValueTypeElement, elements);
for (ExecutableElement element : methods) {
if (element.getSimpleName().contentEquals("describeContents")
&& MoreTypes.isTypeOf(int.class, element.getReturnType())
&& element.getParameters().isEmpty()
&& !element.getModifiers().contains(ABSTRACT)) {
return false;
}
}
return true;
}
/**
* Returns a key of {@link Map}{@code <K, WrappingClass<V>>} if the input key represents a
* {@code Map<K, V>}.
*/
private Optional<Key> maybeWrapMapValue(Key possibleMapKey, Class<?> wrappingClass) {
if (MoreTypes.isTypeOf(Map.class, possibleMapKey.type())) {
DeclaredType declaredMapType = MoreTypes.asDeclared(possibleMapKey.type());
TypeMirror mapValueType = Util.getValueTypeOfMap(declaredMapType);
if (!MoreTypes.isTypeOf(wrappingClass, mapValueType)) {
DeclaredType keyType = Util.getKeyTypeOfMap(declaredMapType);
TypeElement wrappingElement = getClassElement(wrappingClass);
if (wrappingElement == null) {
// This target might not be compiled with Producers, so wrappingClass might not have an
// associated element.
return Optional.absent();
}
DeclaredType wrappedType = types.getDeclaredType(wrappingElement, mapValueType);
TypeMirror mapType = types.getDeclaredType(getMapElement(), keyType, wrappedType);
return Optional.<Key>of(new AutoValue_Key(
possibleMapKey.wrappedQualifier(),
MoreTypes.equivalence().wrap(mapType)));
}
}
return Optional.absent();
}
/**
* Constructs a key based on the type {@code type} and any {@link Qualifier}s in {@code
* annotations}.
*
* <p>If {@code type} is a {@code Provider<T>}, the returned {@link Key}'s {@link #type()} is
* {@code T}. If {@code type} is a primitive, the returned {@link Key}'s {@link #type()} is the
* corresponding {@linkplain Types#boxedClass(PrimitiveType) boxed type}.
*
* <p>For example:
* <table>
* <tr><th>Input type <th>{@code Key.type()}
* <tr><td>{@code String} <td>{@code String}
* <tr><td>{@code Provider<String>} <td>{@code String}
* <tr><td>{@code int} <td>{@code Integer}
* </table>
*/
static Key create(
TypeMirror type, Iterable<? extends AnnotationMirror> annotations, Types types) {
ImmutableSet.Builder<AnnotationMirror> qualifiers = ImmutableSet.builder();
for (AnnotationMirror annotation : annotations) {
if (isAnnotationPresent(annotation.getAnnotationType().asElement(), Qualifier.class)) {
qualifiers.add(annotation);
}
}
// TODO(gak): check for only one qualifier rather than using the first
Optional<AnnotationMirror> qualifier = FluentIterable.from(qualifiers.build()).first();
TypeMirror keyType =
isProvider(type)
? MoreTypes.asDeclared(type).getTypeArguments().get(0)
: boxedType(type, types);
return new AutoValue_Key(
MoreTypes.equivalence().wrap(keyType),
wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), qualifier));
}
/** Traverses includes from superclasses and adds them into the builder. */
private static void addIncludesFromSuperclasses(Types types, TypeElement element,
ImmutableSet.Builder<TypeElement> builder, TypeMirror objectType) {
// Also add the superclass to the queue, in case any @Module definitions were on that.
TypeMirror superclass = element.getSuperclass();
while (!types.isSameType(objectType, superclass)
&& superclass.getKind().equals(TypeKind.DECLARED)) {
element = MoreElements.asType(types.asElement(superclass));
Optional<AnnotationMirror> moduleMirror = getAnnotationMirror(element, Module.class)
.or(getAnnotationMirror(element, ProducerModule.class));
if (moduleMirror.isPresent()) {
builder.addAll(MoreTypes.asTypeElements(getModuleIncludes(moduleMirror.get())));
}
superclass = element.getSuperclass();
}
}
private void parse() throws Throwable {
List<Element> allElements = new ArrayList<>();
allElements.add(mSourceClassEle);
Element currentClass = mSourceClassEle;
do {
Optional<DeclaredType> superClass = MoreTypes.nonObjectSuperclass(GlobalEnvironment.getProcessingEnv().getTypeUtils(),
GlobalEnvironment.getProcessingEnv().getElementUtils(), (DeclaredType) currentClass.asType());
if (superClass.isPresent()) {
currentClass = superClass.get().asElement();
allElements.add(currentClass);
LogUtil.logger("superclass.get().asElement().toString(): " + currentClass.toString());
} else {
currentClass = null;
}
} while (null != currentClass);
for (int i = allElements.size() - 1; i >= 0; i--) {
buildAllColumns(allElements.get(i));
}
}
private Optional<ExecutableElement> addAllPutAll(
TypeElement barBuilderTypeElement,
DeclaredType barBuilderDeclaredType,
TypeMirror barTypeMirror) {
return MoreElements.getLocalAndInheritedMethods(barBuilderTypeElement, typeUtils, elementUtils)
.stream()
.filter(
method ->
ADD_ALL_PUT_ALL.contains(method.getSimpleName().toString())
&& method.getParameters().size() == 1)
.filter(
method -> {
ExecutableType methodMirror =
MoreTypes.asExecutable(typeUtils.asMemberOf(barBuilderDeclaredType, method));
return typeUtils.isAssignable(barTypeMirror, methodMirror.getParameterTypes().get(0));
})
.findFirst();
}
/**
* Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of
* {@code TypeMirror} where each type is an annotation type.
*/
// TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
private ImmutableSet<TypeMirror> getExcludedAnnotationTypes(Element element) {
Optional<AnnotationMirror> maybeAnnotation =
getAnnotationMirror(element, COPY_ANNOTATIONS_NAME);
if (!maybeAnnotation.isPresent()) {
return ImmutableSet.of();
}
@SuppressWarnings("unchecked")
List<AnnotationValue> excludedClasses =
(List<AnnotationValue>) getAnnotationValue(maybeAnnotation.get(), "exclude").getValue();
return excludedClasses.stream()
.map(
annotationValue ->
MoreTypes.equivalence().wrap((TypeMirror) annotationValue.getValue()))
// TODO(b/122509249): Move TypeMirrorSet to common package instead of doing this.
.distinct()
.map(Wrapper::get)
.collect(toImmutableSet());
}
protected static TypeMirror getElementType(Element element) {
if (useInterface(element)) {
TypeMirror objectReader = ((TypeElement) typeUtils.asElement(element.asType())).getInterfaces().get(0);
return MoreTypes.asDeclared(objectReader).getTypeArguments().get(0);
} else {
return element.asType();
}
}
private TypeMirror getBeanType(Element element) {
if (useInterface(element)) {
TypeMirror objectReader = ((TypeElement) typeUtils.asElement(element.asType())).getInterfaces().get(0);
return MoreTypes.asDeclared(objectReader).getTypeArguments().get(0);
} else {
return element.asType();
}
}
Field(String name, TypeMirror type, boolean isNullable) {
this.name = name;
this.isNullable = isNullable;
TypeElement typeElement = MoreElements.asType(MoreTypes.asElement(type));
if (typeElement.getQualifiedName().contentEquals("java.util.List")) {
this.type = Type.LIST;
this.componentTypeName =
MoreTypes.asElement(MoreTypes.asDeclared(type).getTypeArguments().get(0))
.getSimpleName()
.toString();
} else {
this.type = Type.SCALAR;
}
this.typeName = typeElement.getSimpleName().toString();
}
/**
* Determines which of the three public non-final methods from {@code java.lang.Object}, if any,
* is overridden by the given method.
*/
static ObjectMethod objectMethodToOverride(ExecutableElement method) {
String name = method.getSimpleName().toString();
switch (method.getParameters().size()) {
case 0:
if (name.equals("toString")) {
return ObjectMethod.TO_STRING;
} else if (name.equals("hashCode")) {
return ObjectMethod.HASH_CODE;
}
break;
case 1:
if (name.equals("equals")) {
TypeMirror param = getOnlyElement(method.getParameters()).asType();
if (param.getKind().equals(TypeKind.DECLARED)) {
TypeElement paramType = MoreTypes.asTypeElement(param);
if (paramType.getQualifiedName().contentEquals("java.lang.Object")) {
return ObjectMethod.EQUALS;
}
}
}
break;
default:
// No relevant Object methods have more than one parameter.
}
return ObjectMethod.NONE;
}
/**
* Returns an {@code 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 {@code Optional.empty()} if the
* conversion isn't possible. An error will have been reported in the latter case.
*/
private Optional<Function<String, String>> getConvertingSetterFunction(
ImmutableList<ExecutableElement> copyOfMethods,
ExecutableElement valueGetter,
ExecutableElement setter,
TypeMirror parameterType) {
DeclaredType targetType = MoreTypes.asDeclared(getterToPropertyType.get(valueGetter));
for (ExecutableElement copyOfMethod : copyOfMethods) {
Optional<Function<String, String>> function =
getConvertingSetterFunction(copyOfMethod, targetType, parameterType);
if (function.isPresent()) {
return function;
}
}
String targetTypeSimpleName = targetType.asElement().getSimpleName().toString();
errorReporter.reportError(
setter,
"Parameter type %s of setter method should be %s to match getter %s.%s,"
+ " or it should be a type that can be passed to %s.%s to produce %s",
parameterType,
targetType,
autoValueClass,
valueGetter.getSimpleName(),
targetTypeSimpleName,
copyOfMethods.get(0).getSimpleName(),
targetType);
return Optional.empty();
}
/**
* Finds any methods in the set that return the builder type. If the builder has type parameters
* {@code <A, B>}, then the return type of the method must be {@code Builder<A, B>} with
* the same parameter names. We enforce elsewhere that the names and bounds of the builder
* parameters must be the same as those of the @RetroFacebook class. Here's a correct example:
* <pre>
* {@code @RetroFacebook abstract class Foo<A extends Number, B> {
* abstract int someProperty();
*
* abstract Builder<A, B> toBuilder();
*
* interface Builder<A extends Number, B> {...}
* }}
* </pre>
* <p/>
* <p>We currently impose that there cannot be more than one such method.</p>
*/
ImmutableSet<ExecutableElement> toBuilderMethods(
Types typeUtils, Set<ExecutableElement> abstractMethods) {
ImmutableList<String> builderTypeParamNames =
FluentIterable.from(builderTypeElement.getTypeParameters())
.transform(SimpleNameFunction.INSTANCE)
.toList();
ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();
for (ExecutableElement method : abstractMethods) {
if (builderTypeElement.equals(typeUtils.asElement(method.getReturnType()))) {
methods.add(method);
DeclaredType returnType = MoreTypes.asDeclared(method.getReturnType());
ImmutableList.Builder<String> typeArguments = ImmutableList.builder();
for (TypeMirror typeArgument : returnType.getTypeArguments()) {
if (typeArgument.getKind().equals(TypeKind.TYPEVAR)) {
typeArguments.add(typeUtils.asElement(typeArgument).getSimpleName().toString());
}
}
if (!builderTypeParamNames.equals(typeArguments.build())) {
errorReporter.reportError(
"Builder converter method should return "
+ builderTypeElement
+ TypeSimplifier.actualTypeParametersString(builderTypeElement),
method);
}
}
}
ImmutableSet<ExecutableElement> builderMethods = methods.build();
if (builderMethods.size() > 1) {
errorReporter.reportError(
"There can be at most one builder converter method", builderMethods.iterator().next());
}
return builderMethods;
}
static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {
for (AnnotationMirror annotation : element.getAnnotationMirrors()) {
TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());
if (annotationElement.getQualifiedName().contentEquals(annotationName)) {
return Optional.of(annotation);
}
}
return Optional.empty();
}
FieldDescriptor create(TypeElement owner, VariableElement element) {
String name = element.getSimpleName().toString();
TypeMirror type = types.asMemberOf((DeclaredType) owner.asType(), element);
TypeMirror fieldType = Utils.replaceTypeVariablesWithUpperBounds(types, type);
Equivalence.Wrapper<TypeMirror> wrappedType = MoreTypes.equivalence().wrap(fieldType);
boolean isVisible = Visibility.ofElement(element) != Visibility.PRIVATE;
boolean isNullable =
Utils.getAnnotationWithSimpleName(element, NON_NULL_ANNOTATION_NAME) == null
&& Utils.getAnnotationWithSimpleName(element, NOT_NULL_ANNOTATION_NAME) == null;
return new AutoValue_FieldDescriptor(element, name, wrappedType, isVisible, isNullable);
}
private void classifyGetter(ExecutableElement builderGetter, ExecutableElement originalGetter) {
String propertyName = getterToPropertyName.get(originalGetter);
TypeMirror originalGetterType = getterToPropertyType.get(originalGetter);
TypeMirror builderGetterType = builderMethodReturnType(builderGetter);
String builderGetterTypeString = TypeEncoder.encodeWithAnnotations(builderGetterType);
if (TYPE_EQUIVALENCE.equivalent(builderGetterType, originalGetterType)) {
builderGetters.put(
propertyName,
new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, null));
return;
}
Optionalish optional = Optionalish.createIfOptional(builderGetterType);
if (optional != null) {
TypeMirror containedType = optional.getContainedType(typeUtils);
// If the original method is int getFoo() then we allow Optional<Integer> here.
// boxedOriginalType is Integer, and containedType is also Integer.
// We don't need any special code for OptionalInt because containedType will be int then.
TypeMirror boxedOriginalType =
originalGetterType.getKind().isPrimitive()
? typeUtils.boxedClass(MoreTypes.asPrimitiveType(originalGetterType)).asType()
: null;
if (TYPE_EQUIVALENCE.equivalent(containedType, originalGetterType)
|| TYPE_EQUIVALENCE.equivalent(containedType, boxedOriginalType)) {
builderGetters.put(
propertyName,
new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, optional));
return;
}
}
errorReporter.reportError(
builderGetter,
"Method matches a property of %1$s but has return type %2$s instead of %3$s "
+ "or an Optional wrapping of %3$s",
autoValueClass, builderGetterType, originalGetterType);
}
private MethodSpec constructor(Context context) {
Types types = context.processingEnvironment().getTypeUtils();
DeclaredType declaredValueType = MoreTypes.asDeclared(context.autoValueClass().asType());
ImmutableList.Builder<ParameterSpec> parameterBuilder = ImmutableList.builder();
for (Map.Entry<String, ExecutableElement> entry : context.properties().entrySet()) {
ExecutableType resolvedExecutableType =
MoreTypes.asExecutable(types.asMemberOf(declaredValueType, entry.getValue()));
TypeName typeName = TypeName.get(resolvedExecutableType.getReturnType());
ParameterSpec.Builder spec = ParameterSpec.builder(typeName, entry.getKey());
AnnotationMirror nullableAnnotation =
Utils.getAnnotationWithSimpleName(entry.getValue(), NULLABLE_ANNOTATION_NAME);
if (nullableAnnotation != null) {
spec.addAnnotation(AnnotationSpec.get(nullableAnnotation));
}
parameterBuilder.add(spec.build());
}
ImmutableList<ParameterSpec> parameters = parameterBuilder.build();
CodeBlock parameterList = CodeBlocks.join(FluentIterable.from(parameters)
.transform(new Function<ParameterSpec, CodeBlock>() {
@Override public CodeBlock apply(ParameterSpec parameterSpec) {
return CodeBlock.of("$N", parameterSpec.name);
}
}), ", ");
return MethodSpec.constructorBuilder()
.addParameters(parameters)
.addStatement("super($L)", parameterList)
.build();
}
TypeMirror methodReturnType(ExecutableElement method, DeclaredType in) {
try {
TypeMirror methodMirror = typeUtils.asMemberOf(in, method);
return MoreTypes.asExecutable(methodMirror).getReturnType();
} catch (IllegalArgumentException e) {
return methodReturnTypes(ImmutableSet.of(method), in).get(method);
}
}
private List<MethodSpec> getSubcomponents() {
if (extractor.getSubcomponentsTypeMirrors().isEmpty()) {
return Collections.emptyList();
}
List<MethodSpec> methodSpecs = new ArrayList<>(extractor.getSubcomponentsTypeMirrors().size());
for (TypeMirror typeMirror : extractor.getSubcomponentsTypeMirrors()) {
Element e = MoreTypes.asElement(typeMirror);
TypeName typeName;
String name;
if (MoreElements.isAnnotationPresent(e, AutoSubcomponent.class)) {
ClassName cls = AutoComponentClassNameUtil.getComponentClassName(e);
typeName = cls;
name = cls.simpleName();
} else {
typeName = TypeName.get(typeMirror);
name = e.getSimpleName().toString();
}
List<TypeMirror> modules = state.getSubcomponentModules(typeMirror);
List<ParameterSpec> parameterSpecs;
if(modules != null) {
parameterSpecs = new ArrayList<>(modules.size());
int count = 0;
for (TypeMirror moduleTypeMirror : modules) {
parameterSpecs.add(ParameterSpec.builder(TypeName.get(moduleTypeMirror), String.format("module%d", ++count)).build());
}
} else {
parameterSpecs = new ArrayList<>(0);
}
methodSpecs.add(MethodSpec.methodBuilder("plus" + name)
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
.addParameters(parameterSpecs)
.returns(typeName)
.build());
}
return methodSpecs;
}
@Override
public boolean processElement(Element element, Errors.ElementErrors elementErrors) {
// @AutoX applied on annotation
if (element.getKind() == ElementKind.ANNOTATION_TYPE) {
// @AutoX is applied on another annotation, find out the targets of that annotation
Set<? extends Element> targetElements = roundEnvironment.getElementsAnnotatedWith(MoreElements.asType(element));
for (Element targetElement : targetElements) {
if (!process(targetElement, element)) {
return false;
}
}
return true;
}
// @AutoX applied on method
// only valid for @AutoExpose with @Provides
if (element.getKind() == ElementKind.METHOD) {
if (processedAnnotation.equals(AutoInjector.class)) {
errors.addInvalid(element, "@AutoInjector cannot be applied on the method %s", element.getSimpleName());
return false;
}
if (!MoreElements.isAnnotationPresent(element, Provides.class)) {
errors.addInvalid(element, "@AutoExpose can be applied on @Provides method only, %s is missing it", element.getSimpleName());
return false;
}
ExecutableElement executableElement = MoreElements.asExecutable(element);
Element returnElement = MoreTypes.asElement(executableElement.getReturnType());
return process(returnElement, element);
}
process(element, element);
return !errors.hasErrors();
}
MembersInjectionBinding getOrFindMembersInjectionBinding(Key key) {
checkNotNull(key);
// TODO(gak): is checking the kind enough?
checkArgument(key.isValidMembersInjectionKey());
MembersInjectionBinding binding = membersInjectionBindings.getBinding(key);
if (binding != null) {
return binding;
}
return registerBinding(membersInjectionBindingFactory.forInjectedType(
MoreTypes.asDeclared(key.type()), Optional.of(key.type())), false);
}
/**
* Tests whether a given parameter can be given to a static method like
* {@code ImmutableMap.copyOf} to produce a value that can be assigned to the given target type.
*
* <p>For example, suppose we have this method in {@code ImmutableMap}:<br>
* {@code static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V>)}<br>
* and we want to know if we can do this:
*
* <pre>
* {@code ImmutableMap<String, Integer> actualParameter = ...;}
* {@code ImmutableMap<String, Number> target = ImmutableMap.copyOf(actualParameter);}
* </pre>
*
* We will infer {@code K=String}, {@code V=Number} based on the target type, and then rewrite the
* formal parameter type from<br>
* {@code Map<? extends K, ? extends V>} to<br>
* {@code Map<? extends String, ? extends Number>}. Then we can check whether
* {@code actualParameter} is assignable to that.
*
* <p>The logic makes some simplifying assumptions, which are met for the {@code copyOf} and
* {@code of} methods that we use this for. The method must be static, it must have exactly one
* parameter, and it must have type parameters without bounds that are the same as the type
* parameters of its return type. We can see that these assumptions are met for the
* {@code ImmutableMap.copyOf} example above.
*/
static boolean canAssignStaticMethodResult(
ExecutableElement method,
TypeMirror actualParameterType,
TypeMirror targetType,
Types typeUtils) {
if (!targetType.getKind().equals(TypeKind.DECLARED)
|| !method.getModifiers().contains(Modifier.STATIC)
|| method.getParameters().size() != 1) {
return false;
}
List<? extends TypeParameterElement> typeParameters = method.getTypeParameters();
List<? extends TypeMirror> targetTypeArguments =
MoreTypes.asDeclared(targetType).getTypeArguments();
if (typeParameters.size() != targetTypeArguments.size()) {
return false;
}
Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();
for (int i = 0; i < typeParameters.size(); i++) {
TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType());
typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i));
}
TypeMirror formalParameterType = method.getParameters().get(0).asType();
SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils);
TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null);
if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) {
// If the target type is Optional<? extends Foo> then <T> T Optional.of(T) will give us
// ? extends Foo here, and typeUtils.isAssignable will return false. But we can in fact
// give a Foo as an argument, so we just replace ? extends Foo with Foo.
WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType);
if (wildcard.getExtendsBound() != null) {
substitutedParameterType = wildcard.getExtendsBound();
}
}
return typeUtils.isAssignable(actualParameterType, substitutedParameterType);
}
static FrameworkField createForMapBindingContribution(
Class<?> frameworkClass, BindingKey bindingKey, String name) {
TypeMirror mapValueType =
MoreTypes.asDeclared(bindingKey.key().type()).getTypeArguments().get(1);
return new AutoValue_FrameworkField(frameworkClass,
TypeNames.forTypeMirror(mapValueType),
bindingKey,
name);
}
static MethodSignature create(
CompilationUnitTree compilationUnitTree, MethodTree tree, Trees trees) {
ImmutableList.Builder<Equivalence.Wrapper<TypeMirror>> parameterTypes =
ImmutableList.builder();
for (VariableTree parameter : tree.getParameters()) {
parameterTypes.add(
MoreTypes.equivalence()
.wrap(trees.getTypeMirror(trees.getPath(compilationUnitTree, parameter))));
}
return new AutoValue_TreeDiffer_MethodSignature(
tree.getName().toString(), parameterTypes.build());
}
@Override
public Optional<Serializer> getSerializer(
TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {
if (typeMirror.getKind() != TypeKind.DECLARED) {
return Optional.empty();
}
DeclaredType declaredType = MoreTypes.asDeclared(typeMirror);
TypeElement typeElement = MoreElements.asType(declaredType.asElement());
if (typeElement.getQualifiedName().contentEquals("java.lang.String")) {
return Optional.of(new TestStringSerializer(typeMirror));
}
return Optional.empty();
}
static boolean isOptional(TypeMirror type) {
if (type.getKind() != TypeKind.DECLARED) {
return false;
}
DeclaredType declaredType = MoreTypes.asDeclared(type);
TypeElement typeElement = MoreElements.asType(declaredType.asElement());
return OPTIONAL_CLASS_NAMES.contains(typeElement.getQualifiedName().toString())
&& typeElement.getTypeParameters().size() == declaredType.getTypeArguments().size();
}
Key forComponentMethod(ExecutableElement componentMethod) {
checkNotNull(componentMethod);
checkArgument(componentMethod.getKind().equals(METHOD));
TypeMirror returnType = normalize(types, componentMethod.getReturnType());
return new AutoValue_Key(
wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), getQualifier(componentMethod)),
MoreTypes.equivalence().wrap(returnType));
}
Key forProductionComponentMethod(ExecutableElement componentMethod) {
checkNotNull(componentMethod);
checkArgument(componentMethod.getKind().equals(METHOD));
TypeMirror returnType = normalize(types, componentMethod.getReturnType());
TypeMirror keyType = returnType;
if (MoreTypes.isTypeOf(ListenableFuture.class, returnType)) {
keyType = Iterables.getOnlyElement(MoreTypes.asDeclared(returnType).getTypeArguments());
}
return new AutoValue_Key(
wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), getQualifier(componentMethod)),
MoreTypes.equivalence().wrap(keyType));
}