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 20d5ae4f56f..48029e5fb6a 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 @@ -24825,6 +24825,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); } + @Test + @TestMetadata("packagePrivateAndPublic.kt") + public void testPackagePrivateAndPublic() throws Exception { + runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt"); + } + @Test @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() 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 092a158504f..34cf670cd11 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 @@ -24825,6 +24825,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); } + @Test + @TestMetadata("packagePrivateAndPublic.kt") + public void testPackagePrivateAndPublic() throws Exception { + runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt"); + } + @Test @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() 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 ea537207826..23ac74c8d73 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 @@ -24825,6 +24825,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); } + @Test + @TestMetadata("packagePrivateAndPublic.kt") + public void testPackagePrivateAndPublic() throws Exception { + runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt"); + } + @Test @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() 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 b492a392710..e651dcd04bf 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 @@ -24831,6 +24831,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); } + @Test + @TestMetadata("packagePrivateAndPublic.kt") + public void testPackagePrivateAndPublic() throws Exception { + runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt"); + } + @Test @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() throws Exception { diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt index f7edc2f5a80..3495a03434f 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.name.Name object FirNativeSessionFactory : FirAbstractSessionFactory() { + @OptIn(SessionConfiguration::class) fun createLibrarySession( mainModuleName: Name, resolvedLibraries: List, @@ -39,6 +40,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { languageVersionSettings, extensionRegistrars, registerExtraComponents = { session -> + session.register(FirVisibilityChecker::class, FirVisibilityChecker.Default) registerExtraComponents(session) }, createKotlinScopeProvider = { FirKotlinScopeProvider() }, diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt index ab956d4b8e5..fd60778d972 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaVisibilityChecker.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.visibility import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.resolve.SupertypeSupplier import org.jetbrains.kotlin.fir.resolve.calls.FirSimpleSyntheticPropertySymbol -import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue import org.jetbrains.kotlin.fir.resolve.isSubclassOf import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol @@ -76,12 +75,12 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() { } override fun platformOverrideVisibilityCheck( - candidateInDerivedClass: FirBasedSymbol<*>, + packageNameOfDerivedClass: FqName, symbolInBaseClass: FirBasedSymbol<*>, visibilityInBaseClass: Visibility, ): Boolean = when (visibilityInBaseClass) { JavaVisibilities.ProtectedAndPackage, JavaVisibilities.ProtectedStaticVisibility -> true - JavaVisibilities.PackageVisibility -> symbolInBaseClass.isInPackage(candidateInDerivedClass.packageFqName()) + JavaVisibilities.PackageVisibility -> symbolInBaseClass.isInPackage(packageNameOfDerivedClass) else -> true } 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 6ec715d0582..6b3fa67f549 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -68,7 +68,7 @@ abstract class FirVisibilityChecker : FirSessionComponent { } override fun platformOverrideVisibilityCheck( - candidateInDerivedClass: FirBasedSymbol<*>, + packageNameOfDerivedClass: FqName, symbolInBaseClass: FirBasedSymbol<*>, visibilityInBaseClass: Visibility, ): Boolean { @@ -151,13 +151,20 @@ abstract class FirVisibilityChecker : FirSessionComponent { fun isVisibleForOverriding( candidateInDerivedClass: FirMemberDeclaration, - candidateInBaseClass: FirMemberDeclaration - ): Boolean = isVisibleForOverriding(candidateInDerivedClass.moduleData, candidateInDerivedClass.symbol, candidateInBaseClass) + candidateInBaseClass: FirMemberDeclaration, + ): Boolean = + isVisibleForOverriding(candidateInDerivedClass.moduleData, candidateInDerivedClass.symbol.packageFqName(), candidateInBaseClass) fun isVisibleForOverriding( derivedClassModuleData: FirModuleData, symbolFromDerivedClass: FirBasedSymbol<*>, candidateInBaseClass: FirMemberDeclaration, + ): Boolean = isVisibleForOverriding(derivedClassModuleData, symbolFromDerivedClass.packageFqName(), candidateInBaseClass) + + fun isVisibleForOverriding( + derivedClassModuleData: FirModuleData, + packageNameOfDerivedClass: FqName, + candidateInBaseClass: FirMemberDeclaration, ): Boolean = when (candidateInBaseClass.visibility) { Visibilities.Internal -> { candidateInBaseClass.moduleData == derivedClassModuleData || @@ -166,7 +173,14 @@ abstract class FirVisibilityChecker : FirSessionComponent { Visibilities.Private, Visibilities.PrivateToThis -> false Visibilities.Protected -> true - else -> platformOverrideVisibilityCheck(symbolFromDerivedClass, candidateInBaseClass.symbol, candidateInBaseClass.visibility) + else -> { + + platformOverrideVisibilityCheck( + packageNameOfDerivedClass, + candidateInBaseClass.symbol, + candidateInBaseClass.visibility + ) + } } private fun isSpecificDeclarationVisible( @@ -249,7 +263,7 @@ abstract class FirVisibilityChecker : FirSessionComponent { ): Boolean protected abstract fun platformOverrideVisibilityCheck( - candidateInDerivedClass: FirBasedSymbol<*>, + packageNameOfDerivedClass: FqName, symbolInBaseClass: FirBasedSymbol<*>, visibilityInBaseClass: Visibility, ): Boolean diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt index d5bd84e5ca3..846432205c1 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScopeContext.kt @@ -39,7 +39,8 @@ class FirTypeIntersectionScopeContext( ) { private val overrideService = session.overrideService - private val isReceiverClassExpect = dispatchReceiverType.toRegularClassSymbol(session)?.isExpect == true + private val dispatchClassSymbol: FirRegularClassSymbol? = dispatchReceiverType.toRegularClassSymbol(session) + private val isReceiverClassExpect = dispatchClassSymbol?.isExpect == true val intersectionOverrides: FirCache, MemberWithBaseScope>, ResultOfIntersection.NonTrivial<*>> = session.intersectionOverrideStorage.cacheByScope.getValue(dispatchReceiverType) @@ -150,9 +151,9 @@ class FirTypeIntersectionScopeContext( val result = mutableListOf>() while (allMembersWithScope.size > 1) { - val groupWithPrivate = + val groupWithInvisible = overrideService.extractBothWaysOverridable(allMembersWithScope.maxByVisibility(), allMembersWithScope, overrideChecker) - val group = groupWithPrivate.filter { !Visibilities.isPrivate(it.member.fir.visibility) }.ifEmpty { groupWithPrivate } + val group = groupWithInvisible.filter { it.isVisible() }.ifEmpty { groupWithInvisible } val nonSubsumed = if (forClassUseSiteScope) group.nonSubsumed() else group val mostSpecific = overrideService.selectMostSpecificMembers(nonSubsumed, ReturnTypeCalculatorForFullBodyResolve.Default) val nonTrivial = if (forClassUseSiteScope) { @@ -186,6 +187,17 @@ class FirTypeIntersectionScopeContext( return result } + private fun MemberWithBaseScope<*>.isVisible(): Boolean { + // Checking for private is not enough because package-private declarations can be hidden, too, if they're in a different package. + val dispatchClassSymbol = dispatchClassSymbol ?: return true + + return session.visibilityChecker.isVisibleForOverriding( + dispatchClassSymbol.moduleData, + dispatchClassSymbol.classId.packageFqName, + member.fir + ) + } + fun > createIntersectionOverride( mostSpecific: List>, extractedOverrides: List>, diff --git a/compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt new file mode 100644 index 00000000000..4b07218e961 --- /dev/null +++ b/compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt @@ -0,0 +1,29 @@ +// FIR_IDENTICAL +// FILE: ViewModel.java +package viewmodel; + +public class ViewModel { + final void clear() { + } +} + +// FILE: samePackage.kt +package viewmodel + +interface IMyViewModel { + fun clear() +} + +class MyViewModel: ViewModel(), IMyViewModel { + override fun clear() = Unit +} + +// FILE: differentPackage.kt +package different + +import viewmodel.IMyViewModel +import viewmodel.ViewModel + +class MyViewModel: ViewModel(), IMyViewModel { + override fun clear() = 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 1e76ecd889d..dfea076a40b 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 @@ -26571,6 +26571,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/kt9550.kt"); } + @Test + @TestMetadata("packagePrivateAndPublic.kt") + public void testPackagePrivateAndPublic() throws Exception { + runTest("compiler/testData/diagnostics/tests/override/clashesOnInheritance/packagePrivateAndPublic.kt"); + } + @Test @TestMetadata("returnTypeMismatch.kt") public void testReturnTypeMismatch() throws Exception {