[AA] Add KtResolveExtensionInfoProvider to AA.
This provider is responsible for answering queries related to resolve extensions. At the moment, this includes retrieving a KtScope with all REx top-level declarations (moved from KtSymbolFromResolveExtensionProvider), and retrieving information necessary to supply a GeneratedSourcesFilter for REx generated code. Future REx-related functions can be added to this interface. ^KT-59329
This commit is contained in:
committed by
Ilya Kirillov
parent
fa0209a322
commit
9f85739599
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.resolveExtensionInfoProvider
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.scopeProvider.TestScopeRenderer.renderForTests
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.resolve.extensions.KtResolveExtensionTestSupport
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.resolve.extensions.getDescription
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtScope
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.assertions
|
||||
|
||||
abstract class AbstractResolveExtensionInfoProviderTest : AbstractAnalysisApiBasedTest() {
|
||||
override fun configureTest(builder: TestConfigurationBuilder) {
|
||||
super.configureTest(builder)
|
||||
KtResolveExtensionTestSupport.configure(builder)
|
||||
}
|
||||
|
||||
private fun List<TestModule>.findMainModule(): TestModule =
|
||||
singleOrNull()
|
||||
?: find { it.name == "main" }
|
||||
?: error("There should either be a single module, or a module named 'main'.")
|
||||
|
||||
private fun List<KtFile>.findMainKt(): KtFile =
|
||||
singleOrNull()
|
||||
?: find { it.name == "main.kt" }
|
||||
?: error("There should either be a single Kotlin file in the main module, or a file named 'main.kt'.")
|
||||
|
||||
override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
|
||||
val mainModule = moduleStructure.modules.findMainModule()
|
||||
val ktFiles = testServices.ktModuleProvider.getModuleFiles(mainModule).filterIsInstance<KtFile>()
|
||||
val mainKt = ktFiles.findMainKt()
|
||||
|
||||
analyseForTest(mainKt) {
|
||||
val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations()
|
||||
|
||||
val actual = resolveExtensionScope.renderSymbolsWithExtendedPsiInfo(pretty = false)
|
||||
val actualPretty = resolveExtensionScope.renderSymbolsWithExtendedPsiInfo(pretty = true)
|
||||
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actualPretty, extension = ".pretty.txt")
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtScope.renderSymbolsWithExtendedPsiInfo(pretty: Boolean) = prettyPrint {
|
||||
renderForTests(this@renderSymbolsWithExtendedPsiInfo, pretty) { symbol ->
|
||||
(symbol as? KtDeclarationSymbol)?.getPsiDeclarationInfo()
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtDeclarationSymbol.getPsiDeclarationInfo(): String = prettyPrint {
|
||||
val ktElement = psi as? KtElement
|
||||
val containingVirtualFile = ktElement?.containingFile?.virtualFile
|
||||
appendLine("PSI: ${ktElement?.getDescription()} [from ${containingVirtualFile?.name}]")
|
||||
if (ktElement == null || containingVirtualFile == null) {
|
||||
return@prettyPrint
|
||||
}
|
||||
|
||||
withIndent {
|
||||
val isResolveExtensionFile = containingVirtualFile.isResolveExtensionFile
|
||||
appendLine("From resolve extension: $isResolveExtensionFile")
|
||||
|
||||
val navTargets = ktElement.getResolveExtensionNavigationElements()
|
||||
appendLine("Resolve extension navigation targets: ${navTargets.size}")
|
||||
withIndent { navTargets.forEach { appendLine(it.toString()) } }
|
||||
}
|
||||
}.trimEnd()
|
||||
}
|
||||
+25
-8
@@ -12,13 +12,15 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension
|
||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile
|
||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionNavigationTargetsProvider
|
||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
|
||||
import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionReferencePsiTargetsProvider
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
class KtResolveExtensionProviderForTest(
|
||||
@@ -56,7 +58,7 @@ class KtResolveExtensionFileForTests(
|
||||
topLevelClassifiersNames: Set<String>,
|
||||
topLevelCallableNames: Set<String>,
|
||||
private val fileText: String,
|
||||
private val psiTargetProvider: KtResolveExtensionReferencePsiTargetsProvider? = null
|
||||
private val navigationTargetsProvider: KtResolveExtensionNavigationTargetsProvider? = null
|
||||
) : KtResolveExtensionFile() {
|
||||
|
||||
private val topLevelClassifiersNames: Set<Name> = topLevelClassifiersNames.mapTo(mutableSetOf()) { Name.identifier(it) }
|
||||
@@ -68,12 +70,27 @@ class KtResolveExtensionFileForTests(
|
||||
|
||||
override fun buildFileText(): String = fileText
|
||||
|
||||
private object EmptyReferencePsiTargetsProvider : KtResolveExtensionReferencePsiTargetsProvider() {
|
||||
override fun KtAnalysisSession.getReferenceTargetsForSymbol(symbol: KtSymbol): Collection<PsiElement> =
|
||||
emptyList()
|
||||
private object ResolveExtensionNavigationTargetProviderForTest : KtResolveExtensionNavigationTargetsProvider() {
|
||||
override fun KtAnalysisSession.getNavigationTargets(element: KtElement): Collection<PsiElement> =
|
||||
listOf(KtResolveExtensionNavigationTargetPsiElementForTest(element))
|
||||
}
|
||||
|
||||
override fun createPsiTargetsProvider(): KtResolveExtensionReferencePsiTargetsProvider =
|
||||
psiTargetProvider ?: EmptyReferencePsiTargetsProvider
|
||||
override fun createNavigationTargetsProvider(): KtResolveExtensionNavigationTargetsProvider =
|
||||
navigationTargetsProvider ?: ResolveExtensionNavigationTargetProviderForTest
|
||||
}
|
||||
|
||||
fun KtElement.getDescription(): String = buildString {
|
||||
val declaration = when (this@getDescription) {
|
||||
is KtDeclaration -> this@getDescription
|
||||
else -> {
|
||||
append("${this@getDescription.javaClass.simpleName} in ")
|
||||
getStrictParentOfType<KtDeclaration>() ?: containingKtFile
|
||||
}
|
||||
}
|
||||
append("${declaration.javaClass.simpleName} ${declaration.name}")
|
||||
}
|
||||
|
||||
class KtResolveExtensionNavigationTargetPsiElementForTest(val originalElement: KtElement) : PsiElement by originalElement {
|
||||
override fun toString() = "[Resolve extension navigation target for test for ${originalElement.getDescription()}]"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user