aboutsummaryrefslogtreecommitdiff
path: root/common/src/main/java/com/google/auto
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/java/com/google/auto')
-rw-r--r--common/src/main/java/com/google/auto/common/AnnotationMirrors.java97
-rw-r--r--common/src/main/java/com/google/auto/common/AnnotationValues.java199
-rw-r--r--common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java37
-rw-r--r--common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java8
-rw-r--r--common/src/main/java/com/google/auto/common/MoreElements.java78
-rw-r--r--common/src/main/java/com/google/auto/common/MoreStreams.java75
-rw-r--r--common/src/main/java/com/google/auto/common/MoreTypes.java70
-rw-r--r--common/src/main/java/com/google/auto/common/Overrides.java25
-rw-r--r--common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java10
-rw-r--r--common/src/main/java/com/google/auto/common/SuperficialValidation.java57
-rw-r--r--common/src/main/java/com/google/auto/common/Visibility.java8
-rw-r--r--common/src/main/java/com/google/auto/common/package-info.java17
12 files changed, 468 insertions, 213 deletions
diff --git a/common/src/main/java/com/google/auto/common/AnnotationMirrors.java b/common/src/main/java/com/google/auto/common/AnnotationMirrors.java
index 62e5834e..9ce5cd9b 100644
--- a/common/src/main/java/com/google/auto/common/AnnotationMirrors.java
+++ b/common/src/main/java/com/google/auto/common/AnnotationMirrors.java
@@ -16,21 +16,21 @@
package com.google.auto.common;
import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.common.MoreStreams.toImmutableSet;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.unmodifiableMap;
import com.google.common.base.Equivalence;
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.lang.annotation.Annotation;
import java.util.Arrays;
-import java.util.List;
import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
@@ -45,20 +45,32 @@ public final class AnnotationMirrors {
new Equivalence<AnnotationMirror>() {
@Override
protected boolean doEquivalent(AnnotationMirror left, AnnotationMirror right) {
- return MoreTypes.equivalence().equivalent(left.getAnnotationType(),
- right.getAnnotationType()) && AnnotationValues.equivalence().pairwise().equivalent(
- getAnnotationValuesWithDefaults(left).values(),
- getAnnotationValuesWithDefaults(right).values());
+ return MoreTypes.equivalence()
+ .equivalent(left.getAnnotationType(), right.getAnnotationType())
+ && AnnotationValues.equivalence()
+ .pairwise()
+ .equivalent(
+ getAnnotationValuesWithDefaults(left).values(),
+ getAnnotationValuesWithDefaults(right).values());
}
+
@Override
protected int doHash(AnnotationMirror annotation) {
DeclaredType type = annotation.getAnnotationType();
Iterable<AnnotationValue> annotationValues =
getAnnotationValuesWithDefaults(annotation).values();
- return Arrays.hashCode(new int[] {MoreTypes.equivalence().hash(type),
- AnnotationValues.equivalence().pairwise().hash(annotationValues)});
+ return Arrays.hashCode(
+ new int[] {
+ MoreTypes.equivalence().hash(type),
+ AnnotationValues.equivalence().pairwise().hash(annotationValues)
+ });
+ }
+
+ @Override
+ public String toString() {
+ return "AnnotationMirrors.equivalence()";
}
- };
+ };
/**
* Returns an {@link Equivalence} for {@link AnnotationMirror} as some implementations
@@ -83,8 +95,10 @@ public final class AnnotationMirrors {
public static ImmutableMap<ExecutableElement, AnnotationValue> getAnnotationValuesWithDefaults(
AnnotationMirror annotation) {
ImmutableMap.Builder<ExecutableElement, AnnotationValue> values = ImmutableMap.builder();
- Map<? extends ExecutableElement, ? extends AnnotationValue> declaredValues =
- annotation.getElementValues();
+ // Use unmodifiableMap to eliminate wildcards, which cause issues for our nullness checker.
+ @SuppressWarnings("GetElementValues")
+ Map<ExecutableElement, AnnotationValue> declaredValues =
+ unmodifiableMap(annotation.getElementValues());
for (ExecutableElement method :
ElementFilter.methodsIn(annotation.getAnnotationType().asElement().getEnclosedElements())) {
// Must iterate and put in this order, to ensure consistency in generated code.
@@ -95,8 +109,10 @@ public final class AnnotationMirrors {
} else {
throw new IllegalStateException(
"Unset annotation value without default should never happen: "
- + MoreElements.asType(method.getEnclosingElement()).getQualifiedName()
- + '.' + method.getSimpleName() + "()");
+ + MoreElements.asType(method.getEnclosingElement()).getQualifiedName()
+ + '.'
+ + method.getSimpleName()
+ + "()");
}
}
return values.build();
@@ -131,25 +147,48 @@ public final class AnnotationMirrors {
return entry;
}
}
- throw new IllegalArgumentException(String.format("@%s does not define an element %s()",
- MoreElements.asType(annotationMirror.getAnnotationType().asElement()).getQualifiedName(),
- elementName));
+ throw new IllegalArgumentException(
+ String.format(
+ "@%s does not define an element %s()",
+ MoreElements.asType(annotationMirror.getAnnotationType().asElement())
+ .getQualifiedName(),
+ elementName));
+ }
+
+ /**
+ * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link
+ * Element} which are themselves annotated with {@code annotationClass}.
+ */
+ public static ImmutableSet<? extends AnnotationMirror> getAnnotatedAnnotations(
+ Element element, Class<? extends Annotation> annotationClass) {
+ String name = annotationClass.getCanonicalName();
+ if (name == null) {
+ return ImmutableSet.of();
+ }
+ return getAnnotatedAnnotations(element, name);
+ }
+
+ /**
+ * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link
+ * Element} which are themselves annotated with {@code annotation}.
+ */
+ public static ImmutableSet<? extends AnnotationMirror> getAnnotatedAnnotations(
+ Element element, TypeElement annotation) {
+ return element.getAnnotationMirrors().stream()
+ .filter(input -> isAnnotationPresent(input.getAnnotationType().asElement(), annotation))
+ .collect(toImmutableSet());
}
/**
- * Returns all {@linkplain AnnotationMirror annotations} that are present on the given
- * {@link Element} which are themselves annotated with {@code annotationType}.
+ * Returns all {@linkplain AnnotationMirror annotations} that are present on the given {@link
+ * Element} which are themselves annotated with an annotation whose type's canonical name is
+ * {@code annotationName}.
*/
- public static ImmutableSet<? extends AnnotationMirror> getAnnotatedAnnotations(Element element,
- final Class<? extends Annotation> annotationType) {
- List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();
- return FluentIterable.from(annotations)
- .filter(new Predicate<AnnotationMirror>() {
- @Override public boolean apply(AnnotationMirror input) {
- return isAnnotationPresent(input.getAnnotationType().asElement(), annotationType);
- }
- })
- .toSet();
+ public static ImmutableSet<? extends AnnotationMirror> getAnnotatedAnnotations(
+ Element element, String annotationName) {
+ return element.getAnnotationMirrors().stream()
+ .filter(input -> isAnnotationPresent(input.getAnnotationType().asElement(), annotationName))
+ .collect(toImmutableSet());
}
private AnnotationMirrors() {}
diff --git a/common/src/main/java/com/google/auto/common/AnnotationValues.java b/common/src/main/java/com/google/auto/common/AnnotationValues.java
index e2339018..0712e56a 100644
--- a/common/src/main/java/com/google/auto/common/AnnotationValues.java
+++ b/common/src/main/java/com/google/auto/common/AnnotationValues.java
@@ -15,8 +15,8 @@
*/
package com.google.auto.common;
+import static com.google.auto.common.MoreStreams.toImmutableList;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
import com.google.common.base.Equivalence;
import com.google.common.collect.ImmutableList;
@@ -37,91 +37,120 @@ import javax.lang.model.util.SimpleAnnotationValueVisitor8;
public final class AnnotationValues {
private static final Equivalence<AnnotationValue> ANNOTATION_VALUE_EQUIVALENCE =
new Equivalence<AnnotationValue>() {
- @Override protected boolean doEquivalent(AnnotationValue left, AnnotationValue right) {
- return left.accept(new SimpleAnnotationValueVisitor8<Boolean, AnnotationValue>() {
- // LHS is not an annotation or array of annotation values, so just test equality.
- @Override protected Boolean defaultAction(Object left, AnnotationValue right) {
- return left.equals(right.accept(
- new SimpleAnnotationValueVisitor8<Object, Void>() {
- @Override protected Object defaultAction(Object object, Void unused) {
- return object;
- }
- }, null));
- }
-
- // LHS is an annotation mirror so test equivalence for RHS annotation mirrors
- // and false for other types.
- @Override public Boolean visitAnnotation(AnnotationMirror left, AnnotationValue right) {
- return right.accept(
- new SimpleAnnotationValueVisitor8<Boolean, AnnotationMirror>() {
- @Override protected Boolean defaultAction(Object right, AnnotationMirror left) {
- return false; // Not an annotation mirror, so can't be equal to such.
- }
- @Override
- public Boolean visitAnnotation(AnnotationMirror right, AnnotationMirror left) {
- return AnnotationMirrors.equivalence().equivalent(left, right);
- }
- }, left);
- }
-
- // LHS is a list of annotation values have to collect-test equivalences, or false
- // for any other types.
- @Override
- public Boolean visitArray(List<? extends AnnotationValue> left, AnnotationValue right) {
- return right.accept(
- new SimpleAnnotationValueVisitor8<Boolean, List<? extends AnnotationValue>>() {
- @Override protected Boolean defaultAction(
- Object ignored, List<? extends AnnotationValue> alsoIgnored) {
- return false; // Not an array, so can't be equal to such.
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast
- @Override public Boolean visitArray(
- List<? extends AnnotationValue> right ,
- List<? extends AnnotationValue> left) {
- return AnnotationValues.equivalence().pairwise().equivalent(
- (List<AnnotationValue>) left, (List<AnnotationValue>) right);
- }
- }, left);
- }
-
- @Override
- public Boolean visitType(TypeMirror left, AnnotationValue right) {
- return right.accept(
- new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
- @Override protected Boolean defaultAction(
- Object ignored, TypeMirror alsoIgnored) {
- return false; // Not an annotation mirror, so can't be equal to such.
- }
-
- @Override public Boolean visitType(TypeMirror right, TypeMirror left) {
- return MoreTypes.equivalence().equivalent(left, right);
- }
- }, left);
- }
- }, right);
+ @Override
+ protected boolean doEquivalent(AnnotationValue left, AnnotationValue right) {
+ return left.accept(
+ new SimpleAnnotationValueVisitor8<Boolean, AnnotationValue>() {
+ // LHS is not an annotation or array of annotation values, so just test equality.
+ @Override
+ protected Boolean defaultAction(Object left, AnnotationValue right) {
+ return left.equals(
+ right.accept(
+ new SimpleAnnotationValueVisitor8<Object, Void>() {
+ @Override
+ protected Object defaultAction(Object object, Void unused) {
+ return object;
+ }
+ },
+ null));
+ }
+
+ // LHS is an annotation mirror so test equivalence for RHS annotation mirrors
+ // and false for other types.
+ @Override
+ public Boolean visitAnnotation(AnnotationMirror left, AnnotationValue right) {
+ return right.accept(
+ new SimpleAnnotationValueVisitor8<Boolean, AnnotationMirror>() {
+ @Override
+ protected Boolean defaultAction(Object right, AnnotationMirror left) {
+ return false; // Not an annotation mirror, so can't be equal to such.
+ }
+
+ @Override
+ public Boolean visitAnnotation(
+ AnnotationMirror right, AnnotationMirror left) {
+ return AnnotationMirrors.equivalence().equivalent(left, right);
+ }
+ },
+ left);
+ }
+
+ // LHS is a list of annotation values have to collect-test equivalences, or false
+ // for any other types.
+ @Override
+ public Boolean visitArray(
+ List<? extends AnnotationValue> left, AnnotationValue right) {
+ return right.accept(
+ new SimpleAnnotationValueVisitor8<
+ Boolean, List<? extends AnnotationValue>>() {
+ @Override
+ protected Boolean defaultAction(
+ Object ignored, List<? extends AnnotationValue> alsoIgnored) {
+ return false; // Not an array, so can't be equal to such.
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ @Override
+ public Boolean visitArray(
+ List<? extends AnnotationValue> right,
+ List<? extends AnnotationValue> left) {
+ return AnnotationValues.equivalence()
+ .pairwise()
+ .equivalent(
+ (List<AnnotationValue>) left, (List<AnnotationValue>) right);
+ }
+ },
+ left);
+ }
+
+ @Override
+ public Boolean visitType(TypeMirror left, AnnotationValue right) {
+ return right.accept(
+ new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
+ @Override
+ protected Boolean defaultAction(Object ignored, TypeMirror alsoIgnored) {
+ return false; // Not an annotation mirror, so can't be equal to such.
+ }
+
+ @Override
+ public Boolean visitType(TypeMirror right, TypeMirror left) {
+ return MoreTypes.equivalence().equivalent(left, right);
+ }
+ },
+ left);
+ }
+ },
+ right);
}
- @Override protected int doHash(AnnotationValue value) {
- return value.accept(new SimpleAnnotationValueVisitor8<Integer, Void>() {
- @Override public Integer visitAnnotation(AnnotationMirror value, Void ignore) {
- return AnnotationMirrors.equivalence().hash(value);
- }
-
- @SuppressWarnings("unchecked") // safe covariant cast
- @Override public Integer visitArray(
- List<? extends AnnotationValue> values, Void ignore) {
- return AnnotationValues.equivalence().pairwise().hash((List<AnnotationValue>) values);
- }
-
- @Override public Integer visitType(TypeMirror value, Void ignore) {
- return MoreTypes.equivalence().hash(value);
- }
-
- @Override protected Integer defaultAction(Object value, Void ignored) {
- return value.hashCode();
- }
- }, null);
+ @Override
+ protected int doHash(AnnotationValue value) {
+ return value.accept(
+ new SimpleAnnotationValueVisitor8<Integer, Void>() {
+ @Override
+ public Integer visitAnnotation(AnnotationMirror value, Void ignore) {
+ return AnnotationMirrors.equivalence().hash(value);
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ @Override
+ public Integer visitArray(List<? extends AnnotationValue> values, Void ignore) {
+ return AnnotationValues.equivalence()
+ .pairwise()
+ .hash((List<AnnotationValue>) values);
+ }
+
+ @Override
+ public Integer visitType(TypeMirror value, Void ignore) {
+ return MoreTypes.equivalence().hash(value);
+ }
+
+ @Override
+ protected Integer defaultAction(Object value, Void ignored) {
+ return value.hashCode();
+ }
+ },
+ null);
}
};
@@ -209,7 +238,6 @@ public final class AnnotationValues {
return value;
}
}
- ;
/**
* Returns the value as a VariableElement.
@@ -486,4 +514,3 @@ public final class AnnotationValues {
private AnnotationValues() {}
}
-
diff --git a/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java b/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java
index 375a4cb8..d951aaf4 100644
--- a/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java
+++ b/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java
@@ -17,14 +17,14 @@ package com.google.auto.common;
import static com.google.auto.common.MoreElements.asExecutable;
import static com.google.auto.common.MoreElements.asPackage;
+import static com.google.auto.common.MoreStreams.toImmutableMap;
+import static com.google.auto.common.MoreStreams.toImmutableSet;
import static com.google.auto.common.SuperficialValidation.validateElement;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Multimaps.filterKeys;
-import static java.util.stream.Collectors.collectingAndThen;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
+import static java.util.Objects.requireNonNull;
import static javax.lang.model.element.ElementKind.PACKAGE;
import static javax.tools.Diagnostic.Kind.ERROR;
@@ -56,6 +56,7 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ErrorType;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleElementVisitor8;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* An abstract {@link Processor} implementation that defers processing of {@link Element}s to later
@@ -162,14 +163,14 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
checkState(steps != null);
return steps.stream()
.flatMap(step -> getSupportedAnnotationTypeElements(step).stream())
- .collect(collectingAndThen(toList(), ImmutableSet::copyOf));
+ .collect(toImmutableSet());
}
private ImmutableSet<TypeElement> getSupportedAnnotationTypeElements(Step step) {
return step.annotations().stream()
.map(elements::getTypeElement)
.filter(Objects::nonNull)
- .collect(collectingAndThen(toList(), ImmutableSet::copyOf));
+ .collect(toImmutableSet());
}
/**
@@ -181,7 +182,7 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
checkState(steps != null);
return steps.stream()
.flatMap(step -> step.annotations().stream())
- .collect(collectingAndThen(toList(), ImmutableSet::copyOf));
+ .collect(toImmutableSet());
}
@Override
@@ -287,10 +288,7 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
// Look at the elements we've found and the new elements from this round and validate them.
for (TypeElement annotationType : getSupportedAnnotationTypeElements()) {
- Set<? extends Element> roundElements =
- (annotationType == null)
- ? ImmutableSet.of()
- : roundEnv.getElementsAnnotatedWith(annotationType);
+ Set<? extends Element> roundElements = roundEnv.getElementsAnnotatedWith(annotationType);
ImmutableSet<Element> prevRoundElements = deferredElementsByAnnotation.get(annotationType);
for (Element element : Sets.union(roundElements, prevRoundElements)) {
ElementName elementName = ElementName.forAnnotatedElement(element);
@@ -376,7 +374,7 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
* IllegalArgumentException} if the provided {@link Element} is a {@link PackageElement} or is
* otherwise not enclosed by a type.
*/
- // TODO(cgruber) move to MoreElements and make public.
+ // TODO(user) move to MoreElements and make public.
private static TypeElement getEnclosingType(Element element) {
return element.accept(
new SimpleElementVisitor8<TypeElement, Void>() {
@@ -478,10 +476,9 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
this.annotationsByName =
processingStep.annotations().stream()
.collect(
- collectingAndThen(
- toMap(
- Class::getCanonicalName, (Class<? extends Annotation> aClass) -> aClass),
- ImmutableMap::copyOf));
+ toImmutableMap(
+ c -> requireNonNull(c.getCanonicalName()),
+ (Class<? extends Annotation> aClass) -> aClass));
}
@Override
@@ -502,8 +499,12 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
elements
.asMap()
.forEach(
- (annotation, annotatedElements) ->
- builder.putAll(annotationsByName.get(annotation), annotatedElements));
+ (annotationName, annotatedElements) -> {
+ Class<? extends Annotation> annotation = annotationsByName.get(annotationName);
+ if (annotation != null) { // should not be null
+ builder.putAll(annotation, annotatedElements);
+ }
+ });
return builder.build();
}
}
@@ -561,7 +562,7 @@ public abstract class BasicAnnotationProcessor extends AbstractProcessor {
}
@Override
- public boolean equals(Object object) {
+ public boolean equals(@Nullable Object object) {
if (!(object instanceof ElementName)) {
return false;
}
diff --git a/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java
index bb35e22f..09d9029e 100644
--- a/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java
+++ b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java
@@ -27,7 +27,7 @@ public final class GeneratedAnnotationSpecs {
private GeneratedAnnotationSpecs() {}
/**
- * Returns {@code @Generated("processorClass"} if either {@code
+ * Returns {@code @Generated("processorClass")} if either {@code
* javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain
* GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.
*
@@ -41,7 +41,7 @@ public final class GeneratedAnnotationSpecs {
}
/**
- * Returns {@code @Generated(value = "processorClass", comments = "comments"} if either {@code
+ * Returns {@code @Generated(value = "processorClass", comments = "comments")} if either {@code
* javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain
* GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.
*
@@ -55,7 +55,7 @@ public final class GeneratedAnnotationSpecs {
}
/**
- * Returns {@code @Generated("processorClass"} for the target {@code SourceVersion}.
+ * Returns {@code @Generated("processorClass")} for the target {@code SourceVersion}.
*
* <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code
* javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is
@@ -68,7 +68,7 @@ public final class GeneratedAnnotationSpecs {
}
/**
- * Returns {@code @Generated(value = "processorClass", comments = "comments"} for the target
+ * Returns {@code @Generated(value = "processorClass", comments = "comments")} for the target
* {@code SourceVersion}.
*
* <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code
diff --git a/common/src/main/java/com/google/auto/common/MoreElements.java b/common/src/main/java/com/google/auto/common/MoreElements.java
index 5e8e3541..dfbbaeef 100644
--- a/common/src/main/java/com/google/auto/common/MoreElements.java
+++ b/common/src/main/java/com/google/auto/common/MoreElements.java
@@ -16,6 +16,7 @@
*/
package com.google.auto.common;
+import static com.google.auto.common.MoreStreams.toImmutableSet;
import static javax.lang.model.element.ElementKind.PACKAGE;
import static javax.lang.model.element.Modifier.STATIC;
@@ -212,29 +213,80 @@ public final class MoreElements {
}
/**
- * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose
- * {@linkplain AnnotationMirror#getAnnotationType() annotation type} has the same canonical name
- * as that of {@code annotationClass}. This method is a safer alternative to calling
- * {@link Element#getAnnotation} and checking for {@code null} as it avoids any interaction with
+ * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain
+ * AnnotationMirror#getAnnotationType() annotation type} has the same canonical name as that of
+ * {@code annotationClass}. This method is a safer alternative to calling {@link
+ * Element#getAnnotation} and checking for {@code null} as it avoids any interaction with
* annotation proxies.
*/
- public static boolean isAnnotationPresent(Element element,
- Class<? extends Annotation> annotationClass) {
+ public static boolean isAnnotationPresent(
+ Element element, Class<? extends Annotation> annotationClass) {
return getAnnotationMirror(element, annotationClass).isPresent();
}
/**
+ * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain
+ * AnnotationMirror#getAnnotationType() annotation type} has the same fully qualified name as that
+ * of {@code annotation}. This method is a safer alternative to calling {@link
+ * Element#getAnnotation} and checking for {@code null} as it avoids any interaction with
+ * annotation proxies.
+ */
+ public static boolean isAnnotationPresent(Element element, TypeElement annotation) {
+ return getAnnotationMirror(element, annotation).isPresent();
+ }
+
+ /**
+ * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose {@linkplain
+ * AnnotationMirror#getAnnotationType() annotation type} has {@code annotationName} as its
+ * canonical name. This method is a safer alternative to calling {@link Element#getAnnotation} and
+ * checking for {@code null} as it avoids any interaction with annotation proxies.
+ */
+ public static boolean isAnnotationPresent(Element element, String annotationName) {
+ return getAnnotationMirror(element, annotationName).isPresent();
+ }
+
+ /**
* Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClass} on
* {@code element}, or {@link Optional#absent()} if no such annotation exists. This method is a
* safer alternative to calling {@link Element#getAnnotation} as it avoids any interaction with
* annotation proxies.
*/
- public static Optional<AnnotationMirror> getAnnotationMirror(Element element,
- Class<? extends Annotation> annotationClass) {
- String annotationClassName = annotationClass.getCanonicalName();
+ public static Optional<AnnotationMirror> getAnnotationMirror(
+ Element element, Class<? extends Annotation> annotationClass) {
+ String name = annotationClass.getCanonicalName();
+ if (name == null) {
+ return Optional.absent();
+ }
+ return getAnnotationMirror(element, name);
+ }
+
+ /**
+ * Returns an {@link AnnotationMirror} for the annotation of type {@code annotation} on {@code
+ * element}, or {@link Optional#absent()} if no such annotation exists. This method is a safer
+ * alternative to calling {@link Element#getAnnotation} as it avoids any interaction with
+ * annotation proxies.
+ */
+ public static Optional<AnnotationMirror> getAnnotationMirror(
+ Element element, TypeElement annotation) {
+ for (AnnotationMirror elementAnnotation : element.getAnnotationMirrors()) {
+ if (elementAnnotation.getAnnotationType().asElement().equals(annotation)) {
+ return Optional.of(elementAnnotation);
+ }
+ }
+ return Optional.absent();
+ }
+
+ /**
+ * Returns an {@link AnnotationMirror} for the annotation whose type's canonical name is on {@code
+ * element}, or {@link Optional#absent()} if no such annotation exists. This method is a safer
+ * alternative to calling {@link Element#getAnnotation} as it avoids any interaction with
+ * annotation proxies.
+ */
+ public static Optional<AnnotationMirror> getAnnotationMirror(
+ Element element, String annotationName) {
for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
TypeElement annotationTypeElement = asType(annotationMirror.getAnnotationType().asElement());
- if (annotationTypeElement.getQualifiedName().contentEquals(annotationClassName)) {
+ if (annotationTypeElement.getQualifiedName().contentEquals(annotationName)) {
return Optional.of(annotationMirror);
}
}
@@ -435,9 +487,9 @@ public final class MoreElements {
}
}
}
- Set<ExecutableElement> methods = new LinkedHashSet<ExecutableElement>(methodMap.values());
- methods.removeAll(overridden);
- return ImmutableSet.copyOf(methods);
+ return methodMap.values().stream()
+ .filter(m -> !overridden.contains(m))
+ .collect(toImmutableSet());
}
// Add to `methods` the static and instance methods from `type`. This means all methods from
diff --git a/common/src/main/java/com/google/auto/common/MoreStreams.java b/common/src/main/java/com/google/auto/common/MoreStreams.java
new file mode 100644
index 00000000..934514ab
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/MoreStreams.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.auto.common;
+
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.toList;
+
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+/**
+ * A utility class that provides Android compatible alternatives to Guava's streaming APIs.
+ *
+ * <p>This is useful when the Android flavor of Guava somehow finds its way onto the processor
+ * classpath.
+ */
+public final class MoreStreams {
+
+ /** Returns a collector for an {@link ImmutableList}. */
+ public static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() {
+ return collectingAndThen(toList(), ImmutableList::copyOf);
+ }
+
+ /** Returns a collector for an {@link ImmutableSet}. */
+ public static <T> Collector<T, ?, ImmutableSet<T>> toImmutableSet() {
+ return collectingAndThen(toList(), ImmutableSet::copyOf);
+ }
+
+ /** Returns a collector for an {@link ImmutableMap}. */
+ public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
+ Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {
+ return Collectors.mapping(
+ value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),
+ Collector.of(
+ ImmutableMap::builder,
+ (ImmutableMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry),
+ (left, right) -> left.putAll(right.build()),
+ ImmutableMap.Builder::build));
+ }
+
+ /** Returns a collector for an {@link ImmutableBiMap}. */
+ public static <T, K, V> Collector<T, ?, ImmutableBiMap<K, V>> toImmutableBiMap(
+ Function<? super T, K> keyMapper, Function<? super T, V> valueMapper) {
+ return Collectors.mapping(
+ value -> Maps.immutableEntry(keyMapper.apply(value), valueMapper.apply(value)),
+ Collector.of(
+ ImmutableBiMap::builder,
+ (ImmutableBiMap.Builder<K, V> builder, Map.Entry<K, V> entry) -> builder.put(entry),
+ (left, right) -> left.putAll(right.build()),
+ ImmutableBiMap.Builder::build));
+ }
+
+ private MoreStreams() {}
+}
diff --git a/common/src/main/java/com/google/auto/common/MoreTypes.java b/common/src/main/java/com/google/auto/common/MoreTypes.java
index e09680bc..1a490626 100644
--- a/common/src/main/java/com/google/auto/common/MoreTypes.java
+++ b/common/src/main/java/com/google/auto/common/MoreTypes.java
@@ -25,7 +25,6 @@ import static javax.lang.model.type.TypeKind.TYPEVAR;
import static javax.lang.model.type.TypeKind.WILDCARD;
import com.google.common.base.Equivalence;
-import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -55,6 +54,7 @@ import javax.lang.model.type.WildcardType;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleTypeVisitor8;
import javax.lang.model.util.Types;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Utilities related to {@link TypeMirror} instances.
@@ -75,6 +75,11 @@ public final class MoreTypes {
protected int doHash(TypeMirror t) {
return MoreTypes.hash(t, ImmutableSet.<Element>of());
}
+
+ @Override
+ public String toString() {
+ return "MoreTypes.equivalence()";
+ }
}
/**
@@ -135,13 +140,11 @@ public final class MoreTypes {
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(@Nullable Object o) {
if (o instanceof ComparedElements) {
ComparedElements that = (ComparedElements) o;
int nArguments = aArguments.size();
- if (!this.a.equals(that.a)
- || !this.b.equals(that.b)
- || nArguments != bArguments.size()) {
+ if (!this.a.equals(that.a) || !this.b.equals(that.b) || nArguments != bArguments.size()) {
// The arguments must be the same size, but we check anyway.
return false;
}
@@ -294,7 +297,14 @@ public final class MoreTypes {
}
@SuppressWarnings("TypeEquals")
- private static boolean equal(TypeMirror a, TypeMirror b, Set<ComparedElements> visiting) {
+ private static boolean equal(
+ @Nullable TypeMirror a, @Nullable TypeMirror b, Set<ComparedElements> visiting) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
// TypeMirror.equals is not guaranteed to return true for types that are equal, but we can
// assume that if it does return true then the types are equal. This check also avoids getting
// stuck in infinite recursion when Eclipse decrees that the upper bound of the second K in
@@ -302,13 +312,15 @@ public final class MoreTypes {
// The javac implementation of ExecutableType, at least in some versions, does not take thrown
// exceptions into account in its equals implementation, so avoid this optimization for
// ExecutableType.
- if (Objects.equal(a, b) && !(a instanceof ExecutableType)) {
+ @SuppressWarnings("TypesEquals")
+ boolean equal = a.equals(b);
+ if (equal && !(a instanceof ExecutableType)) {
return true;
}
EqualVisitorParam p = new EqualVisitorParam();
p.type = b;
p.visiting = visiting;
- return (a == b) || (a != null && b != null && a.accept(EqualVisitor.INSTANCE, p));
+ return a.accept(EqualVisitor.INSTANCE, p);
}
/**
@@ -318,7 +330,7 @@ public final class MoreTypes {
* <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=508222">this bug</a> whereby
* the Eclipse compiler returns a value for static classes that is not NoType.
*/
- private static TypeMirror enclosingType(DeclaredType t) {
+ private static @Nullable TypeMirror enclosingType(DeclaredType t) {
TypeMirror enclosing = t.getEnclosingType();
if (enclosing.getKind().equals(TypeKind.NONE)
|| t.asElement().getModifiers().contains(Modifier.STATIC)) {
@@ -337,16 +349,14 @@ public final class MoreTypes {
Iterator<? extends TypeMirror> aIterator = a.iterator();
Iterator<? extends TypeMirror> bIterator = b.iterator();
while (aIterator.hasNext()) {
- if (!bIterator.hasNext()) {
- return false;
- }
+ // We checked that the lists have the same size, so we know that bIterator.hasNext() too.
TypeMirror nextMirrorA = aIterator.next();
TypeMirror nextMirrorB = bIterator.next();
if (!equal(nextMirrorA, nextMirrorB, visiting)) {
return false;
}
}
- return !aIterator.hasNext();
+ return true;
}
private static final int HASH_SEED = 17;
@@ -433,7 +443,7 @@ public final class MoreTypes {
public Integer visitUnknown(TypeMirror t, Set<Element> visiting) {
throw new UnsupportedOperationException();
}
- };
+ }
private static int hashList(List<? extends TypeMirror> mirrors, Set<Element> visiting) {
int result = HASH_SEED;
@@ -460,17 +470,17 @@ public final class MoreTypes {
}
private static final class ReferencedTypes
- extends SimpleTypeVisitor8<Void, ImmutableSet.Builder<TypeElement>> {
+ extends SimpleTypeVisitor8<@Nullable Void, ImmutableSet.Builder<TypeElement>> {
private static final ReferencedTypes INSTANCE = new ReferencedTypes();
@Override
- public Void visitArray(ArrayType t, ImmutableSet.Builder<TypeElement> p) {
+ public @Nullable Void visitArray(ArrayType t, ImmutableSet.Builder<TypeElement> p) {
t.getComponentType().accept(this, p);
return null;
}
@Override
- public Void visitDeclared(DeclaredType t, ImmutableSet.Builder<TypeElement> p) {
+ public @Nullable Void visitDeclared(DeclaredType t, ImmutableSet.Builder<TypeElement> p) {
p.add(MoreElements.asType(t.asElement()));
for (TypeMirror typeArgument : t.getTypeArguments()) {
typeArgument.accept(this, p);
@@ -479,14 +489,14 @@ public final class MoreTypes {
}
@Override
- public Void visitTypeVariable(TypeVariable t, ImmutableSet.Builder<TypeElement> p) {
+ public @Nullable Void visitTypeVariable(TypeVariable t, ImmutableSet.Builder<TypeElement> p) {
t.getLowerBound().accept(this, p);
t.getUpperBound().accept(this, p);
return null;
}
@Override
- public Void visitWildcard(WildcardType t, ImmutableSet.Builder<TypeElement> p) {
+ public @Nullable Void visitWildcard(WildcardType t, ImmutableSet.Builder<TypeElement> p) {
TypeMirror extendsBound = t.getExtendsBound();
if (extendsBound != null) {
extendsBound.accept(this, p);
@@ -534,7 +544,8 @@ public final class MoreTypes {
public Element visitTypeVariable(TypeVariable t, Void p) {
return t.asElement();
}
- };
+ }
+ ;
// TODO(gak): consider removing these two methods as they're pretty trivial now
public static TypeElement asTypeElement(TypeMirror mirror) {
@@ -833,6 +844,11 @@ public final class MoreTypes {
}
@Override
+ public Boolean visitError(ErrorType errorType, Void p) {
+ return false;
+ }
+
+ @Override
public Boolean visitPrimitive(PrimitiveType type, Void p) {
switch (type.getKind()) {
case BOOLEAN:
@@ -873,11 +889,11 @@ public final class MoreTypes {
* {@link Optional#absent()} if {@code type} is an interface or {@link Object} or its superclass
* is {@link Object}.
*/
- // TODO(user): Remove unused parameter Elements?
- public static Optional<DeclaredType> nonObjectSuperclass(Types types, Elements elements,
- DeclaredType type) {
+ // TODO(bcorso): Remove unused parameter Elements?
+ public static Optional<DeclaredType> nonObjectSuperclass(
+ Types types, Elements elements, DeclaredType type) {
checkNotNull(types);
- checkNotNull(elements); // This is no longer used, but here to avoid changing the API.
+ checkNotNull(elements); // This is no longer used, but here to avoid changing the API.
checkNotNull(type);
TypeMirror superclassType = asTypeElement(type).getSuperclass();
@@ -885,7 +901,7 @@ public final class MoreTypes {
return Optional.absent();
}
- DeclaredType superclass = asDeclared(superclassType);
+ DeclaredType superclass = asDeclared(superclassType);
if (isObjectType(superclass)) {
return Optional.absent();
}
@@ -912,8 +928,8 @@ public final class MoreTypes {
* {@code container} of type {@code Set<String>}, and a variable corresponding to the {@code E e}
* parameter in the {@code Set.add(E e)} method, this will return a TypeMirror for {@code String}.
*/
- public static TypeMirror asMemberOf(Types types, DeclaredType container,
- VariableElement variable) {
+ public static TypeMirror asMemberOf(
+ Types types, DeclaredType container, VariableElement variable) {
if (variable.getKind().equals(ElementKind.PARAMETER)) {
ExecutableElement methodOrConstructor =
MoreElements.asExecutable(variable.getEnclosingElement());
diff --git a/common/src/main/java/com/google/auto/common/Overrides.java b/common/src/main/java/com/google/auto/common/Overrides.java
index 19a45862..775c304a 100644
--- a/common/src/main/java/com/google/auto/common/Overrides.java
+++ b/common/src/main/java/com/google/auto/common/Overrides.java
@@ -15,6 +15,8 @@
*/
package com.google.auto.common;
+import static java.util.stream.Collectors.toList;
+
import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
@@ -38,6 +40,7 @@ import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleTypeVisitor8;
import javax.lang.model.util.Types;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Determines if one method overrides another. This class defines two ways of doing that:
@@ -114,12 +117,11 @@ abstract class Overrides {
// can't be overridden.
return false;
}
- TypeElement overriddenType;
if (!(overridden.getEnclosingElement() instanceof TypeElement)) {
return false;
// We don't know how this could happen but we avoid blowing up if it does.
}
- overriddenType = MoreElements.asType(overridden.getEnclosingElement());
+ TypeElement overriddenType = MoreElements.asType(overridden.getEnclosingElement());
// We erase the types before checking subtypes, because the TypeMirror we get for List<E> is
// not a subtype of the one we get for Collection<E> since the two E instances are not the
// same. For the purposes of overriding, type parameters in the containing type should not
@@ -141,7 +143,8 @@ abstract class Overrides {
// the enclosing elements rather than the methods themselves for the reason described
// at the start of the method.
ExecutableElement inherited = methodFromSuperclasses(in, overridden);
- return !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
+ return inherited != null
+ && !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
} else if (overriddenType.getKind().isInterface()) {
// ...overrides from C another method mI declared in interface I. We've already checked
// the conditions (assuming that the only alternative to mI being abstract or default is
@@ -157,7 +160,8 @@ abstract class Overrides {
// to methodFromSuperclasses above.
if (overrider.getModifiers().contains(Modifier.ABSTRACT)) {
ExecutableElement inherited = methodFromSuperinterfaces(in, overridden);
- return !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
+ return inherited != null
+ && !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
} else {
return true;
}
@@ -215,6 +219,7 @@ abstract class Overrides {
* implements List<E>}. The parameter types are erased since the purpose of this method is to
* determine whether two methods are candidates for one to override the other.
*/
+ @Nullable
ImmutableList<TypeMirror> erasedParameterTypes(ExecutableElement method, TypeElement in) {
if (method.getParameters().isEmpty()) {
return ImmutableList.of();
@@ -241,6 +246,7 @@ abstract class Overrides {
*/
private final Map<TypeParameterElement, TypeMirror> typeBindings = Maps.newLinkedHashMap();
+ @Nullable
ImmutableList<TypeMirror> erasedParameterTypes(ExecutableElement method, TypeElement in) {
if (method.getEnclosingElement().equals(in)) {
ImmutableList.Builder<TypeMirror> params = ImmutableList.builder();
@@ -261,6 +267,10 @@ abstract class Overrides {
TypeElement element = MoreElements.asType(declared.asElement());
List<? extends TypeMirror> actuals = declared.getTypeArguments();
List<? extends TypeParameterElement> formals = element.getTypeParameters();
+ if (actuals.isEmpty()) {
+ // Either the formal type arguments are also empty or `declared` is raw.
+ actuals = formals.stream().map(t -> t.getBounds().get(0)).collect(toList());
+ }
Verify.verify(actuals.size() == formals.size());
for (int i = 0; i < actuals.size(); i++) {
typeBindings.put(formals.get(i), actuals.get(i));
@@ -315,7 +325,7 @@ abstract class Overrides {
* or the nearest override in a superclass of the given type, or null if the method is not
* found in the given type or any of its superclasses.
*/
- ExecutableElement methodFromSuperclasses(TypeElement in, ExecutableElement method) {
+ @Nullable ExecutableElement methodFromSuperclasses(TypeElement in, ExecutableElement method) {
for (TypeElement t = in; t != null; t = superclass(t)) {
ExecutableElement tMethod = methodInType(t, method);
if (tMethod != null) {
@@ -330,6 +340,7 @@ abstract class Overrides {
* itself, or the nearest override in a superinterface of the given type, or null if the method
* is not found in the given type or any of its transitive superinterfaces.
*/
+ @Nullable
ExecutableElement methodFromSuperinterfaces(TypeElement in, ExecutableElement method) {
TypeElement methodContainer = MoreElements.asType(method.getEnclosingElement());
Preconditions.checkArgument(methodContainer.getKind().isInterface());
@@ -366,7 +377,7 @@ abstract class Overrides {
* Returns the method from within the given type that has the same erased signature as the given
* method, or null if there is no such method.
*/
- private ExecutableElement methodInType(TypeElement type, ExecutableElement method) {
+ private @Nullable ExecutableElement methodInType(TypeElement type, ExecutableElement method) {
int nParams = method.getParameters().size();
List<TypeMirror> params = erasedParameterTypes(method, type);
if (params == null) {
@@ -388,7 +399,7 @@ abstract class Overrides {
return null;
}
- private TypeElement superclass(TypeElement type) {
+ private @Nullable TypeElement superclass(TypeElement type) {
TypeMirror sup = type.getSuperclass();
if (sup.getKind() == TypeKind.DECLARED) {
return MoreElements.asType(typeUtils.asElement(sup));
diff --git a/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java b/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java
index 7d508e32..7952eb37 100644
--- a/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java
+++ b/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java
@@ -16,8 +16,8 @@
package com.google.auto.common;
+import static com.google.auto.common.MoreStreams.toImmutableMap;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static javax.lang.model.util.ElementFilter.methodsIn;
import com.google.common.base.Joiner;
@@ -32,6 +32,7 @@ import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* A simple implementation of the {@link AnnotationMirror} interface.
@@ -65,7 +66,7 @@ public final class SimpleAnnotationMirror implements AnnotationMirror {
missingMembers.add(memberName);
}
}
-
+
checkArgument(
unusedValues.isEmpty(),
"namedValues has entries for members that are not in %s: %s",
@@ -77,8 +78,7 @@ public final class SimpleAnnotationMirror implements AnnotationMirror {
this.annotationType = annotationType;
this.namedValues = ImmutableMap.copyOf(namedValues);
this.elementValues =
- methodsIn(annotationType.getEnclosedElements())
- .stream()
+ methodsIn(annotationType.getEnclosedElements()).stream()
.collect(toImmutableMap(e -> e, e -> values.get(e.getSimpleName().toString())));
}
@@ -123,7 +123,7 @@ public final class SimpleAnnotationMirror implements AnnotationMirror {
}
@Override
- public boolean equals(Object other) {
+ public boolean equals(@Nullable Object other) {
return other instanceof AnnotationMirror
&& AnnotationMirrors.equivalence().equivalent(this, (AnnotationMirror) other);
}
diff --git a/common/src/main/java/com/google/auto/common/SuperficialValidation.java b/common/src/main/java/com/google/auto/common/SuperficialValidation.java
index 5ef4dbf2..614e2626 100644
--- a/common/src/main/java/com/google/auto/common/SuperficialValidation.java
+++ b/common/src/main/java/com/google/auto/common/SuperficialValidation.java
@@ -57,23 +57,27 @@ public final class SuperficialValidation {
private static final ElementVisitor<Boolean, Void> ELEMENT_VALIDATING_VISITOR =
new AbstractElementVisitor8<Boolean, Void>() {
- @Override public Boolean visitPackage(PackageElement e, Void p) {
+ @Override
+ public Boolean visitPackage(PackageElement e, Void p) {
// don't validate enclosed elements because it will return types in the package
return validateAnnotations(e.getAnnotationMirrors());
}
- @Override public Boolean visitType(TypeElement e, Void p) {
+ @Override
+ public Boolean visitType(TypeElement e, Void p) {
return isValidBaseElement(e)
&& validateElements(e.getTypeParameters())
&& validateTypes(e.getInterfaces())
&& validateType(e.getSuperclass());
}
- @Override public Boolean visitVariable(VariableElement e, Void p) {
+ @Override
+ public Boolean visitVariable(VariableElement e, Void p) {
return isValidBaseElement(e);
}
- @Override public Boolean visitExecutable(ExecutableElement e, Void p) {
+ @Override
+ public Boolean visitExecutable(ExecutableElement e, Void p) {
AnnotationValue defaultValue = e.getDefaultValue();
return isValidBaseElement(e)
&& (defaultValue == null || validateAnnotationValue(defaultValue, e.getReturnType()))
@@ -83,12 +87,13 @@ public final class SuperficialValidation {
&& validateElements(e.getParameters());
}
- @Override public Boolean visitTypeParameter(TypeParameterElement e, Void p) {
- return isValidBaseElement(e)
- && validateTypes(e.getBounds());
+ @Override
+ public Boolean visitTypeParameter(TypeParameterElement e, Void p) {
+ return isValidBaseElement(e) && validateTypes(e.getBounds());
}
- @Override public Boolean visitUnknown(Element e, Void p) {
+ @Override
+ public Boolean visitUnknown(Element e, Void p) {
// just assume that unknown elements are OK
return true;
}
@@ -206,16 +211,19 @@ public final class SuperficialValidation {
private static final AnnotationValueVisitor<Boolean, TypeMirror> VALUE_VALIDATING_VISITOR =
new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
- @Override protected Boolean defaultAction(Object o, TypeMirror expectedType) {
+ @Override
+ protected Boolean defaultAction(Object o, TypeMirror expectedType) {
return MoreTypes.isTypeOf(o.getClass(), expectedType);
}
- @Override public Boolean visitUnknown(AnnotationValue av, TypeMirror expectedType) {
+ @Override
+ public Boolean visitUnknown(AnnotationValue av, TypeMirror expectedType) {
// just take the default action for the unknown
return defaultAction(av, expectedType);
}
- @Override public Boolean visitAnnotation(AnnotationMirror a, TypeMirror expectedType) {
+ @Override
+ public Boolean visitAnnotation(AnnotationMirror a, TypeMirror expectedType) {
return MoreTypes.equivalence().equivalent(a.getAnnotationType(), expectedType)
&& validateAnnotation(a);
}
@@ -235,7 +243,8 @@ public final class SuperficialValidation {
&& validateElement(enumConstant);
}
- @Override public Boolean visitType(TypeMirror type, TypeMirror ignored) {
+ @Override
+ public Boolean visitType(TypeMirror type, TypeMirror ignored) {
// We could check assignability here, but would require a Types instance. Since this
// isn't really the sort of thing that shows up in a bad AST from upstream compilation
// we ignore the expected type and just validate the type. It might be wrong, but
@@ -243,35 +252,43 @@ public final class SuperficialValidation {
return validateType(type);
}
- @Override public Boolean visitBoolean(boolean b, TypeMirror expectedType) {
+ @Override
+ public Boolean visitBoolean(boolean b, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Boolean.TYPE, expectedType);
}
- @Override public Boolean visitByte(byte b, TypeMirror expectedType) {
+ @Override
+ public Boolean visitByte(byte b, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Byte.TYPE, expectedType);
}
- @Override public Boolean visitChar(char c, TypeMirror expectedType) {
+ @Override
+ public Boolean visitChar(char c, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Character.TYPE, expectedType);
}
- @Override public Boolean visitDouble(double d, TypeMirror expectedType) {
+ @Override
+ public Boolean visitDouble(double d, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Double.TYPE, expectedType);
}
- @Override public Boolean visitFloat(float f, TypeMirror expectedType) {
+ @Override
+ public Boolean visitFloat(float f, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Float.TYPE, expectedType);
}
- @Override public Boolean visitInt(int i, TypeMirror expectedType) {
+ @Override
+ public Boolean visitInt(int i, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Integer.TYPE, expectedType);
}
- @Override public Boolean visitLong(long l, TypeMirror expectedType) {
+ @Override
+ public Boolean visitLong(long l, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Long.TYPE, expectedType);
}
- @Override public Boolean visitShort(short s, TypeMirror expectedType) {
+ @Override
+ public Boolean visitShort(short s, TypeMirror expectedType) {
return MoreTypes.isTypeOf(Short.TYPE, expectedType);
}
};
diff --git a/common/src/main/java/com/google/auto/common/Visibility.java b/common/src/main/java/com/google/auto/common/Visibility.java
index f82fdd59..36f4ad6d 100644
--- a/common/src/main/java/com/google/auto/common/Visibility.java
+++ b/common/src/main/java/com/google/auto/common/Visibility.java
@@ -16,14 +16,15 @@
package com.google.auto.common;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Comparators.min;
import static javax.lang.model.element.ElementKind.PACKAGE;
import com.google.common.base.Enums;
-import com.google.common.collect.Ordering;
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents the visibility of a given {@link Element}: {@code public}, {@code protected},
@@ -41,7 +42,7 @@ public enum Visibility {
// TODO(ronshapiro): remove this and reference ElementKind.MODULE directly once we start building
// with -source 9
- private static final ElementKind MODULE =
+ private static final @Nullable ElementKind MODULE =
Enums.getIfPresent(ElementKind.class, "MODULE").orNull();
/**
@@ -76,8 +77,7 @@ public enum Visibility {
Visibility effectiveVisibility = PUBLIC;
Element currentElement = element;
while (currentElement != null) {
- effectiveVisibility =
- Ordering.natural().min(effectiveVisibility, ofElement(currentElement));
+ effectiveVisibility = min(effectiveVisibility, ofElement(currentElement));
currentElement = currentElement.getEnclosingElement();
}
return effectiveVisibility;
diff --git a/common/src/main/java/com/google/auto/common/package-info.java b/common/src/main/java/com/google/auto/common/package-info.java
new file mode 100644
index 00000000..22b0c45a
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/package-info.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.auto.common;
+