diff --git a/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java b/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java index f12299a510..85a24cb455 100644 --- a/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java +++ b/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java @@ -25,12 +25,15 @@ import com.google.auto.service.AutoService; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -68,6 +71,8 @@ public class AutoServiceProcessor extends AbstractProcessor { @VisibleForTesting static final String MISSING_SERVICES_ERROR = "No service interfaces provided for element!"; + private final List exceptionStacks = Collections.synchronizedList(new ArrayList<>()); + /** * Maps the class names of service provider interfaces to the * class names of the concrete classes which implement them. @@ -109,11 +114,17 @@ public boolean process(Set annotations, RoundEnvironment processImpl(annotations, roundEnv); } catch (RuntimeException e) { // We don't allow exceptions of any kind to propagate to the compiler - fatalError(getStackTraceAsString(e)); + String trace = getStackTraceAsString(e); + exceptionStacks.add(trace); + fatalError(trace); } return false; } + ImmutableList exceptionStacks() { + return ImmutableList.copyOf(exceptionStacks); + } + private void processImpl(Set annotations, RoundEnvironment roundEnv) { if (roundEnv.processingOver()) { generateConfigFiles(); @@ -291,7 +302,7 @@ private String getBinaryNameImpl(TypeElement element, String className) { private ImmutableSet getValueFieldOfClasses(AnnotationMirror annotationMirror) { return getAnnotationValue(annotationMirror, "value") .accept( - new SimpleAnnotationValueVisitor8, Void>() { + new SimpleAnnotationValueVisitor8, Void>(ImmutableSet.of()) { @Override public ImmutableSet visitType(TypeMirror typeMirror, Void v) { // TODO(ronshapiro): class literals may not always be declared types, i.e. diff --git a/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java b/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java index 35615689c0..7a176dd93c 100644 --- a/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java +++ b/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java @@ -17,6 +17,7 @@ import static com.google.auto.service.processor.AutoServiceProcessor.MISSING_SERVICES_ERROR; import static com.google.testing.compile.CompilationSubject.assertThat; +import static com.google.common.truth.Truth.assertThat; import com.google.common.io.Resources; import com.google.testing.compile.Compilation; @@ -144,4 +145,18 @@ public void nestedGenericWithVerifyOptionAndSuppressWarnings() { .contentsAsUtf8String() .isEqualTo("test.EnclosingGeneric$GenericServiceProvider\n"); } + + @Test + public void missing() { + AutoServiceProcessor processor = new AutoServiceProcessor(); + Compilation compilation = + Compiler.javac() + .withProcessors(processor) + .withOptions("-Averify=true") + .compile( + JavaFileObjects.forResource( + "test/GenericServiceProviderWithMissingServiceClass.java")); + assertThat(compilation).failed(); + assertThat(processor.exceptionStacks()).isEmpty(); + } } diff --git a/service/processor/src/test/resources/test/GenericServiceProviderWithMissingServiceClass.java b/service/processor/src/test/resources/test/GenericServiceProviderWithMissingServiceClass.java new file mode 100644 index 0000000000..3ca344548d --- /dev/null +++ b/service/processor/src/test/resources/test/GenericServiceProviderWithMissingServiceClass.java @@ -0,0 +1,25 @@ +/* + * 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 test; + +import com.google.auto.service.AutoService; + +/** + * A service that references a missing class. This is useful for testing that the processor behaves + * correctly. + */ +@AutoService(MissingServiceClass.class) +public class GenericServiceProviderWithMissingServiceClass implements MissingServiceClass {}