[FIR] Do not include transitive friend dependencies in symbol provider
When flattening a dependency FirSymbolProvider, make sure transitive dependency FirSymbolProviders are not included. This requires checking that nested symbol provider sessions match the composite symbol provider session when they are both source sessions. ^KT-60614 Fixed
This commit is contained in:
+6
@@ -23260,6 +23260,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dependencyModule.kt")
|
||||
public void testDependencyModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multimodule/dependencyModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dependsOnModule.kt")
|
||||
public void testDependsOnModule() throws Exception {
|
||||
|
||||
+6
@@ -23266,6 +23266,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dependencyModule.kt")
|
||||
public void testDependencyModule() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/multimodule/dependencyModule.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("dependsOnModule.kt")
|
||||
public void testDependsOnModule() throws Exception {
|
||||
|
||||
+11
-12
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.session
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.container.topologicalSort
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
@@ -146,37 +145,37 @@ abstract class FirAbstractSessionFactory {
|
||||
}
|
||||
|
||||
private fun FirSession.computeDependencyProviderList(moduleData: FirModuleData): List<FirSymbolProvider> {
|
||||
val visited = mutableSetOf<FirSymbolProvider>()
|
||||
|
||||
// dependsOnDependencies can actualize declarations from their dependencies. Because actual declarations can be more specific
|
||||
// (e.g. have additional supertypes), the modules must be ordered from most specific (i.e. actual) to most generic (i.e. expect)
|
||||
// to prevent false positive resolution errors (see KT-57369 for an example).
|
||||
return (moduleData.dependencies + moduleData.friendDependencies + moduleData.allDependsOnDependencies)
|
||||
.mapNotNull { sessionProvider?.getSession(it) }
|
||||
.map { it.symbolProvider }
|
||||
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
|
||||
.flatMap { it.symbolProvider.flatten() }
|
||||
.distinct()
|
||||
.sortedBy { it.session.kind }
|
||||
}
|
||||
|
||||
/* It eliminates dependency and composite providers since the current dependency provider is composite in fact.
|
||||
* To prevent duplications and resolving errors, library or source providers from other modules should be filtered out during flattening.
|
||||
* It depends on the session's kind of the top-level provider */
|
||||
private fun FirSymbolProvider.flatten(
|
||||
visited: MutableSet<FirSymbolProvider>,
|
||||
collectSourceProviders: Boolean
|
||||
): List<FirSymbolProvider> {
|
||||
private fun FirSymbolProvider.flatten(): List<FirSymbolProvider> {
|
||||
val originalSession = session.takeIf { it.kind == FirSession.Kind.Source }
|
||||
val result = mutableListOf<FirSymbolProvider>()
|
||||
|
||||
fun FirSymbolProvider.collectProviders() {
|
||||
if (!visited.add(this)) return
|
||||
when {
|
||||
// When provider is composite, unwrap all contained providers and recurse.
|
||||
this is FirCachingCompositeSymbolProvider -> {
|
||||
for (provider in providers) {
|
||||
provider.collectProviders()
|
||||
}
|
||||
}
|
||||
collectSourceProviders && session.kind == FirSession.Kind.Source ||
|
||||
!collectSourceProviders && session.kind == FirSession.Kind.Library -> {
|
||||
|
||||
// Make sure only source symbol providers from the same session as the original symbol provider are flattened. A composite
|
||||
// symbol provider can contain source symbol providers from multiple sessions that may represent dependency symbol providers
|
||||
// which should not be propagated transitively.
|
||||
originalSession != null && session.kind == FirSession.Kind.Source && session == originalSession ||
|
||||
originalSession == null && session.kind == FirSession.Kind.Library -> {
|
||||
result.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
-6
@@ -504,12 +504,6 @@ public class FirLightTreeJvmIrTextTestGenerated extends AbstractFirLightTreeJvmI
|
||||
runTest("compiler/testData/ir/irText/declarations/kt35550.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt45308.kt")
|
||||
public void testKt45308() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/declarations/kt45308.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47527.kt")
|
||||
public void testKt47527() throws Exception {
|
||||
|
||||
compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/FirPsiJvmIrTextTestGenerated.java
Generated
-6
@@ -504,12 +504,6 @@ public class FirPsiJvmIrTextTestGenerated extends AbstractFirPsiJvmIrTextTest {
|
||||
runTest("compiler/testData/ir/irText/declarations/kt35550.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt45308.kt")
|
||||
public void testKt45308() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/declarations/kt45308.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt47527.kt")
|
||||
public void testKt47527() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user