From 42ebbb937cf142c3d52afa86cd72b8fe370e96af Mon Sep 17 00:00:00 2001 From: Brian Norman Date: Fri, 21 Jul 2023 15:29:55 -0500 Subject: [PATCH] [FIR] Recursively search dependsOn modules in visibility checks #KT-59071 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++ ...sticCompilerFE10TestDataTestGenerated.java | 6 ++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 ++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 ++ .../fir/session/FirAbstractSessionFactory.kt | 4 +- .../kotlin/fir/FirVisibilityChecker.kt | 9 ++- .../tests/multimodule/dependsOnModule.kt | 56 +++++++++++++++++++ .../tests/multimodule/dependsOnModule.txt | 44 +++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ 9 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt create mode 100644 compiler/testData/diagnostics/tests/multimodule/dependsOnModule.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 2ba1ee18690..97c90adeb3e 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -22184,6 +22184,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("dependsOnModule.kt") + public void testDependsOnModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt"); + } + @Test @TestMetadata("friendModule.kt") public void testFriendModule() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 64e3832ea0c..afd2ac2d625 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -22184,6 +22184,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("dependsOnModule.kt") + public void testDependsOnModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt"); + } + @Test @TestMetadata("friendModule.kt") public void testFriendModule() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index c477a9de022..a908f4578b0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -22184,6 +22184,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("dependsOnModule.kt") + public void testDependsOnModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt"); + } + @Test @TestMetadata("friendModule.kt") public void testFriendModule() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 0defec62bf6..bfe2117846e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -22190,6 +22190,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("dependsOnModule.kt") + public void testDependsOnModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt"); + } + @Test @TestMetadata("friendModule.kt") public void testFriendModule() throws Exception { diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt index 203a9fa1790..810a2e8a968 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt @@ -149,9 +149,7 @@ abstract class FirAbstractSessionFactory { // 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). - val dependsOnDependencies = topologicalSort(moduleData.dependsOnDependencies) { it.dependsOnDependencies } - - return (moduleData.dependencies + moduleData.friendDependencies + dependsOnDependencies) + 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) } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index 619bef97d34..3be93da6f4f 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.container.topologicalSort import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.declarations.* @@ -34,12 +35,14 @@ abstract class FirModuleVisibilityChecker : FirSessionComponent { abstract fun isInFriendModule(declaration: FirMemberDeclaration): Boolean class Standard(val session: FirSession) : FirModuleVisibilityChecker() { + private val useSiteModuleData = session.moduleData + private val allDependsOnDependencies = useSiteModuleData.allDependsOnDependencies + override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean { - val useSiteModuleData = session.moduleData return when (declaration.moduleData) { useSiteModuleData, in useSiteModuleData.friendDependencies, - in useSiteModuleData.dependsOnDependencies -> true + in allDependsOnDependencies -> true else -> false } @@ -47,6 +50,8 @@ abstract class FirModuleVisibilityChecker : FirSessionComponent { } } +val FirModuleData.allDependsOnDependencies: List get() = topologicalSort(dependsOnDependencies) { it.dependsOnDependencies } + abstract class FirVisibilityChecker : FirSessionComponent { @NoMutableState object Default : FirVisibilityChecker() { diff --git a/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt b/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt new file mode 100644 index 00000000000..f821578e1a8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt @@ -0,0 +1,56 @@ +// FIR_IDENTICAL +// !DIAGNOSTICS: -UNUSED_VARIABLE + +// MODULE: m1 +// FILE: a.kt + +package p + +public class A { + internal val a = A() + internal var v = A() + internal fun a() = A() + internal inner class B +} + +internal val a = A() +internal var v = A() +internal fun a() = A() +internal class B + +// MODULE: m2()()(m1) +// FILE: b.kt + +import p.* + +fun test2() { + val _a = a + val _v = v + a() + B() + + val inst = A() + val ia = inst.a + val iv = inst.v + inst.a() + inst.B() +} + + +// MODULE: m3()()(m2) +// FILE: c.kt + +import p.* + +fun test3() { + val _a = a + val _v = v + a() + B() + + val inst = A() + val ia = inst.a + val iv = inst.v + inst.a() + inst.B() +} diff --git a/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.txt b/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.txt new file mode 100644 index 00000000000..63f96098c56 --- /dev/null +++ b/compiler/testData/diagnostics/tests/multimodule/dependsOnModule.txt @@ -0,0 +1,44 @@ +// -- Module: -- +package + +package p { + internal val a: p.A + internal var v: p.A + internal fun a(): p.A + + public final class A { + public constructor A() + internal final val a: p.A + internal final var v: p.A + internal final fun a(): p.A + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + internal final inner class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + } + + internal final class B { + public constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +// -- Module: -- +package + +public fun test2(): kotlin.Unit + +// -- Module: -- +package + +public fun test2(): kotlin.Unit +public fun test3(): kotlin.Unit + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 032d6582bdd..6192613f390 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -22190,6 +22190,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("dependsOnModule.kt") + public void testDependsOnModule() throws Exception { + runTest("compiler/testData/diagnostics/tests/multimodule/dependsOnModule.kt"); + } + @Test @TestMetadata("friendModule.kt") public void testFriendModule() throws Exception {