Kapt: support multiple annotation processing steps (KT-13651)
(cherry picked from commit 880e183)
This commit is contained in:
committed by
Yan Zhulanow
parent
6ceaac63dc
commit
824b778a7b
+136
-112
@@ -19,18 +19,16 @@ package org.jetbrains.kotlin.annotation
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.annotation.processing.RoundAnnotations
|
||||
import org.jetbrains.kotlin.annotation.processing.diagnostic.ErrorsAnnotationProcessing
|
||||
import org.jetbrains.kotlin.annotation.processing.impl.*
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
|
||||
import java.io.File
|
||||
@@ -65,6 +63,8 @@ abstract class AbstractAnnotationProcessingExtension(
|
||||
if (verboseOutput) messager.printMessage(Diagnostic.Kind.OTHER, "Kapt: " + message())
|
||||
}
|
||||
|
||||
private fun Int.count(noun: String) = if (this == 1) "$this $noun" else "$this ${noun}s"
|
||||
|
||||
override fun analysisCompleted(
|
||||
project: Project,
|
||||
module: ModuleDescriptor,
|
||||
@@ -80,53 +80,146 @@ abstract class AbstractAnnotationProcessingExtension(
|
||||
log { "No annotation processors detected, exiting" }
|
||||
return null
|
||||
}
|
||||
|
||||
log { "Analysing Kotlin files: " + files.map { it.virtualFile.path } }
|
||||
|
||||
val analysisContext = AnalysisContext(hashMapOf())
|
||||
analysisContext.analyzeFiles(files)
|
||||
|
||||
log { "Analysing Java source roots: $javaSourceRoots" }
|
||||
|
||||
|
||||
val appendJavaSourceRootsHandler = project.getUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY)
|
||||
if (appendJavaSourceRootsHandler == null) {
|
||||
log { "Java source root handler is not set, exiting" }
|
||||
return null
|
||||
}
|
||||
|
||||
val psiManager = PsiManager.getInstance(project)
|
||||
for (javaSourceRoot in javaSourceRoots) {
|
||||
javaSourceRoot.walk().filter { it.isFile && it.extension == "java" }.forEach {
|
||||
val vFile = StandardFileSystems.local().findFileByPath(it.absolutePath)
|
||||
if (vFile != null) {
|
||||
val javaFile = psiManager.findFile(vFile) as? PsiJavaFile
|
||||
if (javaFile != null) {
|
||||
analysisContext.analyzeFile(javaFile)
|
||||
val javaPsiFacade = JavaPsiFacade.getInstance(project)
|
||||
val projectScope = GlobalSearchScope.projectScope(project)
|
||||
|
||||
val options = emptyMap<String, String>()
|
||||
log { "Options: $options" }
|
||||
|
||||
val filer = KotlinFiler(generatedSourcesOutputDir, classesOutputDir)
|
||||
val types = KotlinTypes(javaPsiFacade, PsiManager.getInstance(project), projectScope)
|
||||
val elements = KotlinElements(javaPsiFacade, projectScope)
|
||||
|
||||
val processingEnvironment = KotlinProcessingEnvironment(
|
||||
elements, types, messager, options, filer, processors,
|
||||
project, psiManager, javaPsiFacade, projectScope, appendJavaSourceRootsHandler)
|
||||
|
||||
val processingResult = processingEnvironment.doAnnotationProcessing(files)
|
||||
|
||||
annotationProcessingComplete = true
|
||||
log {
|
||||
"Annotation processing complete, " +
|
||||
processingResult.errorCount.count("error") + ", " +
|
||||
processingResult.warningCount.count("warning")
|
||||
}
|
||||
|
||||
if (processingResult.errorCount != 0) {
|
||||
val reportFile = files.firstOrNull()
|
||||
if (reportFile != null) {
|
||||
bindingTrace.report(ErrorsAnnotationProcessing.ANNOTATION_PROCESSING_ERROR.on(reportFile))
|
||||
}
|
||||
|
||||
// Do not restart Kotlin file analysis
|
||||
return null
|
||||
}
|
||||
|
||||
if (!processingResult.wasAnythingGenerated) {
|
||||
// Nothing was generated, do not need to restart analysis
|
||||
return null
|
||||
}
|
||||
|
||||
return AnalysisResult.RetryWithAdditionalJavaRoots(
|
||||
bindingTrace.bindingContext,
|
||||
module,
|
||||
listOf(generatedSourcesOutputDir),
|
||||
addToEnvironment = false)
|
||||
}
|
||||
|
||||
private fun KotlinProcessingEnvironment.doAnnotationProcessing(files: Collection<KtFile>): ProcessingResult {
|
||||
run initializeProcessors@ {
|
||||
processors.forEach { it.init(this) }
|
||||
log { "Initialized processors: " + processors.joinToString { it.javaClass.name } }
|
||||
}
|
||||
|
||||
val firstRoundAnnotations = RoundAnnotations()
|
||||
|
||||
run analyzeFilesForFirstRound@ {
|
||||
log { "Analysing Kotlin files: " + files.map { it.virtualFile.path } }
|
||||
firstRoundAnnotations.analyzeFiles(files)
|
||||
|
||||
log { "Analysing Java source roots: $javaSourceRoots" }
|
||||
for (javaSourceRoot in javaSourceRoots) {
|
||||
javaSourceRoot.walk().filter { it.isFile && it.extension == "java" }.forEach {
|
||||
val vFile = StandardFileSystems.local().findFileByPath(it.absolutePath)
|
||||
if (vFile != null) {
|
||||
val javaFile = psiManager.findFile(vFile) as? PsiJavaFile
|
||||
if (javaFile != null) {
|
||||
firstRoundAnnotations.analyzeFile(javaFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val options = emptyMap<String, String>()
|
||||
log { "Options: $options" }
|
||||
val finalRoundNumber = run annotationProcessing@ {
|
||||
val firstRoundEnvironment = KotlinRoundEnvironment(firstRoundAnnotations, false, 1)
|
||||
process(firstRoundEnvironment)
|
||||
} + 1
|
||||
|
||||
val javaPsiFacade = JavaPsiFacade.getInstance(project)
|
||||
val projectScope = GlobalSearchScope.projectScope(project)
|
||||
log { "Starting round $finalRoundNumber (final)" }
|
||||
val finalRoundEnvironment = KotlinRoundEnvironment(RoundAnnotations(), true, finalRoundNumber)
|
||||
for (processor in processors) {
|
||||
processor.process(emptySet(), finalRoundEnvironment)
|
||||
}
|
||||
|
||||
return ProcessingResult(messager.errorCount, messager.warningCount, filer.wasAnythingGenerated)
|
||||
}
|
||||
|
||||
private tailrec fun KotlinProcessingEnvironment.process(roundEnvironment: KotlinRoundEnvironment): Int {
|
||||
val newFiles = doRound(roundEnvironment)
|
||||
val newJavaFiles = newFiles.filter { it.extension.toLowerCase() == "java" }
|
||||
if (newJavaFiles.isEmpty() || messager.errorCount != 0) {
|
||||
return roundEnvironment.roundNumber
|
||||
}
|
||||
|
||||
val filer = KotlinFiler(generatedSourcesOutputDir, classesOutputDir)
|
||||
val types = KotlinTypes(javaPsiFacade, PsiManager.getInstance(project), projectScope)
|
||||
val elements = KotlinElements(javaPsiFacade, projectScope)
|
||||
// Add new Java source roots after the first round
|
||||
if (roundEnvironment.roundNumber == 1) {
|
||||
appendJavaSourceRootsHandler(listOf(generatedSourcesOutputDir))
|
||||
}
|
||||
|
||||
val processingEnvironment = KotlinProcessingEnvironment(elements, types, messager, options, filer)
|
||||
processors.forEach { it.init(processingEnvironment) }
|
||||
// Update the platform caches
|
||||
(PsiManager.getInstance(project).modificationTracker as? PsiModificationTrackerImpl)?.incCounter()
|
||||
|
||||
log { "Initialized processors: " + processors.joinToString { it.javaClass.name } }
|
||||
// Find generated files
|
||||
val localFileSystem = StandardFileSystems.local()
|
||||
val psiFiles = newJavaFiles
|
||||
.map { localFileSystem.findFileByPath(it.absolutePath)?.let { psiManager.findFile(it) } }
|
||||
.filterIsInstance<PsiJavaFile>()
|
||||
|
||||
if (psiFiles.isEmpty()) {
|
||||
log { "Something is strange, files were generated but not found by PsiManager" }
|
||||
return roundEnvironment.roundNumber
|
||||
}
|
||||
|
||||
log { "Starting round 1" }
|
||||
val round1Environment = KotlinRoundEnvironment(analysisContext)
|
||||
// Start the next round
|
||||
val nextRoundAnnotations = RoundAnnotations().apply { analyzeFiles(psiFiles) }
|
||||
val nextRoundEnvironment = KotlinRoundEnvironment(nextRoundAnnotations, false, roundEnvironment.roundNumber + 1)
|
||||
return process(nextRoundEnvironment)
|
||||
}
|
||||
|
||||
private fun KotlinProcessingEnvironment.doRound(roundEnvironment: KotlinRoundEnvironment): List<File> {
|
||||
log { "Starting round ${roundEnvironment.roundNumber}" }
|
||||
|
||||
val newFiles = mutableListOf<File>()
|
||||
filer.onFileCreatedHandler = { newFiles += it }
|
||||
|
||||
for (processor in processors) {
|
||||
val supportedAnnotationNames = processor.supportedAnnotationTypes
|
||||
val supportsAnyAnnotation = supportedAnnotationNames.contains("*")
|
||||
|
||||
val applicableAnnotationNames = when (supportsAnyAnnotation) {
|
||||
true -> analysisContext.annotationsMap.keys
|
||||
false -> processor.supportedAnnotationTypes.filter { it in analysisContext.annotationsMap }
|
||||
val acceptsAnyAnnotation = supportedAnnotationNames.contains("*")
|
||||
|
||||
val applicableAnnotationNames = when (acceptsAnyAnnotation) {
|
||||
true -> roundEnvironment.annotationsMap.keys
|
||||
false -> processor.supportedAnnotationTypes.filter { it in roundEnvironment.annotationsMap }
|
||||
}
|
||||
|
||||
|
||||
if (applicableAnnotationNames.isEmpty()) {
|
||||
log { "Skipping processor " + processor.javaClass.name + ": no relevant annotations" }
|
||||
continue
|
||||
@@ -135,89 +228,20 @@ abstract class AbstractAnnotationProcessingExtension(
|
||||
val applicableAnnotations = applicableAnnotationNames
|
||||
.map { javaPsiFacade.findClass(it, projectScope)?.let { JeTypeElement(it) } }
|
||||
.filterNotNullTo(hashSetOf())
|
||||
|
||||
|
||||
log {
|
||||
val annotationNames = applicableAnnotations.joinToString { it.qualifiedName.toString() }
|
||||
"Processing with " + processor.javaClass.name + " (annotations: " + annotationNames + ")"
|
||||
}
|
||||
|
||||
processor.process(applicableAnnotations, round1Environment)
|
||||
}
|
||||
|
||||
log { "Starting round 2 (final)" }
|
||||
val round2Environment = KotlinRoundEnvironment(AnalysisContext(hashMapOf()), isProcessingOver = true)
|
||||
for (processor in processors) {
|
||||
processor.process(emptySet(), round2Environment)
|
||||
processor.process(applicableAnnotations, roundEnvironment)
|
||||
}
|
||||
|
||||
fun Int.count(noun: String) = if (this == 1) "$this $noun" else "$this ${noun}s"
|
||||
log { "Annotation processing complete, ${messager.errorCount.count("error")}, ${messager.warningCount.count("warning")}" }
|
||||
|
||||
if (messager.errorCount != 0) {
|
||||
val reportFile = files.firstOrNull()
|
||||
if (reportFile != null) {
|
||||
bindingTrace.report(ErrorsAnnotationProcessing.ANNOTATION_PROCESSING_ERROR.on(reportFile))
|
||||
}
|
||||
|
||||
// Do not restart analysis
|
||||
return null
|
||||
}
|
||||
|
||||
annotationProcessingComplete = true
|
||||
return AnalysisResult.RetryWithAdditionalJavaRoots(bindingTrace.bindingContext, module, listOf(generatedSourcesOutputDir))
|
||||
log { "Round ${roundEnvironment.roundNumber} finished, ${newFiles.size.count("file")} generated (${newFiles.joinToString()})" }
|
||||
return newFiles
|
||||
}
|
||||
|
||||
protected abstract fun loadAnnotationProcessors(): List<Processor>
|
||||
}
|
||||
|
||||
internal class AnalysisContext(annotationsMap: MutableMap<String, MutableList<PsiModifierListOwner>>) {
|
||||
private val mutableAnnotationsMap = annotationsMap
|
||||
|
||||
val annotationsMap: Map<String, List<PsiModifierListOwner>>
|
||||
get() = mutableAnnotationsMap
|
||||
|
||||
fun analyzeFiles(files: Collection<KtFile>) {
|
||||
for (file in files) {
|
||||
analyzeFile(file)
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeFile(file: KtFile) {
|
||||
val lightClass = file.findFacadeClass()
|
||||
|
||||
if (lightClass != null) {
|
||||
analyzeDeclaration(lightClass)
|
||||
}
|
||||
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration !is KtClassOrObject) continue
|
||||
val clazz = declaration.toLightClass() ?: continue
|
||||
analyzeDeclaration(clazz)
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeFile(file: PsiJavaFile) {
|
||||
file.classes.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
fun analyzeDeclaration(declaration: PsiElement) {
|
||||
if (declaration !is PsiModifierListOwner) return
|
||||
|
||||
for (annotation in declaration.getAnnotationsWithInherited()) {
|
||||
val fqName = annotation.qualifiedName ?: return
|
||||
mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration)
|
||||
}
|
||||
|
||||
if (declaration is PsiClass) {
|
||||
declaration.methods.forEach { analyzeDeclaration(it) }
|
||||
declaration.fields.forEach { analyzeDeclaration(it) }
|
||||
declaration.innerClasses.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
if (declaration is PsiMethod) {
|
||||
for (parameter in declaration.parameterList.parameters) {
|
||||
analyzeDeclaration(parameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private class ProcessingResult(val errorCount: Int, val warningCount: Int, val wasAnythingGenerated: Boolean)
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.kotlin.annotation.processing
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
internal class RoundAnnotations() {
|
||||
private val mutableAnnotationsMap = mutableMapOf<String, MutableList<PsiModifierListOwner>>()
|
||||
|
||||
val annotationsMap: Map<String, List<PsiModifierListOwner>>
|
||||
get() = mutableAnnotationsMap
|
||||
|
||||
fun analyzeFiles(files: Collection<KtFile>) = files.forEach { analyzeFile(it) }
|
||||
|
||||
@JvmName("analyzePsiJavaFiles")
|
||||
fun analyzeFiles(files: Collection<PsiJavaFile>) = files.forEach { analyzeFile(it) }
|
||||
|
||||
fun analyzeFile(file: KtFile) {
|
||||
val lightClass = file.findFacadeClass()
|
||||
|
||||
if (lightClass != null) {
|
||||
analyzeDeclaration(lightClass)
|
||||
}
|
||||
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration !is KtClassOrObject) continue
|
||||
val clazz = declaration.toLightClass() ?: continue
|
||||
analyzeDeclaration(clazz)
|
||||
}
|
||||
}
|
||||
|
||||
fun analyzeFile(file: PsiJavaFile) {
|
||||
file.classes.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
fun analyzeDeclaration(declaration: PsiElement) {
|
||||
if (declaration !is PsiModifierListOwner) return
|
||||
|
||||
for (annotation in declaration.getAnnotationsWithInherited()) {
|
||||
val fqName = annotation.qualifiedName ?: return
|
||||
mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration)
|
||||
}
|
||||
|
||||
if (declaration is PsiClass) {
|
||||
declaration.methods.forEach { analyzeDeclaration(it) }
|
||||
declaration.fields.forEach { analyzeDeclaration(it) }
|
||||
declaration.innerClasses.forEach { analyzeDeclaration(it) }
|
||||
}
|
||||
|
||||
if (declaration is PsiMethod) {
|
||||
for (parameter in declaration.parameterList.parameters) {
|
||||
analyzeDeclaration(parameter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -24,11 +24,18 @@ import javax.tools.JavaFileManager
|
||||
import javax.tools.JavaFileObject
|
||||
import javax.tools.StandardLocation
|
||||
|
||||
class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Filer {
|
||||
class KotlinFiler(
|
||||
val generatedSourceDir: File,
|
||||
val classesOutputDir: File,
|
||||
internal var onFileCreatedHandler: (File) -> Unit = {}
|
||||
) : Filer {
|
||||
private companion object {
|
||||
val PACKAGE_INFO_SUFFIX = ".packageInfo"
|
||||
}
|
||||
|
||||
internal var wasAnythingGenerated: Boolean = false
|
||||
private set
|
||||
|
||||
private fun getGeneratedFile(nameCharSequence: CharSequence, extension: String): File {
|
||||
val name = nameCharSequence.toString()
|
||||
val isPackageInfo = name.endsWith(PACKAGE_INFO_SUFFIX)
|
||||
@@ -47,8 +54,13 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi
|
||||
return File(packageDir, fileName)
|
||||
}
|
||||
|
||||
private fun File.notifyCreated() = apply {
|
||||
wasAnythingGenerated = true
|
||||
onFileCreatedHandler(this)
|
||||
}
|
||||
|
||||
override fun createSourceFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
||||
return KotlinJavaFileObject(getGeneratedFile(name, ".java"))
|
||||
return KotlinJavaFileObject(getGeneratedFile(name, ".java").notifyCreated())
|
||||
}
|
||||
|
||||
override fun getResource(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): FileObject? {
|
||||
@@ -63,7 +75,7 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi
|
||||
): FileObject? {
|
||||
val resourceFile = getResourceFile(location, pkg, relativeName)
|
||||
resourceFile.parentFile.mkdirs()
|
||||
return KotlinFileObject(resourceFile)
|
||||
return KotlinFileObject(resourceFile.notifyCreated())
|
||||
}
|
||||
|
||||
private fun getResourceFile(location: JavaFileManager.Location, pkg: CharSequence, relativeName: CharSequence): File {
|
||||
@@ -80,6 +92,6 @@ class KotlinFiler(val generatedSourceDir: File, val classesOutputDir: File) : Fi
|
||||
}
|
||||
|
||||
override fun createClassFile(name: CharSequence, vararg originatingElements: Element?): JavaFileObject {
|
||||
return KotlinJavaFileObject(getGeneratedFile(name, ".class"))
|
||||
return KotlinJavaFileObject(getGeneratedFile(name, ".class").notifyCreated())
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.annotation.processing.impl
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import javax.annotation.processing.Filer
|
||||
import javax.annotation.processing.Messager
|
||||
import javax.annotation.processing.ProcessingEnvironment
|
||||
import javax.annotation.processing.Processor
|
||||
import javax.lang.model.SourceVersion
|
||||
import javax.lang.model.util.Elements
|
||||
import javax.lang.model.util.Types
|
||||
@@ -27,9 +31,17 @@ import javax.lang.model.util.Types
|
||||
class KotlinProcessingEnvironment(
|
||||
private val elements: Elements,
|
||||
private val types: Types,
|
||||
private val messager: Messager,
|
||||
private val messager: KotlinMessager,
|
||||
options: Map<String, String>,
|
||||
private val filer: Filer
|
||||
private val filer: KotlinFiler,
|
||||
|
||||
internal val processors: List<Processor>,
|
||||
|
||||
internal val project: Project,
|
||||
internal val psiManager: PsiManager,
|
||||
internal val javaPsiFacade: JavaPsiFacade,
|
||||
internal val projectScope: GlobalSearchScope,
|
||||
internal val appendJavaSourceRootsHandler: (List<File>) -> Unit
|
||||
) : ProcessingEnvironment {
|
||||
private val options = Collections.unmodifiableMap(options)
|
||||
|
||||
|
||||
+10
-4
@@ -16,23 +16,29 @@
|
||||
|
||||
package org.jetbrains.kotlin.annotation.processing.impl
|
||||
|
||||
import org.jetbrains.kotlin.annotation.AnalysisContext
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.annotation.processing.RoundAnnotations
|
||||
import org.jetbrains.kotlin.java.model.toJeElement
|
||||
import javax.annotation.processing.RoundEnvironment
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.TypeElement
|
||||
|
||||
internal class KotlinRoundEnvironment(
|
||||
private val context: AnalysisContext,
|
||||
private val isProcessingOver: Boolean = false) : RoundEnvironment {
|
||||
private val roundAnnotations: RoundAnnotations,
|
||||
private val isProcessingOver: Boolean,
|
||||
internal val roundNumber: Int
|
||||
) : RoundEnvironment {
|
||||
private var isError = false
|
||||
|
||||
internal val annotationsMap: Map<String, List<PsiModifierListOwner>>
|
||||
get() = roundAnnotations.annotationsMap
|
||||
|
||||
override fun getRootElements() = emptySet<Element>()
|
||||
|
||||
override fun processingOver() = isProcessingOver
|
||||
|
||||
private fun getElementsAnnotatedWith(fqName: String): Set<Element> {
|
||||
val declarations = context.annotationsMap[fqName] ?: return emptySet()
|
||||
val declarations = roundAnnotations.annotationsMap[fqName] ?: return emptySet()
|
||||
return hashSetOf<Element>().apply {
|
||||
for (declaration in declarations) {
|
||||
declaration.toJeElement()?.let { add(it) }
|
||||
|
||||
Reference in New Issue
Block a user