diff options
Diffstat (limited to 'common/src/main/java/com/google/auto')
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; + |