aboutsummaryrefslogtreecommitdiff
path: root/factory
diff options
context:
space:
mode:
authorÉamonn McManus <emcmanus@google.com>2020-12-15 11:35:31 -0800
committerGoogle Java Core Libraries <java-core-libraries-team+copybara@google.com>2020-12-15 11:36:12 -0800
commit3141e796b907acaec6d88c0affeffea2d9a37cdb (patch)
treeda06878417bf9d637bafb20eadf47020fb8dba29 /factory
parent9cc29ca31a07cc94d205b306b5c8d8ec2314658b (diff)
downloadauto-3141e796b907acaec6d88c0affeffea2d9a37cdb.tar.gz
Handle `@AutoFactory` constructors that throw checked exceptions.
The generated `create` method needs to declare the same exceptions. Fixes https://github.com/google/auto/issues/90. RELNOTES=`@AutoFactory` constructors can now declare checked exceptions. The same exceptions will be declared on the generated `create` method. PiperOrigin-RevId: 347657308
Diffstat (limited to 'factory')
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java1
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java6
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java7
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java9
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java5
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java7
-rw-r--r--factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java30
-rw-r--r--factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java58
-rw-r--r--factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java37
-rw-r--r--factory/src/test/resources/expected/SimpleClassThrowsFactory.java32
-rw-r--r--factory/src/test/resources/good/ConstructorAnnotatedThrows.java29
-rw-r--r--factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java29
-rw-r--r--factory/src/test/resources/good/SimpleClassThrows.java24
13 files changed, 262 insertions, 12 deletions
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 b07786a5..91ad9462 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
@@ -192,6 +192,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/FactoryDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
index 090ac27a..670d8fba 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
@@ -194,12 +194,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);
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 4faa6e7a..0816aef4 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
@@ -134,6 +134,8 @@ final class FactoryDescriptorGenerator {
.passedParameters(passedParameters)
.creationParameters(Parameter.forParameterList(constructor.getParameters(), types))
.isVarArgs(constructor.isVarArgs())
+ .exceptions(constructor.getThrownTypes())
+ .overridingMethod(false)
.build();
}
@@ -144,9 +146,12 @@ final class FactoryDescriptorGenerator {
.name("create")
.returnType(type.asType())
.publicMethod(type.getModifiers().contains(PUBLIC))
+ .providedParameters(ImmutableSet.of())
.passedParameters(ImmutableSet.of())
.creationParameters(ImmutableSet.of())
- .providedParameters(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..5f4ad294 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
@@ -38,8 +38,9 @@ abstract class FactoryMethodDescriptor {
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();
@@ -47,10 +48,7 @@ abstract class FactoryMethodDescriptor {
static Builder builder(AutoFactoryDeclaration declaration) {
return new AutoValue_FactoryMethodDescriptor.Builder()
- .declaration(checkNotNull(declaration))
- .publicMethod(false)
- .overridingMethod(false)
- .isVarArgs(false);
+ .declaration(checkNotNull(declaration));
}
@AutoValue.Builder
@@ -64,6 +62,7 @@ abstract class FactoryMethodDescriptor {
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() {
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 b1ba2f18..3dbcf41c 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
@@ -20,6 +20,7 @@ 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.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;
@@ -152,6 +153,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();
@@ -199,6 +202,8 @@ 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)",
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 b7367a6c..b5faa272 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
@@ -26,11 +26,10 @@ abstract class ImplementationMethodDescriptor {
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
@@ -49,6 +48,8 @@ abstract class ImplementationMethodDescriptor {
abstract Builder isVarArgs(boolean isVarargs);
+ abstract Builder exceptions(Iterable<? extends TypeMirror> exceptions);
+
abstract ImplementationMethodDescriptor build();
}
}
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 de3af5fb..9593139a 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
@@ -49,6 +49,16 @@ public class AutoFactoryProcessorTest {
}
@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() {
Compilation compilation = javac.compile(JavaFileObjects.forResource("good/NestedClasses.java"));
assertThat(compilation).succeededWithoutWarnings();
@@ -150,6 +160,15 @@ public class AutoFactoryProcessorTest {
}
@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"));
@@ -257,6 +276,17 @@ public class AutoFactoryProcessorTest {
}
@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_withConstructorParams() {
JavaFileObject file =
JavaFileObjects.forResource("bad/FactoryExtendingAbstractClassWithConstructorParams.java");
diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java
new file mode 100644
index 00000000..13f9e994
--- /dev/null
+++ b/factory/src/test/resources/expected/ConstructorAnnotatedThrowsFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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/FactoryExtendingAbstractClassThrowsFactory.java b/factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java
new file mode 100644
index 00000000..c2640f54
--- /dev/null
+++ b/factory/src/test/resources/expected/FactoryExtendingAbstractClassThrowsFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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/SimpleClassThrowsFactory.java b/factory/src/test/resources/expected/SimpleClassThrowsFactory.java
new file mode 100644
index 00000000..d54dd528
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassThrowsFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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/good/ConstructorAnnotatedThrows.java b/factory/src/test/resources/good/ConstructorAnnotatedThrows.java
new file mode 100644
index 00000000..1a22f562
--- /dev/null
+++ b/factory/src/test/resources/good/ConstructorAnnotatedThrows.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 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/FactoryExtendingAbstractClassThrows.java b/factory/src/test/resources/good/FactoryExtendingAbstractClassThrows.java
new file mode 100644
index 00000000..52ce2aaa
--- /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 {}
+
+ static abstract class AbstractFactory {
+ abstract FactoryExtendingAbstractClassThrows newInstance() throws Exception;
+ }
+}
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 {}
+}