[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:
+1
@@ -80,6 +80,7 @@ class KtFe10AnalysisSession(
|
|||||||
override val substitutorProviderImpl: KtSubstitutorProvider
|
override val substitutorProviderImpl: KtSubstitutorProvider
|
||||||
get() = throw NotSupportedForK1Exception()
|
get() = throw NotSupportedForK1Exception()
|
||||||
|
|
||||||
|
@Suppress("OVERRIDE_DEPRECATION")
|
||||||
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession =
|
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession =
|
||||||
KtFe10AnalysisSession(originalKtFile.project, elementToReanalyze, token)
|
KtFe10AnalysisSession(originalKtFile.project, elementToReanalyze, token)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -135,7 +135,7 @@ private constructor(
|
|||||||
|
|
||||||
override val substitutorProviderImpl: KtSubstitutorProvider = KtFirSubstitutorProvider(this)
|
override val substitutorProviderImpl: KtSubstitutorProvider = KtFirSubstitutorProvider(this)
|
||||||
|
|
||||||
@Suppress("AnalysisApiMissingLifetimeCheck")
|
@Suppress("AnalysisApiMissingLifetimeCheck", "OVERRIDE_DEPRECATION")
|
||||||
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession {
|
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession {
|
||||||
check(mode == AnalysisSessionMode.REGULAR) {
|
check(mode == AnalysisSessionMode.REGULAR) {
|
||||||
"Cannot create context-dependent copy of KtAnalysis session from a context dependent one"
|
"Cannot create context-dependent copy of KtAnalysis session from a context dependent one"
|
||||||
|
|||||||
+200
@@ -69,4 +69,204 @@ public class FirIdeDependentAnalysisSourceModuleDanglingFileReferenceResolveTest
|
|||||||
public void testFunctionSameFile() throws Exception {
|
public void testFunctionSameFile() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class IgnoreSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInIgnoreSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class PreferSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInPreferSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+200
@@ -69,4 +69,204 @@ public class FirIdeNormalAnalysisLibrarySourceModuleDanglingFileReferenceResolve
|
|||||||
public void testFunctionSameFile() throws Exception {
|
public void testFunctionSameFile() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class IgnoreSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInIgnoreSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class PreferSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInPreferSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+200
@@ -69,4 +69,204 @@ public class FirIdeNormalAnalysisSourceModuleDanglingFileReferenceResolveTestGen
|
|||||||
public void testFunctionSameFile() throws Exception {
|
public void testFunctionSameFile() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class IgnoreSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInIgnoreSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class PreferSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInPreferSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+48
@@ -6,15 +6,44 @@
|
|||||||
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
|
package org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
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.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.project.structure.ktModuleProvider
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
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.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
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.TestModuleStructure
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
|
||||||
abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResolveTest() {
|
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? {
|
override fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? {
|
||||||
val containingFile = symbol.psi?.containingFile ?: return null
|
val containingFile = symbol.psi?.containingFile ?: return null
|
||||||
return containingFile.name
|
return containingFile.name
|
||||||
@@ -29,6 +58,25 @@ abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResol
|
|||||||
val ktPsiFactory = KtPsiFactory.contextual(mainKtFile, markGenerated = true, eventSystemEnabled = true)
|
val ktPsiFactory = KtPsiFactory.contextual(mainKtFile, markGenerated = true, eventSystemEnabled = true)
|
||||||
val fakeKtFile = ktPsiFactory.createFile("fake.kt", mainKtFile.text)
|
val fakeKtFile = ktPsiFactory.createFile("fake.kt", mainKtFile.text)
|
||||||
|
|
||||||
|
if (mainModule.directives.contains(COPY_RESOLUTION_MODE)) {
|
||||||
|
fakeKtFile.originalFile = mainKtFile
|
||||||
|
}
|
||||||
|
|
||||||
doTestByFileStructure(fakeKtFile, caretPosition, mainModule, testServices)
|
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.services.expressionMarkerProvider
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
|
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
|
||||||
import org.jetbrains.kotlin.idea.references.KtReference
|
import org.jetbrains.kotlin.idea.references.KtReference
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||||
@@ -74,12 +75,11 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
|||||||
testServices.assertions.fail { "No references at caret found" }
|
testServices.assertions.fail { "No references at caret found" }
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedTo =
|
val resolvedTo = analyzeReferenceElement(ktReferences.first().element, mainModule) {
|
||||||
analyseForTest(ktReferences.first().element) {
|
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
||||||
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
||||||
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
||||||
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (Directives.UNRESOLVED_REFERENCE in mainModule.directives) {
|
if (Directives.UNRESOLVED_REFERENCE in mainModule.directives) {
|
||||||
return
|
return
|
||||||
@@ -89,6 +89,10 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
|||||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
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
|
open fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? = null
|
||||||
|
|
||||||
private fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
|
private fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
|
||||||
|
|||||||
+200
@@ -69,4 +69,204 @@ public class FirStandaloneNormalAnalysisSourceModuleDanglingFileReferenceResolve
|
|||||||
public void testFunctionSameFile() throws Exception {
|
public void testFunctionSameFile() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/functionSameFile.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class IgnoreSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInIgnoreSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class PreferSelf {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInPreferSelf() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("classTypeParameter.kt")
|
||||||
|
public void testClassTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/classTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("companionObject.kt")
|
||||||
|
public void testCompanionObject() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/companionObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionTypeParameter.kt")
|
||||||
|
public void testFunctionTypeParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/functionTypeParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localClass.kt")
|
||||||
|
public void testLocalClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("localVariable.kt")
|
||||||
|
public void testLocalVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/localVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClassProperty.kt")
|
||||||
|
public void testOuterClassProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/outerClassProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("primaryConstructorParameter.kt")
|
||||||
|
public void testPrimaryConstructorParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/primaryConstructorParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateClass.kt")
|
||||||
|
public void testPrivateClass() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateFunction.kt")
|
||||||
|
public void testPrivateFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("privateProperty.kt")
|
||||||
|
public void testPrivateProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/privateProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicFunction.kt")
|
||||||
|
public void testPublicFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("publicProperty.kt")
|
||||||
|
public void testPublicProperty() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/publicProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticFieldVariable.kt")
|
||||||
|
public void testSyntheticFieldVariable() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/syntheticFieldVariable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("topLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/topLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("valueParameter.kt")
|
||||||
|
public void testValueParameter() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/valueParameter.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke
|
|||||||
*
|
*
|
||||||
* @see analyzeInDependedAnalysisSession
|
* @see analyzeInDependedAnalysisSession
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("On-air analysis is obsolete. Use 'analyzeCopy()' instead")
|
||||||
public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession
|
public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession
|
||||||
|
|
||||||
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
|
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
|
||||||
|
|||||||
@@ -7,9 +7,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api
|
package org.jetbrains.kotlin.analysis.api
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
import org.jetbrains.kotlin.analysis.api.session.KtAnalysisSessionProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.withDanglingFileResolutionMode
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
@@ -51,10 +54,41 @@ public inline fun <R> analyze(
|
|||||||
*
|
*
|
||||||
* @see KtAnalysisSession.createContextDependentCopy
|
* @see KtAnalysisSession.createContextDependentCopy
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(
|
||||||
|
"On-air analysis is obsolete. Use 'analyzeCopy()' instead",
|
||||||
|
ReplaceWith(
|
||||||
|
"analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE.SELF)",
|
||||||
|
imports = [
|
||||||
|
"org.jetbrains.kotlin.analysis.api.analyzeCopy",
|
||||||
|
"org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
public inline fun <R> analyzeInDependedAnalysisSession(
|
public inline fun <R> analyzeInDependedAnalysisSession(
|
||||||
originalFile: KtFile,
|
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||||
elementToReanalyze: KtElement,
|
elementToReanalyze: KtElement,
|
||||||
action: KtAnalysisSession.() -> R
|
crossinline action: KtAnalysisSession.() -> R
|
||||||
): R =
|
): R {
|
||||||
KtAnalysisSessionProvider.getInstance(originalFile.project)
|
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action)
|
||||||
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, action)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the given [action] in a [KtAnalysisSession] context.
|
||||||
|
* Depending on the passed [resolutionMode], declarations inside a file copy will be treated in a specific way.
|
||||||
|
*
|
||||||
|
* Note that the [useSiteKtElement] must be inside a dangling file copy.
|
||||||
|
* Specifically, [PsiFile.getOriginalFile] must point to the copy source.
|
||||||
|
*
|
||||||
|
* The project will be analyzed from the perspective of [useSiteKtElement]'s module, also called the use-site module.
|
||||||
|
*/
|
||||||
|
@OptIn(KtModuleStructureInternals::class)
|
||||||
|
public inline fun <R> analyzeCopy(
|
||||||
|
useSiteKtElement: KtElement,
|
||||||
|
resolutionMode: DanglingFileResolutionMode,
|
||||||
|
crossinline action: KtAnalysisSession.() -> R,
|
||||||
|
): R {
|
||||||
|
val containingFile = useSiteKtElement.containingKtFile
|
||||||
|
return withDanglingFileResolutionMode(containingFile, resolutionMode) {
|
||||||
|
analyze(containingFile, action)
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
-8
@@ -10,9 +10,11 @@ import com.intellij.openapi.project.Project
|
|||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||||
|
import org.jetbrains.kotlin.analysis.api.analyzeCopy
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.impl.NoWriteActionInAnalyseCallChecker
|
import org.jetbrains.kotlin.analysis.api.lifetime.impl.NoWriteActionInAnalyseCallChecker
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
|
||||||
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenFactory
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -20,8 +22,8 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
/**
|
/**
|
||||||
* Provides [KtAnalysisSession]s by use-site [KtElement]s or [KtModule]s.
|
* Provides [KtAnalysisSession]s by use-site [KtElement]s or [KtModule]s.
|
||||||
*
|
*
|
||||||
* This provider should not be used directly. Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or
|
* This provider should not be used directly.
|
||||||
* [analyzeInDependedAnalysisSession][org.jetbrains.kotlin.analysis.api.analyzeInDependedAnalysisSession] instead.
|
* Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or [analyzeCopy][org.jetbrains.kotlin.analysis.api.analyzeCopy] instead.
|
||||||
*/
|
*/
|
||||||
@OptIn(KtAnalysisApiInternals::class)
|
@OptIn(KtAnalysisApiInternals::class)
|
||||||
public abstract class KtAnalysisSessionProvider(public val project: Project) : Disposable {
|
public abstract class KtAnalysisSessionProvider(public val project: Project) : Disposable {
|
||||||
@@ -37,15 +39,22 @@ public abstract class KtAnalysisSessionProvider(public val project: Project) : D
|
|||||||
|
|
||||||
public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule): KtAnalysisSession
|
public abstract fun getAnalysisSessionByUseSiteKtModule(useSiteKtModule: KtModule): KtAnalysisSession
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"On-air analysis is obsolete. Use 'analyzeCopy()' instead",
|
||||||
|
replaceWith = ReplaceWith(
|
||||||
|
"analyzeCopy(elementToReanalyze, DanglingFileAnalysisMode.IGNORE_SELF, action)",
|
||||||
|
imports = [
|
||||||
|
"org.jetbrains.kotlin.analysis.api.analyzeCopy",
|
||||||
|
"org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
public inline fun <R> analyseInDependedAnalysisSession(
|
public inline fun <R> analyseInDependedAnalysisSession(
|
||||||
originalFile: KtFile,
|
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||||
elementToReanalyze: KtElement,
|
elementToReanalyze: KtElement,
|
||||||
action: KtAnalysisSession.() -> R,
|
crossinline action: KtAnalysisSession.() -> R,
|
||||||
): R {
|
): R {
|
||||||
val originalAnalysisSession = getAnalysisSession(originalFile)
|
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action)
|
||||||
val dependedAnalysisSession = originalAnalysisSession
|
|
||||||
.createContextDependentCopy(originalFile, elementToReanalyze)
|
|
||||||
return analyse(dependedAnalysisSession, action)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <R> analyse(
|
public inline fun <R> analyse(
|
||||||
|
|||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo<Value> {
|
||||||
|
fun foo() {
|
||||||
|
call<V<caret>alue>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> call(): T? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: Value [classTypeParameter.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
consume(F<caret>oo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun consume(obj: Any) {}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) companion object [companionObject.kt]
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun <Value> foo() {
|
||||||
|
call<V<caret>alue>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> call(): T? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: Value [fake.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
private fun foo() {
|
||||||
|
class Local {
|
||||||
|
fun call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lo<caret>cal().call()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: Foo.foo.Local) constructor() [fake.kt]
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
class Foo {
|
||||||
|
private fun foo() {
|
||||||
|
val name = "Foo"
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: Foo.foo) val name: kotlin.String [fake.kt]
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Outer {
|
||||||
|
val foo: String = "foo"
|
||||||
|
|
||||||
|
inner class Inner {
|
||||||
|
fun test() {
|
||||||
|
f<caret>oo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Outer) val foo: kotlin.String [outerClassProperty.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo(name: String) {
|
||||||
|
private val userName: String
|
||||||
|
|
||||||
|
init {
|
||||||
|
userName = n<caret>ame
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: name: kotlin.String [primaryConstructorParameter.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
private class Bar {
|
||||||
|
fun call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
B<caret>ar().call()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo.Bar) constructor() [privateClass.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo() {
|
||||||
|
private fun call() {}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) private fun call() [privateFunction.kt]
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class Foo(private val name: String) {
|
||||||
|
private fun foo() {
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) private val name: kotlin.String [privateProperty.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo() {
|
||||||
|
fun call() {}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) fun call() [publicFunction.kt]
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class Foo(val name: String) {
|
||||||
|
private fun foo() {
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) val name: kotlin.String [publicProperty.kt]
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
var x: Int = 0
|
||||||
|
get() = f<caret>ield + 1
|
||||||
|
set(value) { field = value - 1 }
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: x) field
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call() {}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in ROOT) fun call() [topLevelFunction.kt]
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo(abc: Int) {
|
||||||
|
a<caret>bc
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: abc: kotlin.Int [fake.kt]
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo<Value> {
|
||||||
|
fun foo() {
|
||||||
|
call<V<caret>alue>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> call(): T? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: Value [fake.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
consume(F<caret>oo)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun consume(obj: Any) {}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) companion object [fake.kt]
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun <Value> foo() {
|
||||||
|
call<V<caret>alue>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> call(): T? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: Value [fake.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
private fun foo() {
|
||||||
|
class Local {
|
||||||
|
fun call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lo<caret>cal().call()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: Foo.foo.Local) constructor() [fake.kt]
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
class Foo {
|
||||||
|
private fun foo() {
|
||||||
|
val name = "Foo"
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: Foo.foo) val name: kotlin.String [fake.kt]
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Outer {
|
||||||
|
val foo: String = "foo"
|
||||||
|
|
||||||
|
inner class Inner {
|
||||||
|
fun test() {
|
||||||
|
f<caret>oo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Outer) val foo: kotlin.String [fake.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo(name: String) {
|
||||||
|
private val userName: String
|
||||||
|
|
||||||
|
init {
|
||||||
|
userName = n<caret>ame
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: name: kotlin.String [fake.kt]
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo {
|
||||||
|
private class Bar {
|
||||||
|
fun call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
B<caret>ar().call()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo.Bar) constructor() [fake.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo() {
|
||||||
|
private fun call() {}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) private fun call() [fake.kt]
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class Foo(private val name: String) {
|
||||||
|
private fun foo() {
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) private val name: kotlin.String [fake.kt]
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class Foo() {
|
||||||
|
fun call() {}
|
||||||
|
|
||||||
|
private fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) fun call() [fake.kt]
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class Foo(val name: String) {
|
||||||
|
private fun foo() {
|
||||||
|
nam<caret>e.length
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in Foo) val name: kotlin.String [fake.kt]
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
var x: Int = 0
|
||||||
|
get() = f<caret>ield + 1
|
||||||
|
set(value) { field = value - 1 }
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in <local>: x) field
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo() {
|
||||||
|
c<caret>all()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call() {}
|
||||||
Vendored
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: (in ROOT) fun call() [fake.kt]
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo(abc: Int) {
|
||||||
|
a<caret>bc
|
||||||
|
}
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
Resolved to:
|
||||||
|
0: abc: kotlin.Int [fake.kt]
|
||||||
+6
-7
@@ -11,7 +11,8 @@ import com.intellij.testFramework.TestDataFile
|
|||||||
import junit.framework.ComparisonFailure
|
import junit.framework.ComparisonFailure
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.analyze
|
import org.jetbrains.kotlin.analysis.api.analyze
|
||||||
import org.jetbrains.kotlin.analysis.api.analyzeInDependedAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.analyzeCopy
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives
|
import org.jetbrains.kotlin.analysis.test.framework.AnalysisApiTestDirectives
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.TestWithDisposable
|
import org.jetbrains.kotlin.analysis.test.framework.TestWithDisposable
|
||||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||||
@@ -205,12 +206,10 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
|||||||
return if (configurator.analyseInDependentSession) {
|
return if (configurator.analyseInDependentSession) {
|
||||||
val originalContainingFile = contextElement.containingKtFile
|
val originalContainingFile = contextElement.containingKtFile
|
||||||
val fileCopy = originalContainingFile.copy() as KtFile
|
val fileCopy = originalContainingFile.copy() as KtFile
|
||||||
val sameElementInCopy = PsiTreeUtil.findSameElementInCopy(contextElement, fileCopy)
|
|
||||||
analyzeInDependedAnalysisSession(
|
analyzeCopy(fileCopy, DanglingFileResolutionMode.IGNORE_SELF) {
|
||||||
originalContainingFile,
|
action(PsiTreeUtil.findSameElementInCopy<KtElement>(contextElement, fileCopy))
|
||||||
sameElementInCopy,
|
}
|
||||||
action = { action(sameElementInCopy) }
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
analyze(contextElement, action = { action(contextElement) })
|
analyze(contextElement, action = { action(contextElement) })
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtMod
|
|||||||
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticProjectStructureProvider
|
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtStaticProjectStructureProvider
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||||
@@ -29,9 +28,7 @@ class KtTestProjectStructureProvider(
|
|||||||
|
|
||||||
@OptIn(KtModuleStructureInternals::class)
|
@OptIn(KtModuleStructureInternals::class)
|
||||||
override fun getModule(element: PsiElement, contextualModule: KtModule?): KtModule {
|
override fun getModule(element: PsiElement, contextualModule: KtModule?): KtModule {
|
||||||
// Unwrap context-dependent file copies coming from dependent sessions
|
val containingFile = element.containingFile
|
||||||
val containingFile = element.containingFile.originalFile
|
|
||||||
|
|
||||||
val virtualFile = containingFile.virtualFile
|
val virtualFile = containingFile.virtualFile
|
||||||
|
|
||||||
if (virtualFile != null) {
|
if (virtualFile != null) {
|
||||||
|
|||||||
+35
-2
@@ -5,11 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.nullableJavaSymbolProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.nullableJavaSymbolProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.getContainingFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isScriptDependentDeclaration
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.unwrapCopy
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
@@ -28,6 +32,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirScriptSymbol
|
|||||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.checkWithAttachment
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
|
|
||||||
@@ -173,14 +178,16 @@ private fun collectDesignationPathWithContainingClass(target: FirDeclaration, co
|
|||||||
if (chunks.any { it.shortClassName.isSpecial }) {
|
if (chunks.any { it.shortClassName.isSpecial }) {
|
||||||
val fallbackResult = collectDesignationPathWithTreeTraversal(target)
|
val fallbackResult = collectDesignationPathWithTreeTraversal(target)
|
||||||
if (fallbackResult != null) {
|
if (fallbackResult != null) {
|
||||||
return fallbackResult
|
return patchDesignationPathIfNeeded(target, fallbackResult)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chunks
|
val result = chunks
|
||||||
.dropWhile { it.shortClassName.isSpecial }
|
.dropWhile { it.shortClassName.isSpecial }
|
||||||
.map { resolveChunk(it) }
|
.map { resolveChunk(it) }
|
||||||
.asReversed()
|
.asReversed()
|
||||||
|
|
||||||
|
return patchDesignationPathIfNeeded(target, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -300,3 +307,29 @@ private fun FirDeclaration.scriptDesignation(): FirDesignationWithFile? {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun patchDesignationPathIfNeeded(target: FirElementWithResolveState, targetPath: List<FirRegularClass>): List<FirRegularClass> {
|
||||||
|
return patchDesignationPathForCopy(target, targetPath) ?: targetPath
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun patchDesignationPathForCopy(target: FirElementWithResolveState, targetPath: List<FirRegularClass>): List<FirRegularClass>? {
|
||||||
|
val targetModule = target.llFirModuleData.ktModule
|
||||||
|
|
||||||
|
if (targetModule is KtDanglingFileModule && targetModule.resolutionMode == DanglingFileResolutionMode.IGNORE_SELF) {
|
||||||
|
val targetPsiFile = targetModule.file
|
||||||
|
|
||||||
|
val contextModule = targetModule.contextModule
|
||||||
|
val contextResolveSession = contextModule.getFirResolveSession(contextModule.project)
|
||||||
|
|
||||||
|
return buildList {
|
||||||
|
for (targetPathClass in targetPath) {
|
||||||
|
val targetPathPsi = targetPathClass.psi as? KtDeclaration ?: return null
|
||||||
|
val originalPathPsi = targetPathPsi.unwrapCopy(targetPsiFile) ?: return null
|
||||||
|
val originalPathClass = originalPathPsi.getOrBuildFirSafe<FirRegularClass>(contextResolveSession) ?: return null
|
||||||
|
add(originalPathClass)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetPath
|
||||||
|
}
|
||||||
+5
-1
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.fir.utils.exceptions.withFirSymbolEntry
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||||
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
||||||
@@ -584,7 +585,10 @@ private fun calculateLazyBodiesForField(designation: FirDesignation) {
|
|||||||
val field = designation.target as FirField
|
val field = designation.target as FirField
|
||||||
require(field.initializer is FirLazyExpression)
|
require(field.initializer is FirLazyExpression)
|
||||||
|
|
||||||
val newField = revive<FirField>(designation, designation.path.last().psi)
|
// 'designation.path.last()' cannot be used here, as for dangling files designation target may be in a different file
|
||||||
|
val psi = field.psi?.getStrictParentOfType<KtClassOrObject>()
|
||||||
|
|
||||||
|
val newField = revive<FirField>(designation, psi)
|
||||||
field.replaceInitializer(newField.initializer)
|
field.replaceInitializer(newField.initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.low.level.api.fir.providers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirEmptySymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolNamesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
internal class LLEmptySymbolProvider(session: FirSession) : FirSymbolProvider(session) {
|
||||||
|
override val symbolNamesProvider: FirSymbolNamesProvider
|
||||||
|
get() = FirEmptySymbolNamesProvider
|
||||||
|
|
||||||
|
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@FirSymbolProviderInternals
|
||||||
|
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPackage(fqName: FqName): FqName? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -33,9 +33,11 @@ internal class LLFirProvider(
|
|||||||
val session: LLFirSession,
|
val session: LLFirSession,
|
||||||
private val moduleComponents: LLFirModuleResolveComponents,
|
private val moduleComponents: LLFirModuleResolveComponents,
|
||||||
canContainKotlinPackage: Boolean,
|
canContainKotlinPackage: Boolean,
|
||||||
|
disregardSelfDeclarations: Boolean = false,
|
||||||
declarationProviderFactory: (GlobalSearchScope) -> KotlinDeclarationProvider?,
|
declarationProviderFactory: (GlobalSearchScope) -> KotlinDeclarationProvider?,
|
||||||
) : FirProvider() {
|
) : FirProvider() {
|
||||||
override val symbolProvider: FirSymbolProvider = SymbolProvider()
|
override val symbolProvider: FirSymbolProvider =
|
||||||
|
if (disregardSelfDeclarations) LLEmptySymbolProvider(session) else SymbolProvider()
|
||||||
|
|
||||||
private val providerHelper = LLFirProviderHelper(
|
private val providerHelper = LLFirProviderHelper(
|
||||||
session,
|
session,
|
||||||
|
|||||||
+1
@@ -494,6 +494,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
|||||||
this,
|
this,
|
||||||
components,
|
components,
|
||||||
canContainKotlinPackage = true,
|
canContainKotlinPackage = true,
|
||||||
|
disregardSelfDeclarations = module.resolutionMode == DanglingFileResolutionMode.IGNORE_SELF,
|
||||||
declarationProviderFactory = { scope -> scope.createScopedDeclarationProviderForFile(danglingFile) }
|
declarationProviderFactory = { scope -> scope.createScopedDeclarationProviderForFile(danglingFile) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.patchDesignationPathIfNeeded
|
||||||
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
|
|
||||||
internal object FirElementFinder {
|
internal object FirElementFinder {
|
||||||
fun findClassifierWithClassId(
|
fun findClassifierWithClassId(
|
||||||
@@ -129,12 +131,17 @@ internal object FirElementFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
find(firFile.declarations, classIdPathIndex = 0)
|
find(firFile.declarations, classIdPathIndex = 0)
|
||||||
return result?.let {
|
|
||||||
FirDeclarationDesignation(
|
if (result == null) {
|
||||||
path = if (path.isEmpty()) emptyList() else path,
|
return null
|
||||||
target = it,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// K1 doesn't perform smart-casts on 'result'
|
||||||
|
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
|
||||||
|
return FirDeclarationDesignation(
|
||||||
|
path = patchDesignationPathIfNeeded(result!!, path).ifEmpty { emptyList() },
|
||||||
|
target = result!!,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified E : FirElement> findElementIn(
|
inline fun <reified E : FirElement> findElementIn(
|
||||||
|
|||||||
+15
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||||
@@ -249,4 +250,17 @@ val PsiElement.parentsWithSelfCodeFragmentAware: Sequence<PsiElement>
|
|||||||
}
|
}
|
||||||
|
|
||||||
val PsiElement.parentsCodeFragmentAware: Sequence<PsiElement>
|
val PsiElement.parentsCodeFragmentAware: Sequence<PsiElement>
|
||||||
get() = parentsWithSelfCodeFragmentAware.drop(1)
|
get() = parentsWithSelfCodeFragmentAware.drop(1)
|
||||||
|
|
||||||
|
internal fun <T : PsiElement> T.unwrapCopy(containingFile: PsiFile = this.containingFile): T? {
|
||||||
|
val originalFile = containingFile.originalFile.takeIf { it !== containingFile }
|
||||||
|
?: (containingFile as? KtFile)?.analysisContext?.containingFile
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
return try {
|
||||||
|
PsiTreeUtil.findSameElementInCopy(this, originalFile)
|
||||||
|
} catch (_: IllegalStateException) {
|
||||||
|
// File copy has a different file structure
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -230,6 +230,11 @@ public interface KtDanglingFileModule : KtModule {
|
|||||||
*/
|
*/
|
||||||
public val contextModule: KtModule
|
public val contextModule: KtModule
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A way of resolving references to non-local declarations in the dangling file.
|
||||||
|
*/
|
||||||
|
public val resolutionMode: DanglingFileResolutionMode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the [file] is a code fragment.
|
* True if the [file] is a code fragment.
|
||||||
* Useful to recognize code fragments when their PSI was collected.
|
* Useful to recognize code fragments when their PSI was collected.
|
||||||
|
|||||||
+72
-6
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.analysis.project.structure
|
package org.jetbrains.kotlin.analysis.project.structure
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.impl.KtDanglingFileModuleImpl
|
import org.jetbrains.kotlin.analysis.project.structure.impl.KtDanglingFileModuleImpl
|
||||||
@@ -13,6 +14,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||||
import org.jetbrains.kotlin.psi.analysisContext
|
import org.jetbrains.kotlin.psi.analysisContext
|
||||||
import org.jetbrains.kotlin.psi.doNotAnalyze
|
import org.jetbrains.kotlin.psi.doNotAnalyze
|
||||||
|
|
||||||
@@ -54,12 +56,21 @@ public abstract class ProjectStructureProvider {
|
|||||||
|
|
||||||
if (file is KtFile && file.isDangling) {
|
if (file is KtFile && file.isDangling) {
|
||||||
val contextModule = computeContextModule(file)
|
val contextModule = computeContextModule(file)
|
||||||
return KtDanglingFileModuleImpl(file, contextModule)
|
val resolutionMode = file.danglingFileResolutionMode ?: computeDefaultDanglingFileResolutionMode(file)
|
||||||
|
return KtDanglingFileModuleImpl(file, contextModule, resolutionMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun computeDefaultDanglingFileResolutionMode(file: KtFile): DanglingFileResolutionMode {
|
||||||
|
if (!file.isPhysical && !file.viewProvider.isEventSystemEnabled && file.originalFile != file) {
|
||||||
|
return DanglingFileResolutionMode.IGNORE_SELF
|
||||||
|
}
|
||||||
|
|
||||||
|
return DanglingFileResolutionMode.PREFER_SELF
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(KtModuleStructureInternals::class)
|
@OptIn(KtModuleStructureInternals::class)
|
||||||
private fun computeContextModule(file: KtFile): KtModule {
|
private fun computeContextModule(file: KtFile): KtModule {
|
||||||
val contextElement = file.context
|
val contextElement = file.context
|
||||||
@@ -97,8 +108,63 @@ public abstract class ProjectStructureProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(KtModuleStructureInternals::class)
|
@OptIn(KtModuleStructureInternals::class)
|
||||||
private val KtFile.isDangling: Boolean
|
public val KtFile.isDangling: Boolean
|
||||||
get() = this is KtCodeFragment
|
get() = when {
|
||||||
|| !isPhysical
|
this is KtCodeFragment -> true
|
||||||
|| analysisContext != null
|
virtualFile?.analysisExtensionFileContextModule != null -> false
|
||||||
|| doNotAnalyze != null
|
!isPhysical -> true
|
||||||
|
analysisContext != null -> true
|
||||||
|
doNotAnalyze != null -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the resolution mode that is explicitly set for this dangling file.
|
||||||
|
* Returns `null` for files that are not dangling, or if the mode was not set.
|
||||||
|
*
|
||||||
|
* Use the `analyzeCopy {}` method for specifying the analysis mode. Note that the effect is thread-local; this is made on purpose, as
|
||||||
|
* the file might potentially be resolved in parallel in different threads.
|
||||||
|
*
|
||||||
|
* Note that the resolution mode affects equality of [KtDanglingFileModule]. It means that for each resolution mode, a separate
|
||||||
|
* resolution session will be created.
|
||||||
|
*/
|
||||||
|
@OptIn(KtModuleStructureInternals::class)
|
||||||
|
public val KtFile.danglingFileResolutionMode: DanglingFileResolutionMode?
|
||||||
|
get() = danglingFileResolutionModeState?.get()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the [action] with a resolution mode being explicitly set for the dangling [file].
|
||||||
|
*
|
||||||
|
* Avoid using this function in client-side code. Use `analyzeCopy {}` from Analysis API instead.
|
||||||
|
*/
|
||||||
|
@KtModuleStructureInternals
|
||||||
|
public fun <R> withDanglingFileResolutionMode(file: KtFile, mode: DanglingFileResolutionMode, action: () -> R): R {
|
||||||
|
require(file.isDangling) { "'withDanglingFileResolutionMode()' is only available to dangling files" }
|
||||||
|
require(file.originalFile != file) { "'withDanglingFileResolutionMode()' is only available to file copies" }
|
||||||
|
|
||||||
|
val modeState = getOrCreateDanglingFileResolutionModeState(file)
|
||||||
|
|
||||||
|
val oldValue = modeState.get()
|
||||||
|
try {
|
||||||
|
modeState.set(mode)
|
||||||
|
return action()
|
||||||
|
} finally {
|
||||||
|
modeState.set(oldValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getOrCreateDanglingFileResolutionModeState(file: KtFile): ThreadLocal<DanglingFileResolutionMode?> {
|
||||||
|
synchronized(file) {
|
||||||
|
val existingState = file.danglingFileResolutionModeState
|
||||||
|
if (existingState != null) {
|
||||||
|
return existingState
|
||||||
|
}
|
||||||
|
|
||||||
|
val newState = ThreadLocal<DanglingFileResolutionMode?>()
|
||||||
|
file.danglingFileResolutionModeState = newState
|
||||||
|
return newState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var KtFile.danglingFileResolutionModeState: ThreadLocal<DanglingFileResolutionMode?>?
|
||||||
|
by UserDataProperty(Key.create("DANGLING_FILE_RESOLUTION_MODE"))
|
||||||
+6
-2
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.project.structure.impl
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
@@ -18,7 +19,8 @@ import java.util.Objects
|
|||||||
|
|
||||||
public class KtDanglingFileModuleImpl(
|
public class KtDanglingFileModuleImpl(
|
||||||
file: KtFile,
|
file: KtFile,
|
||||||
override val contextModule: KtModule
|
override val contextModule: KtModule,
|
||||||
|
override val resolutionMode: DanglingFileResolutionMode
|
||||||
) : KtDanglingFileModule {
|
) : KtDanglingFileModule {
|
||||||
override val isCodeFragment: Boolean = file is KtCodeFragment
|
override val isCodeFragment: Boolean = file is KtCodeFragment
|
||||||
|
|
||||||
@@ -67,7 +69,9 @@ public class KtDanglingFileModuleImpl(
|
|||||||
if (other is KtDanglingFileModuleImpl) {
|
if (other is KtDanglingFileModuleImpl) {
|
||||||
val selfFile = this.fileRef.element
|
val selfFile = this.fileRef.element
|
||||||
val otherFile = other.fileRef.element
|
val otherFile = other.fileRef.element
|
||||||
return selfFile != null && selfFile == otherFile && contextModule == other.contextModule
|
return selfFile != null && selfFile == otherFile
|
||||||
|
&& contextModule == other.contextModule
|
||||||
|
&& resolutionMode == other.resolutionMode
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
+11
@@ -64,3 +64,14 @@ public inline fun <reified M : KtModule> KtModule.allDirectDependenciesOfType():
|
|||||||
*/
|
*/
|
||||||
public fun computeTransitiveDependsOnDependencies(directDependsOnDependencies: List<KtModule>): List<KtModule> =
|
public fun computeTransitiveDependsOnDependencies(directDependsOnDependencies: List<KtModule>): List<KtModule> =
|
||||||
topologicalSort(directDependsOnDependencies) { this.directDependsOnDependencies }
|
topologicalSort(directDependsOnDependencies) { this.directDependsOnDependencies }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies how references to non-local declarations in the dangling files should be resolved.
|
||||||
|
*/
|
||||||
|
public enum class DanglingFileResolutionMode {
|
||||||
|
/** Resolve first to declarations in the dangling file, and delegate to the original file or module only when needed. */
|
||||||
|
PREFER_SELF,
|
||||||
|
|
||||||
|
/** * Resolve only to declarations in the original file or module. Ignore all non-local declarations in the dangling file copy. */
|
||||||
|
IGNORE_SELF
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user