[FIR] Recursively search dependsOn modules in visibility checks
#KT-59071 Fixed
This commit is contained in:
+6
@@ -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");
|
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
|
@Test
|
||||||
@TestMetadata("friendModule.kt")
|
@TestMetadata("friendModule.kt")
|
||||||
public void testFriendModule() throws Exception {
|
public void testFriendModule() throws Exception {
|
||||||
|
|||||||
+6
@@ -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");
|
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
|
@Test
|
||||||
@TestMetadata("friendModule.kt")
|
@TestMetadata("friendModule.kt")
|
||||||
public void testFriendModule() throws Exception {
|
public void testFriendModule() throws Exception {
|
||||||
|
|||||||
+6
@@ -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");
|
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
|
@Test
|
||||||
@TestMetadata("friendModule.kt")
|
@TestMetadata("friendModule.kt")
|
||||||
public void testFriendModule() throws Exception {
|
public void testFriendModule() throws Exception {
|
||||||
|
|||||||
+6
@@ -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");
|
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
|
@Test
|
||||||
@TestMetadata("friendModule.kt")
|
@TestMetadata("friendModule.kt")
|
||||||
public void testFriendModule() throws Exception {
|
public void testFriendModule() throws Exception {
|
||||||
|
|||||||
+1
-3
@@ -149,9 +149,7 @@ abstract class FirAbstractSessionFactory {
|
|||||||
// dependsOnDependencies can actualize declarations from their dependencies. Because actual declarations can be more specific
|
// 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)
|
// (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).
|
// to prevent false positive resolution errors (see KT-57369 for an example).
|
||||||
val dependsOnDependencies = topologicalSort(moduleData.dependsOnDependencies) { it.dependsOnDependencies }
|
return (moduleData.dependencies + moduleData.friendDependencies + moduleData.allDependsOnDependencies)
|
||||||
|
|
||||||
return (moduleData.dependencies + moduleData.friendDependencies + dependsOnDependencies)
|
|
||||||
.mapNotNull { sessionProvider?.getSession(it) }
|
.mapNotNull { sessionProvider?.getSession(it) }
|
||||||
.map { it.symbolProvider }
|
.map { it.symbolProvider }
|
||||||
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
|
.flatMap { it.flatten(visited, collectSourceProviders = it.session.kind == FirSession.Kind.Source) }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.container.topologicalSort
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
@@ -34,12 +35,14 @@ abstract class FirModuleVisibilityChecker : FirSessionComponent {
|
|||||||
abstract fun isInFriendModule(declaration: FirMemberDeclaration): Boolean
|
abstract fun isInFriendModule(declaration: FirMemberDeclaration): Boolean
|
||||||
|
|
||||||
class Standard(val session: FirSession) : FirModuleVisibilityChecker() {
|
class Standard(val session: FirSession) : FirModuleVisibilityChecker() {
|
||||||
|
private val useSiteModuleData = session.moduleData
|
||||||
|
private val allDependsOnDependencies = useSiteModuleData.allDependsOnDependencies
|
||||||
|
|
||||||
override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean {
|
override fun isInFriendModule(declaration: FirMemberDeclaration): Boolean {
|
||||||
val useSiteModuleData = session.moduleData
|
|
||||||
return when (declaration.moduleData) {
|
return when (declaration.moduleData) {
|
||||||
useSiteModuleData,
|
useSiteModuleData,
|
||||||
in useSiteModuleData.friendDependencies,
|
in useSiteModuleData.friendDependencies,
|
||||||
in useSiteModuleData.dependsOnDependencies -> true
|
in allDependsOnDependencies -> true
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@@ -47,6 +50,8 @@ abstract class FirModuleVisibilityChecker : FirSessionComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val FirModuleData.allDependsOnDependencies: List<FirModuleData> get() = topologicalSort(dependsOnDependencies) { it.dependsOnDependencies }
|
||||||
|
|
||||||
abstract class FirVisibilityChecker : FirSessionComponent {
|
abstract class FirVisibilityChecker : FirSessionComponent {
|
||||||
@NoMutableState
|
@NoMutableState
|
||||||
object Default : FirVisibilityChecker() {
|
object Default : FirVisibilityChecker() {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// -- Module: <m1> --
|
||||||
|
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: <m2> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun test2(): kotlin.Unit
|
||||||
|
|
||||||
|
// -- Module: <m3> --
|
||||||
|
package
|
||||||
|
|
||||||
|
public fun test2(): kotlin.Unit
|
||||||
|
public fun test3(): kotlin.Unit
|
||||||
|
|
||||||
Generated
+6
@@ -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);
|
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
|
@Test
|
||||||
@TestMetadata("friendModule.kt")
|
@TestMetadata("friendModule.kt")
|
||||||
public void testFriendModule() throws Exception {
|
public void testFriendModule() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user