KT-63096 [LL] Make KotlinStaticAnnotationsResolver more correct
By using `KotlinDeclarationProvider`, it can now check that the annotation is actually present in the scope
This commit is contained in:
+1
-1
@@ -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<KtFile>
|
||||
|
||||
+26
-4
@@ -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<KtFile>,
|
||||
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<KtDeclaration> 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<KtClass> { it.isAnnotation() }
|
||||
|
||||
return annotations.singleOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
public class KotlinStaticAnnotationsResolverFactory(private val files: Collection<KtFile>) : KotlinAnnotationsResolverFactory {
|
||||
public class KotlinStaticAnnotationsResolverFactory(
|
||||
private val project: Project,
|
||||
private val files: Collection<KtFile>,
|
||||
) : KotlinAnnotationsResolverFactory {
|
||||
override fun createAnnotationResolver(searchScope: GlobalSearchScope): KotlinAnnotationsResolver {
|
||||
return KotlinStaticAnnotationsResolver(files, searchScope)
|
||||
return KotlinStaticAnnotationsResolver(project, files, searchScope)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user