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()
|
testServices.environmentManager.getProjectEnvironment()
|
||||||
).distinct()
|
).distinct()
|
||||||
project.apply {
|
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 filter = BuiltInDefinitionFile.FILTER_OUT_CLASSES_EXISTING_AS_JVM_CLASS_FILES
|
||||||
val ktFilesForBinaries: List<KtFile>
|
val ktFilesForBinaries: List<KtFile>
|
||||||
|
|||||||
+26
-4
@@ -5,22 +5,33 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.providers.impl
|
package org.jetbrains.kotlin.analysis.providers.impl
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolver
|
||||||
import org.jetbrains.kotlin.analysis.providers.KotlinAnnotationsResolverFactory
|
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.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
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 class KotlinStaticAnnotationsResolver(
|
||||||
|
private val project: Project,
|
||||||
ktFiles: Collection<KtFile>,
|
ktFiles: Collection<KtFile>,
|
||||||
scope: GlobalSearchScope
|
scope: GlobalSearchScope
|
||||||
) : KotlinAnnotationsResolver {
|
) : KotlinAnnotationsResolver {
|
||||||
|
private val declarationProvider: KotlinDeclarationProvider by lazy {
|
||||||
|
project.createDeclarationProvider(scope, contextualModule = null)
|
||||||
|
}
|
||||||
|
|
||||||
private val filesInScope = ktFiles.filter { scope.contains(it.virtualFile) }
|
private val filesInScope = ktFiles.filter { scope.contains(it.virtualFile) }
|
||||||
|
|
||||||
private val allDeclarations: List<KtDeclaration> by lazy {
|
private val allDeclarations: List<KtDeclaration> by lazy {
|
||||||
@@ -54,12 +65,23 @@ private class KotlinStaticAnnotationsResolver(
|
|||||||
return declaration.annotationEntries.asSequence()
|
return declaration.annotationEntries.asSequence()
|
||||||
.mapNotNull { it.typeReference?.text }
|
.mapNotNull { it.typeReference?.text }
|
||||||
.map { ClassId.topLevel(FqName(it)) }
|
.map { ClassId.topLevel(FqName(it)) }
|
||||||
|
.filter { it.resolveToAnnotation() != null }
|
||||||
.toSet()
|
.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 {
|
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(KotlinModificationTrackerFactory::class.java, KotlinStaticModificationTrackerFactory::class.java)
|
||||||
registerService(KotlinGlobalModificationService::class.java, KotlinStaticGlobalModificationService::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)
|
registerService(KotlinResolutionScopeProvider::class.java, KotlinByModulesResolutionScopeProvider::class.java)
|
||||||
val declarationProviderFactory = KotlinStaticDeclarationProviderFactory(
|
val declarationProviderFactory = KotlinStaticDeclarationProviderFactory(
|
||||||
this,
|
this,
|
||||||
|
|||||||
Reference in New Issue
Block a user