diff options
Diffstat (limited to 'factory')
78 files changed, 1404 insertions, 892 deletions
diff --git a/factory/pom.xml b/factory/pom.xml index 48bcfeff..629223a9 100644 --- a/factory/pom.xml +++ b/factory/pom.xml @@ -36,9 +36,11 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <auto-service.version>1.0</auto-service.version> + <auto-value.version>1.8.1</auto-value.version> <java.version>1.8</java.version> - <guava.version>28.2-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> @@ -69,43 +71,25 @@ <dependency> <groupId>com.google.auto</groupId> <artifactId>auto-common</artifactId> - <version>0.10</version> + <version>1.1</version> </dependency> <dependency> <groupId>com.google.auto.value</groupId> <artifactId>auto-value-annotations</artifactId> - <version>1.7</version> - </dependency> - <dependency> - <groupId>com.google.auto.value</groupId> - <artifactId>auto-value</artifactId> - <version>1.7</version> - <scope>provided</scope> + <version>${auto-value.version}</version> </dependency> <dependency> <groupId>com.google.auto.service</groupId> - <artifactId>auto-service</artifactId> - <version>1.0-rc6</version> - <scope>provided</scope> + <artifactId>auto-service-annotations</artifactId> + <version>${auto-service.version}</version> </dependency> <dependency> <groupId>net.ltgt.gradle.incap</groupId> <artifactId>incap</artifactId> - <version>0.2</version> + <version>0.3</version> <scope>provided</scope> </dependency> <dependency> - <groupId>net.ltgt.gradle.incap</groupId> - <artifactId>incap-processor</artifactId> - <version>0.2</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.google.googlejavaformat</groupId> - <artifactId>google-java-format</artifactId> - <version>1.7</version> - </dependency> - <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version> @@ -113,7 +97,7 @@ <dependency> <groupId>com.squareup</groupId> <artifactId>javapoet</artifactId> - <version>1.12.1</version> + <version>1.13.0</version> </dependency> <dependency> <groupId>javax.inject</groupId> @@ -124,13 +108,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.13</version> + <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> @@ -157,29 +141,54 @@ <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> <compilerArgument>-Xlint:all</compilerArgument> <showWarnings>true</showWarnings> <showDeprecation>true</showDeprecation> + <annotationProcessorPaths> + <path> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service</artifactId> + <version>${auto-service.version}</version> + </path> + <path> + <groupId>com.google.auto.value</groupId> + <artifactId>auto-value</artifactId> + <version>${auto-value.version}</version> + </path> + <path> + <groupId>net.ltgt.gradle.incap</groupId> + <artifactId>incap-processor</artifactId> + <version>0.3</version> + </path> + </annotationProcessorPaths> </configuration> <dependencies> <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-surefire-plugin</artifactId> + <version>2.22.2</version> + <configuration> + <argLine>${test.jvm.flags}</argLine> + </configuration> + </plugin> + <plugin> <artifactId>maven-jar-plugin</artifactId> - <version>3.0.2</version> + <version>3.2.0</version> </plugin> <plugin> <artifactId>maven-invoker-plugin</artifactId> - <version>3.0.1</version> + <version>3.2.2</version> <configuration> <addTestClassPath>true</addTestClassPath> <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> @@ -205,4 +214,15 @@ </plugin> </plugins> </build> + <profiles> + <profile> + <id>open-modules</id> + <activation> + <jdk>[9,)</jdk> + </activation> + <properties> + <test.jvm.flags>--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</test.jvm.flags> + </properties> + </profile> + </profiles> </project> diff --git a/factory/src/it/functional/pom.xml b/factory/src/it/functional/pom.xml index 56e8f6f2..a7a1853e 100644 --- a/factory/src/it/functional/pom.xml +++ b/factory/src/it/functional/pom.xml @@ -45,7 +45,7 @@ <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> - <version>27.0.1-jre</version> + <version>29.0-jre</version> </dependency> <dependency> <groupId>com.google.inject</groupId> @@ -66,7 +66,7 @@ <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> - <version>4.12</version> + <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> @@ -82,12 +82,12 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.0.2</version> + <version>3.2.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.7.0</version> + <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> @@ -99,7 +99,7 @@ <dependency> <groupId>org.codehaus.plexus</groupId> <artifactId>plexus-java</artifactId> - <version>0.9.4</version> + <version>1.0.5</version> </dependency> </dependencies> </plugin> diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java index 4c4a38af..f32e9f8d 100644 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java @@ -16,44 +16,44 @@ package com.google.auto.factory; import com.google.auto.factory.otherpackage.OtherPackage; +import dagger.Binds; import dagger.Module; import dagger.Provides; @Module -final class DaggerModule { - @Provides Dependency provideDependency(DependencyImpl impl) { - return impl; - } +abstract class DaggerModule { + private DaggerModule() {} // no instances - @Provides + @Binds + abstract Dependency provideDependency(DependencyImpl impl); + + @Binds @Qualifier - Dependency provideQualifiedDependency(QualifiedDependencyImpl impl) { - return impl; - } + abstract Dependency provideQualifiedDependency(QualifiedDependencyImpl impl); @Provides - int providePrimitive() { + static int providePrimitive() { return 1; } @Provides @Qualifier - int provideQualifiedPrimitive() { + static int provideQualifiedPrimitive() { return 2; } @Provides - Number provideNumber() { + static Number provideNumber() { return 3; } @Provides - ReferencePackage provideReferencePackage(ReferencePackageFactory factory) { + static ReferencePackage provideReferencePackage(ReferencePackageFactory factory) { return factory.create(17); } @Provides - OtherPackage provideOtherPackage() { + static OtherPackage provideOtherPackage() { return new OtherPackage(null, 23); } } diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java index 4c019ea6..d94a3cf6 100644 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java @@ -18,5 +18,6 @@ package com.google.auto.factory; import javax.inject.Inject; public class DependencyImpl implements Dependency { - @Inject DependencyImpl() {} + @Inject + DependencyImpl() {} } diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java index f7c13b41..31954a19 100644 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java @@ -28,10 +28,7 @@ public class GenericFoo<A, B extends List<? extends A>, C, E extends Enum<E>> { private final E depE; <D extends IntAccessor & StringAccessor> GenericFoo( - @Provided Provider<A> depA, - B depB, - D depD, - E depE) { + @Provided Provider<A> depA, B depB, D depD, E depE) { this.depA = depA.get(); this.depB = depB; this.depDIntAccessor = depD; diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java index 45d4d26e..77346655 100644 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java @@ -18,7 +18,8 @@ package com.google.auto.factory; import com.google.inject.AbstractModule; public class GuiceModule extends AbstractModule { - @Override protected void configure() { + @Override + protected void configure() { bind(Dependency.class).to(DependencyImpl.class); bind(Dependency.class).annotatedWith(Qualifier.class).to(QualifiedDependencyImpl.class); bind(Integer.class).toInstance(1); diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/ReferencePackage.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/ReferencePackage.java index 22aff651..4f67c3b3 100644..100755 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/ReferencePackage.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/ReferencePackage.java @@ -25,9 +25,7 @@ public class ReferencePackage { private final int random; @Inject - public ReferencePackage( - @Provided OtherPackageFactory otherPackageFactory, - int random) { + ReferencePackage(@Provided OtherPackageFactory otherPackageFactory, int random) { this.otherPackageFactory = otherPackageFactory; this.random = random; } diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/otherpackage/OtherPackage.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/otherpackage/OtherPackage.java index b9925a18..b9925a18 100644..100755 --- a/factory/src/it/functional/src/main/java/com/google/auto/factory/otherpackage/OtherPackage.java +++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/otherpackage/OtherPackage.java diff --git a/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java index e1412117..3caa5a54 100644 --- a/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java +++ b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java @@ -19,7 +19,8 @@ public class DependencyInjectionIntegrationTest { private static final IntAndStringAccessor INT_AND_STRING_ACCESSOR = new IntAndStringAccessor() {}; - @Test public void daggerInjectedFactory() { + @Test + public void daggerInjectedFactory() { FooFactory fooFactory = DaggerFactoryComponent.create().factory(); Foo one = fooFactory.create("A"); Foo two = fooFactory.create("B"); @@ -46,8 +47,9 @@ public class DependencyInjectionIntegrationTest { genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1); ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>(); intAndStringAccessorArrayList.add(4.0); - GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create( - intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2); + GenericFoo<Number, ArrayList<Double>, Long, DepE> four = + genericFooFactory.create( + intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2); assertThat(three.getDepA()).isEqualTo(3); ImmutableList<Long> unusedLongList = three.getDepB(); assertThat(three.getDepB()).containsExactly(3L); @@ -75,7 +77,8 @@ public class DependencyInjectionIntegrationTest { assertThat(otherPackage.random()).isEqualTo(5); } - @Test public void guiceInjectedFactory() { + @Test + public void guiceInjectedFactory() { FooFactory fooFactory = Guice.createInjector(new GuiceModule()).getInstance(FooFactory.class); Foo one = fooFactory.create("A"); Foo two = fooFactory.create("B"); @@ -103,8 +106,9 @@ public class DependencyInjectionIntegrationTest { genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1); ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>(); intAndStringAccessorArrayList.add(4.0); - GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create( - intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2); + GenericFoo<Number, ArrayList<Double>, Long, DepE> four = + genericFooFactory.create( + intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2); assertThat(three.getDepA()).isEqualTo(3); ImmutableList<Long> unusedLongList = three.getDepB(); assertThat(three.getDepB()).containsExactly(3L); @@ -124,8 +128,7 @@ public class DependencyInjectionIntegrationTest { @Test public void guiceInjectedPackageSpanningFactory() { ReferencePackageFactory referencePackageFactory = - Guice.createInjector(new GuiceModule()) - .getInstance(ReferencePackageFactory.class); + Guice.createInjector(new GuiceModule()).getInstance(ReferencePackageFactory.class); ReferencePackage referencePackage = referencePackageFactory.create(5); OtherPackage otherPackage = referencePackage.otherPackage(); assertThat(otherPackage.referencePackageFactory()).isNotSameInstanceAs(referencePackageFactory); diff --git a/factory/src/main/java/com/google/auto/factory/AutoFactory.java b/factory/src/main/java/com/google/auto/factory/AutoFactory.java index 2ef84cc3..3b5d90ea 100644 --- a/factory/src/main/java/com/google/auto/factory/AutoFactory.java +++ b/factory/src/main/java/com/google/auto/factory/AutoFactory.java @@ -32,7 +32,7 @@ import java.lang.annotation.Target; * * @author Gregory Kick */ -@Target({ TYPE, CONSTRUCTOR }) +@Target({TYPE, CONSTRUCTOR}) public @interface AutoFactory { /** * The <i>simple</i> name of the generated factory; the factory is always generated in the same @@ -50,7 +50,7 @@ public @interface AutoFactory { /** * A list of interfaces that the generated factory is required to implement. */ - Class<?>[] implementing() default { }; + Class<?>[] implementing() default {}; /** * The type that the generated factory is require to extend. diff --git a/factory/src/main/java/com/google/auto/factory/Provided.java b/factory/src/main/java/com/google/auto/factory/Provided.java index e81e4aa6..226a16f4 100644 --- a/factory/src/main/java/com/google/auto/factory/Provided.java +++ b/factory/src/main/java/com/google/auto/factory/Provided.java @@ -26,4 +26,4 @@ import java.lang.annotation.Target; * @author Gregory Kick */ @Target(PARAMETER) -public @interface Provided { } +public @interface Provided {} diff --git a/factory/src/main/java/com/google/auto/factory/package-info.java b/factory/src/main/java/com/google/auto/factory/package-info.java new file mode 100644 index 00000000..ea1ddd88 --- /dev/null +++ b/factory/src/main/java/com/google/auto/factory/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.factory; + diff --git a/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java b/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java index b767c47f..53d38a40 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java +++ b/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java @@ -32,24 +32,29 @@ final class AnnotationValues { static boolean asBoolean(AnnotationValue value) { return value.accept( new SimpleAnnotationValueVisitor6<Boolean, Void>() { - @Override protected Boolean defaultAction(Object o, Void p) { + @Override + protected Boolean defaultAction(Object o, Void p) { throw new IllegalArgumentException(); } - @Override public Boolean visitBoolean(boolean b, Void p) { + @Override + public Boolean visitBoolean(boolean b, Void p) { return b; } - }, null); + }, + null); } static TypeElement asType(AnnotationValue value) { return value.accept( new SimpleAnnotationValueVisitor6<TypeElement, Void>() { - @Override protected TypeElement defaultAction(Object o, Void p) { + @Override + protected TypeElement defaultAction(Object o, Void p) { throw new IllegalArgumentException(); } - @Override public TypeElement visitType(TypeMirror t, Void p) { + @Override + public TypeElement visitType(TypeMirror t, Void p) { return t.accept( new SimpleTypeVisitor6<TypeElement, Void>() { @Override @@ -59,12 +64,14 @@ final class AnnotationValues { @Override public TypeElement visitDeclared(DeclaredType t, Void p) { - return Iterables.getOnlyElement(ElementFilter.typesIn( - ImmutableList.of(t.asElement()))); + return Iterables.getOnlyElement( + ElementFilter.typesIn(ImmutableList.of(t.asElement()))); } - }, null); + }, + null); } - }, null); + }, + null); } static ImmutableList<? extends AnnotationValue> asList(AnnotationValue value) { @@ -80,6 +87,7 @@ final class AnnotationValues { List<? extends AnnotationValue> vals, Void p) { return ImmutableList.copyOf(vals); } - }, null); + }, + null); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java index e2da6eae..889d8e41 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java +++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java @@ -21,13 +21,13 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getOnlyElement; +import static java.util.Objects.requireNonNull; import static javax.lang.model.element.ElementKind.PACKAGE; import static javax.lang.model.util.ElementFilter.typesIn; import static javax.tools.Diagnostic.Kind.ERROR; import com.google.auto.factory.AutoFactory; import com.google.auto.value.AutoValue; -import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; @@ -36,6 +36,7 @@ import com.google.common.collect.ImmutableSet; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.annotation.processing.Messager; import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; @@ -54,12 +55,19 @@ import javax.lang.model.util.Elements; @AutoValue abstract class AutoFactoryDeclaration { abstract TypeElement targetType(); + abstract Element target(); + abstract Optional<String> className(); + abstract TypeElement extendingType(); + abstract ImmutableSet<TypeElement> implementingTypes(); + abstract boolean allowSubclasses(); + abstract AnnotationMirror mirror(); + abstract ImmutableMap<String, AnnotationValue> valuesMap(); PackageAndClass getFactoryName() { @@ -97,52 +105,70 @@ abstract class AutoFactoryDeclaration { Optional<AutoFactoryDeclaration> createIfValid(Element element) { checkNotNull(element); AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get(); - checkArgument(Mirrors.getQualifiedName(mirror.getAnnotationType()). - contentEquals(AutoFactory.class.getName())); + checkArgument( + Mirrors.getQualifiedName(mirror.getAnnotationType()) + .contentEquals(AutoFactory.class.getName())); Map<String, AnnotationValue> values = Mirrors.simplifyAnnotationValueMap(elements.getElementValuesWithDefaults(mirror)); checkState(values.size() == 4); - // className value is a string, so we can just call toString - AnnotationValue classNameValue = values.get("className"); + // className value is a string, so we can just call toString. We know values.get("className") + // is non-null because @AutoFactory has an annotation element of that name. + AnnotationValue classNameValue = requireNonNull(values.get("className")); String className = classNameValue.getValue().toString(); if (!className.isEmpty() && !isValidIdentifier(className)) { - messager.printMessage(ERROR, + messager.printMessage( + ERROR, String.format("\"%s\" is not a valid Java identifier", className), - element, mirror, classNameValue); - return Optional.absent(); + element, + mirror, + classNameValue); + return Optional.empty(); } AnnotationValue extendingValue = checkNotNull(values.get("extending")); TypeElement extendingType = AnnotationValues.asType(extendingValue); if (extendingType == null) { - messager.printMessage(ERROR, "Unable to find the type: " - + extendingValue.getValue().toString(), - element, mirror, extendingValue); - return Optional.absent(); + messager.printMessage( + ERROR, + "Unable to find the type: " + extendingValue.getValue(), + element, + mirror, + extendingValue); + return Optional.empty(); } else if (!isValidSupertypeForClass(extendingType)) { - messager.printMessage(ERROR, - String.format("%s is not a valid supertype for a factory. " - + "Supertypes must be non-final classes.", - extendingType.getQualifiedName()), - element, mirror, extendingValue); - return Optional.absent(); + messager.printMessage( + ERROR, + String.format( + "%s is not a valid supertype for a factory. " + + "Supertypes must be non-final classes.", + extendingType.getQualifiedName()), + element, + mirror, + extendingValue); + return Optional.empty(); } ImmutableList<ExecutableElement> noParameterConstructors = FluentIterable.from(ElementFilter.constructorsIn(extendingType.getEnclosedElements())) - .filter(new Predicate<ExecutableElement>() { - @Override public boolean apply(ExecutableElement constructor) { - return constructor.getParameters().isEmpty(); - } - }) + .filter( + new Predicate<ExecutableElement>() { + @Override + public boolean apply(ExecutableElement constructor) { + return constructor.getParameters().isEmpty(); + } + }) .toList(); - if (noParameterConstructors.size() == 0) { - messager.printMessage(ERROR, - String.format("%s is not a valid supertype for a factory. " - + "Factory supertypes must have a no-arg constructor.", - extendingType.getQualifiedName()), - element, mirror, extendingValue); - return Optional.absent(); + if (noParameterConstructors.isEmpty()) { + messager.printMessage( + ERROR, + String.format( + "%s is not a valid supertype for a factory. " + + "Factory supertypes must have a no-arg constructor.", + extendingType.getQualifiedName()), + element, + mirror, + extendingValue); + return Optional.empty(); } else if (noParameterConstructors.size() > 1) { throw new IllegalStateException("Multiple constructors with no parameters??"); } @@ -161,7 +187,7 @@ abstract class AutoFactoryDeclaration { new AutoValue_AutoFactoryDeclaration( getAnnotatedType(element), element, - className.isEmpty() ? Optional.<String>absent() : Optional.of(className), + className.isEmpty() ? Optional.empty() : Optional.of(className), extendingType, implementingTypes, allowSubclasses, diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java index 5cc1d94d..82349f21 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java +++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java @@ -19,7 +19,6 @@ import com.google.auto.common.MoreTypes; import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; import com.google.auto.service.AutoService; -import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableListMultimap; @@ -30,7 +29,9 @@ import com.google.common.collect.Iterables; import java.io.IOException; import java.util.Arrays; import java.util.Comparator; +import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Messager; @@ -83,8 +84,9 @@ public final class AutoFactoryProcessor extends AbstractProcessor { try { doProcess(roundEnv); } catch (Throwable e) { - messager.printMessage(Kind.ERROR, "Failed to process @AutoFactory annotations:\n" - + Throwables.getStackTraceAsString(e)); + messager.printMessage( + Kind.ERROR, + "Failed to process @AutoFactory annotations:\n" + Throwables.getStackTraceAsString(e)); } return false; } @@ -127,49 +129,58 @@ public final class AutoFactoryProcessor extends AbstractProcessor { simpleNamesToNames(indexedMethods.keySet()); FactoryWriter factoryWriter = new FactoryWriter(processingEnv, factoriesBeingCreated); - indexedMethods.asMap().forEach( - (factoryName, methodDescriptors) -> { - // The sets of classes that are mentioned in the `extending` and `implementing` elements, - // respectively, of the @AutoFactory annotations for this factory. - ImmutableSet.Builder<TypeMirror> extending = newTypeSetBuilder(); - ImmutableSortedSet.Builder<TypeMirror> implementing = newTypeSetBuilder(); - boolean publicType = false; - Boolean allowSubclasses = null; - boolean skipCreation = false; - for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) { - extending.add(methodDescriptor.declaration().extendingType().asType()); - for (TypeElement implementingType : - methodDescriptor.declaration().implementingTypes()) { - implementing.add(implementingType.asType()); - } - publicType |= methodDescriptor.publicMethod(); - if (allowSubclasses == null) { - allowSubclasses = methodDescriptor.declaration().allowSubclasses(); - } else if (!allowSubclasses.equals(methodDescriptor.declaration().allowSubclasses())) { - skipCreation = true; - messager.printMessage(Kind.ERROR, - "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.", - methodDescriptor.declaration().target(), - methodDescriptor.declaration().mirror(), - methodDescriptor.declaration().valuesMap().get("allowSubclasses")); - } - } - if (!skipCreation) { - try { - factoryWriter.writeFactory( - FactoryDescriptor.create( - factoryName, - Iterables.getOnlyElement(extending.build()), - implementing.build(), - publicType, - ImmutableSet.copyOf(methodDescriptors), - implementationMethodDescriptors.get(factoryName), - allowSubclasses)); - } catch (IOException e) { - messager.printMessage(Kind.ERROR, "failed: " + e); - } - } - }); + indexedMethods + .asMap() + .forEach( + (factoryName, methodDescriptors) -> { + if (methodDescriptors.isEmpty()) { + // This shouldn't happen, but check anyway to avoid an exception for + // methodDescriptors.iterator().next() below. + return; + } + // The sets of classes that are mentioned in the `extending` and `implementing` + // elements, respectively, of the @AutoFactory annotations for this factory. + ImmutableSet.Builder<TypeMirror> extending = newTypeSetBuilder(); + ImmutableSortedSet.Builder<TypeMirror> implementing = newTypeSetBuilder(); + boolean publicType = false; + Set<Boolean> allowSubclassesSet = new HashSet<>(); + boolean skipCreation = false; + for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) { + extending.add(methodDescriptor.declaration().extendingType().asType()); + for (TypeElement implementingType : + methodDescriptor.declaration().implementingTypes()) { + implementing.add(implementingType.asType()); + } + publicType |= methodDescriptor.publicMethod(); + allowSubclassesSet.add(methodDescriptor.declaration().allowSubclasses()); + if (allowSubclassesSet.size() > 1) { + skipCreation = true; + messager.printMessage( + Kind.ERROR, + "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.", + methodDescriptor.declaration().target(), + methodDescriptor.declaration().mirror(), + methodDescriptor.declaration().valuesMap().get("allowSubclasses")); + } + } + // The set can't be empty because we eliminated methodDescriptors.isEmpty() above. + boolean allowSubclasses = allowSubclassesSet.iterator().next(); + if (!skipCreation) { + try { + factoryWriter.writeFactory( + FactoryDescriptor.create( + factoryName, + Iterables.getOnlyElement(extending.build()), + implementing.build(), + publicType, + ImmutableSet.copyOf(methodDescriptors), + implementationMethodDescriptors.get(factoryName), + allowSubclasses)); + } catch (IOException e) { + messager.printMessage(Kind.ERROR, "failed: " + e); + } + } + }); } private ImmutableSet<ImplementationMethodDescriptor> implementationMethods( @@ -180,8 +191,7 @@ public final class AutoFactoryProcessor extends AbstractProcessor { ElementFilter.methodsIn(elements.getAllMembers(supertype))) { if (implementationMethod.getModifiers().contains(Modifier.ABSTRACT)) { ExecutableType methodType = - Elements2.getExecutableElementAsMemberOf( - types, implementationMethod, supertype); + Elements2.getExecutableElementAsMemberOf(types, implementationMethod, supertype); ImmutableSet<Parameter> passedParameters = Parameter.forParameterList( implementationMethod.getParameters(), methodType.getParameterTypes(), types); @@ -192,6 +202,7 @@ public final class AutoFactoryProcessor extends AbstractProcessor { .publicMethod() .passedParameters(passedParameters) .isVarArgs(implementationMethod.isVarArgs()) + .exceptions(implementationMethod.getThrownTypes()) .build()); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/Elements2.java b/factory/src/main/java/com/google/auto/factory/processor/Elements2.java index 30230f7f..3663f370 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/Elements2.java +++ b/factory/src/main/java/com/google/auto/factory/processor/Elements2.java @@ -22,10 +22,10 @@ import static javax.lang.model.element.ElementKind.PACKAGE; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.STATIC; +import com.google.auto.common.MoreTypes; import com.google.common.collect.ImmutableSet; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; @@ -33,7 +33,7 @@ import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Types; final class Elements2 { - private Elements2() { } + private Elements2() {} static ImmutableSet<ExecutableElement> getConstructors(TypeElement type) { checkNotNull(type); @@ -72,11 +72,11 @@ final class Elements2 { throw new IllegalStateException( "Expected subTypeElement.asType() to return a class/interface type."); } - TypeMirror subExecutableTypeMirror = types.asMemberOf( - (DeclaredType) subTypeMirror, executableElement); + TypeMirror subExecutableTypeMirror = + types.asMemberOf(MoreTypes.asDeclared(subTypeMirror), executableElement); if (!subExecutableTypeMirror.getKind().equals(TypeKind.EXECUTABLE)) { throw new IllegalStateException("Expected subExecutableTypeMirror to be an executable type."); } - return (ExecutableType) subExecutableTypeMirror; + return MoreTypes.asExecutable(subExecutableTypeMirror); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java index 5ed2307a..019295f6 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java +++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java @@ -17,16 +17,15 @@ package com.google.auto.factory.processor; import com.google.auto.value.AutoValue; import com.google.common.base.CharMatcher; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; -import java.util.Collection; +import com.google.common.collect.Streams; import java.util.HashSet; -import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.type.TypeMirror; @@ -47,20 +46,28 @@ abstract class FactoryDescriptor { }; abstract PackageAndClass name(); + abstract TypeMirror extendingType(); + abstract ImmutableSet<TypeMirror> implementingTypes(); + abstract boolean publicType(); + abstract ImmutableSet<FactoryMethodDescriptor> methodDescriptors(); + abstract ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors(); + abstract boolean allowSubclasses(); + abstract ImmutableMap<Key, ProviderField> providers(); final AutoFactoryDeclaration declaration() { - return Iterables.getFirst(methodDescriptors(), null).declaration(); + // There is always at least one method descriptor. + return methodDescriptors().iterator().next().declaration(); } private static class UniqueNameSet { - private final Set<String> uniqueNames = new HashSet<String>(); + private final Set<String> uniqueNames = new HashSet<>(); /** * Generates a unique name using {@code base}. If {@code base} has not yet been added, it will @@ -92,33 +99,37 @@ abstract class FactoryDescriptor { } ImmutableMap.Builder<Key, ProviderField> providersBuilder = ImmutableMap.builder(); UniqueNameSet uniqueNames = new UniqueNameSet(); - for (Entry<Key, Collection<Parameter>> entry : - parametersForProviders.build().asMap().entrySet()) { - Key key = entry.getKey(); - switch (entry.getValue().size()) { - case 0: - throw new AssertionError(); - case 1: - Parameter parameter = Iterables.getOnlyElement(entry.getValue()); - providersBuilder.put( - key, - ProviderField.create( - uniqueNames.getUniqueName(parameter.name() + "Provider"), - key, - parameter.nullable())); - break; - default: - String providerName = - uniqueNames.getUniqueName( - invalidIdentifierCharacters.replaceFrom(key.toString(), '_') + "Provider"); - Optional<AnnotationMirror> nullable = Optional.absent(); - for (Parameter param : entry.getValue()) { - nullable = nullable.or(param.nullable()); - } - providersBuilder.put(key, ProviderField.create(providerName, key, nullable)); - break; - } - } + parametersForProviders + .build() + .asMap() + .forEach( + (key, parameters) -> { + switch (parameters.size()) { + case 0: + throw new AssertionError(); + case 1: + Parameter parameter = Iterables.getOnlyElement(parameters); + providersBuilder.put( + key, + ProviderField.create( + uniqueNames.getUniqueName(parameter.name() + "Provider"), + key, + parameter.nullable())); + break; + default: + String providerName = + uniqueNames.getUniqueName( + invalidIdentifierCharacters.replaceFrom(key.toString(), '_') + + "Provider"); + Optional<AnnotationMirror> nullable = + parameters.stream() + .map(Parameter::nullable) + .flatMap(Streams::stream) + .findFirst(); + providersBuilder.put(key, ProviderField.create(providerName, key, nullable)); + break; + } + }); ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor> duplicateMethodDescriptors = @@ -129,8 +140,8 @@ abstract class FactoryDescriptor { getDeduplicatedMethodDescriptors(methodDescriptors, duplicateMethodDescriptors); ImmutableSet<ImplementationMethodDescriptor> deduplicatedImplementationMethodDescriptors = - ImmutableSet.copyOf( - Sets.difference(implementationMethodDescriptors, duplicateMethodDescriptors.values())); + Sets.difference(implementationMethodDescriptors, duplicateMethodDescriptors.values()) + .immutableCopy(); return new AutoValue_FactoryDescriptor( name, @@ -191,12 +202,12 @@ abstract class FactoryDescriptor { duplicateMethodDescriptors.get(methodDescriptor); FactoryMethodDescriptor newMethodDescriptor = - (duplicateMethodDescriptor != null) - ? methodDescriptor - .toBuilder() + (duplicateMethodDescriptor != null) + ? methodDescriptor.toBuilder() .overridingMethod(true) .publicMethod(duplicateMethodDescriptor.publicMethod()) .returnType(duplicateMethodDescriptor.returnType()) + .exceptions(duplicateMethodDescriptor.exceptions()) .build() : methodDescriptor; deduplicatedMethodDescriptors.add(newMethodDescriptor); @@ -213,8 +224,7 @@ abstract class FactoryDescriptor { * in the same order. */ private static boolean areDuplicateMethodDescriptors( - FactoryMethodDescriptor factory, - ImplementationMethodDescriptor implementation) { + FactoryMethodDescriptor factory, ImplementationMethodDescriptor implementation) { if (!factory.name().equals(implementation.name())) { return false; diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java index d2331f42..70a21ea2 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java +++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java @@ -18,6 +18,8 @@ package com.google.auto.factory.processor; import static com.google.auto.common.MoreElements.isAnnotationPresent; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.partitioningBy; import static javax.lang.model.element.Modifier.ABSTRACT; import static javax.lang.model.element.Modifier.PUBLIC; import static javax.tools.Diagnostic.Kind.ERROR; @@ -26,13 +28,11 @@ import com.google.auto.common.MoreElements; import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimaps; +import java.util.List; +import java.util.Map; +import java.util.Optional; import javax.annotation.processing.Messager; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; @@ -54,9 +54,7 @@ final class FactoryDescriptorGenerator { private final AutoFactoryDeclaration.Factory declarationFactory; FactoryDescriptorGenerator( - Messager messager, - Types types, - AutoFactoryDeclaration.Factory declarationFactory) { + Messager messager, Types types, AutoFactoryDeclaration.Factory declarationFactory) { this.messager = messager; this.types = types; this.declarationFactory = declarationFactory; @@ -68,70 +66,75 @@ final class FactoryDescriptorGenerator { if (!declaration.isPresent()) { return ImmutableSet.of(); } - return element.accept(new ElementKindVisitor6<ImmutableSet<FactoryMethodDescriptor>, Void>() { - @Override - protected ImmutableSet<FactoryMethodDescriptor> defaultAction(Element e, Void p) { - throw new AssertionError("@AutoFactory applied to an impossible element"); - } + return element.accept( + new ElementKindVisitor6<ImmutableSet<FactoryMethodDescriptor>, Void>() { + @Override + protected ImmutableSet<FactoryMethodDescriptor> defaultAction(Element e, Void p) { + throw new AssertionError("@AutoFactory applied to an impossible element"); + } - @Override - public ImmutableSet<FactoryMethodDescriptor> visitTypeAsClass(TypeElement type, Void p) { - if (type.getModifiers().contains(ABSTRACT)) { - // applied to an abstract factory - messager.printMessage(ERROR, - "Auto-factory doesn't support being applied to abstract classes.", type, mirror); - return ImmutableSet.of(); - } else { - // applied to the type to be created - ImmutableSet<ExecutableElement> constructors = Elements2.getConstructors(type); - if (constructors.isEmpty()) { - return generateDescriptorForDefaultConstructor(declaration.get(), type); - } else { - return FluentIterable.from(constructors) - .transform(new Function<ExecutableElement, FactoryMethodDescriptor>() { - @Override public FactoryMethodDescriptor apply(ExecutableElement constructor) { - return generateDescriptorForConstructor(declaration.get(), constructor); - } - }) - .toSet(); + @Override + public ImmutableSet<FactoryMethodDescriptor> visitTypeAsClass(TypeElement type, Void p) { + if (type.getModifiers().contains(ABSTRACT)) { + // applied to an abstract factory + messager.printMessage( + ERROR, + "Auto-factory doesn't support being applied to abstract classes.", + type, + mirror); + return ImmutableSet.of(); + } else { + // applied to the type to be created + ImmutableSet<ExecutableElement> constructors = Elements2.getConstructors(type); + if (constructors.isEmpty()) { + return generateDescriptorForDefaultConstructor(declaration.get(), type); + } else { + return FluentIterable.from(constructors) + .transform( + new Function<ExecutableElement, FactoryMethodDescriptor>() { + @Override + public FactoryMethodDescriptor apply(ExecutableElement constructor) { + return generateDescriptorForConstructor(declaration.get(), constructor); + } + }) + .toSet(); + } + } } - } - } - @Override - public ImmutableSet<FactoryMethodDescriptor> visitTypeAsInterface(TypeElement type, Void p) { - // applied to the factory interface - messager.printMessage(ERROR, - "Auto-factory doesn't support being applied to interfaces.", type, mirror); - return ImmutableSet.of(); - } + @Override + public ImmutableSet<FactoryMethodDescriptor> visitTypeAsInterface( + TypeElement type, Void p) { + // applied to the factory interface + messager.printMessage( + ERROR, "Auto-factory doesn't support being applied to interfaces.", type, mirror); + return ImmutableSet.of(); + } - @Override - public ImmutableSet<FactoryMethodDescriptor> visitExecutableAsConstructor(ExecutableElement e, - Void p) { - // applied to a constructor of a type to be created - return ImmutableSet.of(generateDescriptorForConstructor(declaration.get(), e)); - } - }, null); + @Override + public ImmutableSet<FactoryMethodDescriptor> visitExecutableAsConstructor( + ExecutableElement e, Void p) { + // applied to a constructor of a type to be created + return ImmutableSet.of(generateDescriptorForConstructor(declaration.get(), e)); + } + }, + null); } - FactoryMethodDescriptor generateDescriptorForConstructor(final AutoFactoryDeclaration declaration, - ExecutableElement constructor) { + FactoryMethodDescriptor generateDescriptorForConstructor( + final AutoFactoryDeclaration declaration, ExecutableElement constructor) { checkNotNull(constructor); checkArgument(constructor.getKind() == ElementKind.CONSTRUCTOR); TypeElement classElement = MoreElements.asType(constructor.getEnclosingElement()); - ImmutableListMultimap<Boolean, ? extends VariableElement> parameterMap = - Multimaps.index(constructor.getParameters(), Functions.forPredicate( - new Predicate<VariableElement>() { - @Override - public boolean apply(VariableElement parameter) { - return isAnnotationPresent(parameter, Provided.class); - } - })); + Map<Boolean, List<VariableElement>> parameterMap = + constructor.getParameters().stream() + .collect(partitioningBy(parameter -> isAnnotationPresent(parameter, Provided.class))); + // The map returned by partitioningBy always has entries for both key values but our + // null-checker isn't yet smart enough to know that. ImmutableSet<Parameter> providedParameters = - Parameter.forParameterList(parameterMap.get(true), types); + Parameter.forParameterList(requireNonNull(parameterMap.get(true)), types); ImmutableSet<Parameter> passedParameters = - Parameter.forParameterList(parameterMap.get(false), types); + Parameter.forParameterList(requireNonNull(parameterMap.get(false)), types); return FactoryMethodDescriptor.builder(declaration) .name("create") .returnType(classElement.asType()) @@ -140,6 +143,8 @@ final class FactoryDescriptorGenerator { .passedParameters(passedParameters) .creationParameters(Parameter.forParameterList(constructor.getParameters(), types)) .isVarArgs(constructor.isVarArgs()) + .exceptions(constructor.getThrownTypes()) + .overridingMethod(false) .build(); } @@ -150,9 +155,12 @@ final class FactoryDescriptorGenerator { .name("create") .returnType(type.asType()) .publicMethod(type.getModifiers().contains(PUBLIC)) - .passedParameters(ImmutableSet.<Parameter>of()) - .creationParameters(ImmutableSet.<Parameter>of()) - .providedParameters(ImmutableSet.<Parameter>of()) + .providedParameters(ImmutableSet.of()) + .passedParameters(ImmutableSet.of()) + .creationParameters(ImmutableSet.of()) + .isVarArgs(false) + .exceptions(ImmutableSet.of()) + .overridingMethod(false) .build()); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java index 43e5097d..45259573 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java +++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java @@ -31,45 +31,65 @@ import javax.lang.model.type.TypeMirror; @AutoValue abstract class FactoryMethodDescriptor { abstract AutoFactoryDeclaration declaration(); + abstract String name(); + abstract TypeMirror returnType(); + abstract boolean publicMethod(); + abstract boolean overridingMethod(); + abstract ImmutableSet<Parameter> passedParameters(); + abstract ImmutableSet<Parameter> providedParameters(); + abstract ImmutableSet<Parameter> creationParameters(); - abstract Builder toBuilder(); + abstract boolean isVarArgs(); + abstract ImmutableSet<TypeMirror> exceptions(); + + abstract Builder toBuilder(); + final PackageAndClass factoryName() { return declaration().getFactoryName(); } static Builder builder(AutoFactoryDeclaration declaration) { - return new AutoValue_FactoryMethodDescriptor.Builder() - .declaration(checkNotNull(declaration)) - .publicMethod(false) - .overridingMethod(false) - .isVarArgs(false); + return new AutoValue_FactoryMethodDescriptor.Builder().declaration(checkNotNull(declaration)); } @AutoValue.Builder abstract static class Builder { abstract Builder declaration(AutoFactoryDeclaration declaration); + abstract Builder name(String name); + abstract Builder returnType(TypeMirror returnType); + abstract Builder publicMethod(boolean publicMethod); + abstract Builder overridingMethod(boolean overridingMethod); + abstract Builder passedParameters(Iterable<Parameter> passedParameters); + abstract Builder providedParameters(Iterable<Parameter> providedParameters); + abstract Builder creationParameters(Iterable<Parameter> creationParameters); + abstract Builder isVarArgs(boolean isVarargs); + + abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions); + abstract FactoryMethodDescriptor buildImpl(); FactoryMethodDescriptor build() { FactoryMethodDescriptor descriptor = buildImpl(); - checkState(descriptor.creationParameters().equals( - Sets.union(descriptor.passedParameters(), descriptor.providedParameters()))); + checkState( + descriptor + .creationParameters() + .equals(Sets.union(descriptor.passedParameters(), descriptor.providedParameters()))); return descriptor; } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java index 53b99cb5..b7f9c3e4 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java +++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java @@ -19,19 +19,22 @@ import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotatio import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder; +import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.collect.FluentIterable; +import com.google.auto.common.AnnotationMirrors; +import com.google.auto.common.AnnotationValues; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.google.common.collect.Streams; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; @@ -43,13 +46,19 @@ import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.TypeVariableName; import java.io.IOException; +import java.lang.annotation.Target; import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; import javax.annotation.processing.Filer; import javax.annotation.processing.ProcessingEnvironment; import javax.inject.Inject; import javax.inject.Provider; import javax.lang.model.SourceVersion; import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; @@ -71,14 +80,10 @@ final class FactoryWriter { this.factoriesBeingCreated = factoriesBeingCreated; } - private static final Joiner ARGUMENT_JOINER = Joiner.on(", "); - - void writeFactory(FactoryDescriptor descriptor) - throws IOException { + void writeFactory(FactoryDescriptor descriptor) throws IOException { String factoryName = descriptor.name().className(); TypeSpec.Builder factory = - classBuilder(factoryName) - .addOriginatingElement(descriptor.declaration().targetType()); + classBuilder(factoryName).addOriginatingElement(descriptor.declaration().targetType()); generatedAnnotationSpec( elements, sourceVersion, @@ -145,7 +150,7 @@ final class FactoryWriter { ImmutableSet<TypeVariableName> factoryTypeVariables) { for (FactoryMethodDescriptor methodDescriptor : descriptor.methodDescriptors()) { MethodSpec.Builder method = - MethodSpec.methodBuilder(methodDescriptor.name()) + methodBuilder(methodDescriptor.name()) .addTypeVariables(getMethodTypeVariables(methodDescriptor, factoryTypeVariables)) .returns(TypeName.get(methodDescriptor.returnType())) .varargs(methodDescriptor.isVarArgs()); @@ -155,6 +160,8 @@ final class FactoryWriter { if (methodDescriptor.publicMethod()) { method.addModifiers(PUBLIC); } + method.addExceptions( + methodDescriptor.exceptions().stream().map(TypeName::get).collect(toList())); CodeBlock.Builder args = CodeBlock.builder(); method.addParameters(parameters(methodDescriptor.passedParameters())); Iterator<Parameter> parameters = methodDescriptor.creationParameters().iterator(); @@ -168,7 +175,7 @@ final class FactoryWriter { checkNotNull = false; } } else { - ProviderField provider = descriptor.providers().get(parameter.key()); + ProviderField provider = requireNonNull(descriptor.providers().get(parameter.key())); argument = CodeBlock.of(provider.name()); if (parameter.isProvider()) { // Providers are checked for nullness in the Factory's constructor. @@ -190,8 +197,7 @@ final class FactoryWriter { } } - private void addImplementationMethods( - TypeSpec.Builder factory, FactoryDescriptor descriptor) { + private void addImplementationMethods(TypeSpec.Builder factory, FactoryDescriptor descriptor) { for (ImplementationMethodDescriptor methodDescriptor : descriptor.implementationMethodDescriptors()) { MethodSpec.Builder implementationMethod = @@ -202,18 +208,12 @@ final class FactoryWriter { if (methodDescriptor.publicMethod()) { implementationMethod.addModifiers(PUBLIC); } + implementationMethod.addExceptions( + methodDescriptor.exceptions().stream().map(TypeName::get).collect(toList())); implementationMethod.addParameters(parameters(methodDescriptor.passedParameters())); implementationMethod.addStatement( "return create($L)", - FluentIterable.from(methodDescriptor.passedParameters()) - .transform( - new Function<Parameter, String>() { - @Override - public String apply(Parameter parameter) { - return parameter.name(); - } - }) - .join(ARGUMENT_JOINER)); + methodDescriptor.passedParameters().stream().map(Parameter::name).collect(joining(", "))); factory.addMethod(implementationMethod.build()); } } @@ -225,17 +225,43 @@ final class FactoryWriter { private ImmutableList<ParameterSpec> parameters(Iterable<Parameter> parameters) { ImmutableList.Builder<ParameterSpec> builder = ImmutableList.builder(); for (Parameter parameter : parameters) { - ParameterSpec.Builder parameterBuilder = - ParameterSpec.builder(resolveTypeName(parameter.type().get()), parameter.name()); - for (AnnotationMirror annotation : - Iterables.concat(parameter.nullable().asSet(), parameter.key().qualifier().asSet())) { - parameterBuilder.addAnnotation(AnnotationSpec.get(annotation)); - } - builder.add(parameterBuilder.build()); + TypeName type = resolveTypeName(parameter.type().get()); + // Remove TYPE_USE annotations, since resolveTypeName will already have included those in + // the TypeName it returns. + List<AnnotationSpec> annotations = + Stream.of(parameter.nullable(), parameter.key().qualifier()) + .flatMap(Streams::stream) + .filter(a -> !isTypeUseAnnotation(a)) + .map(AnnotationSpec::get) + .collect(toList()); + ParameterSpec parameterSpec = + ParameterSpec.builder(type, parameter.name()).addAnnotations(annotations).build(); + builder.add(parameterSpec); } return builder.build(); } + private static boolean isTypeUseAnnotation(AnnotationMirror mirror) { + Element annotationElement = mirror.getAnnotationType().asElement(); + // This is basically equivalent to: + // Target target = annotationElement.getAnnotation(Target.class); + // return target != null + // && Arrays.asList(annotationElement.getAnnotation(Target.class)).contains(TYPE_USE); + // but that might blow up if the annotation is being compiled at the same time and has an + // undefined identifier in its @Target values. The rigmarole below avoids that problem. + Optional<AnnotationMirror> maybeTargetMirror = + Mirrors.getAnnotationMirror(annotationElement, Target.class); + return maybeTargetMirror + .map( + targetMirror -> + AnnotationValues.getEnums( + AnnotationMirrors.getAnnotationValue(targetMirror, "value")) + .stream() + .map(VariableElement::getSimpleName) + .anyMatch(name -> name.contentEquals("TYPE_USE"))) + .orElse(false); + } + private static void addCheckNotNullMethod( TypeSpec.Builder factory, FactoryDescriptor descriptor) { if (shouldGenerateCheckNotNull(descriptor)) { @@ -290,17 +316,20 @@ final class FactoryWriter { * {@code @AutoFactory class Foo} has a constructor parameter of type {@code BarFactory} and * {@code @AutoFactory class Bar} has a constructor parameter of type {@code FooFactory}. We did * in fact find instances of this in Google's source base. + * + * <p>If the type has type annotations then include those in the returned {@link TypeName}. */ private TypeName resolveTypeName(TypeMirror type) { - if (type.getKind() != TypeKind.ERROR) { - return TypeName.get(type); - } - ImmutableSet<PackageAndClass> factoryNames = factoriesBeingCreated.get(type.toString()); - if (factoryNames.size() == 1) { - PackageAndClass packageAndClass = Iterables.getOnlyElement(factoryNames); - return ClassName.get(packageAndClass.packageName(), packageAndClass.className()); + TypeName typeName = TypeName.get(type); + if (type.getKind() == TypeKind.ERROR) { + ImmutableSet<PackageAndClass> factoryNames = factoriesBeingCreated.get(type.toString()); + if (factoryNames.size() == 1) { + PackageAndClass packageAndClass = Iterables.getOnlyElement(factoryNames); + typeName = ClassName.get(packageAndClass.packageName(), packageAndClass.className()); + } } - return TypeName.get(type); + return typeName.annotated( + type.getAnnotationMirrors().stream().map(AnnotationSpec::get).collect(toList())); } private static ImmutableSet<TypeVariableName> getFactoryTypeVariables( diff --git a/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java index 9ddc249f..b2705b7e 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java +++ b/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java @@ -22,21 +22,25 @@ import javax.lang.model.type.TypeMirror; @AutoValue abstract class ImplementationMethodDescriptor { abstract String name(); + abstract TypeMirror returnType(); + abstract boolean publicMethod(); + abstract ImmutableSet<Parameter> passedParameters(); + abstract boolean isVarArgs(); + abstract ImmutableSet<TypeMirror> exceptions(); + static Builder builder() { - return new AutoValue_ImplementationMethodDescriptor.Builder() - .publicMethod(true) - .isVarArgs(false); + return new AutoValue_ImplementationMethodDescriptor.Builder(); } @AutoValue.Builder - static abstract class Builder { + abstract static class Builder { abstract Builder name(String name); - + abstract Builder returnType(TypeMirror returnTypeElement); abstract Builder publicMethod(boolean publicMethod); @@ -49,6 +53,8 @@ abstract class ImplementationMethodDescriptor { abstract Builder isVarArgs(boolean isVarargs); + abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions); + abstract ImplementationMethodDescriptor build(); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/Key.java b/factory/src/main/java/com/google/auto/factory/processor/Key.java index 04bd4f37..728149eb 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/Key.java +++ b/factory/src/main/java/com/google/auto/factory/processor/Key.java @@ -24,9 +24,8 @@ import com.google.auto.common.AnnotationMirrors; import com.google.auto.common.MoreTypes; import com.google.auto.value.AutoValue; import com.google.common.base.Equivalence; -import com.google.common.base.Optional; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableSet; +import java.util.Collection; +import java.util.Optional; import javax.inject.Qualifier; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.type.TypeMirror; @@ -65,17 +64,15 @@ abstract class Key { * <tr><td>{@code int} <td>{@code Integer} * </table> */ - static Key create( - TypeMirror type, Iterable<? extends AnnotationMirror> annotations, Types types) { - ImmutableSet.Builder<AnnotationMirror> qualifiers = ImmutableSet.builder(); - for (AnnotationMirror annotation : annotations) { - if (isAnnotationPresent(annotation.getAnnotationType().asElement(), Qualifier.class)) { - qualifiers.add(annotation); - } - } - + static Key create(TypeMirror type, Collection<AnnotationMirror> annotations, Types types) { // TODO(gak): check for only one qualifier rather than using the first - Optional<AnnotationMirror> qualifier = FluentIterable.from(qualifiers.build()).first(); + Optional<AnnotationMirror> qualifier = + annotations.stream() + .filter( + annotation -> + isAnnotationPresent( + annotation.getAnnotationType().asElement(), Qualifier.class)) + .findFirst(); TypeMirror keyType = isProvider(type) @@ -97,7 +94,7 @@ abstract class Key { } @Override - public String toString() { + public final String toString() { String typeQualifiedName = MoreTypes.asTypeElement(type().get()).toString(); return qualifier().isPresent() ? qualifier().get() + "/" + typeQualifiedName diff --git a/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java b/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java index c5b7d8bf..313fc9ee 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java +++ b/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java @@ -17,11 +17,11 @@ package com.google.auto.factory.processor; import com.google.auto.common.MoreTypes; import com.google.common.base.Equivalence; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import java.lang.annotation.Annotation; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import javax.inject.Provider; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -34,20 +34,23 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleElementVisitor6; final class Mirrors { - private Mirrors() { } + private Mirrors() {} static Name getQualifiedName(DeclaredType type) { - return type.asElement().accept(new SimpleElementVisitor6<Name, Void>() { - @Override - protected Name defaultAction(Element e, Void p) { - throw new AssertionError("DeclaredTypes should be TypeElements"); - } + return type.asElement() + .accept( + new SimpleElementVisitor6<Name, Void>() { + @Override + protected Name defaultAction(Element e, Void p) { + throw new AssertionError("DeclaredTypes should be TypeElements"); + } - @Override - public Name visitType(TypeElement e, Void p) { - return e.getQualifiedName(); - } - }, null); + @Override + public Name visitType(TypeElement e, Void p) { + return e.getQualifiedName(); + } + }, + null); } /** {@code true} if {@code type} is a {@link Provider}. */ @@ -62,8 +65,8 @@ final class Mirrors { static ImmutableMap<String, AnnotationValue> simplifyAnnotationValueMap( Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValueMap) { ImmutableMap.Builder<String, AnnotationValue> builder = ImmutableMap.builder(); - for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry - : annotationValueMap.entrySet()) { + for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : + annotationValueMap.entrySet()) { builder.put(entry.getKey().getSimpleName().toString(), entry.getValue()); } return builder.build(); @@ -73,15 +76,13 @@ final class Mirrors { * Get the {@link AnnotationMirror} for the type {@code annotationType} present on the given * {@link Element} if it exists. */ - static Optional<AnnotationMirror> getAnnotationMirror(Element element, - Class<? extends Annotation> annotationType) { + static Optional<AnnotationMirror> getAnnotationMirror( + Element element, Class<? extends Annotation> annotationType) { String annotationName = annotationType.getName(); - for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { - if (getQualifiedName(annotationMirror.getAnnotationType()).contentEquals(annotationName)) { - return Optional.of(annotationMirror); - } - } - return Optional.absent(); + return element.getAnnotationMirrors().stream() + .filter(a -> getQualifiedName(a.getAnnotationType()).contentEquals(annotationName)) + .<AnnotationMirror>map(x -> x) // get rid of wildcard <? extends AnnotationMirror> + .findFirst(); } /** @@ -91,9 +92,7 @@ final class Mirrors { // TODO(ronshapiro): this is used in AutoFactory and Dagger, consider moving it into auto-common. static <T> Optional<Equivalence.Wrapper<T>> wrapOptionalInEquivalence( Equivalence<T> equivalence, Optional<T> optional) { - return optional.isPresent() - ? Optional.of(equivalence.wrap(optional.get())) - : Optional.<Equivalence.Wrapper<T>>absent(); + return optional.map(equivalence::wrap); } /** @@ -102,8 +101,6 @@ final class Mirrors { */ static <T> Optional<T> unwrapOptionalEquivalence( Optional<Equivalence.Wrapper<T>> wrappedOptional) { - return wrappedOptional.isPresent() - ? Optional.of(wrappedOptional.get().get()) - : Optional.<T>absent(); + return wrappedOptional.map(Equivalence.Wrapper::get); } } diff --git a/factory/src/main/java/com/google/auto/factory/processor/Parameter.java b/factory/src/main/java/com/google/auto/factory/processor/Parameter.java index 781225a2..c5059ece 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/Parameter.java +++ b/factory/src/main/java/com/google/auto/factory/processor/Parameter.java @@ -18,19 +18,20 @@ package com.google.auto.factory.processor; import static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence; import static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.stream.Collectors.toList; import com.google.auto.common.AnnotationMirrors; import com.google.auto.common.MoreElements; import com.google.auto.common.MoreTypes; import com.google.auto.value.AutoValue; import com.google.common.base.Equivalence; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Stream; import javax.inject.Provider; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.TypeElement; @@ -63,6 +64,7 @@ abstract class Parameter { abstract String name(); abstract Key key(); + abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper(); Optional<AnnotationMirror> nullable() { @@ -71,15 +73,12 @@ abstract class Parameter { private static Parameter forVariableElement( VariableElement variable, TypeMirror type, Types types) { - Optional<AnnotationMirror> nullable = Optional.absent(); - Iterable<? extends AnnotationMirror> annotations = - Iterables.concat(variable.getAnnotationMirrors(), type.getAnnotationMirrors()); - for (AnnotationMirror annotation : annotations) { - if (isNullable(annotation)) { - nullable = Optional.of(annotation); - break; - } - } + List<AnnotationMirror> annotations = + Stream.of(variable.getAnnotationMirrors(), type.getAnnotationMirrors()) + .flatMap(List::stream) + .collect(toList()); + Optional<AnnotationMirror> nullable = + annotations.stream().filter(Parameter::isNullable).findFirst(); Key key = Key.create(type, annotations, types); return new AutoValue_Parameter( @@ -108,7 +107,7 @@ abstract class Parameter { Set<String> names = Sets.newHashSetWithExpectedSize(variables.size()); for (int i = 0; i < variables.size(); i++) { Parameter parameter = forVariableElement(variables.get(i), variableTypes.get(i), types); - checkArgument(names.add(parameter.name())); + checkArgument(names.add(parameter.name()), "Duplicate parameter name: %s", parameter.name()); builder.add(parameter); } ImmutableSet<Parameter> parameters = builder.build(); diff --git a/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java index fe4c1fd2..bd88f837 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java +++ b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java @@ -26,6 +26,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.VariableElement; import javax.lang.model.util.ElementKindVisitor6; +import org.checkerframework.checker.nullness.qual.Nullable; final class ProvidedChecker { private final Messager messager; @@ -35,41 +36,54 @@ final class ProvidedChecker { } void checkProvidedParameter(Element element) { - checkArgument(isAnnotationPresent(element, Provided.class), "%s not annoated with @Provided", - element); - element.accept(new ElementKindVisitor6<Void, Void>() { - @Override - protected Void defaultAction(Element e, Void p) { - throw new AssertionError("Provided can only be applied to parameters"); - } - - @Override - public Void visitVariableAsParameter(final VariableElement providedParameter, Void p) { - providedParameter.getEnclosingElement().accept(new ElementKindVisitor6<Void, Void>() { + checkArgument( + isAnnotationPresent(element, Provided.class), "%s not annoated with @Provided", element); + element.accept( + new ElementKindVisitor6<@Nullable Void, @Nullable Void>() { @Override - protected Void defaultAction(Element e, Void p) { - raiseError(providedParameter, "@%s may only be applied to constructor parameters"); - return null; + protected @Nullable Void defaultAction(Element e, @Nullable Void p) { + throw new AssertionError("Provided can only be applied to parameters"); } @Override - public Void visitExecutableAsConstructor(ExecutableElement constructor, Void p) { - if (!(annotatedWithAutoFactory(constructor) - || annotatedWithAutoFactory(constructor.getEnclosingElement()))) { - raiseError(providedParameter, - "@%s may only be applied to constructors requesting an auto-factory"); - } + public @Nullable Void visitVariableAsParameter( + VariableElement providedParameter, @Nullable Void p) { + providedParameter + .getEnclosingElement() + .accept( + new ElementKindVisitor6<@Nullable Void, @Nullable Void>() { + @Override + protected @Nullable Void defaultAction(Element e, @Nullable Void p) { + raiseError( + providedParameter, "@%s may only be applied to constructor parameters"); + return null; + } + + @Override + public @Nullable Void visitExecutableAsConstructor( + ExecutableElement constructor, @Nullable Void p) { + if (!(annotatedWithAutoFactory(constructor) + || annotatedWithAutoFactory(constructor.getEnclosingElement()))) { + raiseError( + providedParameter, + "@%s may only be applied to constructors requesting an auto-factory"); + } + return null; + } + }, + p); return null; } - }, p); - return null; - } - }, null); + }, + null); } private void raiseError(VariableElement providedParameter, String messageFormat) { - messager.printMessage(ERROR, String.format(messageFormat, Provided.class.getSimpleName()), - providedParameter, Mirrors.getAnnotationMirror(providedParameter, Provided.class).get()); + messager.printMessage( + ERROR, + String.format(messageFormat, Provided.class.getSimpleName()), + providedParameter, + Mirrors.getAnnotationMirror(providedParameter, Provided.class).get()); } private static boolean annotatedWithAutoFactory(Element e) { diff --git a/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java b/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java index 855c1feb..99847ec0 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java +++ b/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java @@ -21,13 +21,15 @@ import static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalenc import com.google.auto.common.AnnotationMirrors; import com.google.auto.value.AutoValue; import com.google.common.base.Equivalence; -import com.google.common.base.Optional; +import java.util.Optional; import javax.lang.model.element.AnnotationMirror; @AutoValue abstract class ProviderField { abstract String name(); + abstract Key key(); + abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper(); Optional<AnnotationMirror> nullable() { diff --git a/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java index 1f894732..4bd546e8 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java +++ b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java @@ -38,8 +38,8 @@ final class TypeVariables { return type.accept(ReferencedTypeVariables.INSTANCE, new HashSet<>()); } - private static final class ReferencedTypeVariables extends - SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Set<Element>> { + private static final class ReferencedTypeVariables + extends SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Set<Element>> { private static final ReferencedTypeVariables INSTANCE = new ReferencedTypeVariables(); @@ -53,8 +53,7 @@ final class TypeVariables { } @Override - public ImmutableSet<TypeVariable> visitDeclared( - DeclaredType t, Set<Element> visited) { + public ImmutableSet<TypeVariable> visitDeclared(DeclaredType t, Set<Element> visited) { if (!visited.add(t.asElement())) { return ImmutableSet.of(); } @@ -66,8 +65,7 @@ final class TypeVariables { } @Override - public ImmutableSet<TypeVariable> visitTypeVariable( - TypeVariable t, Set<Element> visited) { + public ImmutableSet<TypeVariable> visitTypeVariable(TypeVariable t, Set<Element> visited) { if (!visited.add(t.asElement())) { return ImmutableSet.of(); } @@ -79,8 +77,7 @@ final class TypeVariables { } @Override - public ImmutableSet<TypeVariable> visitUnion( - UnionType t, Set<Element> visited) { + public ImmutableSet<TypeVariable> visitUnion(UnionType t, Set<Element> visited) { ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder(); for (TypeMirror unionType : t.getAlternatives()) { typeVariables.addAll(unionType.accept(this, visited)); @@ -89,8 +86,7 @@ final class TypeVariables { } @Override - public ImmutableSet<TypeVariable> visitIntersection( - IntersectionType t, Set<Element> visited) { + public ImmutableSet<TypeVariable> visitIntersection(IntersectionType t, Set<Element> visited) { ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder(); for (TypeMirror intersectionType : t.getBounds()) { typeVariables.addAll(intersectionType.accept(this, visited)); @@ -99,8 +95,7 @@ final class TypeVariables { } @Override - public ImmutableSet<TypeVariable> visitWildcard( - WildcardType t, Set<Element> visited) { + public ImmutableSet<TypeVariable> visitWildcard(WildcardType t, Set<Element> visited) { ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder(); TypeMirror extendsBound = t.getExtendsBound(); if (extendsBound != null) { diff --git a/factory/src/main/java/com/google/auto/factory/processor/package-info.java b/factory/src/main/java/com/google/auto/factory/processor/package-info.java index 7339020a..4a7c4b10 100644 --- a/factory/src/main/java/com/google/auto/factory/processor/package-info.java +++ b/factory/src/main/java/com/google/auto/factory/processor/package-info.java @@ -15,4 +15,5 @@ * This package contains the annotation processor that implements the * {@link com.google.auto.factory.AutoFactory} API. */ -package com.google.auto.factory.processor;
\ No newline at end of file +package com.google.auto.factory.processor; + diff --git a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java index 1b23a65d..7bef2334 100644 --- a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java +++ b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java @@ -24,7 +24,8 @@ import org.junit.runners.JUnit4; @RunWith(JUnit4.class) public class AutoFactoryDeclarationTest { - @Test public void identifiers() { + @Test + public void identifiers() { assertThat(isValidIdentifier("String")).isTrue(); assertThat(isValidIdentifier("9CantStartWithNumber")).isFalse(); assertThat(isValidIdentifier("enum")).isFalse(); diff --git a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java index 3088bb2e..0df4c9ca 100644 --- a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java +++ b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java @@ -15,15 +15,16 @@ */ package com.google.auto.factory.processor; -import static com.google.common.truth.Truth.assertAbout; -import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource; -import static com.google.testing.compile.JavaSourcesSubject.assertThat; -import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources; +import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION; +import static com.google.common.truth.TruthJUnit.assume; +import static com.google.testing.compile.CompilationSubject.assertThat; +import static java.lang.Math.max; +import static java.lang.Math.min; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.common.collect.ImmutableSet; import com.google.common.io.Resources; -import com.google.testing.compile.CompilationRule; +import com.google.testing.compile.Compilation; +import com.google.testing.compile.Compiler; import com.google.testing.compile.JavaFileObjects; import java.io.IOException; import java.io.UncheckedIOException; @@ -31,415 +32,489 @@ import java.util.Collections; import java.util.List; import javax.lang.model.SourceVersion; import javax.tools.JavaFileObject; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * Functional tests for the {@link AutoFactoryProcessor}. - */ +/** Functional tests for the {@link AutoFactoryProcessor}. */ @RunWith(JUnit4.class) public class AutoFactoryProcessorTest { + private final Compiler javac = Compiler.javac().withProcessors(new AutoFactoryProcessor()); - @Rule public final CompilationRule compilationRule = new CompilationRule(); + @Test + public void simpleClass() { + Compilation compilation = javac.compile(JavaFileObjects.forResource("good/SimpleClass.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassFactory.java")); + } - @Test public void simpleClass() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClass.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassFactory.java")); + @Test + public void simpleClassWithConstructorThrowsClause() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassThrows.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassThrowsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassThrowsFactory.java")); } @Test public void nestedClasses() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/NestedClasses.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( - loadExpectedFile("expected/NestedClasses_SimpleNestedClassFactory.java"), - loadExpectedFile("expected/NestedClassCustomNamedFactory.java")); - } - - @Test public void simpleClassNonFinal() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClassNonFinal.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassNonFinalFactory.java")); - } - - @Test public void publicClass() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/PublicClass.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/PublicClassFactory.java")); - } - - @Test public void simpleClassCustomName() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClassCustomName.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/CustomNamedFactory.java")); - } - - @Test public void simpleClassMixedDeps() { - assertAbout(javaSources()) - .that( - ImmutableSet.of( - JavaFileObjects.forResource("good/SimpleClassMixedDeps.java"), - JavaFileObjects.forResource("support/AQualifier.java"))) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassMixedDepsFactory.java")); - } - - @Test public void simpleClassPassedDeps() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClassPassedDeps.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassPassedDepsFactory.java")); - } - - @Test public void simpleClassProvidedDeps() { - assertAbout(javaSources()) - .that( - ImmutableSet.of( - JavaFileObjects.forResource("support/AQualifier.java"), - JavaFileObjects.forResource("support/BQualifier.java"), - JavaFileObjects.forResource("good/SimpleClassProvidedDeps.java"))) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassProvidedDepsFactory.java")); + Compilation compilation = javac.compile(JavaFileObjects.forResource("good/NestedClasses.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.NestedClasses_SimpleNestedClassFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/NestedClasses_SimpleNestedClassFactory.java")); + assertThat(compilation) + .generatedSourceFile("tests.NestedClassCustomNamedFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/NestedClassCustomNamedFactory.java")); + } + + @Test + public void simpleClassNonFinal() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassNonFinal.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassNonFinalFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassNonFinalFactory.java")); + } + + @Test + public void publicClass() { + Compilation compilation = javac.compile(JavaFileObjects.forResource("good/PublicClass.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.PublicClassFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/PublicClassFactory.java")); + } + + @Test + public void simpleClassCustomName() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassCustomName.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.CustomNamedFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/CustomNamedFactory.java")); + } + + @Test + public void simpleClassMixedDeps() { + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("good/SimpleClassMixedDeps.java"), + JavaFileObjects.forResource("support/AQualifier.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassMixedDepsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassMixedDepsFactory.java")); + } + + @Test + public void simpleClassPassedDeps() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassPassedDeps.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassPassedDepsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassPassedDepsFactory.java")); + } + + @Test + public void simpleClassProvidedDeps() { + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("support/AQualifier.java"), + JavaFileObjects.forResource("support/BQualifier.java"), + JavaFileObjects.forResource("good/SimpleClassProvidedDeps.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassProvidedDepsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassProvidedDepsFactory.java")); } @Test public void simpleClassProvidedProviderDeps() { - assertAbout(javaSources()) - .that( - ImmutableSet.of( - JavaFileObjects.forResource("support/AQualifier.java"), - JavaFileObjects.forResource("support/BQualifier.java"), - JavaFileObjects.forResource("good/SimpleClassProvidedProviderDeps.java"))) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassProvidedProviderDepsFactory.java")); - } - - @Test public void constructorAnnotated() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/ConstructorAnnotated.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/ConstructorAnnotatedFactory.java")); - } - - @Test public void constructorAnnotatedNonFinal() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/ConstructorAnnotatedNonFinal.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/ConstructorAnnotatedNonFinalFactory.java")); - } - - @Test public void simpleClassImplementingMarker() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClassImplementingMarker.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassImplementingMarkerFactory.java")); - } - - @Test public void simpleClassImplementingSimpleInterface() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/SimpleClassImplementingSimpleInterface.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("support/AQualifier.java"), + JavaFileObjects.forResource("support/BQualifier.java"), + JavaFileObjects.forResource("good/SimpleClassProvidedProviderDeps.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassProvidedProviderDepsFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/SimpleClassProvidedProviderDepsFactory.java")); + } + + @Test + public void constructorAnnotated() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/ConstructorAnnotated.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.ConstructorAnnotatedFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/ConstructorAnnotatedFactory.java")); + } + + @Test + public void constructorWithThrowsClauseAnnotated() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/ConstructorAnnotatedThrows.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.ConstructorAnnotatedThrowsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/ConstructorAnnotatedThrowsFactory.java")); + } + + @Test + public void constructorAnnotatedNonFinal() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/ConstructorAnnotatedNonFinal.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.ConstructorAnnotatedNonFinalFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/ConstructorAnnotatedNonFinalFactory.java")); + } + + @Test + public void simpleClassImplementingMarker() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassImplementingMarker.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassImplementingMarkerFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/SimpleClassImplementingMarkerFactory.java")); + } + + @Test + public void simpleClassImplementingSimpleInterface() { + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("good/SimpleClassImplementingSimpleInterface.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassImplementingSimpleInterfaceFactory") + .hasSourceEquivalentTo( loadExpectedFile("expected/SimpleClassImplementingSimpleInterfaceFactory.java")); } - @Test public void mixedDepsImplementingInterfaces() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/MixedDepsImplementingInterfaces.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/MixedDepsImplementingInterfacesFactory.java")); + @Test + public void mixedDepsImplementingInterfaces() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/MixedDepsImplementingInterfaces.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.MixedDepsImplementingInterfacesFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/MixedDepsImplementingInterfacesFactory.java")); } - @Test public void failsWithMixedFinals() { + @Test + public void failsWithMixedFinals() { JavaFileObject file = JavaFileObjects.forResource("bad/MixedFinals.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining( + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.") - .in(file).onLine(24) - .and().withErrorContaining( + .inFile(file) + .onLine(24); + assertThat(compilation) + .hadErrorContaining( "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.") - .in(file).onLine(27); + .inFile(file) + .onLine(27); } - @Test public void providedButNoAutoFactory() { + @Test + public void providedButNoAutoFactory() { JavaFileObject file = JavaFileObjects.forResource("bad/ProvidedButNoAutoFactory.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining( + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( "@Provided may only be applied to constructors requesting an auto-factory") - .in(file).onLine(21).atColumn(38); + .inFile(file) + .onLineContaining("@Provided"); } - @Test public void providedOnMethodParameter() { + @Test + public void providedOnMethodParameter() { JavaFileObject file = JavaFileObjects.forResource("bad/ProvidedOnMethodParameter.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining( - "@Provided may only be applied to constructor parameters") - .in(file).onLine(21).atColumn(23); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining("@Provided may only be applied to constructor parameters") + .inFile(file) + .onLineContaining("@Provided"); } - @Test public void invalidCustomName() { + @Test + public void invalidCustomName() { JavaFileObject file = JavaFileObjects.forResource("bad/InvalidCustomName.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining("\"SillyFactory!\" is not a valid Java identifier") - .in(file).onLine(20); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining("\"SillyFactory!\" is not a valid Java identifier") + .inFile(file) + .onLineContaining("SillyFactory!"); + } + + @Test + public void factoryExtendingAbstractClass() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/FactoryExtendingAbstractClass.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.FactoryExtendingAbstractClassFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/FactoryExtendingAbstractClassFactory.java")); + } + + @Test + public void factoryWithConstructorThrowsClauseExtendingAbstractClass() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/FactoryExtendingAbstractClassThrows.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.FactoryExtendingAbstractClassThrowsFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/FactoryExtendingAbstractClassThrowsFactory.java")); } - @Test public void factoryExtendingAbstractClass() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/FactoryExtendingAbstractClass.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/FactoryExtendingAbstractClassFactory.java")); + @Test + public void factoryExtendingAbstractClass_withConstructorParams() { + JavaFileObject file = + JavaFileObjects.forResource("bad/FactoryExtendingAbstractClassWithConstructorParams.java"); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( + "tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory is not a" + + " valid supertype for a factory. Factory supertypes must have a no-arg" + + " constructor.") + .inFile(file) + .onLineContaining("@AutoFactory"); } - @Test public void factoryExtendingAbstractClass_withConstructorParams() { + @Test + public void factoryExtendingAbstractClass_multipleConstructors() { JavaFileObject file = - JavaFileObjects.forResource("good/FactoryExtendingAbstractClassWithConstructorParams.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining( - "tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory " - + "is not a valid supertype for a factory. " - + "Factory supertypes must have a no-arg constructor.") - .in(file).onLine(21); - } - - @Test public void factoryExtendingAbstractClass_multipleConstructors() { - JavaFileObject file = JavaFileObjects.forResource( - "good/FactoryExtendingAbstractClassWithMultipleConstructors.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError(); - } - - @Test public void factoryExtendingInterface() { + JavaFileObjects.forResource( + "good/FactoryExtendingAbstractClassWithMultipleConstructors.java"); + Compilation compilation = javac.compile(file); + assertThat(compilation).succeededWithoutWarnings(); + } + + @Test + public void factoryExtendingInterface() { JavaFileObject file = JavaFileObjects.forResource("bad/InterfaceSupertype.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining("java.lang.Runnable is not a valid supertype for a factory. " - + "Supertypes must be non-final classes.") - .in(file).onLine(20); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( + "java.lang.Runnable is not a valid supertype for a factory. Supertypes must be" + + " non-final classes.") + .inFile(file) + .onLineContaining("@AutoFactory"); } - @Test public void factoryExtendingEnum() { + @Test + public void factoryExtendingEnum() { JavaFileObject file = JavaFileObjects.forResource("bad/EnumSupertype.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining( - "java.util.concurrent.TimeUnit is not a valid supertype for a factory. " - + "Supertypes must be non-final classes.") - .in(file).onLine(21); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( + "java.util.concurrent.TimeUnit is not a valid supertype for a factory. Supertypes must" + + " be non-final classes.") + .inFile(file) + .onLineContaining("@AutoFactory"); } - @Test public void factoryExtendingFinalClass() { + @Test + public void factoryExtendingFinalClass() { JavaFileObject file = JavaFileObjects.forResource("bad/FinalSupertype.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .failsToCompile() - .withErrorContaining("java.lang.Boolean is not a valid supertype for a factory. " - + "Supertypes must be non-final classes.") - .in(file).onLine(20); + Compilation compilation = javac.compile(file); + assertThat(compilation).failed(); + assertThat(compilation) + .hadErrorContaining( + "java.lang.Boolean is not a valid supertype for a factory. Supertypes must be" + + " non-final classes.") + .inFile(file) + .onLineContaining("@AutoFactory"); } - @Test public void factoryImplementingGenericInterfaceExtension() { + @Test + public void factoryImplementingGenericInterfaceExtension() { JavaFileObject file = JavaFileObjects.forResource("good/FactoryImplementingGenericInterfaceExtension.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( + Compilation compilation = javac.compile(file); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.FactoryImplementingGenericInterfaceExtensionFactory") + .hasSourceEquivalentTo( loadExpectedFile("expected/FactoryImplementingGenericInterfaceExtensionFactory.java")); } - @Test public void multipleFactoriesImpementingInterface() { + @Test + public void multipleFactoriesImpementingInterface() { JavaFileObject file = JavaFileObjects.forResource("good/MultipleFactoriesImplementingInterface.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( - loadExpectedFile("expected/MultipleFactoriesImplementingInterface_ClassAFactory.java"), + Compilation compilation = javac.compile(file); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.MultipleFactoriesImplementingInterface_ClassAFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/MultipleFactoriesImplementingInterface_ClassAFactory.java")); + assertThat(compilation) + .generatedSourceFile("tests.MultipleFactoriesImplementingInterface_ClassBFactory") + .hasSourceEquivalentTo( loadExpectedFile("expected/MultipleFactoriesImplementingInterface_ClassBFactory.java")); } - @Test public void classUsingQualifierWithArgs() { - assertAbout(javaSources()) - .that( - ImmutableSet.of( - JavaFileObjects.forResource("support/QualifierWithArgs.java"), - JavaFileObjects.forResource("good/ClassUsingQualifierWithArgs.java"))) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/ClassUsingQualifierWithArgsFactory.java")); + @Test + public void classUsingQualifierWithArgs() { + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("support/QualifierWithArgs.java"), + JavaFileObjects.forResource("good/ClassUsingQualifierWithArgs.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.ClassUsingQualifierWithArgsFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/ClassUsingQualifierWithArgsFactory.java")); } - @Test public void factoryImplementingInterfaceWhichRedeclaresCreateMethods() { - JavaFileObject file = - JavaFileObjects.forResource("good/FactoryImplementingCreateMethod.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( + @Test + public void factoryImplementingInterfaceWhichRedeclaresCreateMethods() { + JavaFileObject file = JavaFileObjects.forResource("good/FactoryImplementingCreateMethod.java"); + Compilation compilation = javac.compile(file); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.FactoryImplementingCreateMethod_ConcreteClassFactory") + .hasSourceEquivalentTo( loadExpectedFile("expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java")); } - @Test public void nullableParams() { - assertAbout(javaSources()) - .that( - ImmutableSet.of( - JavaFileObjects.forResource("good/SimpleClassNullableParameters.java"), - JavaFileObjects.forResource("support/AQualifier.java"), - JavaFileObjects.forResource("support/BQualifier.java"))) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassNullableParametersFactory.java")); - } - - @Test public void customNullableType() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/CustomNullable.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/CustomNullableFactory.java")); - } - - @Test public void checkerFrameworkNullableType() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/CheckerFrameworkNullable.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/CheckerFrameworkNullableFactory.java")); - } - - @Test public void multipleProvidedParamsWithSameKey() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/MultipleProvidedParamsSameKey.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/MultipleProvidedParamsSameKeyFactory.java")); - } - - @Test public void providerArgumentToCreateMethod() { - assertAbout(javaSource()) - .that(JavaFileObjects.forResource("good/ProviderArgumentToCreateMethod.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/ProviderArgumentToCreateMethodFactory.java")); - } - - @Test public void multipleFactoriesConflictingParameterNames() { - assertThat( + @Test + public void nullableParams() { + Compilation compilation = + javac.compile( + JavaFileObjects.forResource("good/SimpleClassNullableParameters.java"), + JavaFileObjects.forResource("support/AQualifier.java"), + JavaFileObjects.forResource("support/BQualifier.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassNullableParametersFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/SimpleClassNullableParametersFactory.java")); + } + + @Test + public void customNullableType() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/CustomNullable.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.CustomNullableFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/CustomNullableFactory.java")); + } + + @Test + public void checkerFrameworkNullableType() { + // TYPE_USE annotations are pretty much unusable with annotation processors on Java 8 because + // of bugs that mean they only appear in the javax.lang.model API when the compiler feels like + // it. Checking for a java.specification.version that does not start with "1." eliminates 8 and + // any earlier version. + assume().that(JAVA_SPECIFICATION_VERSION.value()).doesNotMatch("1\\..*"); + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/CheckerFrameworkNullable.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.CheckerFrameworkNullableFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/CheckerFrameworkNullableFactory.java")); + } + + @Test + public void multipleProvidedParamsWithSameKey() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/MultipleProvidedParamsSameKey.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.MultipleProvidedParamsSameKeyFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/MultipleProvidedParamsSameKeyFactory.java")); + } + + @Test + public void providerArgumentToCreateMethod() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/ProviderArgumentToCreateMethod.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.ProviderArgumentToCreateMethodFactory") + .hasSourceEquivalentTo( + loadExpectedFile("expected/ProviderArgumentToCreateMethodFactory.java")); + } + + @Test + public void multipleFactoriesConflictingParameterNames() { + Compilation compilation = + javac.compile( JavaFileObjects.forResource("good/MultipleFactoriesConflictingParameterNames.java"), - JavaFileObjects.forResource("support/AQualifier.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources( + JavaFileObjects.forResource("support/AQualifier.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.MultipleFactoriesConflictingParameterNamesFactory") + .hasSourceEquivalentTo( loadExpectedFile("expected/MultipleFactoriesConflictingParameterNamesFactory.java")); } - @Test public void factoryVarargs() { - assertThat(JavaFileObjects.forResource("good/SimpleClassVarargs.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/SimpleClassVarargsFactory.java")); + @Test + public void factoryVarargs() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/SimpleClassVarargs.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.SimpleClassVarargsFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/SimpleClassVarargsFactory.java")); } - @Test public void onlyPrimitives() { - assertThat(JavaFileObjects.forResource("good/OnlyPrimitives.java")) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/OnlyPrimitivesFactory.java")); + @Test + public void onlyPrimitives() { + Compilation compilation = + javac.compile(JavaFileObjects.forResource("good/OnlyPrimitives.java")); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("tests.OnlyPrimitivesFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/OnlyPrimitivesFactory.java")); } @Test public void defaultPackage() { JavaFileObject file = JavaFileObjects.forResource("good/DefaultPackage.java"); - assertAbout(javaSource()) - .that(file) - .processedWith(new AutoFactoryProcessor()) - .compilesWithoutError() - .and() - .generatesSources(loadExpectedFile("expected/DefaultPackageFactory.java")); + Compilation compilation = javac.compile(file); + assertThat(compilation).succeededWithoutWarnings(); + assertThat(compilation) + .generatedSourceFile("DefaultPackageFactory") + .hasSourceEquivalentTo(loadExpectedFile("expected/DefaultPackageFactory.java")); } private JavaFileObject loadExpectedFile(String resourceName) { + if (isJavaxAnnotationProcessingGeneratedAvailable()) { + return JavaFileObjects.forResource(resourceName); + } try { List<String> sourceLines = Resources.readLines(Resources.getResource(resourceName), UTF_8); - if (!isJavaxAnnotationProcessingGeneratedAvailable()) { - replaceGeneratedImport(sourceLines); - } + replaceGeneratedImport(sourceLines); return JavaFileObjects.forSourceLines( resourceName.replace('/', '.').replace(".java", ""), sourceLines); } catch (IOException e) { @@ -457,8 +532,8 @@ public class AutoFactoryProcessorTest { int lastImport = -1; for (String line : sourceLines) { if (line.startsWith("import ") && !line.startsWith("import static ")) { - firstImport = Math.min(firstImport, i); - lastImport = Math.max(lastImport, i); + firstImport = min(firstImport, i); + lastImport = max(lastImport, i); } i++; } diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithConstructorParams.java b/factory/src/test/resources/bad/FactoryExtendingAbstractClassWithConstructorParams.java index 98c5f667..7c7120bf 100644 --- a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithConstructorParams.java +++ b/factory/src/test/resources/bad/FactoryExtendingAbstractClassWithConstructorParams.java @@ -20,9 +20,9 @@ import tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory; @AutoFactory(extending = AbstractFactory.class) final class FactoryExtendingAbstractClassWithConstructorParams { - static abstract class AbstractFactory { + abstract static class AbstractFactory { protected AbstractFactory(Object obj) {} - + abstract FactoryExtendingAbstractClassWithConstructorParams newInstance(); } } diff --git a/factory/src/test/resources/bad/InvalidCustomName.java b/factory/src/test/resources/bad/InvalidCustomName.java index 5734ee7f..6d0a2f91 100644 --- a/factory/src/test/resources/bad/InvalidCustomName.java +++ b/factory/src/test/resources/bad/InvalidCustomName.java @@ -18,4 +18,4 @@ package tests; import com.google.auto.factory.AutoFactory; @AutoFactory(className = "SillyFactory!") -final class InvalidCustomName { } +final class InvalidCustomName {} diff --git a/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java b/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java index 79175c7e..faa83971 100644 --- a/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java +++ b/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java @@ -15,6 +15,7 @@ */ package tests; +import java.util.Map; import javax.annotation.processing.Generated; import javax.inject.Inject; import javax.inject.Provider; @@ -22,26 +23,34 @@ import org.checkerframework.checker.nullness.compatqual.NullableDecl; import org.checkerframework.checker.nullness.compatqual.NullableType; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" -) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class CheckerFrameworkNullableFactory { private final Provider<String> java_lang_StringProvider; + private final Provider<Map.@NullableType Entry<?, ?>> providedNestedNullableTypeProvider; + @Inject CheckerFrameworkNullableFactory( - Provider<String> java_lang_StringProvider) { + Provider<String> java_lang_StringProvider, + Provider<Map.@NullableType Entry<?, ?>> providedNestedNullableTypeProvider) { this.java_lang_StringProvider = checkNotNull(java_lang_StringProvider, 1); + this.providedNestedNullableTypeProvider = checkNotNull(providedNestedNullableTypeProvider, 2); } CheckerFrameworkNullable create( - @NullableDecl String nullableDecl, @NullableType String nullableType) { + @NullableDecl String nullableDecl, + @NullableType String nullableType, + Map.@NullableType Entry<?, ?> nestedNullableType) { return new CheckerFrameworkNullable( nullableDecl, java_lang_StringProvider.get(), nullableType, - java_lang_StringProvider.get()); + java_lang_StringProvider.get(), + nestedNullableType, + providedNestedNullableTypeProvider.get()); } private static <T> T checkNotNull(T reference, int argumentIndex) { diff --git a/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java b/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java index b5bd89c1..8d889eed 100644 --- a/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java +++ b/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java @@ -20,14 +20,15 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class ClassUsingQualifierWithArgsFactory { private final Provider<String> providedDepAProvider; - @Inject ClassUsingQualifierWithArgsFactory( - @QualifierWithArgs(name="Fred", count=3) Provider<String> providedDepAProvider) { + @Inject + ClassUsingQualifierWithArgsFactory( + @QualifierWithArgs(name = "Fred", count = 3) Provider<String> providedDepAProvider) { this.providedDepAProvider = checkNotNull(providedDepAProvider, 1); } diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java index 6e9d242e..22349851 100644 --- a/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java +++ b/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java @@ -20,13 +20,14 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class ConstructorAnnotatedFactory { private final Provider<Object> objProvider; - @Inject ConstructorAnnotatedFactory(Provider<Object> objProvider) { + @Inject + ConstructorAnnotatedFactory(Provider<Object> objProvider) { this.objProvider = checkNotNull(objProvider, 1); } diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java index f662642d..25ec894f 100644 --- a/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java +++ b/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java @@ -20,13 +20,14 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) class ConstructorAnnotatedNonFinalFactory { private final Provider<Object> objProvider; - @Inject ConstructorAnnotatedNonFinalFactory(Provider<Object> objProvider) { + @Inject + ConstructorAnnotatedNonFinalFactory(Provider<Object> objProvider) { this.objProvider = checkNotNull(objProvider, 1); } diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java new file mode 100644 index 00000000..05b30fdf --- /dev/null +++ b/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 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 tests; + +import java.io.IOException; +import javax.annotation.processing.Generated; +import javax.inject.Inject; +import javax.inject.Provider; + +@Generated( + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) +final class ConstructorAnnotatedThrowsFactory { + private final Provider<Object> objProvider; + + @Inject + ConstructorAnnotatedThrowsFactory(Provider<Object> objProvider) { + this.objProvider = checkNotNull(objProvider, 1); + } + + ConstructorAnnotatedThrows create() throws IOException, InterruptedException { + return new ConstructorAnnotatedThrows(); + } + + ConstructorAnnotatedThrows create(String s) { + return new ConstructorAnnotatedThrows(checkNotNull(s, 1)); + } + + ConstructorAnnotatedThrows create(int i) throws IOException { + return new ConstructorAnnotatedThrows(checkNotNull(objProvider.get(), 1), i); + } + + ConstructorAnnotatedThrows create(char c) throws InterruptedException { + return new ConstructorAnnotatedThrows(checkNotNull(objProvider.get(), 1), c); + } + + private static <T> T checkNotNull(T reference, int argumentIndex) { + if (reference == null) { + throw new NullPointerException( + "@AutoFactory method argument is null but is not marked @Nullable. Argument index: " + + argumentIndex); + } + return reference; + } +} diff --git a/factory/src/test/resources/expected/CustomNamedFactory.java b/factory/src/test/resources/expected/CustomNamedFactory.java index c388387c..512c244c 100644 --- a/factory/src/test/resources/expected/CustomNamedFactory.java +++ b/factory/src/test/resources/expected/CustomNamedFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class CustomNamedFactory { - @Inject CustomNamedFactory() {} + @Inject + CustomNamedFactory() {} SimpleClassCustomName create() { return new SimpleClassCustomName(); diff --git a/factory/src/test/resources/expected/CustomNullableFactory.java b/factory/src/test/resources/expected/CustomNullableFactory.java index 31bb5bfa..c8f2f286 100644 --- a/factory/src/test/resources/expected/CustomNullableFactory.java +++ b/factory/src/test/resources/expected/CustomNullableFactory.java @@ -20,9 +20,9 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class CustomNullableFactory { private final Provider<Object> objectProvider; diff --git a/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java b/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java index c56afb0a..f35b414e 100644 --- a/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java +++ b/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java @@ -19,18 +19,20 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class FactoryExtendingAbstractClassFactory extends FactoryExtendingAbstractClass.AbstractFactory { - @Inject FactoryExtendingAbstractClassFactory() {} + @Inject + FactoryExtendingAbstractClassFactory() {} FactoryExtendingAbstractClass create() { return new FactoryExtendingAbstractClass(); } - @Override public FactoryExtendingAbstractClass newInstance() { + @Override + public FactoryExtendingAbstractClass newInstance() { return create(); } } diff --git a/factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java b/factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java new file mode 100644 index 00000000..402f8946 --- /dev/null +++ b/factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020 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 tests; + +import java.io.IOException; +import javax.annotation.processing.Generated; +import javax.inject.Inject; + +@Generated( + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) +final class FactoryExtendingAbstractClassThrowsFactory + extends FactoryExtendingAbstractClassThrows.AbstractFactory { + @Inject + FactoryExtendingAbstractClassThrowsFactory() {} + + FactoryExtendingAbstractClassThrows create() throws IOException, InterruptedException { + return new FactoryExtendingAbstractClassThrows(); + } + + @Override + public FactoryExtendingAbstractClassThrows newInstance() throws Exception { + return create(); + } +} diff --git a/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java b/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java index f23dc9ab..2d8a392d 100644 --- a/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java +++ b/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java @@ -20,9 +20,9 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class FactoryImplementingCreateMethod_ConcreteClassFactory implements FactoryImplementingCreateMethod.FactoryInterfaceWithCreateMethod { @@ -40,7 +40,8 @@ final class FactoryImplementingCreateMethod_ConcreteClassFactory } @Override - public FactoryImplementingCreateMethod.ConcreteClass create(List<Integer> genericWithDifferentArgumentName) { + public FactoryImplementingCreateMethod.ConcreteClass create( + List<Integer> genericWithDifferentArgumentName) { return new FactoryImplementingCreateMethod.ConcreteClass( checkNotNull(genericWithDifferentArgumentName, 1)); } diff --git a/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java b/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java index 3bfc5262..9f2bf0ae 100644 --- a/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java +++ b/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java @@ -20,20 +20,23 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class FactoryImplementingGenericInterfaceExtensionFactory implements FactoryImplementingGenericInterfaceExtension.MyFactory { private final Provider<String> sProvider; + @Inject FactoryImplementingGenericInterfaceExtensionFactory(Provider<String> sProvider) { this.sProvider = checkNotNull(sProvider, 1); } + FactoryImplementingGenericInterfaceExtension create(Integer i) { return new FactoryImplementingGenericInterfaceExtension( checkNotNull(sProvider.get(), 1), checkNotNull(i, 2)); } + @Override public FactoryImplementingGenericInterfaceExtension make(Integer arg) { return create(arg); diff --git a/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java b/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java index 19f2c138..ec4089b7 100644 --- a/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java +++ b/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java @@ -23,15 +23,18 @@ import javax.inject.Provider; * @author Gregory Kick */ @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" -) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class MixedDepsImplementingInterfacesFactory - implements MixedDepsImplementingInterfaces.FromInt, MixedDepsImplementingInterfaces.FromObject, - MixedDepsImplementingInterfaces.MarkerA, MixedDepsImplementingInterfaces.MarkerB { + implements MixedDepsImplementingInterfaces.FromInt, + MixedDepsImplementingInterfaces.FromObject, + MixedDepsImplementingInterfaces.MarkerA, + MixedDepsImplementingInterfaces.MarkerB { private final Provider<String> sProvider; - @Inject MixedDepsImplementingInterfacesFactory(Provider<String> sProvider) { + @Inject + MixedDepsImplementingInterfacesFactory(Provider<String> sProvider) { this.sProvider = checkNotNull(sProvider, 1); } @@ -43,11 +46,13 @@ final class MixedDepsImplementingInterfacesFactory return new MixedDepsImplementingInterfaces(checkNotNull(o, 1)); } - @Override public MixedDepsImplementingInterfaces fromInt(int i) { + @Override + public MixedDepsImplementingInterfaces fromInt(int i) { return create(i); } - @Override public MixedDepsImplementingInterfaces fromObject(Object o) { + @Override + public MixedDepsImplementingInterfaces fromObject(Object o) { return create(o); } diff --git a/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java b/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java index fac6e13a..3eaf3afa 100644 --- a/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java +++ b/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java @@ -22,7 +22,7 @@ import javax.inject.Provider; @Generated( value = "com.google.auto.factory.processor.AutoFactoryProcessor", comments = "https://github.com/google/auto/tree/master/factory" -) + ) final class MultipleFactoriesConflictingParameterNamesFactory { private final Provider<String> stringProvider; diff --git a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java index 5ee2b2fe..6fcfb036 100644 --- a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java +++ b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java @@ -19,9 +19,9 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class MultipleFactoriesImplementingInterface_ClassAFactory implements MultipleFactoriesImplementingInterface.Base.Factory { @Inject diff --git a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java index f6540683..56646891 100644 --- a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java +++ b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java @@ -19,9 +19,9 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class MultipleFactoriesImplementingInterface_ClassBFactory implements MultipleFactoriesImplementingInterface.Base.Factory { @Inject diff --git a/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java b/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java index de7bad72..97cc8ac2 100644 --- a/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java +++ b/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java @@ -20,9 +20,9 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class MultipleProvidedParamsSameKeyFactory { private final Provider<String> java_lang_StringProvider; diff --git a/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java b/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java index bf6a4681..fe7aa1a9 100644 --- a/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java +++ b/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class NestedClassCustomNamedFactory { - @Inject NestedClassCustomNamedFactory() {} + @Inject + NestedClassCustomNamedFactory() {} NestedClasses.SimpleNestedClassWithCustomFactory create() { return new NestedClasses.SimpleNestedClassWithCustomFactory(); diff --git a/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java b/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java index f982e86f..41ecc52e 100644 --- a/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java +++ b/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class NestedClasses_SimpleNestedClassFactory { - @Inject NestedClasses_SimpleNestedClassFactory() {} + @Inject + NestedClasses_SimpleNestedClassFactory() {} NestedClasses.SimpleNestedClass create() { return new NestedClasses.SimpleNestedClass(); diff --git a/factory/src/test/resources/expected/OnlyPrimitivesFactory.java b/factory/src/test/resources/expected/OnlyPrimitivesFactory.java index ec60c58e..b931a222 100644 --- a/factory/src/test/resources/expected/OnlyPrimitivesFactory.java +++ b/factory/src/test/resources/expected/OnlyPrimitivesFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class OnlyPrimitivesFactory { - @Inject OnlyPrimitivesFactory() {} + @Inject + OnlyPrimitivesFactory() {} OnlyPrimitives create(int i, long l) { return new OnlyPrimitives(i, l); diff --git a/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java b/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java index 4d1a4cf5..75a6291c 100644 --- a/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java +++ b/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java @@ -22,10 +22,11 @@ import javax.inject.Provider; @Generated( value = "com.google.auto.factory.processor.AutoFactoryProcessor", comments = "https://github.com/google/auto/tree/master/factory" -) + ) final class ProviderArgumentToCreateMethodFactory - implements ProviderArgumentToCreateMethod.CustomCreator{ - @Inject ProviderArgumentToCreateMethodFactory() {} + implements ProviderArgumentToCreateMethod.CustomCreator { + @Inject + ProviderArgumentToCreateMethodFactory() {} ProviderArgumentToCreateMethod create(Provider<String> stringProvider) { return new ProviderArgumentToCreateMethod(checkNotNull(stringProvider, 1)); diff --git a/factory/src/test/resources/expected/PublicClassFactory.java b/factory/src/test/resources/expected/PublicClassFactory.java index 06671dc6..9e5c113d 100644 --- a/factory/src/test/resources/expected/PublicClassFactory.java +++ b/factory/src/test/resources/expected/PublicClassFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) public final class PublicClassFactory { - @Inject public PublicClassFactory() {} + @Inject + public PublicClassFactory() {} public PublicClass create() { return new PublicClass(); diff --git a/factory/src/test/resources/expected/SimpleClassFactory.java b/factory/src/test/resources/expected/SimpleClassFactory.java index 308d2cdc..4741b752 100644 --- a/factory/src/test/resources/expected/SimpleClassFactory.java +++ b/factory/src/test/resources/expected/SimpleClassFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassFactory { - @Inject SimpleClassFactory() {} + @Inject + SimpleClassFactory() {} SimpleClass create() { return new SimpleClass(); diff --git a/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java b/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java index 6c611e99..17701387 100644 --- a/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java +++ b/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java @@ -20,11 +20,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassImplementingMarkerFactory implements RandomAccess { - @Inject SimpleClassImplementingMarkerFactory() {} + @Inject + SimpleClassImplementingMarkerFactory() {} SimpleClassImplementingMarker create() { return new SimpleClassImplementingMarker(); diff --git a/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java b/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java index 720e7d0f..7dd91bea 100644 --- a/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java +++ b/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java @@ -19,18 +19,20 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassImplementingSimpleInterfaceFactory implements SimpleClassImplementingSimpleInterface.SimpleInterface { - @Inject SimpleClassImplementingSimpleInterfaceFactory() {} + @Inject + SimpleClassImplementingSimpleInterfaceFactory() {} SimpleClassImplementingSimpleInterface create() { return new SimpleClassImplementingSimpleInterface(); } - @Override public SimpleClassImplementingSimpleInterface newInstance() { + @Override + public SimpleClassImplementingSimpleInterface newInstance() { return create(); } } diff --git a/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java index ccdea61c..b69ea326 100644 --- a/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java +++ b/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java @@ -20,14 +20,14 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassMixedDepsFactory { private final Provider<String> providedDepAProvider; - @Inject SimpleClassMixedDepsFactory( - @AQualifier Provider<String> providedDepAProvider) { + @Inject + SimpleClassMixedDepsFactory(@AQualifier Provider<String> providedDepAProvider) { this.providedDepAProvider = checkNotNull(providedDepAProvider, 1); } diff --git a/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java b/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java index d323812e..5ab90306 100644 --- a/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java +++ b/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) class SimpleClassNonFinalFactory { - @Inject SimpleClassNonFinalFactory() {} + @Inject + SimpleClassNonFinalFactory() {} SimpleClassNonFinal create() { return new SimpleClassNonFinal(); diff --git a/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java b/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java index e3540386..5b955964 100644 --- a/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java +++ b/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java @@ -21,9 +21,9 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassNullableParametersFactory { private final Provider<String> providedNullableProvider; diff --git a/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java index 3260c36e..9cc8a166 100644 --- a/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java +++ b/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java @@ -19,11 +19,12 @@ import javax.annotation.processing.Generated; import javax.inject.Inject; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassPassedDepsFactory { - @Inject SimpleClassPassedDepsFactory() {} + @Inject + SimpleClassPassedDepsFactory() {} SimpleClassPassedDeps create(String depA, String depB) { return new SimpleClassPassedDeps(checkNotNull(depA, 1), checkNotNull(depB, 2)); diff --git a/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java index 05d1e5ab..52448aad 100644 --- a/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java +++ b/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java @@ -20,9 +20,9 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassProvidedDepsFactory { private final Provider<Integer> providedPrimitiveAProvider; private final Provider<Integer> providedPrimitiveBProvider; diff --git a/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java b/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java index aafdcec2..7bf2372c 100644 --- a/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java +++ b/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java @@ -20,9 +20,9 @@ import javax.inject.Inject; import javax.inject.Provider; @Generated( - value = "com.google.auto.factory.processor.AutoFactoryProcessor", - comments = "https://github.com/google/auto/tree/master/factory" - ) + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) final class SimpleClassProvidedProviderDepsFactory { private final Provider<String> providedDepAProvider; private final Provider<String> providedDepBProvider; diff --git a/factory/src/test/resources/expected/SimpleClassThrowsFactory.java b/factory/src/test/resources/expected/SimpleClassThrowsFactory.java new file mode 100644 index 00000000..eda503a4 --- /dev/null +++ b/factory/src/test/resources/expected/SimpleClassThrowsFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright 2020 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 tests; + +import java.io.IOException; +import javax.annotation.processing.Generated; +import javax.inject.Inject; + +@Generated( + value = "com.google.auto.factory.processor.AutoFactoryProcessor", + comments = "https://github.com/google/auto/tree/master/factory" + ) +final class SimpleClassThrowsFactory { + @Inject + SimpleClassThrowsFactory() {} + + SimpleClassThrows create() throws IOException, InterruptedException { + return new SimpleClassThrows(); + } +} diff --git a/factory/src/test/resources/expected/SimpleClassVarargsFactory.java b/factory/src/test/resources/expected/SimpleClassVarargsFactory.java index 51c7f466..ac7c4bdc 100644 --- a/factory/src/test/resources/expected/SimpleClassVarargsFactory.java +++ b/factory/src/test/resources/expected/SimpleClassVarargsFactory.java @@ -21,9 +21,10 @@ import javax.inject.Inject; @Generated( value = "com.google.auto.factory.processor.AutoFactoryProcessor", comments = "https://github.com/google/auto/tree/master/factory" -) + ) final class SimpleClassVarargsFactory implements SimpleClassVarargs.InterfaceWithVarargs { - @Inject SimpleClassVarargsFactory() {} + @Inject + SimpleClassVarargsFactory() {} SimpleClassVarargs create(String... args) { return new SimpleClassVarargs(checkNotNull(args, 1)); diff --git a/factory/src/test/resources/good/CheckerFrameworkNullable.java b/factory/src/test/resources/good/CheckerFrameworkNullable.java index 7f2a0fee..8b9cbc26 100644 --- a/factory/src/test/resources/good/CheckerFrameworkNullable.java +++ b/factory/src/test/resources/good/CheckerFrameworkNullable.java @@ -17,6 +17,7 @@ package tests; import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; +import java.util.Map; import org.checkerframework.checker.nullness.compatqual.NullableDecl; import org.checkerframework.checker.nullness.compatqual.NullableType; @@ -27,5 +28,7 @@ final class CheckerFrameworkNullable { @NullableDecl String nullableDecl, @Provided @NullableDecl String providedNullableDecl, @NullableType String nullableType, - @Provided @NullableType String providedNullableType) {} + @Provided @NullableType String providedNullableType, + Map.@NullableType Entry<?, ?> nestedNullableType, + @Provided Map.@NullableType Entry<?, ?> providedNestedNullableType) {} } diff --git a/factory/src/test/resources/good/ConstructorAnnotated.java b/factory/src/test/resources/good/ConstructorAnnotated.java index fdc02f35..ddb154f4 100644 --- a/factory/src/test/resources/good/ConstructorAnnotated.java +++ b/factory/src/test/resources/good/ConstructorAnnotated.java @@ -19,9 +19,17 @@ import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; final class ConstructorAnnotated { - @AutoFactory ConstructorAnnotated() {} + @AutoFactory + ConstructorAnnotated() {} + ConstructorAnnotated(Object obj) {} - @AutoFactory ConstructorAnnotated(String s) {} - @AutoFactory ConstructorAnnotated(@Provided Object obj, int i) {} - @AutoFactory ConstructorAnnotated(@Provided Object obj, char c) {} + + @AutoFactory + ConstructorAnnotated(String s) {} + + @AutoFactory + ConstructorAnnotated(@Provided Object obj, int i) {} + + @AutoFactory + ConstructorAnnotated(@Provided Object obj, char c) {} } diff --git a/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java b/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java index 5bed1e60..1b10e79e 100644 --- a/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java +++ b/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java @@ -19,9 +19,17 @@ import com.google.auto.factory.AutoFactory; import com.google.auto.factory.Provided; final class ConstructorAnnotatedNonFinal { - @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal() {} + @AutoFactory(allowSubclasses = true) + ConstructorAnnotatedNonFinal() {} + ConstructorAnnotatedNonFinal(Object obj) {} - @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(String s) {} - @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(@Provided Object obj, int i) {} - @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(@Provided Object obj, char c) {} + + @AutoFactory(allowSubclasses = true) + ConstructorAnnotatedNonFinal(String s) {} + + @AutoFactory(allowSubclasses = true) + ConstructorAnnotatedNonFinal(@Provided Object obj, int i) {} + + @AutoFactory(allowSubclasses = true) + ConstructorAnnotatedNonFinal(@Provided Object obj, char c) {} } diff --git a/factory/src/test/resources/good/ConstructorAnnotatedThrows.java b/factory/src/test/resources/good/ConstructorAnnotatedThrows.java new file mode 100644 index 00000000..58a52d0b --- /dev/null +++ b/factory/src/test/resources/good/ConstructorAnnotatedThrows.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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 tests; + +import com.google.auto.factory.AutoFactory; +import com.google.auto.factory.Provided; +import java.io.IOException; + +final class ConstructorAnnotatedThrows { + @AutoFactory + ConstructorAnnotatedThrows() throws IOException, InterruptedException {} + + ConstructorAnnotatedThrows(Object obj) {} + + @AutoFactory + ConstructorAnnotatedThrows(String s) {} + + @AutoFactory + ConstructorAnnotatedThrows(@Provided Object obj, int i) throws IOException {} + + @AutoFactory + ConstructorAnnotatedThrows(@Provided Object obj, char c) throws InterruptedException {} +} diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClass.java b/factory/src/test/resources/good/FactoryExtendingAbstractClass.java index 5511e99e..bd3a4dc7 100644 --- a/factory/src/test/resources/good/FactoryExtendingAbstractClass.java +++ b/factory/src/test/resources/good/FactoryExtendingAbstractClass.java @@ -20,7 +20,7 @@ import tests.FactoryExtendingAbstractClass.AbstractFactory; @AutoFactory(extending = AbstractFactory.class) final class FactoryExtendingAbstractClass { - static abstract class AbstractFactory { + abstract static class AbstractFactory { abstract FactoryExtendingAbstractClass newInstance(); } } diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java b/factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java new file mode 100644 index 00000000..2ac43f3f --- /dev/null +++ b/factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java @@ -0,0 +1,29 @@ +/* + * Copyright 2020 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 tests; + +import com.google.auto.factory.AutoFactory; +import java.io.IOException; +import tests.FactoryExtendingAbstractClassThrows.AbstractFactory; + +@AutoFactory(extending = AbstractFactory.class) +final class FactoryExtendingAbstractClassThrows { + FactoryExtendingAbstractClassThrows() throws IOException, InterruptedException {} + + abstract static class AbstractFactory { + abstract FactoryExtendingAbstractClassThrows newInstance() throws Exception; + } +} diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java index 43e94ce1..20e0b838 100644 --- a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java +++ b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java @@ -20,10 +20,11 @@ import tests.FactoryExtendingAbstractClassWithMultipleConstructors.AbstractFacto @AutoFactory(extending = AbstractFactory.class) final class FactoryExtendingAbstractClassWithMultipleConstructors { - static abstract class AbstractFactory { + abstract static class AbstractFactory { protected AbstractFactory(Object obj) {} + protected AbstractFactory() {} - + abstract FactoryExtendingAbstractClassWithMultipleConstructors newInstance(); } } diff --git a/factory/src/test/resources/good/FactoryImplementingCreateMethod.java b/factory/src/test/resources/good/FactoryImplementingCreateMethod.java index db15eefe..d2659667 100644 --- a/factory/src/test/resources/good/FactoryImplementingCreateMethod.java +++ b/factory/src/test/resources/good/FactoryImplementingCreateMethod.java @@ -26,7 +26,7 @@ final class FactoryImplementingCreateMethod { Interface create(); Interface create(int a); - + Interface create(List<Integer> generic); } diff --git a/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java b/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java index c7435edd..05ee0df9 100644 --- a/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java +++ b/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java @@ -24,18 +24,18 @@ import com.google.auto.factory.Provided; final class MixedDepsImplementingInterfaces { @AutoFactory(implementing = {FromInt.class, MarkerA.class}) MixedDepsImplementingInterfaces(@Provided String s, int i) {} - + @AutoFactory(implementing = {FromObject.class, MarkerB.class}) MixedDepsImplementingInterfaces(Object o) {} interface FromInt { MixedDepsImplementingInterfaces fromInt(int i); } - + interface FromObject { MixedDepsImplementingInterfaces fromObject(Object o); } - + interface MarkerA {} interface MarkerB {} diff --git a/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java b/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java index 2eecf1ae..f7709ec0 100644 --- a/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java +++ b/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java @@ -17,7 +17,7 @@ package tests; import com.google.auto.factory.AutoFactory; -class MultipleFactoriesImplementingInterface { +class MultipleFactoriesImplementingInterface { static interface Base { static interface Factory { public abstract Base abstractNonDefaultCreate(); @@ -25,8 +25,8 @@ class MultipleFactoriesImplementingInterface { } @AutoFactory(implementing = Base.Factory.class) - static class ClassA implements Base { } + static class ClassA implements Base {} @AutoFactory(implementing = Base.Factory.class) static class ClassB implements Base {} -} +} diff --git a/factory/src/test/resources/good/SimpleClassImplementingMarker.java b/factory/src/test/resources/good/SimpleClassImplementingMarker.java index 24e3abc0..52a1fd5a 100644 --- a/factory/src/test/resources/good/SimpleClassImplementingMarker.java +++ b/factory/src/test/resources/good/SimpleClassImplementingMarker.java @@ -1,11 +1,11 @@ /* * Copyright 2013 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 @@ -17,5 +17,4 @@ import com.google.auto.factory.AutoFactory; import java.util.RandomAccess; @AutoFactory(implementing = RandomAccess.class) -class SimpleClassImplementingMarker { -} +class SimpleClassImplementingMarker {} diff --git a/factory/src/test/resources/good/SimpleClassProvidedDeps.java b/factory/src/test/resources/good/SimpleClassProvidedDeps.java index ffcefd2a..fa9e0c41 100644 --- a/factory/src/test/resources/good/SimpleClassProvidedDeps.java +++ b/factory/src/test/resources/good/SimpleClassProvidedDeps.java @@ -1,11 +1,11 @@ /* * Copyright 2013 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 diff --git a/factory/src/test/resources/good/SimpleClassThrows.java b/factory/src/test/resources/good/SimpleClassThrows.java new file mode 100644 index 00000000..67155952 --- /dev/null +++ b/factory/src/test/resources/good/SimpleClassThrows.java @@ -0,0 +1,24 @@ +/* + * Copyright 2020 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 tests; + +import com.google.auto.factory.AutoFactory; +import java.io.IOException; + +@AutoFactory +final class SimpleClassThrows { + SimpleClassThrows() throws IOException, InterruptedException {} +} diff --git a/factory/src/test/resources/support/QualifierWithArgs.java b/factory/src/test/resources/support/QualifierWithArgs.java index 81e3f84b..89f54eb6 100644 --- a/factory/src/test/resources/support/QualifierWithArgs.java +++ b/factory/src/test/resources/support/QualifierWithArgs.java @@ -29,5 +29,6 @@ import javax.inject.Qualifier; @Retention(RUNTIME) @interface QualifierWithArgs { String name(); + int count(); } |