From 67e6687e890f7c90daeda84dc6bd3b9405949a11 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Mon, 30 May 2022 11:58:32 +0300 Subject: [PATCH] FIR: Fix FP error on a call to constructor of a private inner class Do not check dispatch receiver applicability when checking visibility for containing class of a callee constructor --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../fir/resolve/calls/ResolutionStages.kt | 25 +++++++------------ .../innerConstructorThroughSubclass.kt | 12 +++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++++ 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 6e8cee95249..39ff8e112bf 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -33496,6 +33496,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/visibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("innerConstructorThroughSubclass.kt") + public void testInnerConstructorThroughSubclass() throws Exception { + runTest("compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt"); + } + @Test @TestMetadata("innerNestedAndAnonymousClasses.kt") public void testInnerNestedAndAnonymousClasses() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index c7c5b97fc22..ff34a085675 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -33496,6 +33496,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/visibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("innerConstructorThroughSubclass.kt") + public void testInnerConstructorThroughSubclass() throws Exception { + runTest("compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt"); + } + @Test @TestMetadata("innerNestedAndAnonymousClasses.kt") public void testInnerNestedAndAnonymousClasses() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 9c11edc71fd..7397667e784 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -33496,6 +33496,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/visibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("innerConstructorThroughSubclass.kt") + public void testInnerConstructorThroughSubclass() throws Exception { + runTest("compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt"); + } + @Test @TestMetadata("innerNestedAndAnonymousClasses.kt") public void testInnerNestedAndAnonymousClasses() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 584b26e90c7..c8f7f18629a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -9,7 +9,9 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirVisibilityChecker import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.* +import org.jetbrains.kotlin.fir.declarations.utils.isInfix +import org.jetbrains.kotlin.fir.declarations.utils.isOperator +import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.matchingParameterFunctionType @@ -516,7 +518,8 @@ internal object CheckVisibility : CheckerStage() { val symbol = candidate.symbol val declaration = symbol.fir if (declaration is FirMemberDeclaration) { - if (!checkVisibility(declaration, sink, candidate, visibilityChecker)) { + if (!visibilityChecker.isVisible(declaration, candidate)) { + sink.yieldDiagnostic(VisibilityError) return } } @@ -529,23 +532,13 @@ internal object CheckVisibility : CheckerStage() { if (classSymbol.fir.classKind.isSingleton) { sink.yieldDiagnostic(VisibilityError) } - checkVisibility(classSymbol.fir, sink, candidate, visibilityChecker) + + if (!visibilityChecker.isVisible(declaration, candidate.callInfo, dispatchReceiverValue = null)) { + sink.yieldDiagnostic(VisibilityError) + } } } } - - private suspend fun checkVisibility( - declaration: T, - sink: CheckerSink, - candidate: Candidate, - visibilityChecker: FirVisibilityChecker - ): Boolean { - if (!visibilityChecker.isVisible(declaration, candidate)) { - sink.yieldDiagnostic(VisibilityError) - return false - } - return true - } } internal object CheckLowPriorityInOverloadResolution : CheckerStage() { diff --git a/compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt b/compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt new file mode 100644 index 00000000000..1f2fecbd334 --- /dev/null +++ b/compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt @@ -0,0 +1,12 @@ +// FIR_IDENTICAL +// SKIP_TXT + +sealed class Outer { + class NestedSubClass : Outer() { + fun foo() { + Inner() + } + } + + private inner class Inner +} 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 75a1c79589b..a94ba349961 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 @@ -33586,6 +33586,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/visibility"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("innerConstructorThroughSubclass.kt") + public void testInnerConstructorThroughSubclass() throws Exception { + runTest("compiler/testData/diagnostics/tests/visibility/innerConstructorThroughSubclass.kt"); + } + @Test @TestMetadata("innerNestedAndAnonymousClasses.kt") public void testInnerNestedAndAnonymousClasses() throws Exception {