diff options
author | Colin Cross <ccross@android.com> | 2022-03-04 20:20:55 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2022-03-04 20:20:55 -0800 |
commit | 85e5c17a9a61aed9f989ebf0c17507cec66e4c39 (patch) | |
tree | 6d8fcf60826daaf24143400633fe8d5dfee49033 /common | |
parent | bb49451a269af9506039d0d22b5fb26f2aae298d (diff) | |
parent | 04ebf9cf9acd8b92a6460bebccc8d4cfb30b938e (diff) | |
download | auto-85e5c17a9a61aed9f989ebf0c17507cec66e4c39.tar.gz |
Merge commit 'auto-value-1.8.2^'
Bug: 219098645
Test: m checkbuild
Change-Id: I64e22d75b4f077b3e4cdfb13b42239d95ae9e86c
Diffstat (limited to 'common')
24 files changed, 1366 insertions, 851 deletions
diff --git a/common/README.md b/common/README.md index 990aa31b..9f8eb79e 100644 --- a/common/README.md +++ b/common/README.md @@ -1,28 +1,30 @@ -Auto Common Utilities -======== +# Auto Common Utilities ## Overview -The Auto project has a set of common utilities to help ease use of the annotation processing -environment. +The Auto project has a set of common utilities to help ease use of the +annotation processing environment. ## Utility classes of note - * MoreTypes - utilities and Equivalence wrappers for TypeMirror and related subtypes - * MoreElements - utilities for Element and related subtypes - * SuperficialValidation - very simple scanner to ensure an Element is valid and free from - distortion from upstream compilation errors - * Visibility - utilities for working with Elements' visibility levels (public, protected, etc.) - * BasicAnnotationProcessor/ProcessingStep - simple types that - - implement a validating annotation processor - - defer invalid elements until later - - break processor actions into multiple steps (which may each handle different annotations) +* MoreTypes - utilities and Equivalence wrappers for TypeMirror and related + subtypes +* MoreElements - utilities for Element and related subtypes +* SuperficialValidation - very simple scanner to ensure an Element is valid + and free from distortion from upstream compilation errors +* Visibility - utilities for working with Elements' visibility levels (public, + protected, etc.) +* BasicAnnotationProcessor/ProcessingStep - simple types that + - implement a validating annotation processor + - defer invalid elements until later + - break processor actions into multiple steps (which may each handle + different annotations) ## Usage/Setup -Auto common utilities have a standard [Maven](http://maven.apache.org) setup which can also be -used from Gradle, Ivy, Ant, or other systems which consume binary artifacts from the central Maven -binary artifact repositories. +Auto common utilities have a standard [Maven](http://maven.apache.org) setup +which can also be used from Gradle, Ivy, Ant, or other systems which consume +binary artifacts from the central Maven binary artifact repositories. ```xml <dependency> @@ -31,49 +33,3 @@ binary artifact repositories. <version>1.0-SNAPSHOT</version> <!-- or use a known release version --> </dependency> ``` - -## Processor Resilience - -Auto Common Utilities is used by a variety of annotation processors in Google and new versions -may have breaking changes. Users of auto-common are urged to use -[shade](https://maven.apache.org/plugins/maven-shade-plugin/) or -[jarjar](https://code.google.com/p/jarjar/) (or something similar) in packaging their processors -so that conflicting versions of this library do not adversely interact with each other. - -For example, in a Maven build you can repackage `com.google.auto.common` into -`your.processor.shaded.auto.common` like this: - -```xml -<project> - <!-- your other config --> - <build> - <plugins> - <plugin> - <artifactId>maven-shade-plugin</artifactId> - <executions> - <execution> - <phase>package</phase> - <goals> - <goal>shade</goal> - </goals> - <configuration> - <artifactSet> - <excludes> - <!-- exclude dependencies you don't want to bundle in your processor --> - </excludes> - </artifactSet> - <relocations> - <relocation> - <pattern>com.google.auto.common</pattern> - <shadedPattern>your.processor.shaded.auto.common</shadedPattern> - </relocation> - </relocations> - </configuration> - </execution> - </executions> - </plugin> - </plugins> - </build> -</project> -``` - diff --git a/common/pom.xml b/common/pom.xml index e4a23e02..2754b81d 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -36,8 +36,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> - <guava.version>29.0-jre</guava.version> - <truth.version>1.0.1</truth.version> + <guava.version>30.1.1-jre</guava.version> + <truth.version>1.1.3</truth.version> </properties> <scm> @@ -89,13 +89,13 @@ <dependency> <groupId>com.google.testing.compile</groupId> <artifactId>compile-testing</artifactId> - <version>0.18</version> + <version>0.19</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.12</version> + <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> @@ -107,7 +107,7 @@ <dependency> <groupId>org.eclipse.jdt</groupId> <artifactId>ecj</artifactId> - <version>3.22.0</version> + <version>3.25.0</version> <scope>test</scope> </dependency> </dependencies> @@ -116,7 +116,7 @@ <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.7.0</version> + <version>3.8.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> @@ -128,14 +128,14 @@ <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-java</artifactId> - <version>0.9.4</version> + <version>1.0.7</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.0.2</version> + <version>3.2.0</version> </plugin> </plugins> </build> 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; + diff --git a/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java b/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java index dfc043ab..b1dfe3b3 100644 --- a/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java +++ b/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java @@ -22,12 +22,17 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.testing.compile.CompilationSubject.assertThat; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableSet; import com.google.common.testing.EquivalenceTester; +import com.google.common.truth.Correspondence; import com.google.testing.compile.CompilationRule; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Map; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleAnnotationValueVisitor6; @@ -46,110 +51,134 @@ public class AnnotationMirrorsTest { private Elements elements; - @Before public void setUp() { + @Before + public void setUp() { this.elements = compilationRule.getElements(); } @interface SimpleAnnotation {} - @SimpleAnnotation class SimplyAnnotated {} - @SimpleAnnotation class AlsoSimplyAnnotated {} + @SimpleAnnotation + static class SimplyAnnotated {} + + @SimpleAnnotation + static class AlsoSimplyAnnotated {} enum SimpleEnum { - BLAH, FOO + BLAH, + FOO } @interface Outer { SimpleEnum value(); } - @Outer(BLAH) static class TestClassBlah {} - @Outer(BLAH) static class TestClassBlah2 {} - @Outer(FOO) static class TestClassFoo {} + @Outer(BLAH) + static class TestClassBlah {} + + @Outer(BLAH) + static class TestClassBlah2 {} + + @Outer(FOO) + static class TestClassFoo {} @interface DefaultingOuter { SimpleEnum value() default SimpleEnum.BLAH; } - @DefaultingOuter class TestWithDefaultingOuterDefault {} - @DefaultingOuter(BLAH) class TestWithDefaultingOuterBlah {} - @DefaultingOuter(FOO) class TestWithDefaultingOuterFoo {} + @DefaultingOuter + static class TestWithDefaultingOuterDefault {} + + @DefaultingOuter(BLAH) + static class TestWithDefaultingOuterBlah {} + + @DefaultingOuter(FOO) + static class TestWithDefaultingOuterFoo {} @interface AnnotatedOuter { DefaultingOuter value(); } - @AnnotatedOuter(@DefaultingOuter) class TestDefaultNestedAnnotated {} - @AnnotatedOuter(@DefaultingOuter(BLAH)) class TestBlahNestedAnnotated {} - @AnnotatedOuter(@DefaultingOuter(FOO)) class TestFooNestedAnnotated {} + @AnnotatedOuter(@DefaultingOuter) + static class TestDefaultNestedAnnotated {} + + @AnnotatedOuter(@DefaultingOuter(BLAH)) + static class TestBlahNestedAnnotated {} + + @AnnotatedOuter(@DefaultingOuter(FOO)) + static class TestFooNestedAnnotated {} @interface OuterWithValueArray { DefaultingOuter[] value() default {}; } - @OuterWithValueArray class TestValueArrayWithDefault {} - @OuterWithValueArray({}) class TestValueArrayWithEmpty {} + @OuterWithValueArray + static class TestValueArrayWithDefault {} + + @OuterWithValueArray({}) + static class TestValueArrayWithEmpty {} - @OuterWithValueArray({@DefaultingOuter}) class TestValueArrayWithOneDefault {} - @OuterWithValueArray(@DefaultingOuter(BLAH)) class TestValueArrayWithOneBlah {} - @OuterWithValueArray(@DefaultingOuter(FOO)) class TestValueArrayWithOneFoo {} + @OuterWithValueArray({@DefaultingOuter}) + static class TestValueArrayWithOneDefault {} + + @OuterWithValueArray(@DefaultingOuter(BLAH)) + static class TestValueArrayWithOneBlah {} + + @OuterWithValueArray(@DefaultingOuter(FOO)) + static class TestValueArrayWithOneFoo {} @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter}) class TestValueArrayWithFooAndDefaultBlah {} + @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)}) class TestValueArrayWithFooBlah {} + @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)}) class TestValueArrayWithFooBlah2 {} // Different instances than on TestValueArrayWithFooBlah. + @OuterWithValueArray({@DefaultingOuter(BLAH), @DefaultingOuter(FOO)}) class TestValueArrayWithBlahFoo {} - @Test public void testEquivalences() { + @Test + public void testEquivalences() { EquivalenceTester<AnnotationMirror> tester = EquivalenceTester.of(AnnotationMirrors.equivalence()); tester.addEquivalenceGroup( - annotationOn(SimplyAnnotated.class), - annotationOn(AlsoSimplyAnnotated.class)); + annotationOn(SimplyAnnotated.class), annotationOn(AlsoSimplyAnnotated.class)); tester.addEquivalenceGroup( - annotationOn(TestClassBlah.class), - annotationOn(TestClassBlah2.class)); + annotationOn(TestClassBlah.class), annotationOn(TestClassBlah2.class)); - tester.addEquivalenceGroup( - annotationOn(TestClassFoo.class)); + tester.addEquivalenceGroup(annotationOn(TestClassFoo.class)); tester.addEquivalenceGroup( annotationOn(TestWithDefaultingOuterDefault.class), annotationOn(TestWithDefaultingOuterBlah.class)); - tester.addEquivalenceGroup( - annotationOn(TestWithDefaultingOuterFoo.class)); + tester.addEquivalenceGroup(annotationOn(TestWithDefaultingOuterFoo.class)); tester.addEquivalenceGroup( annotationOn(TestDefaultNestedAnnotated.class), annotationOn(TestBlahNestedAnnotated.class)); - tester.addEquivalenceGroup( - annotationOn(TestFooNestedAnnotated.class)); + tester.addEquivalenceGroup(annotationOn(TestFooNestedAnnotated.class)); tester.addEquivalenceGroup( - annotationOn(TestValueArrayWithDefault.class), - annotationOn(TestValueArrayWithEmpty.class)); + annotationOn(TestValueArrayWithDefault.class), annotationOn(TestValueArrayWithEmpty.class)); tester.addEquivalenceGroup( annotationOn(TestValueArrayWithOneDefault.class), annotationOn(TestValueArrayWithOneBlah.class)); - tester.addEquivalenceGroup( - annotationOn(TestValueArrayWithOneFoo.class)); + tester.addEquivalenceGroup(annotationOn(TestValueArrayWithOneFoo.class)); tester.addEquivalenceGroup( annotationOn(TestValueArrayWithFooAndDefaultBlah.class), annotationOn(TestValueArrayWithFooBlah.class), annotationOn(TestValueArrayWithFooBlah2.class)); - tester.addEquivalenceGroup( - annotationOn(TestValueArrayWithBlahFoo.class)); + tester.addEquivalenceGroup(annotationOn(TestValueArrayWithBlahFoo.class)); tester.test(); } @@ -158,44 +187,61 @@ public class AnnotationMirrorsTest { String value() default "default"; } - @Stringy class StringyUnset {} - @Stringy("foo") class StringySet {} + @Stringy + static class StringyUnset {} + + @Stringy("foo") + static class StringySet {} - @Test public void testGetDefaultValuesUnset() { + @Test + public void testGetDefaultValuesUnset() { assertThat(annotationOn(StringyUnset.class).getElementValues()).isEmpty(); - Iterable<AnnotationValue> values = AnnotationMirrors.getAnnotationValuesWithDefaults( - annotationOn(StringyUnset.class)).values(); - String value = getOnlyElement(values).accept(new SimpleAnnotationValueVisitor6<String, Void>() { - @Override public String visitString(String value, Void ignored) { - return value; - } - }, null); + Iterable<AnnotationValue> values = + AnnotationMirrors.getAnnotationValuesWithDefaults(annotationOn(StringyUnset.class)) + .values(); + String value = + getOnlyElement(values) + .accept( + new SimpleAnnotationValueVisitor6<String, Void>() { + @Override + public String visitString(String value, Void ignored) { + return value; + } + }, + null); assertThat(value).isEqualTo("default"); } - @Test public void testGetDefaultValuesSet() { - Iterable<AnnotationValue> values = AnnotationMirrors.getAnnotationValuesWithDefaults( - annotationOn(StringySet.class)).values(); - String value = getOnlyElement(values).accept(new SimpleAnnotationValueVisitor6<String, Void>() { - @Override public String visitString(String value, Void ignored) { - return value; - } - }, null); + @Test + public void testGetDefaultValuesSet() { + Iterable<AnnotationValue> values = + AnnotationMirrors.getAnnotationValuesWithDefaults(annotationOn(StringySet.class)).values(); + String value = + getOnlyElement(values) + .accept( + new SimpleAnnotationValueVisitor6<String, Void>() { + @Override + public String visitString(String value, Void ignored) { + return value; + } + }, + null); assertThat(value).isEqualTo("foo"); } - @Test public void testGetValueEntry() { + @Test + public void testGetValueEntry() { Map.Entry<ExecutableElement, AnnotationValue> elementValue = - AnnotationMirrors.getAnnotationElementAndValue( - annotationOn(TestClassBlah.class), "value"); + AnnotationMirrors.getAnnotationElementAndValue(annotationOn(TestClassBlah.class), "value"); assertThat(elementValue.getKey().getSimpleName().toString()).isEqualTo("value"); assertThat(elementValue.getValue().getValue()).isInstanceOf(VariableElement.class); - AnnotationValue value = AnnotationMirrors.getAnnotationValue( - annotationOn(TestClassBlah.class), "value"); + AnnotationValue value = + AnnotationMirrors.getAnnotationValue(annotationOn(TestClassBlah.class), "value"); assertThat(value.getValue()).isInstanceOf(VariableElement.class); } - @Test public void testGetValueEntryFailure() { + @Test + public void testGetValueEntryFailure() { try { AnnotationMirrors.getAnnotationValue(annotationOn(TestClassBlah.class), "a"); } catch (IllegalArgumentException e) { @@ -212,4 +258,52 @@ public class AnnotationMirrorsTest { return getOnlyElement(elements.getTypeElement(clazz.getCanonicalName()).getAnnotationMirrors()); } + @Retention(RetentionPolicy.RUNTIME) + private @interface AnnotatingAnnotation {} + + @AnnotatingAnnotation + @Retention(RetentionPolicy.RUNTIME) + private @interface AnnotatedAnnotation1 {} + + @AnnotatingAnnotation + @Retention(RetentionPolicy.RUNTIME) + private @interface AnnotatedAnnotation2 {} + + @Retention(RetentionPolicy.RUNTIME) + private @interface NotAnnotatedAnnotation {} + + @AnnotatedAnnotation1 + @NotAnnotatedAnnotation + @AnnotatedAnnotation2 + private static final class AnnotatedClass {} + + @Test + public void getAnnotatedAnnotations() { + TypeElement element = elements.getTypeElement(AnnotatedClass.class.getCanonicalName()); + + // Test Class API + getAnnotatedAnnotationsAsserts( + AnnotationMirrors.getAnnotatedAnnotations(element, AnnotatingAnnotation.class)); + + // Test String API + String annotatingAnnotationName = AnnotatingAnnotation.class.getCanonicalName(); + getAnnotatedAnnotationsAsserts( + AnnotationMirrors.getAnnotatedAnnotations(element, annotatingAnnotationName)); + + // Test TypeElement API + TypeElement annotatingAnnotationElement = elements.getTypeElement(annotatingAnnotationName); + getAnnotatedAnnotationsAsserts( + AnnotationMirrors.getAnnotatedAnnotations(element, annotatingAnnotationElement)); + } + + private void getAnnotatedAnnotationsAsserts( + ImmutableSet<? extends AnnotationMirror> annotatedAnnotations) { + assertThat(annotatedAnnotations) + .comparingElementsUsing( + Correspondence.transforming( + (AnnotationMirror a) -> MoreTypes.asTypeElement(a.getAnnotationType()), "has type")) + .containsExactly( + elements.getTypeElement(AnnotatedAnnotation1.class.getCanonicalName()), + elements.getTypeElement(AnnotatedAnnotation2.class.getCanonicalName())); + } } diff --git a/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java b/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java index 1c816c10..f9426527 100644 --- a/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java +++ b/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java @@ -18,6 +18,7 @@ package com.google.auto.common; import static com.google.common.truth.Truth.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Objects.requireNonNull; import static org.junit.Assume.assumeTrue; import com.google.common.collect.ImmutableList; @@ -31,6 +32,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.net.URI; import java.nio.file.Files; +import java.util.Objects; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; @@ -44,6 +46,7 @@ import javax.tools.SimpleJavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; +import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -99,12 +102,12 @@ public class GeneratedAnnotationsTest { * Run {@link TestProcessor} in a compilation with the given {@code options}, and prevent the * compilation from accessing classes with the qualified names in {@code maskFromClasspath}. */ - private String runProcessor(ImmutableList<String> options, String packageToMask) + private String runProcessor(ImmutableList<String> options, @Nullable String packageToMask) throws IOException { File tempDir = temporaryFolder.newFolder(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager standardFileManager = - compiler.getStandardFileManager(/* diagnostics= */ null, /* locale= */ null, UTF_8); + compiler.getStandardFileManager(/* diagnosticListener= */ null, /* locale= */ null, UTF_8); standardFileManager.setLocation(StandardLocation.CLASS_OUTPUT, ImmutableList.of(tempDir)); StandardJavaFileManager proxyFileManager = Reflection.newProxy( @@ -142,18 +145,20 @@ public class GeneratedAnnotationsTest { */ private static class FileManagerInvocationHandler implements InvocationHandler { private final StandardJavaFileManager fileManager; - private final String packageToMask; + private final @Nullable String packageToMask; - FileManagerInvocationHandler(StandardJavaFileManager fileManager, String packageToMask) { + FileManagerInvocationHandler( + StandardJavaFileManager fileManager, @Nullable String packageToMask) { this.fileManager = fileManager; this.packageToMask = packageToMask; } @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + public Object invoke(Object proxy, Method method, @Nullable Object @Nullable [] args) + throws Throwable { if (method.getName().equals("list")) { - String packageName = (String) args[1]; - if (packageName.equals(packageToMask)) { + String packageName = (String) requireNonNull(args)[1]; + if (Objects.equals(packageName, packageToMask)) { return ImmutableList.of(); } } @@ -187,8 +192,7 @@ public class GeneratedAnnotationsTest { // An alternative would be to delete this test method. JDK8 always has // javax.annotation.Generated so it isn't really meaningful to test it without. ImmutableList<String> options = ImmutableList.of("-source", "8", "-target", "8"); - String generated = - runProcessor(options, "javax.annotation"); + String generated = runProcessor(options, "javax.annotation"); assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED); assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED); } diff --git a/common/src/test/java/com/google/auto/common/MoreElementsTest.java b/common/src/test/java/com/google/auto/common/MoreElementsTest.java index 95043cf3..b98b79b9 100644 --- a/common/src/test/java/com/google/auto/common/MoreElementsTest.java +++ b/common/src/test/java/com/google/auto/common/MoreElementsTest.java @@ -18,6 +18,7 @@ package com.google.auto.common; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static java.util.Objects.requireNonNull; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -58,13 +59,14 @@ public class MoreElementsTest { @Rule public CompilationRule compilation = new CompilationRule(); @Rule public Expect expect = Expect.create(); + private Elements elements; private PackageElement javaLangPackageElement; private TypeElement objectElement; private TypeElement stringElement; @Before public void initializeTestElements() { - Elements elements = compilation.getElements(); + this.elements = compilation.getElements(); this.javaLangPackageElement = elements.getPackageElement("java.lang"); this.objectElement = elements.getTypeElement(Object.class.getCanonicalName()); this.stringElement = elements.getTypeElement(String.class.getCanonicalName()); @@ -80,8 +82,7 @@ public class MoreElementsTest { @Test public void asPackage() { - assertThat(MoreElements.asPackage(javaLangPackageElement)) - .isEqualTo(javaLangPackageElement); + assertThat(MoreElements.asPackage(javaLangPackageElement)).isEqualTo(javaLangPackageElement); } @Test @@ -89,19 +90,20 @@ public class MoreElementsTest { try { MoreElements.asPackage(stringElement); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } - @Test public void asTypeElement() { - Element typeElement = - compilation.getElements().getTypeElement(String.class.getCanonicalName()); + @Test + public void asTypeElement() { + Element typeElement = elements.getTypeElement(String.class.getCanonicalName()); assertTrue(MoreElements.isType(typeElement)); assertThat(MoreElements.asType(typeElement)).isEqualTo(typeElement); } - @Test public void asTypeElement_notATypeElement() { - TypeElement typeElement = - compilation.getElements().getTypeElement(String.class.getCanonicalName()); + @Test + public void asTypeElement_notATypeElement() { + TypeElement typeElement = elements.getTypeElement(String.class.getCanonicalName()); for (ExecutableElement e : ElementFilter.methodsIn(typeElement.getEnclosedElements())) { assertFalse(MoreElements.isType(e)); try { @@ -143,7 +145,8 @@ public class MoreElementsTest { try { MoreElements.asType(javaLangPackageElement); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } @Test @@ -158,7 +161,8 @@ public class MoreElementsTest { try { MoreElements.asVariable(javaLangPackageElement); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } @Test @@ -166,8 +170,8 @@ public class MoreElementsTest { for (Element methodElement : ElementFilter.methodsIn(stringElement.getEnclosedElements())) { assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement); } - for (Element methodElement - : ElementFilter.constructorsIn(stringElement.getEnclosedElements())) { + for (Element methodElement : + ElementFilter.constructorsIn(stringElement.getEnclosedElements())) { assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement); } } @@ -177,7 +181,8 @@ public class MoreElementsTest { try { MoreElements.asExecutable(javaLangPackageElement); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } @Retention(RetentionPolicy.RUNTIME) @@ -190,39 +195,90 @@ public class MoreElementsTest { @Test public void isAnnotationPresent() { TypeElement annotatedAnnotationElement = - compilation.getElements().getTypeElement(AnnotatedAnnotation.class.getCanonicalName()); - assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, Documented.class)) - .isTrue(); - assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, InnerAnnotation.class)) - .isTrue(); - assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, SuppressWarnings.class)) - .isFalse(); + elements.getTypeElement(AnnotatedAnnotation.class.getCanonicalName()); + + // Test Class API + isAnnotationPresentAsserts( + MoreElements.isAnnotationPresent(annotatedAnnotationElement, Documented.class), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, InnerAnnotation.class), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, SuppressWarnings.class)); + + // Test String API + String documentedName = Documented.class.getCanonicalName(); + String innerAnnotationName = InnerAnnotation.class.getCanonicalName(); + String suppressWarningsName = SuppressWarnings.class.getCanonicalName(); + isAnnotationPresentAsserts( + MoreElements.isAnnotationPresent(annotatedAnnotationElement, documentedName), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, innerAnnotationName), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, suppressWarningsName)); + + // Test TypeElement API + TypeElement documentedElement = elements.getTypeElement(documentedName); + TypeElement innerAnnotationElement = elements.getTypeElement(innerAnnotationName); + TypeElement suppressWarningsElement = elements.getTypeElement(suppressWarningsName); + isAnnotationPresentAsserts( + MoreElements.isAnnotationPresent(annotatedAnnotationElement, documentedElement), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, innerAnnotationElement), + MoreElements.isAnnotationPresent(annotatedAnnotationElement, suppressWarningsElement)); + } + + private void isAnnotationPresentAsserts( + boolean isDocumentedPresent, + boolean isInnerAnnotationPresent, + boolean isSuppressWarningsPresent) { + assertThat(isDocumentedPresent).isTrue(); + assertThat(isInnerAnnotationPresent).isTrue(); + assertThat(isSuppressWarningsPresent).isFalse(); } @Test public void getAnnotationMirror() { TypeElement element = - compilation.getElements().getTypeElement(AnnotatedAnnotation.class.getCanonicalName()); - - Optional<AnnotationMirror> documented = - MoreElements.getAnnotationMirror(element, Documented.class); - Optional<AnnotationMirror> innerAnnotation = - MoreElements.getAnnotationMirror(element, InnerAnnotation.class); - Optional<AnnotationMirror> suppressWarnings = - MoreElements.getAnnotationMirror(element, SuppressWarnings.class); - + elements.getTypeElement(AnnotatedAnnotation.class.getCanonicalName()); + + // Test Class API + getAnnotationMirrorAsserts( + MoreElements.getAnnotationMirror(element, Documented.class), + MoreElements.getAnnotationMirror(element, InnerAnnotation.class), + MoreElements.getAnnotationMirror(element, SuppressWarnings.class)); + + // Test String API + String documentedName = Documented.class.getCanonicalName(); + String innerAnnotationName = InnerAnnotation.class.getCanonicalName(); + String suppressWarningsName = SuppressWarnings.class.getCanonicalName(); + getAnnotationMirrorAsserts( + MoreElements.getAnnotationMirror(element, documentedName), + MoreElements.getAnnotationMirror(element, innerAnnotationName), + MoreElements.getAnnotationMirror(element, suppressWarningsName)); + + // Test TypeElement API + TypeElement documentedElement = elements.getTypeElement(documentedName); + TypeElement innerAnnotationElement = elements.getTypeElement(innerAnnotationName); + TypeElement suppressWarningsElement = elements.getTypeElement(suppressWarningsName); + getAnnotationMirrorAsserts( + MoreElements.getAnnotationMirror(element, documentedElement), + MoreElements.getAnnotationMirror(element, innerAnnotationElement), + MoreElements.getAnnotationMirror(element, suppressWarningsElement)); + } + + private void getAnnotationMirrorAsserts( + Optional<AnnotationMirror> documented, + Optional<AnnotationMirror> innerAnnotation, + Optional<AnnotationMirror> suppressWarnings) { expect.that(documented).isPresent(); expect.that(innerAnnotation).isPresent(); expect.that(suppressWarnings).isAbsent(); Element annotationElement = documented.get().getAnnotationType().asElement(); expect.that(MoreElements.isType(annotationElement)).isTrue(); - expect.that(MoreElements.asType(annotationElement).getQualifiedName().toString()) + expect + .that(MoreElements.asType(annotationElement).getQualifiedName().toString()) .isEqualTo(Documented.class.getCanonicalName()); annotationElement = innerAnnotation.get().getAnnotationType().asElement(); expect.that(MoreElements.isType(annotationElement)).isTrue(); - expect.that(MoreElements.asType(annotationElement).getQualifiedName().toString()) + expect + .that(MoreElements.asType(annotationElement).getQualifiedName().toString()) .isEqualTo(InnerAnnotation.class.getCanonicalName()); } @@ -231,6 +287,7 @@ public class MoreElementsTest { abstract String foo(); + @SuppressWarnings("unused") private void privateMethod() {} } @@ -259,7 +316,6 @@ public class MoreElementsTest { @Test public void getLocalAndInheritedMethods_Old() { - Elements elements = compilation.getElements(); Types types = compilation.getTypes(); TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT); TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG); @@ -270,19 +326,20 @@ public class MoreElementsTest { Set<ExecutableElement> objectMethods = visibleMethodsFromObject(); assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods); Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods); - assertThat(nonObjectMethods).containsExactly( + assertThat(nonObjectMethods) + .containsExactly( getMethod(ParentInterface.class, "bar", longMirror), getMethod(ParentClass.class, "foo"), getMethod(Child.class, "bar"), getMethod(Child.class, "baz"), getMethod(Child.class, "buh", intMirror), getMethod(Child.class, "buh", intMirror, intMirror)) - .inOrder();; + .inOrder(); + ; } @Test public void getLocalAndInheritedMethods() { - Elements elements = compilation.getElements(); Types types = compilation.getTypes(); TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT); TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG); @@ -293,7 +350,8 @@ public class MoreElementsTest { Set<ExecutableElement> objectMethods = visibleMethodsFromObject(); assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods); Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods); - assertThat(nonObjectMethods).containsExactly( + assertThat(nonObjectMethods) + .containsExactly( getMethod(ParentInterface.class, "bar", longMirror), getMethod(ParentClass.class, "foo"), getMethod(Child.class, "bar"), @@ -305,7 +363,6 @@ public class MoreElementsTest { @Test public void getAllMethods() { - Elements elements = compilation.getElements(); Types types = compilation.getTypes(); TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT); TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG); @@ -316,7 +373,8 @@ public class MoreElementsTest { Set<ExecutableElement> objectMethods = allMethodsFromObject(); assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods); Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods); - assertThat(nonObjectMethods).containsExactly( + assertThat(nonObjectMethods) + .containsExactly( getMethod(ParentInterface.class, "staticMethod"), getMethod(ParentInterface.class, "bar", longMirror), getMethod(ParentClass.class, "staticMethod"), @@ -355,10 +413,9 @@ public class MoreElementsTest { // Example from https://github.com/williamlian/daggerbug @Test public void getLocalAndInheritedMethods_DaggerBug() { - Elements elementUtils = compilation.getElements(); - TypeElement main = elementUtils.getTypeElement(Main.ParentComponent.class.getCanonicalName()); - Set<ExecutableElement> methods = MoreElements.getLocalAndInheritedMethods( - main, compilation.getTypes(), elementUtils); + TypeElement main = elements.getTypeElement(Main.ParentComponent.class.getCanonicalName()); + Set<ExecutableElement> methods = + MoreElements.getLocalAndInheritedMethods(main, compilation.getTypes(), elements); assertThat(methods).hasSize(1); ExecutableElement method = methods.iterator().next(); assertThat(method.getSimpleName().toString()).isEqualTo("injectable"); @@ -404,7 +461,7 @@ public class MoreElementsTest { } private ExecutableElement getMethod(Class<?> c, String methodName, TypeMirror... parameterTypes) { - TypeElement type = compilation.getElements().getTypeElement(c.getCanonicalName()); + TypeElement type = elements.getTypeElement(c.getCanonicalName()); Types types = compilation.getTypes(); ExecutableElement found = null; for (ExecutableElement method : ElementFilter.methodsIn(type.getEnclosedElements())) { @@ -423,7 +480,7 @@ public class MoreElementsTest { } } assertWithMessage(methodName + Arrays.toString(parameterTypes)).that(found).isNotNull(); - return found; + return requireNonNull(found); } private abstract static class AbstractAbstractList extends AbstractList<String> {} @@ -458,8 +515,6 @@ public class MoreElementsTest { // are implemented in AbstractList. @Test public void getLocalAndInheritedMethods_AbstractList() { - Elements elements = compilation.getElements(); - TypeElement abstractType = elements.getTypeElement(AbstractAbstractList.class.getCanonicalName()); Set<ExecutableElement> abstractTypeMethods = diff --git a/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java b/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java index 05a0a119..7cd7865d 100644 --- a/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java +++ b/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java @@ -43,13 +43,15 @@ public class MoreTypesIsTypeOfTest { private Elements elements; - @Before public void setUp() { + @Before + public void setUp() { this.elements = compilationRule.getElements(); } private interface TestType {} - @Test public void isTypeOf_DeclaredType() { + @Test + public void isTypeOf_declaredType() { assertTrue(MoreTypes.isType(typeElementFor(TestType.class).asType())); assertWithMessage("mirror represents the TestType") .that(MoreTypes.isTypeOf(TestType.class, typeElementFor(TestType.class).asType())) @@ -63,7 +65,8 @@ public class MoreTypesIsTypeOfTest { String[] array(); } - @Test public void isTypeOf_ArrayType() { + @Test + public void isTypeOf_arrayType() { assertTrue(MoreTypes.isType(typeElementFor(ArrayType.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(ArrayType.class)); assertWithMessage("array mirror represents an array Class object") @@ -75,7 +78,8 @@ public class MoreTypesIsTypeOfTest { boolean method(); } - @Test public void isTypeOf_PrimitiveBoolean() { + @Test + public void isTypeOf_primitiveBoolean() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveBoolean.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveBoolean.class)); assertWithMessage("mirror of a boolean").that(MoreTypes.isTypeOf(Boolean.TYPE, type)).isTrue(); @@ -85,7 +89,8 @@ public class MoreTypesIsTypeOfTest { byte method(); } - @Test public void isTypeOf_PrimitiveByte() { + @Test + public void isTypeOf_primitiveByte() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveByte.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveByte.class)); assertWithMessage("mirror of a byte").that(MoreTypes.isTypeOf(Byte.TYPE, type)).isTrue(); @@ -95,7 +100,8 @@ public class MoreTypesIsTypeOfTest { char method(); } - @Test public void isTypeOf_PrimitiveChar() { + @Test + public void isTypeOf_primitiveChar() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveChar.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveChar.class)); assertWithMessage("mirror of a char").that(MoreTypes.isTypeOf(Character.TYPE, type)).isTrue(); @@ -105,7 +111,8 @@ public class MoreTypesIsTypeOfTest { double method(); } - @Test public void isTypeOf_PrimitiveDouble() { + @Test + public void isTypeOf_primitiveDouble() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveDouble.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveDouble.class)); assertWithMessage("mirror of a double").that(MoreTypes.isTypeOf(Double.TYPE, type)).isTrue(); @@ -115,7 +122,8 @@ public class MoreTypesIsTypeOfTest { float method(); } - @Test public void isTypeOf_PrimitiveFloat() { + @Test + public void isTypeOf_primitiveFloat() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveFloat.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveFloat.class)); assertWithMessage("mirror of a float").that(MoreTypes.isTypeOf(Float.TYPE, type)).isTrue(); @@ -125,7 +133,8 @@ public class MoreTypesIsTypeOfTest { int method(); } - @Test public void isTypeOf_PrimitiveInt() { + @Test + public void isTypeOf_primitiveInt() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveInt.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveInt.class)); assertWithMessage("mirror of a int").that(MoreTypes.isTypeOf(Integer.TYPE, type)).isTrue(); @@ -135,7 +144,8 @@ public class MoreTypesIsTypeOfTest { long method(); } - @Test public void isTypeOf_PrimitiveLong() { + @Test + public void isTypeOf_primitiveLong() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveLong.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveLong.class)); assertWithMessage("mirror of a long").that(MoreTypes.isTypeOf(Long.TYPE, type)).isTrue(); @@ -145,7 +155,8 @@ public class MoreTypesIsTypeOfTest { short method(); } - @Test public void isTypeOf_PrimitiveShort() { + @Test + public void isTypeOf_primitiveShort() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveShort.class).asType())); TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveShort.class)); assertWithMessage("mirror of a short").that(MoreTypes.isTypeOf(Short.TYPE, type)).isTrue(); @@ -155,7 +166,8 @@ public class MoreTypesIsTypeOfTest { void method(); } - @Test public void isTypeOf_void() { + @Test + public void isTypeOf_primitiveVoid() { assertTrue(MoreTypes.isType(typeElementFor(PrimitiveVoid.class).asType())); TypeMirror primitive = extractReturnTypeFromHolder(typeElementFor(PrimitiveVoid.class)); assertWithMessage("mirror of a void").that(MoreTypes.isTypeOf(Void.TYPE, primitive)).isTrue(); @@ -165,21 +177,25 @@ public class MoreTypesIsTypeOfTest { Void method(); } - @Test public void isTypeOf_Void() { + @Test + public void isTypeOf_declaredVoid() { assertTrue(MoreTypes.isType(typeElementFor(DeclaredVoid.class).asType())); TypeMirror declared = extractReturnTypeFromHolder(typeElementFor(DeclaredVoid.class)); assertWithMessage("mirror of a void").that(MoreTypes.isTypeOf(Void.class, declared)).isTrue(); } - @Test public void isTypeOf_fail() { - assertFalse(MoreTypes.isType( - getOnlyElement(typeElementFor(DeclaredVoid.class).getEnclosedElements()).asType())); + @Test + public void isTypeOf_fail() { + assertFalse( + MoreTypes.isType( + getOnlyElement(typeElementFor(DeclaredVoid.class).getEnclosedElements()).asType())); TypeMirror method = getOnlyElement(typeElementFor(DeclaredVoid.class).getEnclosedElements()).asType(); try { MoreTypes.isTypeOf(String.class, method); fail(); - } catch (IllegalArgumentException expected) {} + } catch (IllegalArgumentException expected) { + } } // Utility methods for this test. diff --git a/common/src/test/java/com/google/auto/common/MoreTypesTest.java b/common/src/test/java/com/google/auto/common/MoreTypesTest.java index 3cd360db..b8e84e08 100644 --- a/common/src/test/java/com/google/auto/common/MoreTypesTest.java +++ b/common/src/test/java/com/google/auto/common/MoreTypesTest.java @@ -16,11 +16,12 @@ package com.google.auto.common; import static com.google.common.truth.Truth.assertThat; +import static java.util.Objects.requireNonNull; import static javax.lang.model.type.TypeKind.NONE; import static javax.lang.model.type.TypeKind.VOID; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.fail; -import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; @@ -49,6 +50,7 @@ import javax.lang.model.type.WildcardType; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -90,48 +92,51 @@ public class MoreTypesTest { DeclaredType containerOfString = types.getDeclaredType(container, stringType); TypeMirror containedInObject = types.asMemberOf(containerOfObject, contained); TypeMirror containedInString = types.asMemberOf(containerOfString, contained); - EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) - .addEquivalenceGroup(types.getNullType()) - .addEquivalenceGroup(types.getNoType(NONE)) - .addEquivalenceGroup(types.getNoType(VOID)) - .addEquivalenceGroup(objectType) - .addEquivalenceGroup(stringType) - .addEquivalenceGroup(containedInObject) - .addEquivalenceGroup(containedInString) - .addEquivalenceGroup(funkyBounds.asType()) - .addEquivalenceGroup(funkyBounds2.asType()) - .addEquivalenceGroup(funkierBounds.asType()) - .addEquivalenceGroup(funkyBoundsVar, funkyBounds2Var) - .addEquivalenceGroup(funkierBoundsVar) - // Enum<E extends Enum<E>> - .addEquivalenceGroup(enumElement.asType()) - // Map<K, V> - .addEquivalenceGroup(mapType) - .addEquivalenceGroup(mapOfObjectToObjectType) - // Map<?, ?> - .addEquivalenceGroup(types.getDeclaredType(mapElement, wildcard, wildcard)) - // Map - .addEquivalenceGroup(types.erasure(mapType), types.erasure(mapOfObjectToObjectType)) - .addEquivalenceGroup(types.getDeclaredType(mapElement, objectType, stringType)) - .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, objectType)) - .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, stringType)) - .addEquivalenceGroup(setOfSetOfObject) - .addEquivalenceGroup(setOfSetOfString) - .addEquivalenceGroup(setOfSetOfSetOfObject) - .addEquivalenceGroup(setOfSetOfSetOfString) - .addEquivalenceGroup(wildcard) - // ? extends Object - .addEquivalenceGroup(types.getWildcardType(objectType, null)) - // ? extends String - .addEquivalenceGroup(types.getWildcardType(stringType, null)) - // ? super String - .addEquivalenceGroup(types.getWildcardType(null, stringType)) - // Map<String, Map<String, Set<Object>>> - .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, - types.getDeclaredType(mapElement, stringType, - types.getDeclaredType(setElement, objectType)))) - .addEquivalenceGroup(FAKE_ERROR_TYPE) - ; + EquivalenceTester<TypeMirror> tester = + EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) + .addEquivalenceGroup(types.getNullType()) + .addEquivalenceGroup(types.getNoType(NONE)) + .addEquivalenceGroup(types.getNoType(VOID)) + .addEquivalenceGroup(objectType) + .addEquivalenceGroup(stringType) + .addEquivalenceGroup(containedInObject) + .addEquivalenceGroup(containedInString) + .addEquivalenceGroup(funkyBounds.asType()) + .addEquivalenceGroup(funkyBounds2.asType()) + .addEquivalenceGroup(funkierBounds.asType()) + .addEquivalenceGroup(funkyBoundsVar, funkyBounds2Var) + .addEquivalenceGroup(funkierBoundsVar) + // Enum<E extends Enum<E>> + .addEquivalenceGroup(enumElement.asType()) + // Map<K, V> + .addEquivalenceGroup(mapType) + .addEquivalenceGroup(mapOfObjectToObjectType) + // Map<?, ?> + .addEquivalenceGroup(types.getDeclaredType(mapElement, wildcard, wildcard)) + // Map + .addEquivalenceGroup(types.erasure(mapType), types.erasure(mapOfObjectToObjectType)) + .addEquivalenceGroup(types.getDeclaredType(mapElement, objectType, stringType)) + .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, objectType)) + .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, stringType)) + .addEquivalenceGroup(setOfSetOfObject) + .addEquivalenceGroup(setOfSetOfString) + .addEquivalenceGroup(setOfSetOfSetOfObject) + .addEquivalenceGroup(setOfSetOfSetOfString) + .addEquivalenceGroup(wildcard) + // ? extends Object + .addEquivalenceGroup(types.getWildcardType(objectType, null)) + // ? extends String + .addEquivalenceGroup(types.getWildcardType(stringType, null)) + // ? super String + .addEquivalenceGroup(types.getWildcardType(null, stringType)) + // Map<String, Map<String, Set<Object>>> + .addEquivalenceGroup( + types.getDeclaredType( + mapElement, + stringType, + types.getDeclaredType( + mapElement, stringType, types.getDeclaredType(setElement, objectType)))) + .addEquivalenceGroup(FAKE_ERROR_TYPE); for (TypeKind kind : TypeKind.values()) { if (kind.isPrimitive()) { @@ -144,20 +149,18 @@ public class MoreTypesTest { } } - ImmutableSet<Class<?>> testClasses = ImmutableSet.of( - ExecutableElementsGroupA.class, - ExecutableElementsGroupB.class, - ExecutableElementsGroupC.class, - ExecutableElementsGroupD.class, - ExecutableElementsGroupE.class); + ImmutableSet<Class<?>> testClasses = + ImmutableSet.of( + ExecutableElementsGroupA.class, + ExecutableElementsGroupB.class, + ExecutableElementsGroupC.class, + ExecutableElementsGroupD.class, + ExecutableElementsGroupE.class); for (Class<?> testClass : testClasses) { - ImmutableList<TypeMirror> equivalenceGroup = FluentIterable.from( - elements.getTypeElement(testClass.getCanonicalName()).getEnclosedElements()) - .transform(new Function<Element, TypeMirror>() { - @Override public TypeMirror apply(Element input) { - return input.asType(); - } - }) + ImmutableList<TypeMirror> equivalenceGroup = + FluentIterable.from( + elements.getTypeElement(testClass.getCanonicalName()).getEnclosedElements()) + .transform(Element::asType) .toList(); tester.addEquivalenceGroup(equivalenceGroup); } @@ -168,35 +171,45 @@ public class MoreTypesTest { @SuppressWarnings("unused") private static final class ExecutableElementsGroupA { ExecutableElementsGroupA() {} + void a() {} + public static void b() {} } @SuppressWarnings("unused") private static final class ExecutableElementsGroupB { ExecutableElementsGroupB(String s) {} + void a(String s) {} + public static void b(String s) {} } @SuppressWarnings("unused") private static final class ExecutableElementsGroupC { ExecutableElementsGroupC() throws Exception {} + void a() throws Exception {} + public static void b() throws Exception {} } @SuppressWarnings("unused") private static final class ExecutableElementsGroupD { ExecutableElementsGroupD() throws RuntimeException {} + void a() throws RuntimeException {} + public static void b() throws RuntimeException {} } @SuppressWarnings("unused") private static final class ExecutableElementsGroupE { <T> ExecutableElementsGroupE() {} + <T> void a() {} + public static <T> void b() {} } @@ -214,53 +227,44 @@ public class MoreTypesTest { @SuppressWarnings("unused") private static final class FunkierBounds<T extends Number & Comparable<T> & Cloneable> {} - @Test public void testReferencedTypes() { + @Test + public void testReferencedTypes() { Elements elements = compilationRule.getElements(); - TypeElement testDataElement = elements - .getTypeElement(ReferencedTypesTestData.class.getCanonicalName()); + TypeElement testDataElement = + elements.getTypeElement(ReferencedTypesTestData.class.getCanonicalName()); ImmutableMap<String, VariableElement> fieldIndex = FluentIterable.from(ElementFilter.fieldsIn(testDataElement.getEnclosedElements())) - .uniqueIndex(new Function<VariableElement, String>() { - @Override public String apply(VariableElement input) { - return input.getSimpleName().toString(); - } - }); - - TypeElement objectElement = - elements.getTypeElement(Object.class.getCanonicalName()); - TypeElement stringElement = - elements.getTypeElement(String.class.getCanonicalName()); - TypeElement integerElement = - elements.getTypeElement(Integer.class.getCanonicalName()); - TypeElement setElement = - elements.getTypeElement(Set.class.getCanonicalName()); - TypeElement mapElement = - elements.getTypeElement(Map.class.getCanonicalName()); + .uniqueIndex(input -> input.getSimpleName().toString()); + + TypeElement objectElement = elements.getTypeElement(Object.class.getCanonicalName()); + TypeElement stringElement = elements.getTypeElement(String.class.getCanonicalName()); + TypeElement integerElement = elements.getTypeElement(Integer.class.getCanonicalName()); + TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName()); + TypeElement mapElement = elements.getTypeElement(Map.class.getCanonicalName()); TypeElement charSequenceElement = elements.getTypeElement(CharSequence.class.getCanonicalName()); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f1").asType())) - .containsExactly(objectElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f2").asType())) - .containsExactly(setElement, stringElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f3").asType())) + assertThat(referencedTypes(fieldIndex, "f1")).containsExactly(objectElement); + assertThat(referencedTypes(fieldIndex, "f2")).containsExactly(setElement, stringElement); + assertThat(referencedTypes(fieldIndex, "f3")) .containsExactly(mapElement, stringElement, objectElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f4").asType())) - .containsExactly(integerElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f5").asType())) - .containsExactly(setElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f6").asType())) - .containsExactly(setElement, charSequenceElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f7").asType())) + assertThat(referencedTypes(fieldIndex, "f4")).containsExactly(integerElement); + assertThat(referencedTypes(fieldIndex, "f5")).containsExactly(setElement); + assertThat(referencedTypes(fieldIndex, "f6")).containsExactly(setElement, charSequenceElement); + assertThat(referencedTypes(fieldIndex, "f7")) .containsExactly(mapElement, stringElement, setElement, charSequenceElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f8").asType())) - .containsExactly(stringElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f9").asType())) - .containsExactly(stringElement); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f10").asType())).isEmpty(); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f11").asType())).isEmpty(); - assertThat(MoreTypes.referencedTypes(fieldIndex.get("f12").asType())) - .containsExactly(setElement, stringElement); + assertThat(referencedTypes(fieldIndex, "f8")).containsExactly(stringElement); + assertThat(referencedTypes(fieldIndex, "f9")).containsExactly(stringElement); + assertThat(referencedTypes(fieldIndex, "f10")).isEmpty(); + assertThat(referencedTypes(fieldIndex, "f11")).isEmpty(); + assertThat(referencedTypes(fieldIndex, "f12")).containsExactly(setElement, stringElement); + } + + private static ImmutableSet<TypeElement> referencedTypes( + ImmutableMap<String, VariableElement> fieldIndex, String fieldName) { + VariableElement field = fieldIndex.get(fieldName); + requireNonNull(field, fieldName); + return MoreTypes.referencedTypes(field.asType()); } @SuppressWarnings("unused") // types used in compiler tests @@ -280,20 +284,23 @@ public class MoreTypesTest { } private static class Parent<T> {} + private static class ChildA extends Parent<Number> {} + private static class ChildB extends Parent<String> {} + private static class GenericChild<T> extends Parent<T> {} + private interface InterfaceType {} @Test public void asElement_throws() { - TypeMirror javaDotLang = - compilationRule.getElements().getPackageElement("java.lang").asType(); + TypeMirror javaDotLang = compilationRule.getElements().getPackageElement("java.lang").asType(); try { MoreTypes.asElement(javaDotLang); fail(); - } catch (IllegalArgumentException expected) {} - + } catch (IllegalArgumentException expected) { + } } @Test @@ -301,8 +308,9 @@ public class MoreTypesTest { Elements elements = compilationRule.getElements(); TypeElement stringElement = elements.getTypeElement("java.lang.String"); assertThat(MoreTypes.asElement(stringElement.asType())).isEqualTo(stringElement); - TypeParameterElement setParameterElement = Iterables.getOnlyElement( - compilationRule.getElements().getTypeElement("java.util.Set").getTypeParameters()); + TypeParameterElement setParameterElement = + Iterables.getOnlyElement( + compilationRule.getElements().getTypeElement("java.util.Set").getTypeParameters()); assertThat(MoreTypes.asElement(setParameterElement.asType())).isEqualTo(setParameterElement); // we don't test error types because those are very hard to get predictably } @@ -320,8 +328,7 @@ public class MoreTypesTest { TypeElement genericChild = elements.getTypeElement(GenericChild.class.getCanonicalName()); TypeMirror genericChildOfNumber = types.getDeclaredType(genericChild, numberType); TypeMirror genericChildOfInteger = types.getDeclaredType(genericChild, integerType); - TypeMirror objectType = - elements.getTypeElement(Object.class.getCanonicalName()).asType(); + TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType(); TypeMirror interfaceType = elements.getTypeElement(InterfaceType.class.getCanonicalName()).asType(); @@ -343,18 +350,20 @@ public class MoreTypesTest { Optional<DeclaredType> parentOfGenericChildOfInteger = MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChildOfInteger); - EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) - .addEquivalenceGroup(parentOfChildA.get(), - types.getDeclaredType(parent, numberType), - parentOfGenericChildOfNumber.get()) - .addEquivalenceGroup(parentOfChildB.get(), types.getDeclaredType(parent, stringType)) - .addEquivalenceGroup(parentOfGenericChild.get(), parent.asType()) - .addEquivalenceGroup(parentOfGenericChildOfInteger.get(), - types.getDeclaredType(parent, integerType)); + EquivalenceTester<TypeMirror> tester = + EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) + .addEquivalenceGroup( + parentOfChildA.get(), + types.getDeclaredType(parent, numberType), + parentOfGenericChildOfNumber.get()) + .addEquivalenceGroup(parentOfChildB.get(), types.getDeclaredType(parent, stringType)) + .addEquivalenceGroup(parentOfGenericChild.get(), parent.asType()) + .addEquivalenceGroup( + parentOfGenericChildOfInteger.get(), types.getDeclaredType(parent, integerType)); tester.test(); } - + @Test public void testAsMemberOf_variableElement() { Types types = compilationRule.getTypes(); @@ -364,11 +373,13 @@ public class MoreTypesTest { TypeMirror integerType = elements.getTypeElement(Integer.class.getCanonicalName()).asType(); TypeElement paramsElement = elements.getTypeElement(Params.class.getCanonicalName()); - VariableElement tParam = Iterables.getOnlyElement(Iterables.getOnlyElement( - ElementFilter.methodsIn(paramsElement.getEnclosedElements())).getParameters()); + VariableElement tParam = + Iterables.getOnlyElement( + Iterables.getOnlyElement(ElementFilter.methodsIn(paramsElement.getEnclosedElements())) + .getParameters()); VariableElement tField = - Iterables.getOnlyElement(ElementFilter.fieldsIn(paramsElement.getEnclosedElements())); - + Iterables.getOnlyElement(ElementFilter.fieldsIn(paramsElement.getEnclosedElements())); + DeclaredType numberParams = (DeclaredType) elements.getTypeElement(NumberParams.class.getCanonicalName()).asType(); DeclaredType stringParams = @@ -376,7 +387,7 @@ public class MoreTypesTest { TypeElement genericParams = elements.getTypeElement(GenericParams.class.getCanonicalName()); DeclaredType genericParamsOfNumber = types.getDeclaredType(genericParams, numberType); DeclaredType genericParamsOfInteger = types.getDeclaredType(genericParams, integerType); - + TypeMirror fieldOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tField); TypeMirror paramOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tParam); TypeMirror fieldOfStringParams = MoreTypes.asMemberOf(types, stringParams, tField); @@ -388,62 +399,76 @@ public class MoreTypesTest { TypeMirror paramOfGenericOfInteger = MoreTypes.asMemberOf(types, genericParamsOfInteger, tParam); - EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) - .addEquivalenceGroup(fieldOfNumberParams, paramOfNumberParams, fieldOfGenericOfNumber, - paramOfGenericOfNumber, numberType) - .addEquivalenceGroup(fieldOfStringParams, paramOfStringParams, stringType) - .addEquivalenceGroup(fieldOfGenericOfInteger, paramOfGenericOfInteger, integerType); + EquivalenceTester<TypeMirror> tester = + EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence()) + .addEquivalenceGroup( + fieldOfNumberParams, + paramOfNumberParams, + fieldOfGenericOfNumber, + paramOfGenericOfNumber, + numberType) + .addEquivalenceGroup(fieldOfStringParams, paramOfStringParams, stringType) + .addEquivalenceGroup(fieldOfGenericOfInteger, paramOfGenericOfInteger, integerType); tester.test(); } - - private static class Params<T> { - @SuppressWarnings("unused") T t; - @SuppressWarnings("unused") void add(T t) {} - } - private static class NumberParams extends Params<Number> {} - private static class StringParams extends Params<String> {} - private static class GenericParams<T> extends Params<T> {} - - private static final ErrorType FAKE_ERROR_TYPE = new ErrorType() { - @Override - public TypeKind getKind() { - return TypeKind.ERROR; - } - @Override - public <R, P> R accept(TypeVisitor<R, P> v, P p) { - return v.visitError(this, p); - } - - @Override - public List<? extends TypeMirror> getTypeArguments() { - return ImmutableList.of(); - } - - @Override - public TypeMirror getEnclosingType() { - return null; - } + private static class Params<T> { + @SuppressWarnings("unused") + T t; - @Override - public Element asElement() { - return null; - } + @SuppressWarnings("unused") + void add(T t) {} + } - // JDK8 Compatibility: + private static class NumberParams extends Params<Number> {} - public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { - return null; - } + private static class StringParams extends Params<String> {} - public <A extends Annotation> A getAnnotation(Class<A> annotationType) { - return null; - } + private static class GenericParams<T> extends Params<T> {} - public List<? extends AnnotationMirror> getAnnotationMirrors() { - return null; - } - }; + private static final ErrorType FAKE_ERROR_TYPE = + new ErrorType() { + @Override + public TypeKind getKind() { + return TypeKind.ERROR; + } + + @Override + public <R, P> R accept(TypeVisitor<R, P> v, P p) { + return v.visitError(this, p); + } + + @Override + public ImmutableList<? extends TypeMirror> getTypeArguments() { + return ImmutableList.of(); + } + + @Override + public @Nullable TypeMirror getEnclosingType() { + return null; + } + + @Override + public @Nullable Element asElement() { + return null; + } + + @Override + public <A extends Annotation> A @Nullable [] getAnnotationsByType(Class<A> annotationType) { + return null; + } + + @Override + public <A extends Annotation> @Nullable A getAnnotation(Class<A> annotationType) { + return null; + } + + @Override + @SuppressWarnings("MutableMethodReturnType") + public List<? extends AnnotationMirror> getAnnotationMirrors() { + return ImmutableList.of(); + } + }; @Test public void testIsConversionFromObjectUnchecked_yes() { @@ -471,6 +496,21 @@ public class MoreTypesTest { } } + @Test + public void testIsTypeOf() { + Types types = compilationRule.getTypes(); + PrimitiveType intType = types.getPrimitiveType(TypeKind.INT); + TypeMirror integerType = types.boxedClass(intType).asType(); + WildcardType wildcardType = types.getWildcardType(null, null); + expect.that(MoreTypes.isTypeOf(int.class, intType)).isTrue(); + expect.that(MoreTypes.isTypeOf(Integer.class, integerType)).isTrue(); + expect.that(MoreTypes.isTypeOf(Integer.class, intType)).isFalse(); + expect.that(MoreTypes.isTypeOf(int.class, integerType)).isFalse(); + expect.that(MoreTypes.isTypeOf(Integer.class, FAKE_ERROR_TYPE)).isFalse(); + assertThrows( + IllegalArgumentException.class, () -> MoreTypes.isTypeOf(Integer.class, wildcardType)); + } + // The type of every field here is such that casting to it provokes an "unchecked" warning. @SuppressWarnings("unused") private static class Unchecked<T> { diff --git a/common/src/test/java/com/google/auto/common/OverridesTest.java b/common/src/test/java/com/google/auto/common/OverridesTest.java index afb79760..c5ccc5f6 100644 --- a/common/src/test/java/com/google/auto/common/OverridesTest.java +++ b/common/src/test/java/com/google/auto/common/OverridesTest.java @@ -17,6 +17,7 @@ package com.google.auto.common; import static com.google.common.truth.Truth.assertThat; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Objects.requireNonNull; import static javax.lang.model.util.ElementFilter.methodsIn; import com.google.common.base.Converter; @@ -57,6 +58,7 @@ import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler; +import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -103,6 +105,7 @@ public class OverridesTest { abstract void initUtils(OverridesTest test); } + private final CompilerType compilerType; private Types typeUtils; @@ -126,12 +129,15 @@ public class OverridesTest { static class TypesForInheritance { interface One { void m(); + void m(String x); + void n(); } interface Two { void m(); + void m(int x); } @@ -142,28 +148,50 @@ public class OverridesTest { static class ChildOfParent extends Parent {} static class ChildOfOne implements One { - @Override public void m() {} - @Override public void m(String x) {} - @Override public void n() {} + @Override + public void m() {} + + @Override + public void m(String x) {} + + @Override + public void n() {} } static class ChildOfOneAndTwo implements One, Two { - @Override public void m() {} - @Override public void m(String x) {} - @Override public void m(int x) {} - @Override public void n() {} + @Override + public void m() {} + + @Override + public void m(String x) {} + + @Override + public void m(int x) {} + + @Override + public void n() {} } static class ChildOfParentAndOne extends Parent implements One { - @Override public void m() {} - @Override public void m(String x) {} - @Override public void n() {} + @Override + public void m() {} + + @Override + public void m(String x) {} + + @Override + public void n() {} } static class ChildOfParentAndOneAndTwo extends Parent implements One, Two { - @Override public void m(String x) {} - @Override public void m(int x) {} - @Override public void n() {} + @Override + public void m(String x) {} + + @Override + public void m(int x) {} + + @Override + public void n() {} } abstract static class AbstractChildOfOne implements One {} @@ -194,14 +222,20 @@ public class OverridesTest { abstract static class BindingDeclaration implements HasKey { abstract Optional<Element> bindingElement(); + abstract Optional<TypeElement> contributingModule(); } - abstract static class MultibindingDeclaration - extends BindingDeclaration implements HasBindingType, HasContributionType { - @Override public abstract Key key(); - @Override public abstract ContributionType contributionType(); - @Override public abstract BindingType bindingType(); + abstract static class MultibindingDeclaration extends BindingDeclaration + implements HasBindingType, HasContributionType { + @Override + public abstract Key key(); + + @Override + public abstract ContributionType contributionType(); + + @Override + public abstract BindingType bindingType(); } } @@ -221,16 +255,26 @@ public class OverridesTest { } static class TypesForGenerics { - interface XCollection<E> { + interface GCollection<E> { boolean add(E x); } - interface XList<E> extends XCollection<E> { - @Override public boolean add(E x); + interface GList<E> extends GCollection<E> { + @Override + boolean add(E x); } - static class StringList implements XList<String> { - @Override public boolean add(String x) { + static class StringList implements GList<String> { + @Override + public boolean add(String x) { + return false; + } + } + + @SuppressWarnings("rawtypes") + static class RawList implements GList { + @Override + public boolean add(Object x) { return false; } } @@ -243,7 +287,8 @@ public class OverridesTest { } static class RawChildOfRaw extends RawParent { - @Override void frob(List x) {} + @Override + void frob(List x) {} } static class NonRawParent { @@ -251,7 +296,8 @@ public class OverridesTest { } static class RawChildOfNonRaw extends NonRawParent { - @Override void frob(List x) {} + @Override + void frob(List x) {} } } @@ -291,8 +337,9 @@ public class OverridesTest { // since the two Es are not the same. @Test public void overridesDiamond() { - checkOverridesInSet(ImmutableSet.<Class<?>>of( - Collection.class, List.class, AbstractCollection.class, AbstractList.class)); + checkOverridesInSet( + ImmutableSet.<Class<?>>of( + Collection.class, List.class, AbstractCollection.class, AbstractList.class)); } private void checkOverridesInContainedClasses(Class<?> container) { @@ -324,10 +371,13 @@ public class OverridesTest { expect .withMessage( "%s.%s overrides %s.%s in %s: javac says %s, we say %s", - overrider.getEnclosingElement(), overrider, - overridden.getEnclosingElement(), overridden, + overrider.getEnclosingElement(), + overrider, + overridden.getEnclosingElement(), + overridden, in, - javacSays, weSay) + javacSays, + weSay) .fail(); } } @@ -355,7 +405,7 @@ public class OverridesTest { } } assertThat(found).isNotNull(); - return found; + return requireNonNull(found); } // These skeletal parallels to the real collection classes ensure that the test is independent @@ -375,8 +425,8 @@ public class OverridesTest { } } - private abstract static class XAbstractList<E> - extends XAbstractCollection<E> implements XList<E> { + private abstract static class XAbstractList<E> extends XAbstractCollection<E> + implements XList<E> { @Override public boolean add(E e) { return true; @@ -440,7 +490,7 @@ public class OverridesTest { extends Converter<String, Range<T>> { @Override protected String doBackward(Range<T> b) { - return null; + return ""; } } @@ -470,9 +520,8 @@ public class OverridesTest { explicitOverrides.methodFromSuperclasses(xAbstractStringList, add); assertThat(addInAbstractStringList).isNull(); - ExecutableElement addInStringList = - explicitOverrides.methodFromSuperclasses(xStringList, add); - assertThat(addInStringList.getEnclosingElement()).isEqualTo(xAbstractList); + ExecutableElement addInStringList = explicitOverrides.methodFromSuperclasses(xStringList, add); + assertThat(requireNonNull(addInStringList).getEnclosingElement()).isEqualTo(xAbstractList); } @Test @@ -487,20 +536,21 @@ public class OverridesTest { ExecutableElement addInAbstractStringList = explicitOverrides.methodFromSuperinterfaces(xAbstractStringList, add); - assertThat(addInAbstractStringList.getEnclosingElement()).isEqualTo(xCollection); + assertThat(requireNonNull(addInAbstractStringList).getEnclosingElement()) + .isEqualTo(xCollection); ExecutableElement addInNumberList = explicitOverrides.methodFromSuperinterfaces(xNumberList, add); - assertThat(addInNumberList.getEnclosingElement()).isEqualTo(xAbstractList); + assertThat(requireNonNull(addInNumberList).getEnclosingElement()).isEqualTo(xAbstractList); - ExecutableElement addInList = - explicitOverrides.methodFromSuperinterfaces(xList, add); - assertThat(addInList.getEnclosingElement()).isEqualTo(xCollection); + ExecutableElement addInList = explicitOverrides.methodFromSuperinterfaces(xList, add); + assertThat(requireNonNull(addInList).getEnclosingElement()).isEqualTo(xCollection); } - private void assertTypeListsEqual(List<TypeMirror> actual, List<TypeMirror> expected) { - assertThat(actual.size()).isEqualTo(expected.size()); - for (int i = 0; i < actual.size(); i++) { + private void assertTypeListsEqual(@Nullable List<TypeMirror> actual, List<TypeMirror> expected) { + requireNonNull(actual); + assertThat(actual).hasSize(expected.size()); + for (int i = 0; i < actual.size(); i++) { assertThat(typeUtils.isSameType(actual.get(i), expected.get(i))).isTrue(); } } @@ -552,10 +602,11 @@ public class OverridesTest { // it hard for ecj to find the boot class path. Elsewhere it is unnecessary but harmless. File rtJar = new File(StandardSystemProperty.JAVA_HOME.value() + "/lib/rt.jar"); if (rtJar.exists()) { - List<File> bootClassPath = ImmutableList.<File>builder() - .add(rtJar) - .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) - .build(); + List<File> bootClassPath = + ImmutableList.<File>builder() + .add(rtJar) + .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH)) + .build(); fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath); } Iterable<? extends JavaFileObject> sources = fileManager.getJavaFileObjects(dummySourceFile); @@ -583,8 +634,7 @@ public class OverridesTest { } @Override - public boolean process( - Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { ecjCompilation.elements = processingEnv.getElementUtils(); ecjCompilation.types = processingEnv.getTypeUtils(); @@ -643,24 +693,24 @@ public class OverridesTest { private static final TypeVisitor<String, Void> ERASED_STRING_TYPE_VISITOR = new SimpleTypeVisitor6<String, Void>() { - @Override - protected String defaultAction(TypeMirror e, Void p) { - return e.toString(); - } + @Override + protected String defaultAction(TypeMirror e, Void p) { + return e.toString(); + } - @Override - public String visitArray(ArrayType t, Void p) { - return visit(t.getComponentType()) + "[]"; - } + @Override + public String visitArray(ArrayType t, Void p) { + return visit(t.getComponentType()) + "[]"; + } - @Override - public String visitDeclared(DeclaredType t, Void p) { - return MoreElements.asType(t.asElement()).getQualifiedName().toString(); - } + @Override + public String visitDeclared(DeclaredType t, Void p) { + return MoreElements.asType(t.asElement()).getQualifiedName().toString(); + } - @Override - public String visitTypeVariable(TypeVariable t, Void p) { - return visit(t.getUpperBound()); - } - }; + @Override + public String visitTypeVariable(TypeVariable t, Void p) { + return visit(t.getUpperBound()); + } + }; } diff --git a/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java b/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java index d73e1b6c..0bad83db 100644 --- a/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java +++ b/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java @@ -46,6 +46,7 @@ public class SimpleAnnotationMirrorTest { @interface MultipleValues { int value1(); + int value2(); } diff --git a/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java b/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java index 4fc61b51..ea85365b 100644 --- a/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java +++ b/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java @@ -28,6 +28,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.SimpleAnnotationValueVisitor8; import javax.lang.model.util.Types; +import org.checkerframework.checker.nullness.qual.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -70,18 +71,21 @@ public class SimpleTypeAnnotationValueTest { @Test public void visitorMethod() { - SimpleTypeAnnotationValue.of(objectType).accept(new SimpleAnnotationValueVisitor8<Void, Void>(){ - @Override - public Void visitType(TypeMirror typeMirror, Void aVoid) { - // do nothing, expected case - return null; - } + SimpleTypeAnnotationValue.of(objectType) + .accept( + new SimpleAnnotationValueVisitor8<@Nullable Void, @Nullable Void>() { + @Override + public @Nullable Void visitType(TypeMirror typeMirror, @Nullable Void aVoid) { + // do nothing, expected case + return null; + } - @Override - protected Void defaultAction(Object o, Void aVoid) { - throw new AssertionError(); - } - }, null); + @Override + protected @Nullable Void defaultAction(Object o, @Nullable Void aVoid) { + throw new AssertionError(); + } + }, + null); } @Test diff --git a/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java b/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java index 15e54fff..c9bcf778 100644 --- a/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java +++ b/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java @@ -35,231 +35,263 @@ import org.junit.runners.JUnit4; public class SuperficialValidationTest { @Test public void missingReturnType() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "abstract class TestClass {", - " abstract MissingType blah();", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "abstract class TestClass {", + " abstract MissingType blah();", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingGenericReturnType() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "abstract class TestClass {", - " abstract MissingType<?> blah();", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "abstract class TestClass {", + " abstract MissingType<?> blah();", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingReturnTypeTypeParameter() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "import java.util.Map;", - "import java.util.Set;", - "", - "abstract class TestClass {", - " abstract Map<Set<?>, MissingType<?>> blah();", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "import java.util.Map;", + "import java.util.Set;", + "", + "abstract class TestClass {", + " abstract Map<Set<?>, MissingType<?>> blah();", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingTypeParameter() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "class TestClass<T extends MissingType> {}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", // + "package test;", + "", + "class TestClass<T extends MissingType> {}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingParameterType() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "abstract class TestClass {", - " abstract void foo(MissingType x);", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "abstract class TestClass {", + " abstract void foo(MissingType x);", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingAnnotation() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "@MissingAnnotation", - "class TestClass {}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", // + "package test;", + "", + "@MissingAnnotation", + "class TestClass {}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void handlesRecursiveTypeParams() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "class TestClass<T extends Comparable<T>> {}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", // + "package test;", + "", + "class TestClass<T extends Comparable<T>> {}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue(); + } + }) .compilesWithoutError(); } @Test public void handlesRecursiveType() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "abstract class TestClass {", - " abstract TestClass foo(TestClass x);", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "abstract class TestClass {", + " abstract TestClass foo(TestClass x);", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue(); + } + }) .compilesWithoutError(); } @Test public void missingWildcardBound() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "import java.util.Set;", - "", - "class TestClass {", - " Set<? extends MissingType> extendsTest() {", - " return null;", - " }", - "", - " Set<? super MissingType> superTest() {", - " return null;", - " }", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "import java.util.Set;", + "", + "class TestClass {", + " Set<? extends MissingType> extendsTest() {", + " return null;", + " }", + "", + " Set<? super MissingType> superTest() {", + " return null;", + " }", + "}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void missingIntersection() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines( - "test.TestClass", - "package test;", - "", - "class TestClass<T extends Number & Missing> {}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.TestClass", + "package test;", + "", + "class TestClass<T extends Number & Missing> {}"); assertAbout(javaSource()) .that(javaFileObject) - .processedWith(new AssertingProcessor() { - @Override void runAssertions() { - TypeElement testClassElement = - processingEnv.getElementUtils().getTypeElement("test.TestClass"); - assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); - } - }) + .processedWith( + new AssertingProcessor() { + @Override + void runAssertions() { + TypeElement testClassElement = + processingEnv.getElementUtils().getTypeElement("test.TestClass"); + assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse(); + } + }) .failsToCompile(); } @Test public void invalidAnnotationValue() { - JavaFileObject javaFileObject = JavaFileObjects.forSourceLines("test.Outer", - "package test;", - "", - "final class Outer {", - " @interface TestAnnotation {", - " Class[] classes();", - " }", - "", - " @TestAnnotation(classes = Foo)", - " static class TestClass {}", - "}"); + JavaFileObject javaFileObject = + JavaFileObjects.forSourceLines( + "test.Outer", + "package test;", + "", + "final class Outer {", + " @interface TestAnnotation {", + " Class[] classes();", + " }", + "", + " @TestAnnotation(classes = Foo)", + " static class TestClass {}", + "}"); assertAbout(javaSource()) .that(javaFileObject) .processedWith( diff --git a/common/src/test/java/com/google/auto/common/VisibilityTest.java b/common/src/test/java/com/google/auto/common/VisibilityTest.java index 6a80b7af..fc5e630b 100644 --- a/common/src/test/java/com/google/auto/common/VisibilityTest.java +++ b/common/src/test/java/com/google/auto/common/VisibilityTest.java @@ -39,9 +39,10 @@ public class VisibilityTest { public void packageVisibility() { assertThat(Visibility.ofElement(compilation.getElements().getPackageElement("java.lang"))) .isEqualTo(PUBLIC); - assertThat(Visibility.ofElement( - compilation.getElements().getPackageElement("com.google.auto.common"))) - .isEqualTo(PUBLIC); + assertThat( + Visibility.ofElement( + compilation.getElements().getPackageElement("com.google.auto.common"))) + .isEqualTo(PUBLIC); } @Test @@ -61,32 +62,44 @@ public class VisibilityTest { @SuppressWarnings("unused") public static class PublicClass { public static class NestedPublicClass {} + protected static class NestedProtectedClass {} + static class NestedDefaultClass {} + private static class NestedPrivateClass {} } @SuppressWarnings("unused") protected static class ProtectedClass { public static class NestedPublicClass {} + protected static class NestedProtectedClass {} + static class NestedDefaultClass {} + private static class NestedPrivateClass {} } @SuppressWarnings("unused") static class DefaultClass { public static class NestedPublicClass {} + protected static class NestedProtectedClass {} + static class NestedDefaultClass {} + private static class NestedPrivateClass {} } @SuppressWarnings("unused") private static class PrivateClass { public static class NestedPublicClass {} + protected static class NestedProtectedClass {} + static class NestedDefaultClass {} + private static class NestedPrivateClass {} } @@ -94,21 +107,25 @@ public class VisibilityTest { public void classVisibility() { assertThat(Visibility.ofElement(compilation.getElements().getTypeElement("java.util.Map"))) .isEqualTo(PUBLIC); - assertThat(Visibility.ofElement( - compilation.getElements().getTypeElement("java.util.Map.Entry"))) - .isEqualTo(PUBLIC); - assertThat(Visibility.ofElement( - compilation.getElements().getTypeElement(PublicClass.class.getCanonicalName()))) - .isEqualTo(PUBLIC); - assertThat(Visibility.ofElement( - compilation.getElements().getTypeElement(ProtectedClass.class.getCanonicalName()))) - .isEqualTo(PROTECTED); - assertThat(Visibility.ofElement( - compilation.getElements().getTypeElement(DefaultClass.class.getCanonicalName()))) - .isEqualTo(DEFAULT); - assertThat(Visibility.ofElement( - compilation.getElements().getTypeElement(PrivateClass.class.getCanonicalName()))) - .isEqualTo(PRIVATE); + assertThat( + Visibility.ofElement(compilation.getElements().getTypeElement("java.util.Map.Entry"))) + .isEqualTo(PUBLIC); + assertThat( + Visibility.ofElement( + compilation.getElements().getTypeElement(PublicClass.class.getCanonicalName()))) + .isEqualTo(PUBLIC); + assertThat( + Visibility.ofElement( + compilation.getElements().getTypeElement(ProtectedClass.class.getCanonicalName()))) + .isEqualTo(PROTECTED); + assertThat( + Visibility.ofElement( + compilation.getElements().getTypeElement(DefaultClass.class.getCanonicalName()))) + .isEqualTo(DEFAULT); + assertThat( + Visibility.ofElement( + compilation.getElements().getTypeElement(PrivateClass.class.getCanonicalName()))) + .isEqualTo(PRIVATE); } @Test @@ -118,14 +135,11 @@ public class VisibilityTest { assertThat(effectiveVisiblityOfClass(DefaultClass.class)).isEqualTo(DEFAULT); assertThat(effectiveVisiblityOfClass(PrivateClass.class)).isEqualTo(PRIVATE); - assertThat(effectiveVisiblityOfClass(PublicClass.NestedPublicClass.class)) - .isEqualTo(PUBLIC); + assertThat(effectiveVisiblityOfClass(PublicClass.NestedPublicClass.class)).isEqualTo(PUBLIC); assertThat(effectiveVisiblityOfClass(PublicClass.NestedProtectedClass.class)) .isEqualTo(PROTECTED); - assertThat(effectiveVisiblityOfClass(PublicClass.NestedDefaultClass.class)) - .isEqualTo(DEFAULT); - assertThat(effectiveVisiblityOfClass(PublicClass.NestedPrivateClass.class)) - .isEqualTo(PRIVATE); + assertThat(effectiveVisiblityOfClass(PublicClass.NestedDefaultClass.class)).isEqualTo(DEFAULT); + assertThat(effectiveVisiblityOfClass(PublicClass.NestedPrivateClass.class)).isEqualTo(PRIVATE); assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPublicClass.class)) .isEqualTo(PROTECTED); @@ -136,23 +150,17 @@ public class VisibilityTest { assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPrivateClass.class)) .isEqualTo(PRIVATE); - assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPublicClass.class)) - .isEqualTo(DEFAULT); + assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPublicClass.class)).isEqualTo(DEFAULT); assertThat(effectiveVisiblityOfClass(DefaultClass.NestedProtectedClass.class)) .isEqualTo(DEFAULT); - assertThat(effectiveVisiblityOfClass(DefaultClass.NestedDefaultClass.class)) - .isEqualTo(DEFAULT); - assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPrivateClass.class)) - .isEqualTo(PRIVATE); + assertThat(effectiveVisiblityOfClass(DefaultClass.NestedDefaultClass.class)).isEqualTo(DEFAULT); + assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPrivateClass.class)).isEqualTo(PRIVATE); - assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPublicClass.class)) - .isEqualTo(PRIVATE); + assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPublicClass.class)).isEqualTo(PRIVATE); assertThat(effectiveVisiblityOfClass(PrivateClass.NestedProtectedClass.class)) .isEqualTo(PRIVATE); - assertThat(effectiveVisiblityOfClass(PrivateClass.NestedDefaultClass.class)) - .isEqualTo(PRIVATE); - assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPrivateClass.class)) - .isEqualTo(PRIVATE); + assertThat(effectiveVisiblityOfClass(PrivateClass.NestedDefaultClass.class)).isEqualTo(PRIVATE); + assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPrivateClass.class)).isEqualTo(PRIVATE); } private Visibility effectiveVisiblityOfClass(Class<?> clazz) { |