From b92f1e20369cd6cc685728e305588bd5ee1e45a5 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 25 May 2023 14:32:23 +0200 Subject: [PATCH] K2: de-prioritize access to Enum.entries properly #KT-57954 Fixed --- .../kotlin/fir/resolve/calls/CandidateFactory.kt | 11 ++++++++--- .../kotlin/fir/resolve/calls/ResolutionStages.kt | 3 --- .../fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt | 3 ++- .../codegen/box/enum/enumEntriesCompatibilityCheck.kt | 1 - .../conflictingPropertyEntriesAndReferenceOn.fir.txt | 6 +++--- .../entries/entriesPropertyAsExtensionClashOn.fir.txt | 2 +- .../entries/entriesPropertyImportedClashOn.fir.txt | 2 +- .../entries/entriesPropertyInCompanionClashOn.fir.txt | 2 +- .../entriesPropertyWithJvmStaticClashOn.fir.txt | 2 +- .../entries/genericEntriesPropertyClashOn.fir.txt | 2 +- .../enum/entries/javaEnumEntriesAmbiguityOn.fir.kt | 10 ++++++---- .../enum/entries/javaEnumEntriesAmbiguityOn.fir.txt | 9 +++++---- .../tests/enum/entries/javaEnumEntriesAmbiguityOn.kt | 10 ++++++---- .../nameShadowingOfExternallyDefinedEntriesOn.fir.kt | 4 ++-- .../nameShadowingOfExternallyDefinedEntriesOn.fir.txt | 4 ++-- 15 files changed, 39 insertions(+), 32 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index be6f61c9b88..d98fcaf06d5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirResolvePhase @@ -15,9 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildErrorProperty import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.* -import org.jetbrains.kotlin.fir.moduleData import org.jetbrains.kotlin.fir.resolve.isIntegerLiteralOrOperatorCall -import org.jetbrains.kotlin.fir.returnExpressions +import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @@ -96,6 +95,12 @@ class CandidateFactory private constructor( // Flag all property references that are resolved from an convention operator call. result.addDiagnostic(PropertyAsOperator) } + if (symbol is FirPropertySymbol) { + val containingClass = symbol.containingClassLookupTag()?.toFirRegularClass(context.session) + if (containingClass != null && symbol.fir.isEnumEntries(containingClass)) { + result.addDiagnostic(LowerPriorityToPreserveCompatibilityDiagnostic) + } + } return result } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index c78887c5d5e..e21b5ab171d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -534,9 +534,6 @@ internal object DiscriminateSynthetics : CheckerStage() { if (candidate.symbol is SyntheticSymbol) { sink.reportDiagnostic(ResolvedWithSynthetic) } - if (candidate.symbol is FirPropertySymbol && candidate.symbol.source?.kind is KtFakeSourceElementKind.EnumGeneratedDeclaration) { - sink.reportDiagnostic(ResolvedWithSynthetic) - } } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt index cbf31a98a20..0041c44fb40 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/Utils.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass +import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.renderer.FirRenderer @@ -255,4 +256,4 @@ fun List.smartPlus(other: List): List = when { } // Source element may be missing if the class came from a library -fun FirVariable.isEnumEntries(containingClass: FirClass) = name == StandardNames.ENUM_ENTRIES && containingClass.isEnumClass +fun FirVariable.isEnumEntries(containingClass: FirClass) = isStatic && name == StandardNames.ENUM_ENTRIES && containingClass.isEnumClass diff --git a/compiler/testData/codegen/box/enum/enumEntriesCompatibilityCheck.kt b/compiler/testData/codegen/box/enum/enumEntriesCompatibilityCheck.kt index 22c3d8d7c63..cf8360a8981 100644 --- a/compiler/testData/codegen/box/enum/enumEntriesCompatibilityCheck.kt +++ b/compiler/testData/codegen/box/enum/enumEntriesCompatibilityCheck.kt @@ -1,6 +1,5 @@ // !LANGUAGE: +EnumEntries // IGNORE_BACKEND: JS, JVM -// IGNORE_BACKEND_K2: JVM_IR, JS_IR, JS_IR_ES6, NATIVE // IGNORE_LIGHT_ANALYSIS // FULL_JDK // WITH_STDLIB diff --git a/compiler/testData/diagnostics/tests/enum/entries/conflictingPropertyEntriesAndReferenceOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/conflictingPropertyEntriesAndReferenceOn.fir.txt index 474fd4ab927..284521e0e38 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/conflictingPropertyEntriesAndReferenceOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/conflictingPropertyEntriesAndReferenceOn.fir.txt @@ -18,8 +18,8 @@ FILE: conflictingPropertyEntriesAndReferenceOn.fir.kt } public final fun test(): R|kotlin/Unit| { - Q|E|::R|/E.entries*s| - lval ref: R|kotlin/reflect/KProperty0>| = Q|E|::R|/E.entries*s| + Q|E|::R|/E.entries| + lval ref: R|kotlin/reflect/KProperty1| = Q|E|::R|/E.entries| lval refType: R|(E) -> kotlin/Int| = Q|E|::R|/E.entries| - lval refTypeWithAnyExpectedType: R|kotlin/Any| = Q|E|::R|/E.entries*s| + lval refTypeWithAnyExpectedType: R|kotlin/Any| = Q|E|::R|/E.entries| } diff --git a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyAsExtensionClashOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyAsExtensionClashOn.fir.txt index e7bc65547b8..c431e7c8c0e 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyAsExtensionClashOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyAsExtensionClashOn.fir.txt @@ -28,7 +28,7 @@ FILE: entriesPropertyAsExtensionClashOn.fir.kt ^ Int(0) } public final fun test(): R|kotlin/Unit| { - Q|pckg/A|.R|pckg/A.entries*s| + Q|pckg/A|.R|pckg/entries| Q|pckg/A.Companion|.R|pckg/entries| R|kotlin/with|(Q|pckg/A|, = with@fun R|pckg/A.Companion|.(): R|kotlin/Int| { this@R|special/anonymous|.R|pckg/entries| diff --git a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyImportedClashOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyImportedClashOn.fir.txt index 5089206581c..95a8a91d6b5 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyImportedClashOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyImportedClashOn.fir.txt @@ -27,7 +27,7 @@ FILE: entriesPropertyImportedClashOn.fir.kt } public final fun test(): R|kotlin/Unit| { - Q|foo/A|.R|foo/A.entries*s| + Q|foo/A|.R|foo/A.Companion.entries| R|kotlin/with|(Q|foo/A|, = with@fun R|foo/A.Companion|.(): R|kotlin/Int| { ^ this@R|special/anonymous|.R|foo/A.Companion.entries| } diff --git a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyInCompanionClashOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyInCompanionClashOn.fir.txt index 9481ac6ab5c..9a823247b95 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyInCompanionClashOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyInCompanionClashOn.fir.txt @@ -25,7 +25,7 @@ FILE: entriesPropertyInCompanionClashOn.fir.kt } public final fun test(): R|kotlin/Unit| { - Q|A|.R|/A.entries*s| + Q|A|.R|/A.Companion.entries| Q|A.Companion|.R|/A.Companion.entries| R|kotlin/with#|>(Q|A|, = with@fun R|A.Companion|.(): { this@R|special/anonymous|.R|/A.Companion.entries| diff --git a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyWithJvmStaticClashOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyWithJvmStaticClashOn.fir.txt index 17d45e47fb7..efe482e6198 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyWithJvmStaticClashOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/entriesPropertyWithJvmStaticClashOn.fir.txt @@ -25,7 +25,7 @@ FILE: entriesPropertyWithJvmStaticClashOn.fir.kt } public final fun test(): R|kotlin/Unit| { - Q|A|.R|/A.entries*s| + Q|A|.R|/A.Companion.entries| R|kotlin/with|(Q|A|, = with@fun R|A.Companion|.(): R|kotlin/Int| { ^ this@R|special/anonymous|.R|/A.Companion.entries| } diff --git a/compiler/testData/diagnostics/tests/enum/entries/genericEntriesPropertyClashOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/genericEntriesPropertyClashOn.fir.txt index 03c1627fc3d..06fa2aabd66 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/genericEntriesPropertyClashOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/genericEntriesPropertyClashOn.fir.txt @@ -28,6 +28,6 @@ FILE: genericEntriesPropertyClashOn.fir.kt ^ Int(0) } public final fun test(): R|kotlin/Unit| { - Q|pckg/A|.R|pckg/A.entries*s| + Q|pckg/A|.R|pckg/entries| Q|pckg/A.Companion|.R|pckg/entries| } diff --git a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.kt b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.kt index 091fd7a03bc..604073d60c0 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.kt @@ -26,9 +26,11 @@ public enum JEnumField { // FILE: test.kt -fun test() { - JEnumEntry.entries - JEnumStaticField.entries +fun test(): String { + val first = JEnumEntry.entries + val second = JEnumStaticField.entries - JEnumField::entries + val third = JEnumField::entries + + return "$first$second$third" } diff --git a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.txt index d9d260e1dd0..d1dd576d590 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.fir.txt @@ -1,6 +1,7 @@ FILE: test.kt - public final fun test(): R|kotlin/Unit| { - Q|JEnumEntry|.R|/JEnumEntry.entries| - Q|JEnumStaticField|.R|/JEnumStaticField.entries*s| - Q|JEnumField|::R|/JEnumField.entries*s| + public final fun test(): R|kotlin/String| { + lval first: R|JEnumEntry| = Q|JEnumEntry|.R|/JEnumEntry.entries| + lval second: R|kotlin/Int| = Q|JEnumStaticField|.R|/JEnumStaticField.entries*s| + lval third: R|kotlin/reflect/KProperty1| = Q|JEnumField|::R|/JEnumField.entries| + ^test (R|/first|, R|/second|, R|/third|) } diff --git a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.kt b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.kt index 8fa4cb1ae41..22cdc603e6d 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.kt +++ b/compiler/testData/diagnostics/tests/enum/entries/javaEnumEntriesAmbiguityOn.kt @@ -26,9 +26,11 @@ public enum JEnumField { // FILE: test.kt -fun test() { - JEnumEntry.entries - JEnumStaticField.entries +fun test(): String { + val first = JEnumEntry.entries + val second = JEnumStaticField.entries - JEnumField::entries + val third = JEnumField::entries + + return "$first$second$third" } diff --git a/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.kt b/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.kt index b3119db94fa..af16bd3a256 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.kt @@ -10,7 +10,7 @@ enum class E { ; fun foo() { - entries.length + entries.length pckg.entries.length } } @@ -21,7 +21,7 @@ class A { class B { fun foo() { - entries.length + entries.length pckg.entries.length } } diff --git a/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.txt b/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.txt index 1fc6c03b925..2a475f30f27 100644 --- a/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.txt +++ b/compiler/testData/diagnostics/tests/enum/entries/nameShadowingOfExternallyDefinedEntriesOn.fir.txt @@ -9,7 +9,7 @@ FILE: nameShadowingOfExternallyDefinedEntriesOn.fir.kt } public final fun foo(): R|kotlin/Unit| { - R|pckg/E.entries*s|.# + R|pckg/entries|.R|kotlin/String.length| Q|pckg|.R|pckg/entries|.R|kotlin/String.length| } @@ -39,7 +39,7 @@ FILE: nameShadowingOfExternallyDefinedEntriesOn.fir.kt } public final fun foo(): R|kotlin/Unit| { - R|pckg/A.E.entries*s|.# + R|pckg/entries|.R|kotlin/String.length| Q|pckg|.R|pckg/entries|.R|kotlin/String.length| }