diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt index d428473572d..ca539d44947 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt @@ -153,11 +153,20 @@ class FirDeclarationCollector>( fun FirDeclarationCollector>.collectClassMembers(klass: FirRegularClassSymbol) { val otherDeclarations = mutableMapOf>>() val functionDeclarations = mutableMapOf>>() - val scope = klass.unsubstitutedScope(context) + val declaredMemberScope = klass.declaredMemberScope(context) + val unsubstitutedScope = klass.unsubstitutedScope(context) - scope.collectLeafFunctions().forEach { - if (it.isCollectable() && it.isVisibleInClass(klass)) { - collect(it, FirRedeclarationPresenter.represent(it), functionDeclarations) + declaredMemberScope.processAllFunctions { declaredFunction -> + if (!declaredFunction.isCollectable()) { + return@processAllFunctions + } + + collect(declaredFunction, FirRedeclarationPresenter.represent(declaredFunction), functionDeclarations) + + unsubstitutedScope.collectLeafFunctionsByName(declaredFunction.name).forEach { anotherFunction -> + if (anotherFunction != declaredFunction && anotherFunction.isCollectable() && anotherFunction.isVisibleInClass(klass)) { + collect(anotherFunction, FirRedeclarationPresenter.represent(anotherFunction), functionDeclarations) + } } } @@ -167,25 +176,24 @@ fun FirDeclarationCollector>.collectClassMembers(klass: FirReg // with functions from this outer class, // so we should avoid checking them twice. if (context.isTopLevel) { - scope.processDeclaredConstructors { + unsubstitutedScope.processDeclaredConstructors { if (it.isCollectable() && it.isVisibleInClass(klass)) { collect(it, FirRedeclarationPresenter.represent(it, klass), functionDeclarations) } } } - val visitedProperties = mutableSetOf>() - - scope.collectLeafProperties().forEach { - if (it.isCollectable() && it.isVisibleInClass(klass)) { - collect(it, FirRedeclarationPresenter.represent(it), otherDeclarations) + declaredMemberScope.processAllProperties { declaredProperty -> + if (!declaredProperty.isCollectable()) { + return@processAllProperties } - visitedProperties.add(it) - } - klass.declaredMemberScope(context).processAllProperties { - if (it !in visitedProperties && it.isCollectable()) { - collect(it, FirRedeclarationPresenter.represent(it), otherDeclarations) + collect(declaredProperty, FirRedeclarationPresenter.represent(declaredProperty), otherDeclarations) + + unsubstitutedScope.collectLeafPropertiesByName(declaredProperty.name).forEach { anotherProperty -> + if (anotherProperty != declaredProperty && anotherProperty.isCollectable() && anotherProperty.isVisibleInClass(klass)) { + collect(anotherProperty, FirRedeclarationPresenter.represent(anotherProperty), otherDeclarations) + } } } @@ -216,25 +224,30 @@ fun FirDeclarationCollector>.collectClassMembers(klass: FirReg } } - val visitedClassifiers = mutableSetOf>() - - scope.processAllClassifiers { - processClassifier(it) - visitedClassifiers.add(it) - } - // Scopes refer to inner classifiers // through maps indexed by names, // so only the last declaration is // observed when processing all // classifiers - for (it in klass.declarationSymbols) { - if (it is FirClassifierSymbol<*> && it !in visitedClassifiers) { - processClassifier(it) + for (declaredClassifier in klass.declarationSymbols) { + if (declaredClassifier is FirClassifierSymbol<*>) { + processClassifier(declaredClassifier) + + unsubstitutedScope.processClassifiersByName(declaredClassifier.name) { anotherClassifier -> + if (anotherClassifier != declaredClassifier) { + processClassifier(anotherClassifier) + } + } } } } +private val FirClassifierSymbol<*>.name: Name + get() = when (this) { + is FirClassLikeSymbol -> name + is FirTypeParameterSymbol -> name + } + fun collectConflictingLocalFunctionsFrom(block: FirBlock, context: CheckerContext): Map, Set>> { val collectables = block.statements.filter { diff --git a/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.fir.kt b/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.fir.kt deleted file mode 100644 index 39eedb05912..00000000000 --- a/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.fir.kt +++ /dev/null @@ -1,55 +0,0 @@ -open class Final { - fun foo() {} - val bar: Int = 0 - var qux: Int = 0 -} - -open class Derived : Final() - -interface IFoo { - fun foo() -} - -class CFoo : IFoo { - override fun foo() {} -} - -interface IBar { - val bar: Int -} - -class CBar : IBar { - override val bar: Int get() = 0 -} - -interface IQux { - val qux: Int -} - -class CQux : IQux { - override val qux: Int get() = 0 -} - -interface IBarT { - val bar: T -} - -class CBarT : IBarT { - override val bar: T get() = null!! -} - -class Test1 : Final(), IFoo by CFoo() - -class Test2 : Final(), IBar by CBar() - -class Test3 : Final(), IQux by CQux() - -class Test4 : Derived(), IFoo by CFoo() - -class Test5 : Derived(), IBar by CBar() - -class Test6 : Derived(), IQux by CQux() - -class Test7 : Final(), IBarT by CBarT() - -class Test8 : Final(), IBarT by CBar() diff --git a/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.kt b/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.kt index 5a99e5f74f4..36416cea52c 100644 --- a/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.kt +++ b/compiler/testData/diagnostics/tests/delegation/clashes/finalMemberOverridden.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL open class Final { fun foo() {} val bar: Int = 0 diff --git a/plugins/fir-plugin-prototype/testData/diagnostics/checkers/mixingComposableAndNormalFunctions.kt b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/mixingComposableAndNormalFunctions.kt index cb2b3ae10c8..bc9c3ad1e22 100644 --- a/plugins/fir-plugin-prototype/testData/diagnostics/checkers/mixingComposableAndNormalFunctions.kt +++ b/plugins/fir-plugin-prototype/testData/diagnostics/checkers/mixingComposableAndNormalFunctions.kt @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.fir.plugin.MyComposable import kotlin.reflect.* -abstract class MyClass: KSuspendFunction0, () -> Unit +abstract class MyClass: KSuspendFunction0, () -> Unit abstract class OurClass: @MyComposable (Int) -> Unit, () -> Unit abstract class YourClass: @MyComposable KFunction1, () -> Unit