[FIR] Collect constructors if nested classes along with member functions
For an example of an object with
an implicit primary constructor,
see `FirPsiOldFrontendDiagnosticsTestGenerated.testSingletonAndFunctionSameName`.
^KT-62005 Fixed
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 18cc3b3..97e7107 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
@@ -826,6 +826,12 @@
}
@Test
+ @TestMetadata("nestedClassConstructorVsMemberFunctionConflict.kt")
+ public void testNestedClassConstructorVsMemberFunctionConflict() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt");
+ }
+
+ @Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
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 d5b4196..0137f1e 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
@@ -826,6 +826,12 @@
}
@Test
+ @TestMetadata("nestedClassConstructorVsMemberFunctionConflict.kt")
+ public void testNestedClassConstructorVsMemberFunctionConflict() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt");
+ }
+
+ @Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
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 5e7bd80..973edb2 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
@@ -826,6 +826,12 @@
}
@Test
+ @TestMetadata("nestedClassConstructorVsMemberFunctionConflict.kt")
+ public void testNestedClassConstructorVsMemberFunctionConflict() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt");
+ }
+
+ @Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
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 337e0ac..7d10744 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
@@ -826,6 +826,12 @@
}
@Test
+ @TestMetadata("nestedClassConstructorVsMemberFunctionConflict.kt")
+ public void testNestedClassConstructorVsMemberFunctionConflict() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt");
+ }
+
+ @Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");
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 4711849..03d70a3 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
@@ -159,7 +159,20 @@
when (it) {
is FirSimpleFunction -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), functionDeclarations)
- is FirRegularClass -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
+ is FirRegularClass -> {
+ collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
+
+ // Objects have implicit FirPrimaryConstructors
+ if (it.symbol.classKind == ClassKind.OBJECT) {
+ continue
+ }
+
+ it.symbol.expandedClassWithConstructorsScope(context)?.let { (_, scopeWithConstructors) ->
+ scopeWithConstructors.processDeclaredConstructors { constructor ->
+ collect(constructor, FirRedeclarationPresenter.represent(constructor, it.symbol), functionDeclarations)
+ }
+ }
+ }
is FirTypeAlias -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
is FirVariable -> collect(it.symbol, FirRedeclarationPresenter.represent(it.symbol), otherDeclarations)
else -> {}
diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt
index eb7c44c..fa149de 100644
--- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt
+++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt
@@ -59,7 +59,13 @@
declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
val typeAliasForConstructorSource = (conflictingDeclaration as? FirConstructorSymbol)?.typeAliasForConstructor?.source
val source = typeAliasForConstructorSource ?: conflictingDeclaration.source
- if (symbols.isEmpty()) return@forEach
+ if (
+ symbols.isEmpty() ||
+ // For every implicit constructor there is a parent,
+ // FirRegularClass declaration, and those clash too,
+ // resulting in REDECLARATION.
+ conflictingDeclaration.isImplicitConstructor && symbols.all { it.isImplicitConstructor }
+ ) return@forEach
val factory =
if (conflictingDeclaration is FirNamedFunctionSymbol || conflictingDeclaration is FirConstructorSymbol) {
@@ -77,6 +83,8 @@
}
}
+ private val FirBasedSymbol<*>.isImplicitConstructor get() = source?.kind is KtFakeSourceElementKind.ImplicitConstructor
+
private fun checkFile(file: FirFile, inspector: FirDeclarationCollector<FirBasedSymbol<*>>, context: CheckerContext) {
val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) {
FirPackageMemberScope(file.packageFqName, context.sessionHolder.session)
diff --git a/compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt b/compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt
new file mode 100644
index 0000000..bc3c1d5
--- /dev/null
+++ b/compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt
@@ -0,0 +1,10 @@
+// FIR_IDENTICAL
+// ISSUE: KT-62005
+
+class A {
+ class NestedInA<!CONFLICTING_OVERLOADS!>()<!>
+ <!CONFLICTING_OVERLOADS!>fun NestedInA()<!> {}
+
+ class <!CONFLICTING_OVERLOADS!>NestedInA2<!>
+ <!CONFLICTING_OVERLOADS!>fun NestedInA2()<!> {}
+}
diff --git a/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt b/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt
index 017df6c..f9e3b17 100644
--- a/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt
+++ b/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt
@@ -15,16 +15,16 @@
<!CONFLICTING_OVERLOADS!>fun a()<!> = 1
class Tram {
- fun f() { }
+ <!CONFLICTING_OVERLOADS!>fun f()<!> { }
- class f() { }
+ class f<!CONFLICTING_OVERLOADS!>()<!> { }
}
class Yvayva {
companion object {
- fun fghj() { }
+ <!CONFLICTING_OVERLOADS!>fun fghj()<!> { }
- class fghj() { }
+ class fghj<!CONFLICTING_OVERLOADS!>()<!> { }
}
}
diff --git a/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt b/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt
index 2952251..625553d 100644
--- a/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt
+++ b/compiler/testData/diagnostics/tests/redeclarations/kt2438.kt
@@ -7,17 +7,21 @@
class B {
class <!REDECLARATION!>C<!>
class <!REDECLARATION!>C<!>
+
+ class <!CONFLICTING_OVERLOADS, REDECLARATION!>D<!>
+ class <!CONFLICTING_OVERLOADS, REDECLARATION!>D<!>
+ <!CONFLICTING_OVERLOADS!>fun D()<!> {}
}
class A {
class <!REDECLARATION!>B<!>
-
+
companion object {
class <!REDECLARATION!>B<!>
class <!REDECLARATION!>B<!>
}
-
+
class <!REDECLARATION!>B<!>
}
diff --git a/compiler/testData/diagnostics/tests/redeclarations/kt2438.txt b/compiler/testData/diagnostics/tests/redeclarations/kt2438.txt
index 24186c2..679e9ff 100644
--- a/compiler/testData/diagnostics/tests/redeclarations/kt2438.txt
+++ b/compiler/testData/diagnostics/tests/redeclarations/kt2438.txt
@@ -46,6 +46,7 @@
public final class B {
public constructor B()
+ public final fun D(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -63,5 +64,20 @@
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
+
+ public final class D {
+ public constructor D()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
+
+ public final class D {
+ public constructor D()
+ public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
+ public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
+ public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
+ }
}
}
+
diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt
index adcde08..e9b668e 100644
--- a/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt
+++ b/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt
@@ -13,15 +13,15 @@
<!CONFLICTING_OVERLOADS!>fun B(x: Int)<!> {}
class Outer {
- class A(x: String = "", y: String = "") {
- constructor(x: String, y: String): <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>(x, y)
- constructor(): <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>("", "")
- constructor(): <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>("", "")
+ class A<!CONFLICTING_OVERLOADS!>(x: String = "", y: String = "")<!> {
+ <!CONFLICTING_OVERLOADS!>constructor(x: String, y: String)<!>: <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>(x, y)
+ <!CONFLICTING_OVERLOADS!>constructor()<!>: <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>("", "")
+ <!CONFLICTING_OVERLOADS!>constructor()<!>: <!OVERLOAD_RESOLUTION_AMBIGUITY!>this<!>("", "")
}
class B {
- constructor(x: Int)
+ <!CONFLICTING_OVERLOADS!>constructor(x: Int)<!>
}
- fun B(x: Int) {}
+ <!CONFLICTING_OVERLOADS!>fun B(x: Int)<!> {}
}
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 965afb7..d99dac6 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
@@ -826,6 +826,12 @@
}
@Test
+ @TestMetadata("nestedClassConstructorVsMemberFunctionConflict.kt")
+ public void testNestedClassConstructorVsMemberFunctionConflict() throws Exception {
+ runTest("compiler/testData/diagnostics/tests/nestedClassConstructorVsMemberFunctionConflict.kt");
+ }
+
+ @Test
@TestMetadata("noLibraryProvidersDuplication.kt")
public void testNoLibraryProvidersDuplication() throws Exception {
runTest("compiler/testData/diagnostics/tests/noLibraryProvidersDuplication.kt");