KT-56687: Unify handling of EnumEntries.

`supportsEnumEntries` in `EnumCLassLowering` is not really
needed, but it was left just in case.
Both K1 and K2 ensure the feature is
enabled before they generate IR.

`supportsEnumEntries` is not enough, because the frontend will not
generate `entries` if `kotlin.enums.EnumEntries` is not available
(linking against an outdated stdlib is considered a valid use-case).

From the resolution point of view,
it's OK to resolve into `entries` while
the feature is off, because then K1 reports an error on the call site.

^KT-56687 Fixed
^KT-55614 Fixed
This commit is contained in:
Nikolay Lunyak
2023-02-16 13:06:22 +02:00
committed by Space Team
parent bcfafc601e
commit bb368bd191
14 changed files with 164 additions and 18 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
import org.jetbrains.kotlin.fir.isEnumEntries
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
@@ -38,7 +39,10 @@ class FirClassDeclaredMemberScopeImpl(
if (declaration is FirCallableDeclaration) {
val name = when (declaration) {
is FirConstructor -> SpecialNames.INIT
is FirVariable -> if (declaration.isSynthetic) continue@loop else declaration.name
is FirVariable -> when {
declaration.isSynthetic || declaration.isEnumEntries(klass) && !klass.supportsEnumEntries -> continue@loop
else -> declaration.name
}
is FirSimpleFunction -> declaration.name
else -> continue@loop
}
@@ -48,6 +52,8 @@ class FirClassDeclaredMemberScopeImpl(
result
}
private val FirClass.supportsEnumEntries get() = useSiteSession.enumEntriesSupport.canSynthesizeEnumEntriesFor(this)
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
if (name == SpecialNames.INIT) return
processCallables(name, processor)
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.hasEnumEntries
import org.jetbrains.kotlin.fir.resolve.providers.getRegularClassSymbolByClassId
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.name.StandardClassIds
open class FirEnumEntriesSupport(val session: FirSession) : FirSessionComponent {
protected val isEnumEntriesAvailable by lazy {
session.symbolProvider.getRegularClassSymbolByClassId(StandardClassIds.EnumEntries) != null
}
open fun canSynthesizeEnumEntriesFor(klass: FirClass): Boolean {
return klass.hasEnumEntries && isEnumEntriesAvailable
}
}
class FirJvmEnumEntriesSupport(session: FirSession) : FirEnumEntriesSupport(session) {
// In JVM modules "entries" can be called even on enum compiled without this property.
override fun canSynthesizeEnumEntriesFor(klass: FirClass): Boolean = isEnumEntriesAvailable
}
val FirSession.enumEntriesSupport: FirEnumEntriesSupport by FirSession.sessionComponentAccessor()