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 e47e67baf7c..81bdcd621bb 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 @@ -26478,6 +26478,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); } + @Test + @TestMetadata("companionPropertyAndTypeParameter.kt") + public void testCompanionPropertyAndTypeParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt"); + } + @Test @TestMetadata("constructorVsCompanion.kt") public void testConstructorVsCompanion() 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 77073b86939..7489a17ea96 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 @@ -26478,6 +26478,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); } + @Test + @TestMetadata("companionPropertyAndTypeParameter.kt") + public void testCompanionPropertyAndTypeParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt"); + } + @Test @TestMetadata("constructorVsCompanion.kt") public void testConstructorVsCompanion() 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 76ef3b02281..d9fb77d5319 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 @@ -26478,6 +26478,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); } + @Test + @TestMetadata("companionPropertyAndTypeParameter.kt") + public void testCompanionPropertyAndTypeParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt"); + } + @Test @TestMetadata("constructorVsCompanion.kt") public void testConstructorVsCompanion() 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 f39f37105fa..0707a8c2ee3 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 @@ -26490,6 +26490,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); } + @Test + @TestMetadata("companionPropertyAndTypeParameter.kt") + public void testCompanionPropertyAndTypeParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt"); + } + @Test @TestMetadata("constructorVsCompanion.kt") public void testConstructorVsCompanion() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 159da702cbb..6a340de3c59 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -424,36 +424,45 @@ class BodyResolveContext( val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type) val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers) - val statics = base - .addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope) - .addNonLocalScopeIfNotNull(towerElementsForClass.staticScope) - val companionReceiver = towerElementsForClass.companionReceiver - val staticsAndCompanion = if (companionReceiver == null) statics else base - .addReceiver(null, companionReceiver) - .addNonLocalScopeIfNotNull(towerElementsForClass.companionStaticScope) - .addNonLocalScopeIfNotNull(towerElementsForClass.staticScope) + val statics = base + .addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope) + + val staticsAndCompanion = when (val companionReceiver = towerElementsForClass.companionReceiver) { + null -> statics + else -> base + .addReceiver(null, companionReceiver) + .addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope) + } val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope() - val forMembersResolution = + // Type parameters must be inserted before all of staticsAndCompanion. + // Optimization: Only rebuild all of staticsAndCompanion that's below type parameters if there are any type parameters. + // Otherwise, reuse staticsAndCompanion. + val forConstructorHeader = if (typeParameterScope != null) { + towerDataContext + .addNonLocalScope(typeParameterScope) + .addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers) + .run { towerElementsForClass.companionReceiver?.let { addReceiver(null, it) } ?: this } + .addNonLocalScopesIfNotNull(towerElementsForClass.companionStaticScope, towerElementsForClass.staticScope) + } else { staticsAndCompanion - .addReceiver(labelName, towerElementsForClass.thisReceiver) - .addContextReceiverGroup(towerElementsForClass.contextReceivers) - .addNonLocalScopeIfNotNull(typeParameterScope) + } - val scopeForConstructorHeader = - staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope) + val forMembersResolution = forConstructorHeader + .addReceiver(labelName, towerElementsForClass.thisReceiver) + .addContextReceiverGroup(towerElementsForClass.contextReceivers) /* * Scope for enum entries is equal to initial scope for constructor header * - * The only difference that we add value parameters to local scope for constructors + * The only difference is that we add value parameters to local scope for constructors * and should not do this for enum entries */ @Suppress("UnnecessaryVariable") - val scopeForEnumEntries = scopeForConstructorHeader + val scopeForEnumEntries = forConstructorHeader val newTowerDataContextForStaticNestedClasses = if ((owner as? FirRegularClass)?.classKind?.isSingleton == true) @@ -470,14 +479,14 @@ class BodyResolveContext( } val newContexts = FirRegularTowerDataContexts( - forMembersResolution, + regular = forMembersResolution, forClassHeaderAnnotations = base, - newTowerDataContextForStaticNestedClasses, - statics, - scopeForConstructorHeader, - scopeForEnumEntries, - primaryConstructorPureParametersScope, - primaryConstructorAllParametersScope + forNestedClasses = newTowerDataContextForStaticNestedClasses, + forCompanionObject = statics, + forConstructorHeaders = forConstructorHeader, + forEnumEntries = scopeForEnumEntries, + primaryConstructorPureParametersScope = primaryConstructorPureParametersScope, + primaryConstructorAllParametersScope = primaryConstructorAllParametersScope ) return withTowerDataContexts(newContexts) { diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ImplicitReceiverUtils.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ImplicitReceiverUtils.kt index 352b68d2405..0f8a4f011be 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ImplicitReceiverUtils.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ImplicitReceiverUtils.kt @@ -202,6 +202,21 @@ class FirTowerDataContext private constructor( return addNonLocalScope(scope) } + // Optimized version for two parameters + fun addNonLocalScopesIfNotNull(scope1: FirScope?, scope2: FirScope?): FirTowerDataContext { + return if (scope1 != null) { + if (scope2 != null) { + addNonLocalScopeElements(listOf(scope1.asTowerDataElement(isLocal = false), scope2.asTowerDataElement(isLocal = false))) + } else { + addNonLocalScope(scope1) + } + } else if (scope2 != null) { + addNonLocalScope(scope2) + } else { + this + } + } + fun addNonLocalScope(scope: FirScope): FirTowerDataContext { val element = scope.asTowerDataElement(isLocal = false) return FirTowerDataContext( @@ -212,6 +227,15 @@ class FirTowerDataContext private constructor( ) } + private fun addNonLocalScopeElements(elements: List): FirTowerDataContext { + return FirTowerDataContext( + towerDataElements.addAll(elements), + implicitReceiverStack, + localScopes, + nonLocalTowerDataElements.addAll(elements) + ) + } + fun createSnapshot(): FirTowerDataContext { return FirTowerDataContext( towerDataElements.map(FirTowerDataElement::createSnapshot).toPersistentList(), diff --git a/compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt b/compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt new file mode 100644 index 00000000000..a10a08391e3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt @@ -0,0 +1,54 @@ +// FIR_IDENTICAL +// DIAGNOSTICS: -UNUSED_VARIABLE + +open class Base(any: Any) { + companion object { + val test = 42L + } +} + +class C1 : Base(test) { + companion object { + val test = 12 + val some: Int = test + } + + val test = "" + val some: String = test + + fun f() { + val test = 1.0 + val some: Double = test + } +} + +class C2 : Base(test) { + companion object { + val test = 12 + val some: Int = test + } + + val some: Int = test + + fun f() { + val test = 1.0 + val some: Double = test + } +} + +class C3 : Base(test) { + val some: Long = test + + fun f() { + val test = 1.0 + val some: Double = test + } +} + +class C4 { + val some = test + + fun f() { + val some = test + } +} diff --git a/compiler/testData/loadJava/compiledKotlin/class/ClassMemberConflict.kt b/compiler/testData/loadJava/compiledKotlin/class/ClassMemberConflict.kt index 6095cab77fd..c70caccdbb7 100644 --- a/compiler/testData/loadJava/compiledKotlin/class/ClassMemberConflict.kt +++ b/compiler/testData/loadJava/compiledKotlin/class/ClassMemberConflict.kt @@ -1,6 +1,4 @@ //ALLOW_AST_ACCESS -// IGNORE_FIR_METADATA_LOADING_K2 -// Ignore reason: KT-58028 package test class ConstructorTypeParamClassObjectTypeConflict { 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 81044d6df0d..c6448f0446e 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 @@ -27262,6 +27262,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/resolve/capturedTypesInLambdaParameter.kt"); } + @Test + @TestMetadata("companionPropertyAndTypeParameter.kt") + public void testCompanionPropertyAndTypeParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/resolve/companionPropertyAndTypeParameter.kt"); + } + @Test @TestMetadata("constructorVsCompanion.kt") public void testConstructorVsCompanion() throws Exception {