[Analysis API] Add IGNORE_SELF dangling file resolution mode
In the 'IGNORE_SELF' mode, dangling files don't have their own declarations in providers. As a result, all references there resolve to declarations of the original file. It is conceptually similar to that we had in on-air resolve, however, now it's possible to work with the whole content of the in-memory 'FirFile'. As it can be seen in 'ProjectStructureProvider.kt' (KtFile.danglingFileResolutionMode), the 'IGNORE_SELF' mode is automatically applied for non-physical files with an original file being set. For other scenarios, now there is a new 'analyzeCopy()' function that allows to pass the analysis mode explicitly.
This commit is contained in:
+48
@@ -6,15 +6,44 @@
|
||||
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.analyzeCopy
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractDanglingFileReferenceResolveTest.Directives.COPY_RESOLUTION_MODE
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResolveTest() {
|
||||
override fun configureTest(builder: TestConfigurationBuilder) {
|
||||
super.configureTest(builder)
|
||||
|
||||
builder.apply {
|
||||
useDirectives(Directives)
|
||||
forTestsMatching("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/*") {
|
||||
defaultDirectives {
|
||||
COPY_RESOLUTION_MODE.with(DanglingFileResolutionMode.IGNORE_SELF)
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/*") {
|
||||
defaultDirectives {
|
||||
COPY_RESOLUTION_MODE.with(DanglingFileResolutionMode.PREFER_SELF)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? {
|
||||
val containingFile = symbol.psi?.containingFile ?: return null
|
||||
return containingFile.name
|
||||
@@ -29,6 +58,25 @@ abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResol
|
||||
val ktPsiFactory = KtPsiFactory.contextual(mainKtFile, markGenerated = true, eventSystemEnabled = true)
|
||||
val fakeKtFile = ktPsiFactory.createFile("fake.kt", mainKtFile.text)
|
||||
|
||||
if (mainModule.directives.contains(COPY_RESOLUTION_MODE)) {
|
||||
fakeKtFile.originalFile = mainKtFile
|
||||
}
|
||||
|
||||
doTestByFileStructure(fakeKtFile, caretPosition, mainModule, testServices)
|
||||
}
|
||||
|
||||
override fun <R> analyzeReferenceElement(element: KtElement, mainModule: TestModule, action: KtAnalysisSession.() -> R): R {
|
||||
val resolutionMode = mainModule.directives.singleOrZeroValue(COPY_RESOLUTION_MODE)
|
||||
return if (resolutionMode != null) {
|
||||
analyzeCopy(element, resolutionMode) { action() }
|
||||
} else {
|
||||
analyze(element) { action() }
|
||||
}
|
||||
}
|
||||
|
||||
private object Directives : SimpleDirectivesContainer() {
|
||||
val COPY_RESOLUTION_MODE by enumDirective(description = "Dangling file resolution mode for a copy") {
|
||||
DanglingFileResolutionMode.valueOf(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModulePr
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||
@@ -74,12 +75,11 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
||||
testServices.assertions.fail { "No references at caret found" }
|
||||
}
|
||||
|
||||
val resolvedTo =
|
||||
analyseForTest(ktReferences.first().element) {
|
||||
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
||||
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
||||
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
||||
}
|
||||
val resolvedTo = analyzeReferenceElement(ktReferences.first().element, mainModule) {
|
||||
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
||||
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
||||
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
||||
}
|
||||
|
||||
if (Directives.UNRESOLVED_REFERENCE in mainModule.directives) {
|
||||
return
|
||||
@@ -89,6 +89,10 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
}
|
||||
|
||||
protected open fun <R> analyzeReferenceElement(element: KtElement, mainModule: TestModule, action: KtAnalysisSession.() -> R): R {
|
||||
return analyseForTest(element) { action() }
|
||||
}
|
||||
|
||||
open fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? = null
|
||||
|
||||
private fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
|
||||
|
||||
Reference in New Issue
Block a user