[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
|
||||
get() = throw NotSupportedForK1Exception()
|
||||
|
||||
@Suppress("OVERRIDE_DEPRECATION")
|
||||
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession =
|
||||
KtFe10AnalysisSession(originalKtFile.project, elementToReanalyze, token)
|
||||
}
|
||||
|
||||
+1
-1
@@ -135,7 +135,7 @@ private constructor(
|
||||
|
||||
override val substitutorProviderImpl: KtSubstitutorProvider = KtFirSubstitutorProvider(this)
|
||||
|
||||
@Suppress("AnalysisApiMissingLifetimeCheck")
|
||||
@Suppress("AnalysisApiMissingLifetimeCheck", "OVERRIDE_DEPRECATION")
|
||||
override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession {
|
||||
check(mode == AnalysisSessionMode.REGULAR) {
|
||||
"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 {
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.analyzeCopy
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.references.AbstractDanglingFileReferenceResolveTest.Directives.COPY_RESOLUTION_MODE
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||
import org.jetbrains.kotlin.analysis.project.structure.DanglingFileResolutionMode
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
|
||||
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
|
||||
abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResolveTest() {
|
||||
override fun configureTest(builder: TestConfigurationBuilder) {
|
||||
super.configureTest(builder)
|
||||
|
||||
builder.apply {
|
||||
useDirectives(Directives)
|
||||
forTestsMatching("analysis/analysis-api/testData/danglingFileReferenceResolve/ignoreSelf/*") {
|
||||
defaultDirectives {
|
||||
COPY_RESOLUTION_MODE.with(DanglingFileResolutionMode.IGNORE_SELF)
|
||||
}
|
||||
}
|
||||
|
||||
forTestsMatching("analysis/analysis-api/testData/danglingFileReferenceResolve/preferSelf/*") {
|
||||
defaultDirectives {
|
||||
COPY_RESOLUTION_MODE.with(DanglingFileResolutionMode.PREFER_SELF)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? {
|
||||
val containingFile = symbol.psi?.containingFile ?: return null
|
||||
return containingFile.name
|
||||
@@ -29,6 +58,25 @@ abstract class AbstractDanglingFileReferenceResolveTest : AbstractReferenceResol
|
||||
val ktPsiFactory = KtPsiFactory.contextual(mainKtFile, markGenerated = true, eventSystemEnabled = true)
|
||||
val fakeKtFile = ktPsiFactory.createFile("fake.kt", mainKtFile.text)
|
||||
|
||||
if (mainModule.directives.contains(COPY_RESOLUTION_MODE)) {
|
||||
fakeKtFile.originalFile = mainKtFile
|
||||
}
|
||||
|
||||
doTestByFileStructure(fakeKtFile, caretPosition, mainModule, testServices)
|
||||
}
|
||||
|
||||
override fun <R> analyzeReferenceElement(element: KtElement, mainModule: TestModule, action: KtAnalysisSession.() -> R): R {
|
||||
val resolutionMode = mainModule.directives.singleOrZeroValue(COPY_RESOLUTION_MODE)
|
||||
return if (resolutionMode != null) {
|
||||
analyzeCopy(element, resolutionMode) { action() }
|
||||
} else {
|
||||
analyze(element) { action() }
|
||||
}
|
||||
}
|
||||
|
||||
private object Directives : SimpleDirectivesContainer() {
|
||||
val COPY_RESOLUTION_MODE by enumDirective(description = "Dangling file resolution mode for a copy") {
|
||||
DanglingFileResolutionMode.valueOf(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModulePr
|
||||
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
|
||||
import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.directives.ConfigurationDirectives
|
||||
@@ -74,12 +75,11 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
||||
testServices.assertions.fail { "No references at caret found" }
|
||||
}
|
||||
|
||||
val resolvedTo =
|
||||
analyseForTest(ktReferences.first().element) {
|
||||
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
||||
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
||||
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
||||
}
|
||||
val resolvedTo = analyzeReferenceElement(ktReferences.first().element, mainModule) {
|
||||
val symbols = ktReferences.flatMap { it.resolveToSymbols() }
|
||||
checkReferenceResultForValidity(ktReferences, mainModule, testServices, symbols)
|
||||
renderResolvedTo(symbols, renderingOptions) { getAdditionalSymbolInfo(it) }
|
||||
}
|
||||
|
||||
if (Directives.UNRESOLVED_REFERENCE in mainModule.directives) {
|
||||
return
|
||||
@@ -89,6 +89,10 @@ abstract class AbstractReferenceResolveTest : AbstractAnalysisApiBasedTest() {
|
||||
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
|
||||
}
|
||||
|
||||
protected open fun <R> analyzeReferenceElement(element: KtElement, mainModule: TestModule, action: KtAnalysisSession.() -> R): R {
|
||||
return analyseForTest(element) { action() }
|
||||
}
|
||||
|
||||
open fun KtAnalysisSession.getAdditionalSymbolInfo(symbol: KtSymbol): String? = null
|
||||
|
||||
private fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
|
||||
|
||||
+200
@@ -69,4 +69,204 @@ public class FirStandaloneNormalAnalysisSourceModuleDanglingFileReferenceResolve
|
||||
public void testFunctionSameFile() throws Exception {
|
||||
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
|
||||
*/
|
||||
@Deprecated("On-air analysis is obsolete. Use 'analyzeCopy()' instead")
|
||||
public abstract fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession
|
||||
|
||||
internal val smartCastProvider: KtSmartCastProvider get() = smartCastProviderImpl
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
|
||||
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.project.structure.DanglingFileResolutionMode
|
||||
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.KtFile
|
||||
|
||||
@@ -51,10 +54,41 @@ public inline fun <R> analyze(
|
||||
*
|
||||
* @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(
|
||||
originalFile: KtFile,
|
||||
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
action: KtAnalysisSession.() -> R
|
||||
): R =
|
||||
KtAnalysisSessionProvider.getInstance(originalFile.project)
|
||||
.analyseInDependedAnalysisSession(originalFile, elementToReanalyze, action)
|
||||
crossinline action: KtAnalysisSession.() -> R
|
||||
): R {
|
||||
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, 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.kotlin.analysis.api.KtAnalysisSession
|
||||
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.KtLifetimeTokenProvider
|
||||
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.psi.KtElement
|
||||
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.
|
||||
*
|
||||
* This provider should not be used directly. Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or
|
||||
* [analyzeInDependedAnalysisSession][org.jetbrains.kotlin.analysis.api.analyzeInDependedAnalysisSession] instead.
|
||||
* This provider should not be used directly.
|
||||
* Please use [analyze][org.jetbrains.kotlin.analysis.api.analyze] or [analyzeCopy][org.jetbrains.kotlin.analysis.api.analyzeCopy] instead.
|
||||
*/
|
||||
@OptIn(KtAnalysisApiInternals::class)
|
||||
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
|
||||
|
||||
@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(
|
||||
originalFile: KtFile,
|
||||
@Suppress("unused", "UNUSED_PARAMETER") originalFile: KtFile,
|
||||
elementToReanalyze: KtElement,
|
||||
action: KtAnalysisSession.() -> R,
|
||||
crossinline action: KtAnalysisSession.() -> R,
|
||||
): R {
|
||||
val originalAnalysisSession = getAnalysisSession(originalFile)
|
||||
val dependedAnalysisSession = originalAnalysisSession
|
||||
.createContextDependentCopy(originalFile, elementToReanalyze)
|
||||
return analyse(dependedAnalysisSession, action)
|
||||
return analyzeCopy(elementToReanalyze, DanglingFileResolutionMode.IGNORE_SELF, action)
|
||||
}
|
||||
|
||||
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 org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
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.TestWithDisposable
|
||||
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
|
||||
@@ -205,12 +206,10 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() {
|
||||
return if (configurator.analyseInDependentSession) {
|
||||
val originalContainingFile = contextElement.containingKtFile
|
||||
val fileCopy = originalContainingFile.copy() as KtFile
|
||||
val sameElementInCopy = PsiTreeUtil.findSameElementInCopy(contextElement, fileCopy)
|
||||
analyzeInDependedAnalysisSession(
|
||||
originalContainingFile,
|
||||
sameElementInCopy,
|
||||
action = { action(sameElementInCopy) }
|
||||
)
|
||||
|
||||
analyzeCopy(fileCopy, DanglingFileResolutionMode.IGNORE_SELF) {
|
||||
action(PsiTreeUtil.findSameElementInCopy<KtElement>(contextElement, fileCopy))
|
||||
}
|
||||
} else {
|
||||
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.project.structure.*
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
@@ -29,9 +28,7 @@ class KtTestProjectStructureProvider(
|
||||
|
||||
@OptIn(KtModuleStructureInternals::class)
|
||||
override fun getModule(element: PsiElement, contextualModule: KtModule?): KtModule {
|
||||
// Unwrap context-dependent file copies coming from dependent sessions
|
||||
val containingFile = element.containingFile.originalFile
|
||||
|
||||
val containingFile = element.containingFile
|
||||
val virtualFile = containingFile.virtualFile
|
||||
|
||||
if (virtualFile != null) {
|
||||
|
||||
+35
-2
@@ -5,11 +5,15 @@
|
||||
|
||||
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.sessions.LLFirLibraryOrLibrarySourceResolvableModuleSession
|
||||
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.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.unexpectedElementError
|
||||
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.visitors.FirVisitorVoid
|
||||
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.errorWithAttachment
|
||||
|
||||
@@ -173,14 +178,16 @@ private fun collectDesignationPathWithContainingClass(target: FirDeclaration, co
|
||||
if (chunks.any { it.shortClassName.isSpecial }) {
|
||||
val fallbackResult = collectDesignationPathWithTreeTraversal(target)
|
||||
if (fallbackResult != null) {
|
||||
return fallbackResult
|
||||
return patchDesignationPathIfNeeded(target, fallbackResult)
|
||||
}
|
||||
}
|
||||
|
||||
return chunks
|
||||
val result = chunks
|
||||
.dropWhile { it.shortClassName.isSpecial }
|
||||
.map { resolveChunk(it) }
|
||||
.asReversed()
|
||||
|
||||
return patchDesignationPathIfNeeded(target, result)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -300,3 +307,29 @@ private fun FirDeclaration.scriptDesignation(): FirDesignationWithFile? {
|
||||
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.transformSingle
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
|
||||
@@ -584,7 +585,10 @@ private fun calculateLazyBodiesForField(designation: FirDesignation) {
|
||||
val field = designation.target as FirField
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+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,
|
||||
private val moduleComponents: LLFirModuleResolveComponents,
|
||||
canContainKotlinPackage: Boolean,
|
||||
disregardSelfDeclarations: Boolean = false,
|
||||
declarationProviderFactory: (GlobalSearchScope) -> KotlinDeclarationProvider?,
|
||||
) : FirProvider() {
|
||||
override val symbolProvider: FirSymbolProvider = SymbolProvider()
|
||||
override val symbolProvider: FirSymbolProvider =
|
||||
if (disregardSelfDeclarations) LLEmptySymbolProvider(session) else SymbolProvider()
|
||||
|
||||
private val providerHelper = LLFirProviderHelper(
|
||||
session,
|
||||
|
||||
+1
@@ -494,6 +494,7 @@ internal abstract class LLFirAbstractSessionFactory(protected val project: Proje
|
||||
this,
|
||||
components,
|
||||
canContainKotlinPackage = true,
|
||||
disregardSelfDeclarations = module.resolutionMode == DanglingFileResolutionMode.IGNORE_SELF,
|
||||
declarationProviderFactory = { scope -> scope.createScopedDeclarationProviderForFile(danglingFile) }
|
||||
)
|
||||
|
||||
|
||||
+12
-5
@@ -5,6 +5,7 @@
|
||||
|
||||
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.fir.FirElement
|
||||
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.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
internal object FirElementFinder {
|
||||
fun findClassifierWithClassId(
|
||||
@@ -129,12 +131,17 @@ internal object FirElementFinder {
|
||||
}
|
||||
|
||||
find(firFile.declarations, classIdPathIndex = 0)
|
||||
return result?.let {
|
||||
FirDeclarationDesignation(
|
||||
path = if (path.isEmpty()) emptyList() else path,
|
||||
target = it,
|
||||
)
|
||||
|
||||
if (result == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 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(
|
||||
|
||||
+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.PsiFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
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.api.LLFirResolveSession
|
||||
@@ -249,4 +250,17 @@ val PsiElement.parentsWithSelfCodeFragmentAware: 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
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Useful to recognize code fragments when their PSI was collected.
|
||||
|
||||
+72
-6
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.project.structure
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
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.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
import org.jetbrains.kotlin.psi.analysisContext
|
||||
import org.jetbrains.kotlin.psi.doNotAnalyze
|
||||
|
||||
@@ -54,12 +56,21 @@ public abstract class ProjectStructureProvider {
|
||||
|
||||
if (file is KtFile && file.isDangling) {
|
||||
val contextModule = computeContextModule(file)
|
||||
return KtDanglingFileModuleImpl(file, contextModule)
|
||||
val resolutionMode = file.danglingFileResolutionMode ?: computeDefaultDanglingFileResolutionMode(file)
|
||||
return KtDanglingFileModuleImpl(file, contextModule, resolutionMode)
|
||||
}
|
||||
|
||||
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)
|
||||
private fun computeContextModule(file: KtFile): KtModule {
|
||||
val contextElement = file.context
|
||||
@@ -97,8 +108,63 @@ public abstract class ProjectStructureProvider {
|
||||
}
|
||||
|
||||
@OptIn(KtModuleStructureInternals::class)
|
||||
private val KtFile.isDangling: Boolean
|
||||
get() = this is KtCodeFragment
|
||||
|| !isPhysical
|
||||
|| analysisContext != null
|
||||
|| doNotAnalyze != null
|
||||
public val KtFile.isDangling: Boolean
|
||||
get() = when {
|
||||
this is KtCodeFragment -> true
|
||||
virtualFile?.analysisExtensionFileContextModule != null -> false
|
||||
!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.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.KtDanglingFileModule
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
@@ -18,7 +19,8 @@ import java.util.Objects
|
||||
|
||||
public class KtDanglingFileModuleImpl(
|
||||
file: KtFile,
|
||||
override val contextModule: KtModule
|
||||
override val contextModule: KtModule,
|
||||
override val resolutionMode: DanglingFileResolutionMode
|
||||
) : KtDanglingFileModule {
|
||||
override val isCodeFragment: Boolean = file is KtCodeFragment
|
||||
|
||||
@@ -67,7 +69,9 @@ public class KtDanglingFileModuleImpl(
|
||||
if (other is KtDanglingFileModuleImpl) {
|
||||
val selfFile = this.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
|
||||
|
||||
+11
@@ -64,3 +64,14 @@ public inline fun <reified M : KtModule> KtModule.allDirectDependenciesOfType():
|
||||
*/
|
||||
public fun computeTransitiveDependsOnDependencies(directDependsOnDependencies: List<KtModule>): List<KtModule> =
|
||||
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