From fc37885d6d5835bb7b24b5e24c63c5ba2e754e74 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Mon, 17 Apr 2023 11:08:16 +0000 Subject: [PATCH] K1: report a warning for invisible setter accessed from a derived class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The issue is that during binding fake overrides, the compiler doesn't differ setters from its properties, so the compiler uses the same visibility for setter and entire property. Changing logic at the binding stage can cause some unpredictable consequences so the fix is to do this differentiation right at the reporting stage ^KT-56662 Fixed Merge-request: KT-MR-9565 Merged-by: Michail Zarečenskij --- ...CompilerTestFE10TestdataTestGenerated.java | 12 ++++ ...sticCompilerFE10TestDataTestGenerated.java | 12 ++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 12 ++++ ...siOldFrontendDiagnosticsTestGenerated.java | 12 ++++ .../cfg/ControlFlowInformationProviderImpl.kt | 50 ++++++++++++++--- .../jetbrains/kotlin/diagnostics/Errors.java | 2 + .../rendering/DefaultErrorMessages.java | 2 + ...ternalSetterAccessFromDeriviedClass.fir.kt | 56 +++++++++++++++++++ ...leInternalSetterAccessFromDeriviedClass.kt | 56 +++++++++++++++++++ ...rnalSetterAccessFromDeriviedClassOn.fir.kt | 56 +++++++++++++++++++ ...InternalSetterAccessFromDeriviedClassOn.kt | 56 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + .../kotlin/resolve/OverridingUtil.java | 2 +- 14 files changed, 332 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.fir.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.fir.kt create mode 100644 compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt 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 7238e2d09ca..9061e417143 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 @@ -27554,6 +27554,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt"); } + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClass.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt"); + } + + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClassOn.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClassOn() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt"); + } + @Test @TestMetadata("invisibleSetter.kt") public void testInvisibleSetter() 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 1e90d730b88..37001f80a67 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 @@ -27554,6 +27554,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt"); } + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClass.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt"); + } + + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClassOn.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClassOn() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt"); + } + @Test @TestMetadata("invisibleSetter.kt") public void testInvisibleSetter() 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 cccb0d8c962..27e1c859594 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 @@ -27554,6 +27554,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt"); } + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClass.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt"); + } + + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClassOn.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClassOn() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt"); + } + @Test @TestMetadata("invisibleSetter.kt") public void testInvisibleSetter() 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 fe53e4ca0f8..5acda395aeb 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 @@ -27566,6 +27566,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt"); } + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClass.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt"); + } + + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClassOn.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClassOn() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt"); + } + @Test @TestMetadata("invisibleSetter.kt") public void testInvisibleSetter() throws Exception { diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index 711cf160a5b..0eb4d7a0ecf 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.resolve.calls.util.* import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor +import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver @@ -494,15 +495,19 @@ class ControlFlowInformationProviderImpl private constructor( if (DescriptorVisibilityUtils.isVisible(receiverValue, variableDescriptor, descriptor, languageVersionSettings) && setterDescriptor != null - && !DescriptorVisibilityUtils.isVisible(receiverValue, setterDescriptor, descriptor, languageVersionSettings) ) { - report( - Errors.INVISIBLE_SETTER.on( - expression, variableDescriptor, setterDescriptor.visibility, - setterDescriptor - ), ctxt - ) - return true + if (!DescriptorVisibilityUtils.isVisible(receiverValue, setterDescriptor, descriptor, languageVersionSettings)) { + report( + INVISIBLE_SETTER.on( + expression, variableDescriptor, setterDescriptor.visibility, + setterDescriptor + ), ctxt + ) + return true + } else { + // don't return anything as only warning is reported (not error), so further diagnostics are also important + reportVisibilityWarningForInternalFakeSetterOverride(setterDescriptor, expression, variableDescriptor, ctxt) + } } } val isThisOrNoDispatchReceiver = PseudocodeUtil.isThisOrNoDispatchReceiver(writeValueInstruction, trace.bindingContext) @@ -560,6 +565,35 @@ class ControlFlowInformationProviderImpl private constructor( return false } + private fun reportVisibilityWarningForInternalFakeSetterOverride( + setterDescriptor: PropertySetterDescriptor, + expression: KtExpression, + variableDescriptor: PropertyDescriptor, + ctxt: VariableInitContext + ) { + if (setterDescriptor.kind.isReal) return + if (setterDescriptor.visibility.isPublicAPI) return + + val containingClass = setterDescriptor.containingDeclaration as? ClassDescriptor ?: return + val firstRealOverridden = setterDescriptor.firstOverridden { it.kind.isReal } ?: return + + val visibleOverrides = OverridingUtil.filterVisibleFakeOverrides(containingClass, listOf(firstRealOverridden)) + if (visibleOverrides.isEmpty()) { + val diagnostic = + when (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAccessToInvisibleSetterFromDerivedClass)) { + true -> INVISIBLE_SETTER + else -> INVISIBLE_SETTER_FROM_DERIVED + } + + report( + diagnostic.on( + expression, variableDescriptor, setterDescriptor.visibility, + setterDescriptor + ), ctxt + ) + } + } + private fun reportValReassigned(expression: KtExpression, variableDescriptor: VariableDescriptor, ctxt: VariableInitContext) { report(VAL_REASSIGNMENT_VIA_BACKING_FIELD.on(languageVersionSettings, expression, variableDescriptor), ctxt) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 0ea6229dedd..dbd9dbcbb84 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -1204,6 +1204,8 @@ public interface Errors { DiagnosticFactory3 INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR); + DiagnosticFactory3 INVISIBLE_SETTER_FROM_DERIVED = + DiagnosticFactory3.create(WARNING); DiagnosticFactory1 VAL_OR_VAR_ON_LOOP_PARAMETER = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 VAL_OR_VAR_ON_FUN_PARAMETER = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 782b708cdf5..1246a34fb65 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -414,6 +414,8 @@ public class DefaultErrorMessages { MAP.put(SETTER_PROJECTED_OUT, "Setter for ''{0}'' is removed by type projection", NAME); MAP.put(INVISIBLE_SETTER, "Cannot assign to ''{0}'': the setter is {1} in {2}", NAME, VISIBILITY, NAME_OF_CONTAINING_DECLARATION_OR_FILE); + MAP.put(INVISIBLE_SETTER_FROM_DERIVED, "Cannot assign to ''{0}'': the setter is {1} in {2}. This warning will be an error soon. See https://youtrack.jetbrains.com/issue/KT-56662 for details", NAME, VISIBILITY, + NAME_OF_CONTAINING_DECLARATION_OR_FILE); MAP.put(INITIALIZATION_BEFORE_DECLARATION, "Variable cannot be initialized before declaration", NAME); MAP.put(VARIABLE_EXPECTED, "Variable expected"); diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.fir.kt b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.fir.kt new file mode 100644 index 00000000000..61fe021dd2a --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.fir.kt @@ -0,0 +1,56 @@ +// !LANGUAGE:-ProhibitAccessToInvisibleSetterFromDerivedClass +// IGNORE_REVERSED_RESOLVE + +// MODULE: m1 +// FILE: base.kt + +open class Base { + var foo: String = "" + internal set +} + +// MODULE: m2(m1) +// FILE: derived1.kt + +fun testBase(b: Base) { + b.foo = "other" +} + +open class Derived1(foo: String) : Base() { + init { + this.foo = foo + } + + fun bar(param: String) { + foo = param + this.foo = param + } +} + +open class Derived2 : Derived1("") + +fun testFunction(d: Derived1) { + d.foo = "other" +} + +// MODULE: m3(m2, m1) +// FILE: derived2.kt + +fun testDerivied1(d: Derived1) { + d.foo = "other" +} + +fun testDerivied2(d: Derived2) { + d.foo = "other" +} + +class Derivied3(foo: String) : Derived2() { + init { + this.foo = foo + } + + fun bar1(param: String) { + foo = param + this.foo = param + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt new file mode 100644 index 00000000000..50176c96cc6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt @@ -0,0 +1,56 @@ +// !LANGUAGE:-ProhibitAccessToInvisibleSetterFromDerivedClass +// IGNORE_REVERSED_RESOLVE + +// MODULE: m1 +// FILE: base.kt + +open class Base { + var foo: String = "" + internal set +} + +// MODULE: m2(m1) +// FILE: derived1.kt + +fun testBase(b: Base) { + b.foo = "other" +} + +open class Derived1(foo: String) : Base() { + init { + this.foo = foo + } + + fun bar(param: String) { + foo = param + this.foo = param + } +} + +open class Derived2 : Derived1("") + +fun testFunction(d: Derived1) { + d.foo = "other" +} + +// MODULE: m3(m2, m1) +// FILE: derived2.kt + +fun testDerivied1(d: Derived1) { + d.foo = "other" +} + +fun testDerivied2(d: Derived2) { + d.foo = "other" +} + +class Derivied3(foo: String) : Derived2() { + init { + this.foo = foo + } + + fun bar1(param: String) { + foo = param + this.foo = param + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.fir.kt b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.fir.kt new file mode 100644 index 00000000000..e0356a364c2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.fir.kt @@ -0,0 +1,56 @@ +// !LANGUAGE:+ProhibitAccessToInvisibleSetterFromDerivedClass +// IGNORE_REVERSED_RESOLVE + +// MODULE: m1 +// FILE: base.kt + +open class Base { + var foo: String = "" + internal set +} + +// MODULE: m2(m1) +// FILE: derived1.kt + +fun testBase(b: Base) { + b.foo = "other" +} + +open class Derived1(foo: String) : Base() { + init { + this.foo = foo + } + + fun bar(param: String) { + foo = param + this.foo = param + } +} + +open class Derived2 : Derived1("") + +fun testFunction(d: Derived1) { + d.foo = "other" +} + +// MODULE: m3(m2, m1) +// FILE: derived2.kt + +fun testDerivied1(d: Derived1) { + d.foo = "other" +} + +fun testDerivied2(d: Derived2) { + d.foo = "other" +} + +class Derivied3(foo: String) : Derived2() { + init { + this.foo = foo + } + + fun bar1(param: String) { + foo = param + this.foo = param + } +} diff --git a/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt new file mode 100644 index 00000000000..44830419f4d --- /dev/null +++ b/compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt @@ -0,0 +1,56 @@ +// !LANGUAGE:+ProhibitAccessToInvisibleSetterFromDerivedClass +// IGNORE_REVERSED_RESOLVE + +// MODULE: m1 +// FILE: base.kt + +open class Base { + var foo: String = "" + internal set +} + +// MODULE: m2(m1) +// FILE: derived1.kt + +fun testBase(b: Base) { + b.foo = "other" +} + +open class Derived1(foo: String) : Base() { + init { + this.foo = foo + } + + fun bar(param: String) { + foo = param + this.foo = param + } +} + +open class Derived2 : Derived1("") + +fun testFunction(d: Derived1) { + d.foo = "other" +} + +// MODULE: m3(m2, m1) +// FILE: derived2.kt + +fun testDerivied1(d: Derived1) { + d.foo = "other" +} + +fun testDerivied2(d: Derived2) { + d.foo = "other" +} + +class Derivied3(foo: String) : Derived2() { + init { + this.foo = foo + } + + fun bar1(param: String) { + foo = param + this.foo = param + } +} 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 cc2e8b9bc74..b027acd2f8b 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 @@ -28332,6 +28332,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.kt"); } + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClass.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClass() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClass.kt"); + } + + @Test + @TestMetadata("invisibleInternalSetterAccessFromDeriviedClassOn.kt") + public void testInvisibleInternalSetterAccessFromDeriviedClassOn() throws Exception { + runTest("compiler/testData/diagnostics/tests/scopes/invisibleInternalSetterAccessFromDeriviedClassOn.kt"); + } + @Test @TestMetadata("invisibleSetter.kt") public void testInvisibleSetter() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 60b6dda2868..2e9768ae29c 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -287,6 +287,7 @@ enum class LanguageFeature( ForbidInferringPostponedTypeVariableIntoDeclaredUpperBound(KOTLIN_2_0, kind = BUG_FIX), // KT-47986 ProhibitUseSiteGetTargetAnnotations(KOTLIN_2_0, kind = BUG_FIX), // KT-15470 KeepNullabilityWhenApproximatingLocalType(KOTLIN_2_0, kind = BUG_FIX), // KT-53982 + ProhibitAccessToInvisibleSetterFromDerivedClass(KOTLIN_2_0, kind = BUG_FIX), // KT-56662 // 2.1 diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java index 14ab093feb7..000ab0041e2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/OverridingUtil.java @@ -805,7 +805,7 @@ public class OverridingUtil { } @NotNull - private static Collection filterVisibleFakeOverrides( + public static Collection filterVisibleFakeOverrides( @NotNull final ClassDescriptor current, @NotNull Collection toFilter ) {