diff --git a/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.kt b/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.kt new file mode 100644 index 0000000000000000000000000000000000000000..868a065a4e4a694e56663c70c447d73b07255626 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.kt @@ -0,0 +1,38 @@ +// FILE: JA.java +public interface JA { + public E getFoo(); +} + +// FILE: main.kt + +interface KB { + override fun getFoo(): F + override fun getBar(): F +} + +interface D1 : JA, KB +interface E1 : D1 { + override fun getFoo(): String + override fun getBar(): String +} + +interface D2 : KB, JA +interface E2 : D2 { + override fun getFoo(): String + override fun getBar(): String +} + +fun main( + d1: D1, e1: E1, + d2: D2, e2: E2, +) { + d1.foo + d1.bar + e1.foo + e1.bar + + d2.foo + d2.bar + e2.foo + e2.bar +} diff --git a/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.txt b/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.txt new file mode 100644 index 0000000000000000000000000000000000000000..51a5f7e4cf3d5f5bf053f234ee142e0829d863f8 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.txt @@ -0,0 +1,33 @@ +FILE: main.kt + public abstract interface KB : R|kotlin/Any| { + public abstract override fun getFoo(): R|F| + + public abstract override fun getBar(): R|F| + + } + public abstract interface D1 : R|JA|, R|KB| { + } + public abstract interface E1 : R|D1| { + public abstract override fun getFoo(): R|kotlin/String| + + public abstract override fun getBar(): R|kotlin/String| + + } + public abstract interface D2 : R|KB|, R|JA| { + } + public abstract interface E2 : R|D2| { + public abstract override fun getFoo(): R|kotlin/String| + + public abstract override fun getBar(): R|kotlin/String| + + } + public final fun main(d1: R|D1|, e1: R|E1|, d2: R|D2|, e2: R|E2|): R|kotlin/Unit| { + R|/d1|.R|/D1.foo| + R|/d1|.# + R|/e1|.R|/E1.foo| + R|/e1|.# + R|/d2|.R|/D2.foo| + R|/d2|.# + R|/e2|.R|/E2.foo| + R|/e2|.# + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index ef937ca6f5a5bdd9c68674e0559dc86da0ceb15d..1f1f945b6027ab7929ebec3adc1cfa18c0cf4b3a 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -1732,6 +1732,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorConversion.kt"); } + @TestMetadata("javaAccessorsComplex.kt") + public void testJavaAccessorsComplex() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.kt"); + } + @TestMetadata("noBackingFieldForExtension.kt") public void testNoBackingFieldForExtension() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/properties/noBackingFieldForExtension.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 90f57b613642cee0d24eba94f66277a96ac8563a..9bd8a7f530afca798540788e7309c1bfd0f362ff 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1732,6 +1732,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorConversion.kt"); } + @TestMetadata("javaAccessorsComplex.kt") + public void testJavaAccessorsComplex() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/properties/javaAccessorsComplex.kt"); + } + @TestMetadata("noBackingFieldForExtension.kt") public void testNoBackingFieldForExtension() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/properties/noBackingFieldForExtension.kt"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt index 85efc7148cb507332f61e32944107e1bde0dc471..6d957a7658ae1ba1d4d33d04a026079439a3efcb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt @@ -41,6 +41,8 @@ class FirTypeIntersectionScope private constructor( private val typeContext = ConeTypeCheckerContext(isErrorTypeEqualsToAnything = false, isStubTypeEqualsToAnything = false, session) + private val overriddenSymbols = mutableMapOf, Collection>>() + override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { if (!processCallablesByName(name, processor, absentFunctions, FirScope::processFunctionsByName)) { super.processFunctionsByName(name, processor) @@ -81,9 +83,11 @@ class FirTypeIntersectionScope private constructor( membersByScope.singleOrNull()?.let { members -> for (member in members) { + overriddenSymbols[member] = listOf(member) processor(member) } + return false } @@ -94,7 +98,7 @@ class FirTypeIntersectionScope private constructor( val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers) val mostSpecific = selectMostSpecificMember(extractedOverrides) - + overriddenSymbols[mostSpecific] = extractedOverrides processor(mostSpecific) } @@ -245,8 +249,17 @@ class FirTypeIntersectionScope private constructor( functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>) -> ProcessorAction ): ProcessorAction { - for (scope in scopes) { - if (!scope.processOverriddenFunctions(functionSymbol, processor)) return ProcessorAction.STOP + @Suppress("UNCHECKED_CAST") + val directOverriddenSymbols = + overriddenSymbols[functionSymbol] as Collection>? + ?: return ProcessorAction.NEXT + + for (directOverridden in directOverriddenSymbols) { + // TODO: Preserve the scope where directOverridden came from + for (scope in scopes) { + if (!processor(directOverridden)) return ProcessorAction.STOP + if (!scope.processOverriddenFunctions(directOverridden, processor)) return ProcessorAction.STOP + } } return ProcessorAction.NEXT diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt index fc5052851a2a5da5b3c44e62f8c98b67037ec642..2a4744d704c826f3d2f7cd7c716ad02c2f2d462d 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt @@ -34,6 +34,6 @@ abstract class FirTypeScope : FirScope() { if (!baseScope.processOverriddenFunctions(overridden, processor)) return ProcessorAction.STOP } - return ProcessorAction.NEXT + return baseScope.processOverriddenFunctions(functionSymbol, processor) } }