diff --git a/common/pom.xml b/common/pom.xml index 096f328c7b..a2a0a8b21f 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -43,6 +43,14 @@ com.google.guava guava + + + com.squareup + javapoet + true + + com.google.guava diff --git a/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java new file mode 100644 index 0000000000..a4694ef514 --- /dev/null +++ b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java @@ -0,0 +1,58 @@ +/* + * 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 com.google.auto.common; + +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import java.util.Optional; +import javax.lang.model.util.Elements; + +/** Utility methods for writing {@code @Generated} annotations using JavaPoet. */ +public final class GeneratedAnnotationSpecs { + + private GeneratedAnnotationSpecs() {} + + /** + * Returns {@code @Generated("processorClass"} if either {@code + * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain + * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}. + */ + public static Optional generatedAnnotationSpec( + Elements elements, Class processorClass) { + return generatedAnnotationSpecBuilder(elements, processorClass) + .map(AnnotationSpec.Builder::build); + } + + /** + * Returns {@code @Generated(value = "processorClass", comments = "comments"} if either {@code + * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain + * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}. + */ + public static Optional generatedAnnotationSpec( + Elements elements, Class processorClass, String comments) { + return generatedAnnotationSpecBuilder(elements, processorClass) + .map(annotation -> annotation.addMember("comments", "$S", comments).build()); + } + + private static Optional generatedAnnotationSpecBuilder( + Elements elements, Class processorClass) { + return GeneratedAnnotations.generatedAnnotation(elements) + .map( + generated -> + AnnotationSpec.builder(ClassName.get(generated)) + .addMember("value", "$S", processorClass.getCanonicalName())); + } +} diff --git a/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java b/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java new file mode 100644 index 0000000000..1a5f089da3 --- /dev/null +++ b/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java @@ -0,0 +1,41 @@ +/* + * 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 com.google.auto.common; + +import java.util.Optional; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; + +/** Utility methods for writing {@code @Generated} annotations. */ +public final class GeneratedAnnotations { + private GeneratedAnnotations() {} + + /** + * Returns the element corresponding to the version of the {@code @Generated} annotation present + * in the compile-time class- or module-path. + * + *

First looks for {@code javax.annotation.processing.Generated}, and then {@code + * javax.annotation.Generated}. Returns whichever is in the classpath (or modulepath), or {@link + * Optional#empty()} if neither is. + */ + public static Optional generatedAnnotation(Elements elements) { + TypeElement jdk9Generated = elements.getTypeElement("javax.annotation.processing.Generated"); + if (jdk9Generated != null) { + return Optional.of(jdk9Generated); + } + return Optional.ofNullable(elements.getTypeElement("javax.annotation.Generated")); + } +}