diff options
author | ronshapiro <ronshapiro@google.com> | 2018-11-01 14:11:51 -0700 |
---|---|---|
committer | Ron Shapiro <shapiro.rd@gmail.com> | 2018-11-06 16:53:54 -0600 |
commit | af1e5daff849b4762062018b9e8bce1716bfc8b0 (patch) | |
tree | b56d93fcccb28de6955480fce2b3c9fe8a7c86ed /service/processor | |
parent | 34a6a037617102c25b8de8dbac6d2adb5fcb2c43 (diff) | |
download | auto-af1e5daff849b4762062018b9e8bce1716bfc8b0.tar.gz |
Separate AutoService annotations and processor
Fixes https://github.com/google/auto/issues/632
RELNOTES=`@AutoService` now has a separate artifact (`auto-service-annotations`) separate from the annotation processor (still `auto-service`)
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=219696198
Diffstat (limited to 'service/processor')
18 files changed, 742 insertions, 0 deletions
diff --git a/service/processor/pom.xml b/service/processor/pom.xml new file mode 100644 index 00000000..341b2087 --- /dev/null +++ b/service/processor/pom.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (C) 2013 Google, Inc. + + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.google.auto</groupId> + <artifactId>auto-parent</artifactId> + <version>6</version> + </parent> + + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service</artifactId> + <version>HEAD-SNAPSHOT</version> + <name>AutoService Processor</name> + <description> + Provider-configuration files for ServiceLoader. + </description> + + <scm> + <url>http://github.com/google/auto</url> + <connection>scm:git:git://github.com/google/auto.git</connection> + <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection> + <tag>HEAD</tag> + </scm> + + <dependencies> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service-annotations</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.google.auto</groupId> + <artifactId>auto-common</artifactId> + <version>0.10</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <!-- test dependencies --> + <dependency> + <groupId>com.google.testing.compile</groupId> + <artifactId>compile-testing</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.truth</groupId> + <artifactId>truth</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <!-- disable processing because the definition in META-INF/services breaks javac --> + <compilerArgument>-proc:none</compilerArgument> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> +</project> 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 new file mode 100644 index 00000000..4bd7ceca --- /dev/null +++ b/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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.service.processor; + +import static com.google.auto.common.AnnotationMirrors.getAnnotationValue; +import static com.google.auto.common.MoreElements.getAnnotationMirror; +import static com.google.common.collect.ImmutableSet.toImmutableSet; + +import com.google.auto.common.MoreTypes; +import com.google.auto.service.AutoService; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.HashMultimap; +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.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Filer; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedOptions; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.SimpleAnnotationValueVisitor8; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic.Kind; +import javax.tools.FileObject; +import javax.tools.StandardLocation; + +/** + * Processes {@link AutoService} annotations and generates the service provider + * configuration files described in {@link java.util.ServiceLoader}. + * <p> + * Processor Options:<ul> + * <li>debug - turns on debug statements</li> + * </ul> + */ +@SupportedOptions({ "debug", "verify" }) +public class AutoServiceProcessor extends AbstractProcessor { + + @VisibleForTesting + static final String MISSING_SERVICES_ERROR = "No service interfaces provided for element!"; + + /** + * Maps the class names of service provider interfaces to the + * class names of the concrete classes which implement them. + * <p> + * For example, + * {@code "com.google.apphosting.LocalRpcService" -> + * "com.google.apphosting.datastore.LocalDatastoreService"} + */ + private Multimap<String, String> providers = HashMultimap.create(); + + @Override + public ImmutableSet<String> getSupportedAnnotationTypes() { + return ImmutableSet.of(AutoService.class.getName()); + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latestSupported(); + } + + /** + * <ol> + * <li> For each class annotated with {@link AutoService}<ul> + * <li> Verify the {@link AutoService} interface value is correct + * <li> Categorize the class by its service interface + * </ul> + * + * <li> For each {@link AutoService} interface <ul> + * <li> Create a file named {@code META-INF/services/<interface>} + * <li> For each {@link AutoService} annotated class for this interface <ul> + * <li> Create an entry in the file + * </ul> + * </ul> + * </ol> + */ + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + try { + return processImpl(annotations, roundEnv); + } catch (Exception e) { + // We don't allow exceptions of any kind to propagate to the compiler + StringWriter writer = new StringWriter(); + e.printStackTrace(new PrintWriter(writer)); + fatalError(writer.toString()); + return true; + } + } + + private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + generateConfigFiles(); + } else { + processAnnotations(annotations, roundEnv); + } + + return true; + } + + private void processAnnotations(Set<? extends TypeElement> annotations, + RoundEnvironment roundEnv) { + + Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(AutoService.class); + + log(annotations.toString()); + log(elements.toString()); + + for (Element e : elements) { + // TODO(gak): check for error trees? + TypeElement providerImplementer = (TypeElement) e; + AnnotationMirror annotationMirror = getAnnotationMirror(e, AutoService.class).get(); + Set<DeclaredType> providerInterfaces = getValueFieldOfClasses(annotationMirror); + if (providerInterfaces.isEmpty()) { + error(MISSING_SERVICES_ERROR, e, annotationMirror); + continue; + } + for (DeclaredType providerInterface : providerInterfaces) { + TypeElement providerType = MoreTypes.asTypeElement(providerInterface); + + log("provider interface: " + providerType.getQualifiedName()); + log("provider implementer: " + providerImplementer.getQualifiedName()); + + if (checkImplementer(providerImplementer, providerType)) { + providers.put(getBinaryName(providerType), getBinaryName(providerImplementer)); + } else { + String message = "ServiceProviders must implement their service provider interface. " + + providerImplementer.getQualifiedName() + " does not implement " + + providerType.getQualifiedName(); + error(message, e, annotationMirror); + } + } + } + } + + private void generateConfigFiles() { + Filer filer = processingEnv.getFiler(); + + for (String providerInterface : providers.keySet()) { + String resourceFile = "META-INF/services/" + providerInterface; + log("Working on resource file: " + resourceFile); + try { + SortedSet<String> allServices = Sets.newTreeSet(); + try { + // would like to be able to print the full path + // before we attempt to get the resource in case the behavior + // of filer.getResource does change to match the spec, but there's + // no good way to resolve CLASS_OUTPUT without first getting a resource. + FileObject existingFile = filer.getResource(StandardLocation.CLASS_OUTPUT, "", + resourceFile); + log("Looking for existing resource file at " + existingFile.toUri()); + Set<String> oldServices = ServicesFiles.readServiceFile(existingFile.openInputStream()); + log("Existing service entries: " + oldServices); + allServices.addAll(oldServices); + } catch (IOException e) { + // According to the javadoc, Filer.getResource throws an exception + // if the file doesn't already exist. In practice this doesn't + // appear to be the case. Filer.getResource will happily return a + // FileObject that refers to a non-existent file but will throw + // IOException if you try to open an input stream for it. + log("Resource file did not already exist."); + } + + Set<String> newServices = new HashSet<String>(providers.get(providerInterface)); + if (allServices.containsAll(newServices)) { + log("No new service entries being added."); + return; + } + + allServices.addAll(newServices); + log("New service file contents: " + allServices); + FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "", + resourceFile); + OutputStream out = fileObject.openOutputStream(); + ServicesFiles.writeServiceFile(allServices, out); + out.close(); + log("Wrote to: " + fileObject.toUri()); + } catch (IOException e) { + fatalError("Unable to create " + resourceFile + ", " + e); + return; + } + } + } + + /** + * Verifies {@link ServiceProvider} constraints on the concrete provider class. + * Note that these constraints are enforced at runtime via the ServiceLoader, + * we're just checking them at compile time to be extra nice to our users. + */ + private boolean checkImplementer(TypeElement providerImplementer, TypeElement providerType) { + + String verify = processingEnv.getOptions().get("verify"); + if (verify == null || !Boolean.valueOf(verify)) { + return true; + } + + // TODO: We're currently only enforcing the subtype relationship + // constraint. It would be nice to enforce them all. + + Types types = processingEnv.getTypeUtils(); + + return types.isSubtype(providerImplementer.asType(), providerType.asType()); + } + + /** + * Returns the binary name of a reference type. For example, + * {@code com.google.Foo$Bar}, instead of {@code com.google.Foo.Bar}. + * + */ + private String getBinaryName(TypeElement element) { + return getBinaryNameImpl(element, element.getSimpleName().toString()); + } + + private String getBinaryNameImpl(TypeElement element, String className) { + Element enclosingElement = element.getEnclosingElement(); + + if (enclosingElement instanceof PackageElement) { + PackageElement pkg = (PackageElement) enclosingElement; + if (pkg.isUnnamed()) { + return className; + } + return pkg.getQualifiedName() + "." + className; + } + + TypeElement typeElement = (TypeElement) enclosingElement; + return getBinaryNameImpl(typeElement, typeElement.getSimpleName() + "$" + className); + } + + /** + * Returns the contents of a {@code Class[]}-typed "value" field in a given {@code annotationMirror}. + */ + private ImmutableSet<DeclaredType> getValueFieldOfClasses(AnnotationMirror annotationMirror) { + return getAnnotationValue(annotationMirror, "value") + .accept( + new SimpleAnnotationValueVisitor8<ImmutableSet<DeclaredType>, Void>() { + @Override + public ImmutableSet<DeclaredType> visitType(TypeMirror typeMirror, Void v) { + // TODO(ronshapiro): class literals may not always be declared types, i.e. int.class, + // int[].class + return ImmutableSet.of(MoreTypes.asDeclared(typeMirror)); + } + + @Override + public ImmutableSet<DeclaredType> visitArray( + List<? extends AnnotationValue> values, Void v) { + return values + .stream() + .flatMap(value -> value.accept(this, null).stream()) + .collect(toImmutableSet()); + } + }, + null); + } + + private void log(String msg) { + if (processingEnv.getOptions().containsKey("debug")) { + processingEnv.getMessager().printMessage(Kind.NOTE, msg); + } + } + + private void error(String msg, Element element, AnnotationMirror annotation) { + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element, annotation); + } + + private void fatalError(String msg) { + processingEnv.getMessager().printMessage(Kind.ERROR, "FATAL ERROR: " + msg); + } +} diff --git a/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java b/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java new file mode 100644 index 00000000..c43200ab --- /dev/null +++ b/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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.service.processor; + +import static com.google.common.base.Charsets.UTF_8; + +import com.google.common.io.Closer; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +/** + * A helper class for reading and writing Services files. + */ +final class ServicesFiles { + public static final String SERVICES_PATH = "META-INF/services"; + + private ServicesFiles() { } + + /** + * Returns an absolute path to a service file given the class + * name of the service. + * + * @param serviceName not {@code null} + * @return SERVICES_PATH + serviceName + */ + static String getPath(String serviceName) { + return SERVICES_PATH + "/" + serviceName; + } + + /** + * Reads the set of service classes from a service file. + * + * @param input not {@code null}. Closed after use. + * @return a not {@code null Set} of service class names. + * @throws IOException + */ + static Set<String> readServiceFile(InputStream input) throws IOException { + HashSet<String> serviceClasses = new HashSet<String>(); + Closer closer = Closer.create(); + try { + // TODO(gak): use CharStreams + BufferedReader r = closer.register(new BufferedReader(new InputStreamReader(input, UTF_8))); + String line; + while ((line = r.readLine()) != null) { + int commentStart = line.indexOf('#'); + if (commentStart >= 0) { + line = line.substring(0, commentStart); + } + line = line.trim(); + if (!line.isEmpty()) { + serviceClasses.add(line); + } + } + return serviceClasses; + } catch (Throwable t) { + throw closer.rethrow(t); + } finally { + closer.close(); + } + } + + /** + * Writes the set of service class names to a service file. + * + * @param output not {@code null}. Not closed after use. + * @param services a not {@code null Collection} of service class names. + * @throws IOException + */ + static void writeServiceFile(Collection<String> services, OutputStream output) + throws IOException { + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8)); + for (String service : services) { + writer.write(service); + writer.newLine(); + } + writer.flush(); + } +}
\ No newline at end of file diff --git a/service/processor/src/main/java/com/google/auto/service/processor/package-info.java b/service/processor/src/main/java/com/google/auto/service/processor/package-info.java new file mode 100644 index 00000000..233f37cf --- /dev/null +++ b/service/processor/src/main/java/com/google/auto/service/processor/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 Google, Inc. + * + * 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. + */ +/** + * This package contains the annotation processor that implements the + * {@link com.google.auto.service.AutoService} API. + */ +package com.google.auto.service.processor;
\ No newline at end of file diff --git a/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 00000000..a4406e1d --- /dev/null +++ b/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +com.google.auto.service.processor.AutoServiceProcessor 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 new file mode 100644 index 00000000..6b5e1cfa --- /dev/null +++ b/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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.service.processor; + +import static com.google.auto.service.processor.AutoServiceProcessor.MISSING_SERVICES_ERROR; +import static com.google.testing.compile.JavaSourcesSubject.assertThat; + +import com.google.testing.compile.JavaFileObjects; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests the {@link AutoServiceProcessor}. + */ +@RunWith(JUnit4.class) +public class AutoServiceProcessorTest { + @Test + public void autoService() { + assertThat( + JavaFileObjects.forResource("test/SomeService.java"), + JavaFileObjects.forResource("test/SomeServiceProvider1.java"), + JavaFileObjects.forResource("test/SomeServiceProvider2.java"), + JavaFileObjects.forResource("test/Enclosing.java"), + JavaFileObjects.forResource("test/AnotherService.java"), + JavaFileObjects.forResource("test/AnotherServiceProvider.java")) + .processedWith(new AutoServiceProcessor()) + .compilesWithoutError() + .and().generatesFiles( + JavaFileObjects.forResource("META-INF/services/test.SomeService"), + JavaFileObjects.forResource("META-INF/services/test.AnotherService")); + } + + @Test + public void multiService() { + assertThat( + JavaFileObjects.forResource("test/SomeService.java"), + JavaFileObjects.forResource("test/AnotherService.java"), + JavaFileObjects.forResource("test/MultiServiceProvider.java")) + .processedWith(new AutoServiceProcessor()) + .compilesWithoutError() + .and().generatesFiles( + JavaFileObjects.forResource("META-INF/services/test.SomeServiceMulti"), + JavaFileObjects.forResource("META-INF/services/test.AnotherServiceMulti")); + } + + @Test + public void badMultiService() { + assertThat(JavaFileObjects.forResource("test/NoServices.java")) + .processedWith(new AutoServiceProcessor()) + .failsToCompile() + .withErrorContaining(MISSING_SERVICES_ERROR); + } +} diff --git a/service/processor/src/test/resources/META-INF/services/test.AnotherService b/service/processor/src/test/resources/META-INF/services/test.AnotherService new file mode 100644 index 00000000..7453e4da --- /dev/null +++ b/service/processor/src/test/resources/META-INF/services/test.AnotherService @@ -0,0 +1 @@ +test.AnotherServiceProvider diff --git a/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti b/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti new file mode 100644 index 00000000..f6ef36ac --- /dev/null +++ b/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti @@ -0,0 +1 @@ +test.MultiServiceProvider diff --git a/service/processor/src/test/resources/META-INF/services/test.SomeService b/service/processor/src/test/resources/META-INF/services/test.SomeService new file mode 100644 index 00000000..1b71d9db --- /dev/null +++ b/service/processor/src/test/resources/META-INF/services/test.SomeService @@ -0,0 +1,3 @@ +test.Enclosing$NestedSomeServiceProvider +test.SomeServiceProvider1 +test.SomeServiceProvider2 diff --git a/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti b/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti new file mode 100644 index 00000000..f6ef36ac --- /dev/null +++ b/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti @@ -0,0 +1 @@ +test.MultiServiceProvider diff --git a/service/processor/src/test/resources/test/AnotherService.java b/service/processor/src/test/resources/test/AnotherService.java new file mode 100644 index 00000000..2cbf7a6b --- /dev/null +++ b/service/processor/src/test/resources/test/AnotherService.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +interface AnotherService { }
\ No newline at end of file diff --git a/service/processor/src/test/resources/test/AnotherServiceProvider.java b/service/processor/src/test/resources/test/AnotherServiceProvider.java new file mode 100644 index 00000000..b425c0ed --- /dev/null +++ b/service/processor/src/test/resources/test/AnotherServiceProvider.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +@AutoService(AnotherService.class) +public class AnotherServiceProvider implements AnotherService { }
\ No newline at end of file diff --git a/service/processor/src/test/resources/test/Enclosing.java b/service/processor/src/test/resources/test/Enclosing.java new file mode 100644 index 00000000..5176a7ee --- /dev/null +++ b/service/processor/src/test/resources/test/Enclosing.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +public class Enclosing { + @AutoService(SomeService.class) + public static class NestedSomeServiceProvider implements SomeService { } +}
\ No newline at end of file diff --git a/service/processor/src/test/resources/test/MultiServiceProvider.java b/service/processor/src/test/resources/test/MultiServiceProvider.java new file mode 100644 index 00000000..804904bf --- /dev/null +++ b/service/processor/src/test/resources/test/MultiServiceProvider.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2017 Google, Inc. + * + * 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; + +@AutoService({SomeService.class, AnotherService.class}) +public class MultiServiceProvider implements SomeService, AnotherService {} diff --git a/service/processor/src/test/resources/test/NoServices.java b/service/processor/src/test/resources/test/NoServices.java new file mode 100644 index 00000000..3687eb55 --- /dev/null +++ b/service/processor/src/test/resources/test/NoServices.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +@AutoService({}) +public class NoServices {} diff --git a/service/processor/src/test/resources/test/SomeService.java b/service/processor/src/test/resources/test/SomeService.java new file mode 100644 index 00000000..5a4a3888 --- /dev/null +++ b/service/processor/src/test/resources/test/SomeService.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +interface SomeService { }
\ No newline at end of file diff --git a/service/processor/src/test/resources/test/SomeServiceProvider1.java b/service/processor/src/test/resources/test/SomeServiceProvider1.java new file mode 100644 index 00000000..1a1a5e8f --- /dev/null +++ b/service/processor/src/test/resources/test/SomeServiceProvider1.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +@AutoService(SomeService.class) +public class SomeServiceProvider1 implements SomeService { }
\ No newline at end of file diff --git a/service/processor/src/test/resources/test/SomeServiceProvider2.java b/service/processor/src/test/resources/test/SomeServiceProvider2.java new file mode 100644 index 00000000..fb6a1bd3 --- /dev/null +++ b/service/processor/src/test/resources/test/SomeServiceProvider2.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * 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; + +@AutoService(SomeService.class) +public class SomeServiceProvider2 implements SomeService { }
\ No newline at end of file |