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
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
}
@@ -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)
}
}
}
@@ -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 <T> List<T>.smartPlus(other: List<T>): List<T> = 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
@@ -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
@@ -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<kotlin/enums/EnumEntries<E>>| = Q|E|::R|/E.entries*s|
Q|E|::R|/E.entries|
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 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)
}
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|<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|
@@ -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|<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|
}
@@ -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<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|
@@ -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|<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|
}
@@ -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|<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
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"
}
@@ -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<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
fun test() {
JEnumEntry.entries
JEnumStaticField.entries
fun test(): String {
val first = JEnumEntry.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() {
entries.<!UNRESOLVED_REFERENCE!>length<!>
entries.length
pckg.entries.length
}
}
@@ -21,7 +21,7 @@ class A {
class B {
fun foo() {
entries.<!UNRESOLVED_REFERENCE!>length<!>
entries.length
pckg.entries.length
}
}
@@ -9,7 +9,7 @@ FILE: nameShadowingOfExternallyDefinedEntriesOn.fir.kt
}
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|
}
@@ -39,7 +39,7 @@ FILE: nameShadowingOfExternallyDefinedEntriesOn.fir.kt
}
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|
}