Remove androidx.annotation dependency from room-compiler-processing.
The main usage of the dependency was to find nullability annotations using the class, but instead we can find those using the class's canonical name.
The second usage of the dep was for @VisibleForTesting, one usage was easily removed (KspReflectiveAnnotationBox) and the other (in JavacTestProcessor) required a bit of refactor.
Fixes: 192608164
Test: ./gradlew :room:r-c-p:test
Change-Id: I5d95fa328f0d875dbb3b1d8a562a4028c518cbfe
diff --git a/room/room-compiler-processing-testing/build.gradle b/room/room-compiler-processing-testing/build.gradle
index 6494d0c..0e8ddae 100644
--- a/room/room-compiler-processing-testing/build.gradle
+++ b/room/room-compiler-processing-testing/build.gradle
@@ -24,7 +24,6 @@
}
dependencies {
- implementation("androidx.annotation:annotation:1.1.0")
api(project(":room:room-compiler-processing"))
implementation(libs.kotlinStdlib)
implementation(libs.kspApi)
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticJavacProcessor.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticJavacProcessor.kt
index 95ede95..8613a86 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticJavacProcessor.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticJavacProcessor.kt
@@ -17,24 +17,35 @@
package androidx.room.compiler.processing
import androidx.room.compiler.processing.util.XTestInvocation
+import javax.annotation.processing.AbstractProcessor
+import javax.annotation.processing.RoundEnvironment
import javax.lang.model.SourceVersion
+import javax.lang.model.element.TypeElement
@Suppress("VisibleForTests")
@ExperimentalProcessingApi
class SyntheticJavacProcessor private constructor(
private val impl: SyntheticProcessorImpl
-) : JavacTestProcessor(), SyntheticProcessor by impl {
+) : AbstractProcessor(), SyntheticProcessor by impl {
constructor(handlers: List<(XTestInvocation) -> Unit>) : this(
SyntheticProcessorImpl(handlers)
)
- override fun doProcess(annotations: Set<XTypeElement>, roundEnv: XRoundEnv): Boolean {
+
+ override fun process(
+ annotations: MutableSet<out TypeElement>,
+ roundEnv: RoundEnvironment
+ ): Boolean {
+ if (roundEnv.processingOver()) {
+ return true
+ }
if (!impl.canRunAnotherRound()) {
return true
}
val xEnv = XProcessingEnv.create(processingEnv)
+ val xRoundEnv = XRoundEnv.create(xEnv, roundEnv)
val testInvocation = XTestInvocation(
processingEnv = xEnv,
- roundEnv = roundEnv
+ roundEnv = xRoundEnv
)
impl.runNextRound(testInvocation)
return impl.expectsAnotherRound()
diff --git a/room/room-compiler-processing/build.gradle b/room/room-compiler-processing/build.gradle
index f1c4286..d1ae9643 100644
--- a/room/room-compiler-processing/build.gradle
+++ b/room/room-compiler-processing/build.gradle
@@ -27,7 +27,6 @@
api(libs.kotlinStdlib)
api(libs.javapoet)
api(libs.kotlinPoet)
- implementation("androidx.annotation:annotation:1.1.0")
implementation(libs.guava)
implementation(libs.autoCommon)
implementation(libs.autoValueAnnotations)
@@ -37,6 +36,7 @@
implementation(libs.kspApi)
implementation(libs.kotlinStdlibJdk8) // KSP defines older version as dependency, force update.
+ testImplementation("androidx.annotation:annotation:1.1.0")
testImplementation(libs.googleCompileTesting)
testImplementation(libs.junit)
testImplementation(libs.jsr250)
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavacTestProcessor.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavacTestProcessor.kt
deleted file mode 100644
index aa9b92a..0000000
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/JavacTestProcessor.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * 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 androidx.room.compiler.processing
-
-import androidx.annotation.VisibleForTesting
-import androidx.room.compiler.processing.javac.JavacProcessingEnv
-import androidx.room.compiler.processing.javac.JavacRoundEnv
-import javax.annotation.processing.AbstractProcessor
-import javax.annotation.processing.RoundEnvironment
-import javax.lang.model.element.TypeElement
-
-/**
- * Javac processor implementation that provides access to the round environment.
- *
- * This is only used in tests, the main processor uses an API similar to the processing step
- * in Auto Common.
- */
-@VisibleForTesting
-@ExperimentalProcessingApi
-abstract class JavacTestProcessor : AbstractProcessor() {
- val xProcessingEnv by lazy {
- // lazily create this as it is not available on construction time
- XProcessingEnv.create(super.processingEnv)
- }
-
- final override fun process(
- annotations: MutableSet<out TypeElement>,
- roundEnv: RoundEnvironment
- ): Boolean {
- if (roundEnv.processingOver()) {
- return true
- }
- val env = xProcessingEnv as JavacProcessingEnv
- val javacRoundEnv = JavacRoundEnv(env, roundEnv)
- val xAnnotations = annotations.mapTo(mutableSetOf()) {
- env.wrapTypeElement(it)
- }
- return doProcess(xAnnotations, javacRoundEnv)
- }
-
- abstract fun doProcess(
- annotations: Set<XTypeElement>,
- roundEnv: XRoundEnv
- ): Boolean
-}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
index 14e4b06..aed0202 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
@@ -21,19 +21,21 @@
import javax.lang.model.element.Element
private val NONNULL_ANNOTATIONS = arrayOf(
- androidx.annotation.NonNull::class.java,
- org.jetbrains.annotations.NotNull::class.java
+ "androidx.annotation.NonNull",
+ "org.jetbrains.annotations.NotNull"
)
private val NULLABLE_ANNOTATIONS = arrayOf(
- androidx.annotation.Nullable::class.java,
- org.jetbrains.annotations.Nullable::class.java
+ "androidx.annotation.Nullable",
+ "org.jetbrains.annotations.Nullable"
)
@Suppress("UnstableApiUsage")
-private fun Element.hasAnyOf(annotations: Array<Class<out Annotation>>) = annotations.any {
- MoreElements.isAnnotationPresent(this, it)
-}
+private fun Element.hasAnyOf(annotations: Array<String>) =
+ annotationMirrors.any { annotationMirror ->
+ val annotationTypeElement = MoreElements.asType(annotationMirror.annotationType.asElement())
+ annotations.any { annotationTypeElement.qualifiedName.contentEquals(it) }
+ }
internal val Element.nullability: XNullability
get() = if (asType().kind.isPrimitive || hasAnyOf(NONNULL_ANNOTATIONS)) {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBox.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBox.kt
index 3bdd7ae..d07a36e 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBox.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBox.kt
@@ -16,7 +16,6 @@
package androidx.room.compiler.processing.ksp
-import androidx.annotation.VisibleForTesting
import androidx.room.compiler.processing.XAnnotationBox
import androidx.room.compiler.processing.XType
@@ -25,7 +24,7 @@
* handles those cases.
* see: https://github.com/google/ksp/issues/53
*/
-internal class KspReflectiveAnnotationBox<T : Annotation> @VisibleForTesting constructor(
+internal class KspReflectiveAnnotationBox<T : Annotation> constructor(
private val env: KspProcessingEnv,
private val annotationClass: Class<T>,
private val annotation: T
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/JavacTestProcessorTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/JavacTestProcessorTest.kt
deleted file mode 100644
index 7b42e74..0000000
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/JavacTestProcessorTest.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * 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 androidx.room.compiler.processing
-
-import androidx.room.compiler.processing.testcode.OtherAnnotation
-import androidx.room.compiler.processing.util.Source
-import androidx.room.compiler.processing.util.getField
-import androidx.room.compiler.processing.util.getMethod
-import com.google.common.truth.Truth.assertAbout
-import com.google.common.truth.Truth.assertThat
-import com.google.testing.compile.JavaSourcesSubjectFactory
-import org.junit.Test
-import java.util.concurrent.atomic.AtomicBoolean
-import kotlin.reflect.KClass
-
-class JavacTestProcessorTest {
-
- @Test
- fun getElementsAnnotatedWith() {
- val source = Source.java(
- "foo.bar.Baz",
- """
- package foo.bar;
- import androidx.room.compiler.processing.testcode.OtherAnnotation;
- @OtherAnnotation(value="xx")
- class Baz {
- @OtherAnnotation(value="xx")
- int myField = 0;
- @OtherAnnotation(value="xx")
- void myFunction() { }
- }
- """.trimIndent()
- )
- testProcessor(listOf(source), listOf(OtherAnnotation::class)) { roundEnv ->
- val annotatedElementsByClass = roundEnv.getElementsAnnotatedWith(
- OtherAnnotation::class
- )
-
- val annotatedElementsByName = roundEnv.getElementsAnnotatedWith(
- OtherAnnotation::class.qualifiedName!!
- )
-
- val targetElement = xProcessingEnv.requireTypeElement("foo.bar.Baz")
- assertThat(
- annotatedElementsByClass
- ).apply {
- containsExactlyElementsIn(annotatedElementsByName)
- hasSize(3)
- contains(targetElement)
- contains(targetElement.getMethod("myFunction"))
- contains(targetElement.getField("myField"))
- }
- }
- }
-
- private fun testProcessor(
- sources: List<Source>,
- annotations: List<KClass<out Annotation>>,
- doProcessTest: JavacTestProcessor.(XRoundEnv) -> Unit
- ) {
- val invoked = AtomicBoolean(false)
-
- val testProcessor = object : JavacTestProcessor() {
- override fun doProcess(annotations: Set<XTypeElement>, roundEnv: XRoundEnv): Boolean {
- invoked.set(true)
-
- doProcessTest(roundEnv)
-
- return true
- }
-
- override fun getSupportedAnnotationTypes(): Set<String> {
- return annotations.map { it.java.canonicalName }.toSet()
- }
- }
- assertAbout(
- JavaSourcesSubjectFactory.javaSources()
- ).that(
- sources.map { it.toJFO() }
- ).processedWith(
- testProcessor
- ).compilesWithoutError()
-
- assertThat(invoked.get()).isTrue()
- }
-}