Fix kapt creates output directories on configuration phase.
Gradle will create such directories itself. Also it should fix build cache issue with kapt tasks - build cache was disabled due to the 'overlapping outputs'. ^KT-45532 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
5abc45e6ff
commit
d46ad6c0ad
@@ -28,6 +28,7 @@ val kotlinGradlePluginAndItsRequired = arrayOf(
|
|||||||
":kotlin-noarg",
|
":kotlin-noarg",
|
||||||
":kotlin-sam-with-receiver",
|
":kotlin-sam-with-receiver",
|
||||||
":kotlin-android-extensions",
|
":kotlin-android-extensions",
|
||||||
|
":kotlin-android-extensions-runtime",
|
||||||
":kotlin-parcelize-compiler",
|
":kotlin-parcelize-compiler",
|
||||||
":kotlin-build-common",
|
":kotlin-build-common",
|
||||||
":kotlin-compiler-embeddable",
|
":kotlin-compiler-embeddable",
|
||||||
|
|||||||
+13
@@ -273,6 +273,19 @@ abstract class Kapt3AndroidIT : Kapt3BaseIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KT-45532
|
||||||
|
@Test
|
||||||
|
open fun kaptTasksShouldNotCreateOutputsOnConfigurationPhase() {
|
||||||
|
Project(
|
||||||
|
"android-dagger",
|
||||||
|
directoryPrefix = "kapt2"
|
||||||
|
).build("--dry-run", "assembleDebug") {
|
||||||
|
assertSuccessful()
|
||||||
|
assertNoSuchFile("app/build/tmp")
|
||||||
|
assertNoSuchFile("app/build/generated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupDataBinding(project: Project) {
|
private fun setupDataBinding(project: Project) {
|
||||||
project.setupWorkingDir()
|
project.setupWorkingDir()
|
||||||
|
|
||||||
|
|||||||
+11
-14
@@ -198,17 +198,13 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
|
|
||||||
private fun Kapt3SubpluginContext.getKaptStubsDir() = temporaryKaptDirectory("stubs")
|
private fun Kapt3SubpluginContext.getKaptStubsDir() = temporaryKaptDirectory("stubs")
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = temporaryKaptDirectory("incrementalData", doMkDirs = false)
|
private fun Kapt3SubpluginContext.getKaptIncrementalDataDir() = temporaryKaptDirectory("incrementalData")
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.getKaptIncrementalAnnotationProcessingCache() = temporaryKaptDirectory("incApCache")
|
private fun Kapt3SubpluginContext.getKaptIncrementalAnnotationProcessingCache() = temporaryKaptDirectory("incApCache")
|
||||||
|
|
||||||
private fun Kapt3SubpluginContext.temporaryKaptDirectory(name: String, doMkDirs: Boolean = true): File {
|
private fun Kapt3SubpluginContext.temporaryKaptDirectory(
|
||||||
val dir = File(project.buildDir, "tmp/kapt3/$name/$sourceSetName")
|
name: String
|
||||||
if (doMkDirs) {
|
) = project.buildDir.resolve("tmp/kapt3/$name/$sourceSetName")
|
||||||
dir.mkdirs()
|
|
||||||
}
|
|
||||||
return dir
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inner class Kapt3SubpluginContext(
|
internal inner class Kapt3SubpluginContext(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
@@ -328,8 +324,6 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
pluginOptions += SubpluginOption("processors", annotationProcessors)
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinSourcesOutputDir.mkdirs()
|
|
||||||
|
|
||||||
val apOptions = getAPOptions().get()
|
val apOptions = getAPOptions().get()
|
||||||
|
|
||||||
pluginOptions += CompositeSubpluginOption(
|
pluginOptions += CompositeSubpluginOption(
|
||||||
@@ -476,7 +470,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
|
|
||||||
kaptTask.kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile
|
kaptTask.kotlinCompileTask = kotlinCompilation.compileKotlinTaskProvider.get() as KotlinCompile
|
||||||
|
|
||||||
kaptTask.stubsDir = getKaptStubsDir()
|
kaptTask.stubsDir.set(getKaptStubsDir())
|
||||||
|
|
||||||
kaptTask.destinationDir = sourcesOutputDir
|
kaptTask.destinationDir = sourcesOutputDir
|
||||||
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
kaptTask.kotlinSourcesDestinationDir = kotlinSourcesOutputDir
|
||||||
@@ -486,7 +480,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
kaptTask.isIncremental = project.isIncrementalKapt()
|
kaptTask.isIncremental = project.isIncrementalKapt()
|
||||||
|
|
||||||
if (kaptTask.isIncremental) {
|
if (kaptTask.isIncremental) {
|
||||||
kaptTask.incAptCache = getKaptIncrementalAnnotationProcessingCache()
|
kaptTask.incAptCache.set(getKaptIncrementalAnnotationProcessingCache())
|
||||||
kaptTask.localState.register(kaptTask.incAptCache)
|
kaptTask.localState.register(kaptTask.incAptCache)
|
||||||
|
|
||||||
kaptTask.classpathStructure = classStructureIfIncremental!!.incoming.artifactView { viewConfig ->
|
kaptTask.classpathStructure = classStructureIfIncremental!!.incoming.artifactView { viewConfig ->
|
||||||
@@ -496,7 +490,10 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
if (kaptTask is KaptWithKotlincTask) {
|
if (kaptTask is KaptWithKotlincTask) {
|
||||||
kaptTask.pluginOptions.addPluginArgument(
|
kaptTask.pluginOptions.addPluginArgument(
|
||||||
getCompilerPluginId(),
|
getCompilerPluginId(),
|
||||||
SubpluginOption("incrementalCache", kaptTask.incAptCache!!.absolutePath)
|
SubpluginOption(
|
||||||
|
"incrementalCache",
|
||||||
|
lazy { kaptTask.incAptCache.asFile.get().absolutePath }
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,7 +609,7 @@ class Kapt3GradleSubplugin @Inject internal constructor(private val registry: To
|
|||||||
val kaptTaskProvider = project.registerTask<KaptGenerateStubsTask>(kaptTaskName) { kaptTask ->
|
val kaptTaskProvider = project.registerTask<KaptGenerateStubsTask>(kaptTaskName) { kaptTask ->
|
||||||
kaptTask.kotlinCompileTask = kotlinCompile.get()
|
kaptTask.kotlinCompileTask = kotlinCompile.get()
|
||||||
|
|
||||||
kaptTask.stubsDir = getKaptStubsDir()
|
kaptTask.stubsDir.set(getKaptStubsDir())
|
||||||
kaptTask.setDestinationDir { getKaptIncrementalDataDir() }
|
kaptTask.setDestinationDir { getKaptIncrementalDataDir() }
|
||||||
kaptTask.mapClasspath { kaptTask.kotlinCompileTask.classpath }
|
kaptTask.mapClasspath { kaptTask.kotlinCompileTask.classpath }
|
||||||
kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir)
|
kaptTask.generatedSourcesDirs = listOf(sourcesOutputDir, kotlinSourcesOutputDir)
|
||||||
|
|||||||
+8
-3
@@ -17,7 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||||
@@ -30,9 +32,12 @@ import org.jetbrains.kotlin.gradle.utils.isParentOf
|
|||||||
import org.jetbrains.kotlin.incremental.classpathAsList
|
import org.jetbrains.kotlin.incremental.classpathAsList
|
||||||
import org.jetbrains.kotlin.incremental.destinationAsFile
|
import org.jetbrains.kotlin.incremental.destinationAsFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
open class KaptGenerateStubsTask : KotlinCompile() {
|
open class KaptGenerateStubsTask @Inject constructor(
|
||||||
|
objectFactory: ObjectFactory
|
||||||
|
) : KotlinCompile() {
|
||||||
override val sourceRootsContainer = FilteringSourceRootsContainer(emptyList(), { isSourceRootAllowed(it) })
|
override val sourceRootsContainer = FilteringSourceRootsContainer(emptyList(), { isSourceRootAllowed(it) })
|
||||||
|
|
||||||
override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsImpl()
|
override val kotlinOptions: KotlinJvmOptions = KotlinJvmOptionsImpl()
|
||||||
@@ -42,7 +47,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
|
|||||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||||
|
|
||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
lateinit var stubsDir: File
|
val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
lateinit var generatedSourcesDirs: List<File>
|
lateinit var generatedSourcesDirs: List<File>
|
||||||
@@ -82,7 +87,7 @@ open class KaptGenerateStubsTask : KotlinCompile() {
|
|||||||
|
|
||||||
private fun isSourceRootAllowed(source: File): Boolean =
|
private fun isSourceRootAllowed(source: File): Boolean =
|
||||||
!destinationDir.isParentOf(source) &&
|
!destinationDir.isParentOf(source) &&
|
||||||
!stubsDir.isParentOf(source) &&
|
!stubsDir.asFile.get().isParentOf(source) &&
|
||||||
generatedSourcesDirs.none { it.isParentOf(source) }
|
generatedSourcesDirs.none { it.isParentOf(source) }
|
||||||
|
|
||||||
private val compileKotlinArgumentsContributor by project.provider {
|
private val compileKotlinArgumentsContributor by project.provider {
|
||||||
|
|||||||
+24
-23
@@ -1,8 +1,10 @@
|
|||||||
package org.jetbrains.kotlin.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.internal.ConventionTask
|
import org.gradle.api.internal.ConventionTask
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.provider.ListProperty
|
import org.gradle.api.provider.ListProperty
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||||
@@ -20,9 +22,12 @@ import org.jetbrains.kotlin.gradle.utils.getValue
|
|||||||
import org.jetbrains.kotlin.gradle.utils.isJavaFile
|
import org.jetbrains.kotlin.gradle.utils.isJavaFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.jar.JarFile
|
import java.util.jar.JarFile
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
abstract class KaptTask @Inject constructor(
|
||||||
|
objectFactory: ObjectFactory
|
||||||
|
): ConventionTask(), TaskWithLocalState {
|
||||||
init {
|
init {
|
||||||
cacheOnlyIfEnabledForKotlin()
|
cacheOnlyIfEnabledForKotlin()
|
||||||
|
|
||||||
@@ -30,14 +35,16 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
|||||||
outputs.cacheIf(reason) { useBuildCache }
|
outputs.cacheIf(reason) { useBuildCache }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun localStateDirectories(): FileCollection = objects.fileCollection().from(incAptCache)
|
override fun localStateDirectories(): FileCollection = objects
|
||||||
|
.fileCollection()
|
||||||
|
.from({ incAptCache.orNull })
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
@field:Transient
|
@field:Transient
|
||||||
internal lateinit var kotlinCompileTask: KotlinCompile
|
internal lateinit var kotlinCompileTask: KotlinCompile
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal lateinit var stubsDir: File
|
internal val stubsDir: DirectoryProperty = objectFactory.directoryProperty()
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal val objects = project.objects
|
internal val objects = project.objects
|
||||||
@@ -67,7 +74,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
|||||||
* annotations are specified during task configuration.
|
* annotations are specified during task configuration.
|
||||||
*/
|
*/
|
||||||
@get:Internal
|
@get:Internal
|
||||||
var incAptCache: File? = null
|
val incAptCache: DirectoryProperty = objectFactory.directoryProperty()
|
||||||
|
|
||||||
@get:OutputDirectory
|
@get:OutputDirectory
|
||||||
internal lateinit var classesDir: File
|
internal lateinit var classesDir: File
|
||||||
@@ -121,23 +128,17 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
|||||||
|
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:PathSensitive(PathSensitivity.RELATIVE)
|
@get:PathSensitive(PathSensitivity.RELATIVE)
|
||||||
val source: Collection<File>
|
val source: FileCollection = objectFactory
|
||||||
get() {
|
.fileCollection()
|
||||||
val result = HashSet<File>()
|
.from(
|
||||||
for (root in javaSourceRoots) {
|
{ kotlinCompileTask.sourceRootsContainer.sourceRoots },
|
||||||
root.walk().filterTo(result) { it.isJavaFile() }
|
stubsDir
|
||||||
}
|
)
|
||||||
return result
|
.asFileTree
|
||||||
|
.matching {
|
||||||
|
it.include("**/*.java")
|
||||||
}
|
}
|
||||||
|
.filter(::isRootAllowed)
|
||||||
// store the files before filtering, so that Gradle doesn't serialize the filtered collection for instant execution state and reuse it
|
|
||||||
private val unfilteredJavaSourceRoots by project.provider {
|
|
||||||
(kotlinCompileTask.sourceRootsContainer.sourceRoots + stubsDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
@get:Internal
|
|
||||||
protected val javaSourceRoots: Set<File>
|
|
||||||
get() = unfilteredJavaSourceRoots.filterTo(HashSet(), ::isRootAllowed)
|
|
||||||
|
|
||||||
@get:Internal
|
@get:Internal
|
||||||
override val metrics: BuildMetricsReporter =
|
override val metrics: BuildMetricsReporter =
|
||||||
@@ -145,8 +146,8 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
|||||||
|
|
||||||
private fun isRootAllowed(file: File): Boolean =
|
private fun isRootAllowed(file: File): Boolean =
|
||||||
file.exists() &&
|
file.exists() &&
|
||||||
!isAncestor(destinationDir, file) &&
|
!isAncestor(destinationDir, file) &&
|
||||||
!isAncestor(classesDir, file)
|
!isAncestor(classesDir, file)
|
||||||
|
|
||||||
//Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache
|
//Have to avoid using FileUtil because it is required system property reading that is not allowed for configuration cache
|
||||||
private fun isAncestor(dir: File, file: File): Boolean {
|
private fun isAncestor(dir: File, file: File): Boolean {
|
||||||
@@ -224,7 +225,7 @@ abstract class KaptTask : ConventionTask(), TaskWithLocalState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
|
private fun findClasspathChanges(inputs: IncrementalTaskInputs): KaptIncrementalChanges {
|
||||||
val incAptCacheDir = incAptCache!!
|
val incAptCacheDir = incAptCache.asFile.get()
|
||||||
incAptCacheDir.mkdirs()
|
incAptCacheDir.mkdirs()
|
||||||
|
|
||||||
val allDataFiles = classpathStructure!!.files
|
val allDataFiles = classpathStructure!!.files
|
||||||
|
|||||||
+6
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.internal
|
|||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.tasks.Classpath
|
import org.gradle.api.tasks.Classpath
|
||||||
import org.gradle.api.tasks.InputFiles
|
import org.gradle.api.tasks.InputFiles
|
||||||
import org.gradle.api.tasks.Internal
|
import org.gradle.api.tasks.Internal
|
||||||
@@ -27,8 +28,11 @@ import org.jetbrains.kotlin.gradle.utils.getValue
|
|||||||
import org.jetbrains.kotlin.gradle.utils.optionalProvider
|
import org.jetbrains.kotlin.gradle.utils.optionalProvider
|
||||||
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
import org.jetbrains.kotlin.gradle.utils.toSortedPathsArray
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
|
abstract class KaptWithKotlincTask @Inject constructor(
|
||||||
|
objectFactory: ObjectFactory
|
||||||
|
) : KaptTask(objectFactory), CompilerArgumentAwareWithInput<K2JVMCompilerArguments> {
|
||||||
@get:Internal
|
@get:Internal
|
||||||
internal val pluginOptions = CompilerPluginOptions()
|
internal val pluginOptions = CompilerPluginOptions()
|
||||||
|
|
||||||
@@ -107,7 +111,7 @@ abstract class KaptWithKotlincTask : KaptTask(), CompilerArgumentAwareWithInput<
|
|||||||
compilerRunner.runJvmCompilerAsync(
|
compilerRunner.runJvmCompilerAsync(
|
||||||
sourcesToCompile = emptyList(),
|
sourcesToCompile = emptyList(),
|
||||||
commonSources = emptyList(),
|
commonSources = emptyList(),
|
||||||
javaSourceRoots = javaSourceRoots,
|
javaSourceRoots = source.files,
|
||||||
javaPackagePrefix = javaPackagePrefix,
|
javaPackagePrefix = javaPackagePrefix,
|
||||||
args = args,
|
args = args,
|
||||||
environment = environment
|
environment = environment
|
||||||
|
|||||||
+9
-4
@@ -6,6 +6,8 @@
|
|||||||
package org.jetbrains.kotlin.gradle.internal
|
package org.jetbrains.kotlin.gradle.internal
|
||||||
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
||||||
@@ -27,7 +29,10 @@ import java.net.URL
|
|||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExecutor: WorkerExecutor) : KaptTask() {
|
abstract class KaptWithoutKotlincTask @Inject constructor(
|
||||||
|
objectFactory: ObjectFactory,
|
||||||
|
private val workerExecutor: WorkerExecutor
|
||||||
|
) : KaptTask(objectFactory) {
|
||||||
@get:InputFiles
|
@get:InputFiles
|
||||||
@get:Classpath
|
@get:Classpath
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@@ -98,16 +103,16 @@ abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExec
|
|||||||
val optionsForWorker = KaptOptionsForWorker(
|
val optionsForWorker = KaptOptionsForWorker(
|
||||||
projectDir,
|
projectDir,
|
||||||
compileClasspath,
|
compileClasspath,
|
||||||
javaSourceRoots.toList(),
|
source.files.toList(),
|
||||||
|
|
||||||
changedFiles,
|
changedFiles,
|
||||||
compiledSources,
|
compiledSources,
|
||||||
incAptCache,
|
incAptCache.orNull?.asFile,
|
||||||
classpathChanges.toList(),
|
classpathChanges.toList(),
|
||||||
|
|
||||||
destinationDir,
|
destinationDir,
|
||||||
classesDir,
|
classesDir,
|
||||||
stubsDir,
|
stubsDir.asFile.get(),
|
||||||
|
|
||||||
kaptClasspath.files.toList(),
|
kaptClasspath.files.toList(),
|
||||||
annotationProcessorFqNames,
|
annotationProcessorFqNames,
|
||||||
|
|||||||
Reference in New Issue
Block a user