diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt index 5ee89c964e3..ffd43d047d0 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiBaseTestServiceRegistrar.kt @@ -72,7 +72,7 @@ object AnalysisApiBaseTestServiceRegistrar: AnalysisApiTestServiceRegistrar() { testServices.environmentManager.getProjectEnvironment() ).distinct() project.apply { - registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(allSourceKtFiles)) + registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(project, allSourceKtFiles)) val filter = BuiltInDefinitionFile.FILTER_OUT_CLASSES_EXISTING_AS_JVM_CLASS_FILES val ktFilesForBinaries: List diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticAnnotationsResolver.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticAnnotationsResolver.kt index d0d19c374ea..77e0b0dd454 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticAnnotationsResolver.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticAnnotationsResolver.kt @@ -5,22 +5,33 @@ package org.jetbrains.kotlin.analysis.providers.impl +import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolverFactory +import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProvider +import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.utils.filterIsInstanceAnd /** - * This implementation works only for fully-qualified annotations usages, and does not check if they resolve somewhere. + * This implementation works only for FQN annotations usages (`@foo.Bar` instead of `@Bar`). + * It does not perform the full resolve of the annotation call, but it checks whether the annotation + * with such FQN is present in the [scope] with [KotlinDeclarationProvider]. * - * Required for the test infrastructure. + * Required for and used only in the test infrastructure. */ private class KotlinStaticAnnotationsResolver( + private val project: Project, ktFiles: Collection, scope: GlobalSearchScope ) : KotlinAnnotationsResolver { + private val declarationProvider: KotlinDeclarationProvider by lazy { + project.createDeclarationProvider(scope, contextualModule = null) + } + private val filesInScope = ktFiles.filter { scope.contains(it.virtualFile) } private val allDeclarations: List by lazy { @@ -54,12 +65,23 @@ private class KotlinStaticAnnotationsResolver( return declaration.annotationEntries.asSequence() .mapNotNull { it.typeReference?.text } .map { ClassId.topLevel(FqName(it)) } + .filter { it.resolveToAnnotation() != null } .toSet() } + + private fun ClassId.resolveToAnnotation(): KtClass? { + val classes = declarationProvider.getAllClassesByClassId(this) + val annotations = classes.filterIsInstanceAnd { it.isAnnotation() } + + return annotations.singleOrNull() + } } -public class KotlinStaticAnnotationsResolverFactory(private val files: Collection) : KotlinAnnotationsResolverFactory { +public class KotlinStaticAnnotationsResolverFactory( + private val project: Project, + private val files: Collection, +) : KotlinAnnotationsResolverFactory { override fun createAnnotationResolver(searchScope: GlobalSearchScope): KotlinAnnotationsResolver { - return KotlinStaticAnnotationsResolver(files, searchScope) + return KotlinStaticAnnotationsResolver(project, files, searchScope) } } \ No newline at end of file diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt index b81bba4eab0..5d55307f05c 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/api/standalone/StandaloneAnalysisAPISessionBuilder.kt @@ -125,7 +125,7 @@ public class StandaloneAnalysisAPISessionBuilder( registerService(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java) registerService(KotlinGlobalModificationService::class.java, KotlinStaticGlobalModificationService::class.java) - registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(sourceKtFiles)) + registerService(KotlinAnnotationsResolverFactory::class.java, KotlinStaticAnnotationsResolverFactory(this, sourceKtFiles)) registerService(KotlinResolutionScopeProvider::class.java, KotlinByModulesResolutionScopeProvider::class.java) val declarationProviderFactory = KotlinStaticDeclarationProviderFactory( this,