K2: de-prioritize access to Enum.entries properly #KT-57954 Fixed

This commit is contained in:
Mikhail Glukhikh
2023-05-25 14:32:23 +02:00
committed by Space Team
parent 978d52d05b
commit b92f1e2036
15 changed files with 39 additions and 32 deletions
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.descriptors.ClassKind 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.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase 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.declarations.fullyExpandedClass
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.isIntegerLiteralOrOperatorCall 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.FirScope
import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator import org.jetbrains.kotlin.fir.scopes.impl.originalForWrappedIntegerOperator
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol 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. // Flag all property references that are resolved from an convention operator call.
result.addDiagnostic(PropertyAsOperator) 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 return result
} }
@@ -534,9 +534,6 @@ internal object DiscriminateSynthetics : CheckerStage() {
if (candidate.symbol is SyntheticSymbol) { if (candidate.symbol is SyntheticSymbol) {
sink.reportDiagnostic(ResolvedWithSynthetic) sink.reportDiagnostic(ResolvedWithSynthetic)
} }
if (candidate.symbol is FirPropertySymbol && candidate.symbol.source?.kind is KtFakeSourceElementKind.EnumGeneratedDeclaration) {
sink.reportDiagnostic(ResolvedWithSynthetic)
}
} }
} }
@@ -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.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass 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.FirBlock
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.renderer.FirRenderer import org.jetbrains.kotlin.fir.renderer.FirRenderer
@@ -255,4 +256,4 @@ fun <T> List<T>.smartPlus(other: List<T>): List<T> = when {
} }
// Source element may be missing if the class came from a library // 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
@@ -1,6 +1,5 @@
// !LANGUAGE: +EnumEntries // !LANGUAGE: +EnumEntries
// IGNORE_BACKEND: JS, JVM // IGNORE_BACKEND: JS, JVM
// IGNORE_BACKEND_K2: JVM_IR, JS_IR, JS_IR_ES6, NATIVE
// IGNORE_LIGHT_ANALYSIS // IGNORE_LIGHT_ANALYSIS
// FULL_JDK // FULL_JDK
// WITH_STDLIB // WITH_STDLIB
@@ -18,8 +18,8 @@ FILE: conflictingPropertyEntriesAndReferenceOn.fir.kt
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
Q|E|::R|/E.entries*s| Q|E|::R|/E.entries|
lval ref: R|kotlin/reflect/KProperty0<kotlin/enums/EnumEntries<E>>| = Q|E|::R|/E.entries*s| lval ref: R|kotlin/reflect/KProperty1<E, kotlin/Int>| = Q|E|::R|/E.entries|
lval refType: R|(E) -> kotlin/Int| = 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|
} }
@@ -28,7 +28,7 @@ FILE: entriesPropertyAsExtensionClashOn.fir.kt
^ Int(0) ^ Int(0)
} }
public final fun test(): R|kotlin/Unit| { 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| Q|pckg/A.Companion|.R|pckg/entries|
R|kotlin/with|<R|pckg/A.Companion|, R|kotlin/Int|>(Q|pckg/A|, <L> = with@fun R|pckg/A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> { R|kotlin/with|<R|pckg/A.Companion|, R|kotlin/Int|>(Q|pckg/A|, <L> = with@fun R|pckg/A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|pckg/entries| this@R|special/anonymous|.R|pckg/entries|
@@ -27,7 +27,7 @@ FILE: entriesPropertyImportedClashOn.fir.kt
} }
public final fun test(): R|kotlin/Unit| { 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|<R|foo/A.Companion|, R|kotlin/Int|>(Q|foo/A|, <L> = with@fun R|foo/A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> { R|kotlin/with|<R|foo/A.Companion|, R|kotlin/Int|>(Q|foo/A|, <L> = with@fun R|foo/A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> {
^ this@R|special/anonymous|.R|foo/A.Companion.entries| ^ this@R|special/anonymous|.R|foo/A.Companion.entries|
} }
@@ -25,7 +25,7 @@ FILE: entriesPropertyInCompanionClashOn.fir.kt
} }
public final fun test(): R|kotlin/Unit| { 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| Q|A.Companion|.R|/A.Companion.entries|
R|kotlin/with<Inapplicable(INAPPLICABLE): kotlin/with>#|<R|A.Companion|, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(Q|A|, <L> = with@fun R|A.Companion|.<anonymous>(): <ERROR TYPE REF: Cannot infer argument for type parameter R> <inline=Inline, kind=EXACTLY_ONCE> { R|kotlin/with<Inapplicable(INAPPLICABLE): kotlin/with>#|<R|A.Companion|, <ERROR TYPE REF: Cannot infer argument for type parameter R>>(Q|A|, <L> = with@fun R|A.Companion|.<anonymous>(): <ERROR TYPE REF: Cannot infer argument for type parameter R> <inline=Inline, kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|/A.Companion.entries| this@R|special/anonymous|.R|/A.Companion.entries|
@@ -25,7 +25,7 @@ FILE: entriesPropertyWithJvmStaticClashOn.fir.kt
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
Q|A|.R|/A.entries*s| Q|A|.R|/A.Companion.entries|
R|kotlin/with|<R|A.Companion|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> { R|kotlin/with|<R|A.Companion|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A.Companion|.<anonymous>(): R|kotlin/Int| <inline=Inline, kind=EXACTLY_ONCE> {
^ this@R|special/anonymous|.R|/A.Companion.entries| ^ this@R|special/anonymous|.R|/A.Companion.entries|
} }
@@ -28,6 +28,6 @@ FILE: genericEntriesPropertyClashOn.fir.kt
^ Int(0) ^ Int(0)
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
Q|pckg/A|.R|pckg/A.entries*s| Q|pckg/A|.R|pckg/entries|<R|pckg/A.Companion|>
Q|pckg/A.Companion|.R|pckg/entries|<R|pckg/A.Companion|> Q|pckg/A.Companion|.R|pckg/entries|<R|pckg/A.Companion|>
} }
@@ -26,9 +26,11 @@ public enum JEnumField {
// FILE: test.kt // FILE: test.kt
fun test() { fun test(): String {
JEnumEntry.entries val first = JEnumEntry.entries
JEnumStaticField.entries val second = JEnumStaticField.entries
JEnumField::entries val third = JEnumField::entries
return "$first$second$third"
} }
@@ -1,6 +1,7 @@
FILE: test.kt FILE: test.kt
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/String| {
Q|JEnumEntry|.R|/JEnumEntry.entries| lval first: R|JEnumEntry| = Q|JEnumEntry|.R|/JEnumEntry.entries|
Q|JEnumStaticField|.R|/JEnumStaticField.entries*s| lval second: R|kotlin/Int| = Q|JEnumStaticField|.R|/JEnumStaticField.entries*s|
Q|JEnumField|::R|/JEnumField.entries*s| lval third: R|kotlin/reflect/KProperty1<JEnumField, kotlin/Int>| = Q|JEnumField|::R|/JEnumField.entries|
^test <strcat>(R|<local>/first|, R|<local>/second|, R|<local>/third|)
} }
@@ -26,9 +26,11 @@ public enum JEnumField {
// FILE: test.kt // FILE: test.kt
fun test() { fun test(): String {
JEnumEntry.entries val first = JEnumEntry.entries
JEnumStaticField.entries val second = JEnumStaticField.entries
JEnumField::<!DEPRECATED_ACCESS_TO_ENUM_ENTRY_PROPERTY_AS_REFERENCE!>entries<!> val third = JEnumField::<!DEPRECATED_ACCESS_TO_ENUM_ENTRY_PROPERTY_AS_REFERENCE!>entries<!>
return "$first$second$third"
} }
@@ -10,7 +10,7 @@ enum class E {
; ;
fun foo() { fun foo() {
entries.<!UNRESOLVED_REFERENCE!>length<!> entries.length
pckg.entries.length pckg.entries.length
} }
} }
@@ -21,7 +21,7 @@ class A {
class B { class B {
fun foo() { fun foo() {
entries.<!UNRESOLVED_REFERENCE!>length<!> entries.length
pckg.entries.length pckg.entries.length
} }
} }
@@ -9,7 +9,7 @@ FILE: nameShadowingOfExternallyDefinedEntriesOn.fir.kt
} }
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
R|pckg/E.entries*s|.<Unresolved name: length># R|pckg/entries|.R|kotlin/String.length|
Q|pckg|.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| { public final fun foo(): R|kotlin/Unit| {
R|pckg/A.E.entries*s|.<Unresolved name: length># R|pckg/entries|.R|kotlin/String.length|
Q|pckg|.R|pckg/entries|.R|kotlin/String.length| Q|pckg|.R|pckg/entries|.R|kotlin/String.length|
} }