[FE] Completely replace FunctionClassKind with FunctionalTypeKind

FunctionalTypeKind can be used in FE 1.0 too, so there is no need to
  keep both classes. Also, removal of FunctionClassKind simplifies work
  with FunctionalTypeKind in common code, like Analysis Api
This commit is contained in:
Dmitriy Novozhilov
2023-01-20 14:54:33 +02:00
committed by Space Team
parent 87a9103cc6
commit 67aa80562d
38 changed files with 242 additions and 262 deletions
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils
import org.jetbrains.kotlin.name.SpecialNames
@@ -31,7 +31,7 @@ internal class KtFe10TypeInfoProvider(
return JavaSingleAbstractMethodUtils.isSamType(type.fe10Type)
}
override fun getFunctionClassKind(type: KtType): FunctionClassKind? {
override fun getFunctionClassKind(type: KtType): FunctionalTypeKind? {
require(type is KtFe10Type)
return type.fe10Type.constructor.declarationDescriptor?.getFunctionalClassKind()
}
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.isSuspendType
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.SimpleType
@@ -116,4 +118,4 @@ internal class KtFe10FunctionalType(
override val ownTypeArguments: List<KtTypeProjection>
get() = withValidityAssertion { fe10Type.arguments.map { it.toKtTypeProjection(analysisContext) } }
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.api.descriptors.utils
import org.jetbrains.kotlin.builtins.FAKE_CONTINUATION_CLASS_DESCRIPTOR
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.isSuspendType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.StandardClassIds
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolEntry
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl
@@ -488,8 +487,7 @@ internal class KtSymbolByFirBuilder constructor(
}
private fun hasFunctionalClassId(coneType: ConeClassLikeTypeImpl): Boolean {
val classId = coneType.classId ?: return false
return FunctionClassKind.byClassNamePrefix(classId.packageFqName, classId.relativeClassName.asString()) != null
return coneType.isSomeFunctionalType(analysisSession.firResolveSession.useSiteFirSession)
}
fun buildKtType(coneType: FirTypeRef): KtType {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.analysis.api.fir.types.KtFirType
import org.jetbrains.kotlin.analysis.api.fir.types.PublicTypeApproximator
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.resolve.FirSamResolver
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.*
@@ -31,18 +31,9 @@ internal class KtFirTypeInfoProvider(
return samResolver.isSamType(coneType)
}
override fun getFunctionClassKind(type: KtType): FunctionClassKind? {
val coneType = (type as KtFirType).coneType
return when (coneType.functionalTypeKind(analysisSession.useSiteSession)) {
ConeFunctionalTypeKind.Function -> FunctionClassKind.Function
ConeFunctionalTypeKind.KFunction -> FunctionClassKind.KFunction
ConeFunctionalTypeKind.SuspendFunction -> FunctionClassKind.SuspendFunction
ConeFunctionalTypeKind.KSuspendFunction -> FunctionClassKind.KSuspendFunction
null -> null
else -> null // TODO: consider handling of custom functional type kinds from plugins
}
override fun getFunctionClassKind(type: KtType): FunctionalTypeKind? {
return (type as KtFirType).coneType.functionalTypeKind(analysisSession.useSiteSession)
}
override fun canBeNull(type: KtType): Boolean = (type as KtFirType).coneType.canBeNull
override fun isDenotable(type: KtType): Boolean {
@@ -23,7 +23,7 @@ abstract class AbstractFunctionClassKindTest : AbstractAnalysisApiSingleFileTes
val (type, functionClassKind) = executeOnPooledThreadInReadAction {
analyseForTest(expressionAtCaret) {
val functionType = expressionAtCaret.getExpectedType()
functionType?.render(position = Variance.INVARIANT) to functionType?.functionClassKind
functionType?.render(position = Variance.INVARIANT) to functionType?.functionalTypeKind
}
}
val actual = buildString {
@@ -13,12 +13,12 @@ import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.name.ClassId
public abstract class KtTypeInfoProvider : KtAnalysisSessionComponent() {
public abstract fun isFunctionalInterfaceType(type: KtType): Boolean
public abstract fun getFunctionClassKind(type: KtType): FunctionClassKind?
public abstract fun getFunctionClassKind(type: KtType): FunctionalTypeKind?
public abstract fun canBeNull(type: KtType): Boolean
public abstract fun isDenotable(type: KtType): Boolean
public abstract fun isArrayOrPrimitiveArray(type: KtType): Boolean
@@ -41,22 +41,22 @@ public interface KtTypeInfoProviderMixIn : KtAnalysisSessionMixIn {
get() = withValidityAssertion { analysisSession.typeInfoProvider.isFunctionalInterfaceType(this) }
/**
* Returns [FunctionClassKind] of the given [KtType]
* Returns [FunctionalTypeKind] of the given [KtType]
*/
public val KtType.functionClassKind: FunctionClassKind?
public val KtType.functionalTypeKind: FunctionalTypeKind?
get() = withValidityAssertion { analysisSession.typeInfoProvider.getFunctionClassKind(this) }
public val KtType.isFunctionType: Boolean
get() = withValidityAssertion { functionClassKind == FunctionClassKind.Function }
get() = withValidityAssertion { functionalTypeKind == FunctionalTypeKind.Function }
public val KtType.isKFunctionType: Boolean
get() = withValidityAssertion { functionClassKind == FunctionClassKind.KFunction }
get() = withValidityAssertion { functionalTypeKind == FunctionalTypeKind.KFunction }
public val KtType.isSuspendFunctionType: Boolean
get() = withValidityAssertion { functionClassKind == FunctionClassKind.SuspendFunction }
get() = withValidityAssertion { functionalTypeKind == FunctionalTypeKind.SuspendFunction }
public val KtType.isKSuspendFunctionType: Boolean
get() = withValidityAssertion { functionClassKind == FunctionClassKind.KSuspendFunction }
get() = withValidityAssertion { functionalTypeKind == FunctionalTypeKind.KSuspendFunction }
/**
* Returns true if a public value of this type can potentially be null. This means this type is not a subtype of [Any]. However, it does not
@@ -1,3 +1,3 @@
expression: xy
expected type: (T) -> R
functionClassKind: Function
functionClassKind: kotlin.FunctionN
@@ -1,3 +1,3 @@
expression: xy
expected type: kotlin.reflect.KFunction1<kotlin.Int, kotlin.String>
functionClassKind: KFunction
functionClassKind: kotlin.reflect.KFunctionN
@@ -1,3 +1,3 @@
expression: xy
expected type: kotlin.reflect.KSuspendFunction0<kotlin.Unit>
functionClassKind: KSuspendFunction
functionClassKind: kotlin.reflect.KSuspendFunctionN
@@ -1,3 +1,3 @@
expression: xy
expected type: suspend () -> kotlin.Unit
functionClassKind: SuspendFunction
functionClassKind: kotlin.coroutines.SuspendFunctionN
@@ -9,7 +9,7 @@ import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.isStaticMethod
@@ -342,8 +342,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
if (classDescriptor is FunctionClassDescriptor) {
if (classDescriptor.hasBigArity ||
classDescriptor.functionKind == FunctionClassKind.KFunction ||
classDescriptor.functionKind == FunctionClassKind.KSuspendFunction
classDescriptor.functionKind == FunctionalTypeKind.KFunction ||
classDescriptor.functionKind == FunctionalTypeKind.KSuspendFunction
) {
// kotlin.reflect.KFunction{n}<P1, ..., Pn, R> is mapped to kotlin.reflect.KFunction<R> (for all n), and
// kotlin.Function{n}<P1, ..., Pn, R> is mapped to kotlin.jvm.functions.FunctionN<R> (for n > 22).
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.types.*
open class ConeTypeRenderer {
@@ -14,7 +15,7 @@ open class ConeTypeRenderer {
open fun renderAsPossibleFunctionType(
type: ConeKotlinType,
functionalClassKindExtractor: (ConeKotlinType) -> ConeFunctionalTypeKind?,
functionalClassKindExtractor: (ConeKotlinType) -> FunctionalTypeKind?,
renderType: ConeTypeProjection.() -> Unit = { render() }
) {
val kind = functionalClassKindExtractor(type)
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.fir.types.ConeFunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeProjection
@@ -19,7 +19,7 @@ class ConeTypeRendererForDebugging() : ConeTypeRenderer() {
override fun renderAsPossibleFunctionType(
type: ConeKotlinType,
functionalClassKindExtractor: (ConeKotlinType) -> ConeFunctionalTypeKind?,
functionalClassKindExtractor: (ConeKotlinType) -> FunctionalTypeKind?,
renderType: ConeTypeProjection.() -> Unit
) {
builder.append("R|")
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.fir.deserialization
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.computeTypeAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
@@ -202,7 +202,7 @@ class FirTypeDeserializer(
val suspendReturnType = continuationType.typeArguments.single() as ConeKotlinTypeProjection
val valueParameters = arguments.dropLast(2)
val kind = FunctionClassKind.SuspendFunction
val kind = FunctionalTypeKind.SuspendFunction
return ConeClassLikeTypeImpl(
ClassId(kind.packageFqName, kind.numberedClassName(valueParameters.size)).toLookupTag(),
(valueParameters + suspendReturnType).toTypedArray(),
@@ -222,7 +222,7 @@ class FirTypeDeserializer(
1 -> {
val arity = arguments.size - 1
if (arity >= 0) {
val kind = FunctionClassKind.SuspendFunction
val kind = FunctionalTypeKind.SuspendFunction
ConeClassLikeTypeImpl(
ClassId(kind.packageFqName, kind.numberedClassName(arity)).toLookupTag(),
arguments,
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.languageVersionSettings
@@ -27,8 +27,8 @@ class TypeApproximatorForMetadataSerializer(session: FirSession) :
fun ConeKotlinType.suspendFunctionTypeToFunctionTypeWithContinuation(session: FirSession, continuationClassId: ClassId): ConeClassLikeType {
require(this.isSuspendFunctionType(session))
val kind =
if (isReflectFunctionalType(session)) FunctionClassKind.KFunction
else FunctionClassKind.Function
if (isReflectFunctionalType(session)) FunctionalTypeKind.KFunction
else FunctionalTypeKind.Function
val fullyExpandedType = type.fullyExpandedType(session)
val typeArguments = fullyExpandedType.typeArguments
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size))
@@ -5,6 +5,9 @@
package org.jetbrains.kotlin.fir.resolve.providers.impl
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.isBuiltin
import org.jetbrains.kotlin.builtins.functions.isSuspendType
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Modality
@@ -43,7 +46,7 @@ class FirExtensionSyntheticFunctionalInterfaceProvider(
moduleData: FirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider
) : FirSyntheticFunctionalInterfaceProviderBase(session, moduleData, kotlinScopeProvider) {
override fun ConeFunctionalTypeKind.isAcceptable(): Boolean {
override fun FunctionalTypeKind.isAcceptable(): Boolean {
return !this.isBuiltin
}
}
@@ -56,7 +59,7 @@ class FirBuiltinSyntheticFunctionalInterfaceProvider(
moduleData: FirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider
) : FirSyntheticFunctionalInterfaceProviderBase(session, moduleData, kotlinScopeProvider) {
override fun ConeFunctionalTypeKind.isAcceptable(): Boolean {
override fun FunctionalTypeKind.isAcceptable(): Boolean {
return this.isBuiltin
}
}
@@ -100,7 +103,7 @@ abstract class FirSyntheticFunctionalInterfaceProviderBase(
private val cache = moduleData.session.firCachesFactory.createCache(::createSyntheticFunctionalInterface)
protected abstract fun ConeFunctionalTypeKind.isAcceptable(): Boolean
protected abstract fun FunctionalTypeKind.isAcceptable(): Boolean
private fun createSyntheticFunctionalInterface(classId: ClassId): FirRegularClassSymbol? {
return with(classId) {
@@ -172,15 +175,13 @@ abstract class FirSyntheticFunctionalInterfaceProviderBase(
isInline = false
isTailRec = false
isExternal = false
isSuspend =
kind == ConeFunctionalTypeKind.SuspendFunction ||
kind == ConeFunctionalTypeKind.KSuspendFunction
isSuspend = kind.isSuspendType
}
val typeArguments = typeParameters.map {
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false).toFirResolvedTypeRef()
}
fun createSuperType(kind: ConeFunctionalTypeKind): FirResolvedTypeRef {
fun createSuperType(kind: FunctionalTypeKind): FirResolvedTypeRef {
return kind.classId(arity).toLookupTag()
.constructClassType(typeArguments.map { it.type }.toTypedArray(), isNullable = false)
.toFirResolvedTypeRef()
@@ -241,5 +242,5 @@ abstract class FirSyntheticFunctionalInterfaceProviderBase(
}
}
private fun ConeFunctionalTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
private fun FunctionalTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
}
@@ -5,50 +5,39 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.extensions.FirFunctionalTypeKindExtension
import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.functionalTypeKindExtensions
import org.jetbrains.kotlin.name.FqName
class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeKindService() {
private val knownKindsByPackageFqName = buildList {
add(ConeFunctionalTypeKind.Function)
add(ConeFunctionalTypeKind.SuspendFunction)
add(ConeFunctionalTypeKind.KFunction)
add(ConeFunctionalTypeKind.KSuspendFunction)
override val extractor: FunctionalTypeKindExtractor = run {
val kinds = buildList {
add(FunctionalTypeKind.Function)
add(FunctionalTypeKind.SuspendFunction)
add(FunctionalTypeKind.KFunction)
add(FunctionalTypeKind.KSuspendFunction)
val registrar = object : FirFunctionalTypeKindExtension.FunctionalTypeKindRegistrar {
override fun registerKind(nonReflectKind: ConeFunctionalTypeKind, reflectKind: ConeFunctionalTypeKind) {
require(nonReflectKind.reflectKind() == reflectKind)
require(reflectKind.nonReflectKind() == nonReflectKind)
add(nonReflectKind)
add(reflectKind)
val registrar = object : FirFunctionalTypeKindExtension.FunctionalTypeKindRegistrar {
override fun registerKind(nonReflectKind: FunctionalTypeKind, reflectKind: FunctionalTypeKind) {
require(nonReflectKind.reflectKind() == reflectKind)
require(reflectKind.nonReflectKind() == nonReflectKind)
add(nonReflectKind)
add(reflectKind)
}
}
for (extension in session.extensionService.functionalTypeKindExtensions) {
with(extension) { registrar.registerKinds() }
}
}.also { kinds ->
val allNames = kinds.map { "${it.packageFqName}.${it.classNamePrefix}" }
require(allNames.distinct() == allNames) {
"There are clashing functional type kinds: $allNames"
}
}
for (extension in session.extensionService.functionalTypeKindExtensions) {
with(extension) { registrar.registerKinds() }
}
}.also { kinds ->
val allNames = kinds.map { "${it.packageFqName}.${it.classNamePrefix}" }
require(allNames.distinct() == allNames) {
"There are clashing functional type kinds: $allNames"
}
}.groupBy { it.packageFqName }
override fun getKindByClassNamePrefix(packageFqName: FqName, className: String): ConeFunctionalTypeKind? {
val kinds = knownKindsByPackageFqName[packageFqName] ?: return null
for (kind in kinds) {
if (!className.startsWith(kind.classNamePrefix)) continue
if (!FunctionClassKind.hasArityAtTheEnd(kind.classNamePrefix, className)) continue
return kind
}
return null
}
override fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
return packageFqName in knownKindsByPackageFqName
FunctionalTypeKindExtractor(kinds)
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
@@ -27,12 +28,12 @@ import org.jetbrains.kotlin.utils.addToStdlib.runUnless
// ---------------------------------------------- is type is a functional type ----------------------------------------------
fun ConeKotlinType.functionalTypeKind(session: FirSession): ConeFunctionalTypeKind? {
fun ConeKotlinType.functionalTypeKind(session: FirSession): FunctionalTypeKind? {
if (this !is ConeClassLikeType) return null
return fullyExpandedType(session).lookupTag.functionalTypeKind(session)
}
private fun ConeClassLikeLookupTag.functionalTypeKind(session: FirSession): ConeFunctionalTypeKind? {
private fun ConeClassLikeLookupTag.functionalTypeKind(session: FirSession): FunctionalTypeKind? {
val classId = classId
return session.functionalTypeService.getKindByClassNamePrefix(classId.packageFqName, classId.shortClassName.asString())
}
@@ -40,7 +41,7 @@ private fun ConeClassLikeLookupTag.functionalTypeKind(session: FirSession): Cone
private inline fun ConeKotlinType.isFunctionalTypeWithPredicate(
session: FirSession,
errorOnNotFunctionalType: Boolean = false,
predicate: (ConeFunctionalTypeKind) -> Boolean
predicate: (FunctionalTypeKind) -> Boolean
): Boolean {
val kind = functionalTypeKind(session)
?: if (errorOnNotFunctionalType) error("$this is not a functional type") else return false
@@ -49,7 +50,7 @@ private inline fun ConeKotlinType.isFunctionalTypeWithPredicate(
// Function
fun ConeKotlinType.isSimpleFunctionType(session: FirSession): Boolean {
return isFunctionalTypeWithPredicate(session) { it == ConeFunctionalTypeKind.Function }
return isFunctionalTypeWithPredicate(session) { it == FunctionalTypeKind.Function }
}
// Function, SuspendFunction, [Custom]Function
@@ -60,7 +61,7 @@ fun ConeKotlinType.isNonReflectFunctionalType(session: FirSession): Boolean {
// SuspendFunction, KSuspendFunction
fun ConeKotlinType.isSuspendFunctionType(session: FirSession): Boolean {
return isFunctionalTypeWithPredicate(session) {
it == ConeFunctionalTypeKind.SuspendFunction || it == ConeFunctionalTypeKind.KSuspendFunction
it == FunctionalTypeKind.SuspendFunction || it == FunctionalTypeKind.KSuspendFunction
}
}
@@ -82,7 +83,7 @@ fun ConeClassLikeLookupTag.isSomeFunctionalType(session: FirSession): Boolean {
// Function, KFunction
private fun ConeKotlinType.isSimpleFunctionalType(session: FirSession, errorOnNotFunctionalType: Boolean): Boolean {
return isFunctionalTypeWithPredicate(session, errorOnNotFunctionalType) {
it == ConeFunctionalTypeKind.Function || it == ConeFunctionalTypeKind.KFunction
it == FunctionalTypeKind.Function || it == FunctionalTypeKind.KFunction
}
}
@@ -99,11 +100,11 @@ private fun ConeKotlinType.isNotSimpleFunctionalType(session: FirSession): Boole
*/
fun ConeKotlinType.customFunctionalTypeToSimpleFunctionalType(session: FirSession): ConeClassLikeType {
val kind = functionalTypeKind(session)
require(kind != null && kind != ConeFunctionalTypeKind.Function && kind != ConeFunctionalTypeKind.KFunction)
require(kind != null && kind != FunctionalTypeKind.Function && kind != FunctionalTypeKind.KFunction)
val newKind = if (kind.isReflectType) {
ConeFunctionalTypeKind.KFunction
FunctionalTypeKind.KFunction
} else {
ConeFunctionalTypeKind.Function
FunctionalTypeKind.Function
}
return createFunctionalTypeWithNewKind(newKind)
}
@@ -119,7 +120,7 @@ fun ConeKotlinType.reflectFunctionalTypeToNonReflectFunctionalType(session: FirS
return createFunctionalTypeWithNewKind(kind.nonReflectKind())
}
private fun ConeKotlinType.createFunctionalTypeWithNewKind(kind: ConeFunctionalTypeKind): ConeClassLikeType {
private fun ConeKotlinType.createFunctionalTypeWithNewKind(kind: FunctionalTypeKind): ConeClassLikeType {
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size - 1))
return functionalTypeId.toLookupTag().constructClassType(typeArguments, isNullable = false, attributes = attributes)
}
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.resolve
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
@@ -143,9 +143,9 @@ fun createFunctionalType(
}
val kind = if (isSuspend) {
if (isKFunctionType) FunctionClassKind.KSuspendFunction else FunctionClassKind.SuspendFunction
if (isKFunctionType) FunctionalTypeKind.KSuspendFunction else FunctionalTypeKind.SuspendFunction
} else {
if (isKFunctionType) FunctionClassKind.KFunction else FunctionClassKind.Function
if (isKFunctionType) FunctionalTypeKind.KFunction else FunctionalTypeKind.Function
}
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(receiverAndParameterTypes.size - 1))
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -575,7 +575,7 @@ class FirCallCompletionResultsWriterTransformer(
null,
functionType.typeArguments.last() as ConeKotlinType,
functionType.classId?.relativeClassName?.asString()
?.startsWith(FunctionClassKind.SuspendFunction.classNamePrefix) == true
?.startsWith(FunctionalTypeKind.SuspendFunction.classNamePrefix) == true
)
}
}
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.fir.extensions
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.types.ConeFunctionalTypeKind
import kotlin.reflect.KClass
abstract class FirFunctionalTypeKindExtension(session: FirSession) : FirExtension(session) {
@@ -21,7 +21,7 @@ abstract class FirFunctionalTypeKindExtension(session: FirSession) : FirExtensio
get() = FirFunctionalTypeKindExtension::class
interface FunctionalTypeKindRegistrar {
fun registerKind(nonReflectKind: ConeFunctionalTypeKind, reflectKind: ConeFunctionalTypeKind)
fun registerKind(nonReflectKind: FunctionalTypeKind, reflectKind: FunctionalTypeKind)
}
abstract fun FunctionalTypeKindRegistrar.registerKinds()
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.renderer
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
import org.jetbrains.kotlin.builtins.functions.AllowedToUsedOnlyInK1
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
@@ -741,12 +743,13 @@ class FirRenderer(
visitTypeRefWithNullability(functionTypeRef)
}
@OptIn(AllowedToUsedOnlyInK1::class)
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
typeRenderer.renderAsPossibleFunctionType(
resolvedTypeRef.type,
l@{
val classId = it.classId ?: return@l null
FirFunctionalTypeKindService.Default.getKindByClassNamePrefix(classId.packageFqName, classId.shortClassName.asString())
FunctionalTypeKindExtractor.Default.getFunctionalClassKind(classId.packageFqName, classId.shortClassName.asString())
}
)
}
@@ -5,39 +5,21 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionComponent
import org.jetbrains.kotlin.name.FqName
abstract class FirFunctionalTypeKindService : FirSessionComponent {
abstract fun getKindByClassNamePrefix(packageFqName: FqName, className: String): ConeFunctionalTypeKind?
abstract fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean
protected abstract val extractor: FunctionalTypeKindExtractor
/*
* Should be used only in places where session is unavaliable by default (e.g. in default cone type render)
*/
object Default : FirFunctionalTypeKindService() {
private val packages = listOf(
ConeFunctionalTypeKind.Function,
ConeFunctionalTypeKind.SuspendFunction,
ConeFunctionalTypeKind.KFunction,
ConeFunctionalTypeKind.KSuspendFunction,
).map { it.packageFqName }.toSet()
fun getKindByClassNamePrefix(packageFqName: FqName, className: String): FunctionalTypeKind? {
return extractor.getFunctionalClassKindWithArity(packageFqName, className)?.kind
}
override fun getKindByClassNamePrefix(packageFqName: FqName, className: String): ConeFunctionalTypeKind? {
return when (FunctionClassKind.parseClassName(className, packageFqName)?.kind) {
FunctionClassKind.Function -> ConeFunctionalTypeKind.Function
FunctionClassKind.SuspendFunction -> ConeFunctionalTypeKind.SuspendFunction
FunctionClassKind.KFunction -> ConeFunctionalTypeKind.KFunction
FunctionClassKind.KSuspendFunction -> ConeFunctionalTypeKind.KSuspendFunction
null -> null
}
}
override fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
return packageFqName in packages
}
fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
return extractor.hasKindWithSpecificPackage(packageFqName)
}
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -22,14 +22,14 @@ object SuspendFunctionAsSupertypeChecker : DeclarationChecker {
val functionalSupertypes = descriptor.getAllSuperClassifiers().filterIsInstance<FunctionClassDescriptor>().toList()
if (functionalSupertypes.none {
it.functionKind == FunctionClassKind.SuspendFunction ||
it.functionKind == FunctionClassKind.KSuspendFunction
it.functionKind == FunctionalTypeKind.SuspendFunction ||
it.functionKind == FunctionalTypeKind.KSuspendFunction
}
) return
if (functionalSupertypes.any {
it.functionKind == FunctionClassKind.Function ||
it.functionKind == FunctionClassKind.KFunction
it.functionKind == FunctionalTypeKind.Function ||
it.functionKind == FunctionalTypeKind.KFunction
}
) {
val reportOn = (declaration as? KtClassOrObject)?.getSuperTypeList() ?: declaration
@@ -9,19 +9,19 @@ import org.jetbrains.kotlin.builtins.CompanionObjectMapping
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
object JavaToKotlinClassMap {
private val NUMBERED_FUNCTION_PREFIX: String =
FunctionClassKind.Function.packageFqName.toString() + "." + FunctionClassKind.Function.classNamePrefix
FunctionalTypeKind.Function.packageFqName.toString() + "." + FunctionalTypeKind.Function.classNamePrefix
private val NUMBERED_K_FUNCTION_PREFIX: String =
FunctionClassKind.KFunction.packageFqName.toString() + "." + FunctionClassKind.KFunction.classNamePrefix
FunctionalTypeKind.KFunction.packageFqName.toString() + "." + FunctionalTypeKind.KFunction.classNamePrefix
private val NUMBERED_SUSPEND_FUNCTION_PREFIX: String =
FunctionClassKind.SuspendFunction.packageFqName.toString() + "." + FunctionClassKind.SuspendFunction.classNamePrefix
FunctionalTypeKind.SuspendFunction.packageFqName.toString() + "." + FunctionalTypeKind.SuspendFunction.classNamePrefix
private val NUMBERED_K_SUSPEND_FUNCTION_PREFIX: String =
FunctionClassKind.KSuspendFunction.packageFqName.toString() + "." + FunctionClassKind.KSuspendFunction.classNamePrefix
FunctionalTypeKind.KSuspendFunction.packageFqName.toString() + "." + FunctionalTypeKind.KSuspendFunction.classNamePrefix
private val FUNCTION_N_CLASS_ID: ClassId = ClassId.topLevel(FqName("kotlin.jvm.functions.FunctionN"))
val FUNCTION_N_FQ_NAME: FqName = FUNCTION_N_CLASS_ID.asSingleFqName()
@@ -97,7 +97,7 @@ object JavaToKotlinClassMap {
addKotlinToJava(FqName(NUMBERED_K_FUNCTION_PREFIX + i), K_FUNCTION_CLASS_ID)
}
for (i in 0 until BuiltInFunctionArity.BIG_ARITY - 1) {
val kSuspendFunction = FunctionClassKind.KSuspendFunction
val kSuspendFunction = FunctionalTypeKind.KSuspendFunction
val kSuspendFun = kSuspendFunction.packageFqName.toString() + "." + kSuspendFunction.classNamePrefix
addKotlinToJava(FqName(kSuspendFun + i), K_FUNCTION_CLASS_ID)
}
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.builtins
import org.jetbrains.kotlin.builtins.StandardNames.FqNames.reflect
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
@@ -252,7 +252,7 @@ object StandardNames {
@JvmStatic
fun getKFunctionFqName(parameterCount: Int): FqNameUnsafe {
return reflect(FunctionClassKind.KFunction.classNamePrefix + parameterCount)
return reflect(FunctionalTypeKind.KFunction.classNamePrefix + parameterCount)
}
@JvmStatic
@@ -263,7 +263,7 @@ object StandardNames {
@JvmStatic
fun getSuspendFunctionName(parameterCount: Int): String {
return FunctionClassKind.SuspendFunction.classNamePrefix + parameterCount
return FunctionalTypeKind.SuspendFunction.classNamePrefix + parameterCount
}
@JvmStatic
@@ -273,7 +273,7 @@ object StandardNames {
@JvmStatic
fun getKSuspendFunctionName(parameterCount: Int): FqNameUnsafe {
return reflect(FunctionClassKind.KSuspendFunction.classNamePrefix + parameterCount)
return reflect(FunctionalTypeKind.KSuspendFunction.classNamePrefix + parameterCount)
}
@JvmStatic
@@ -1,62 +0,0 @@
/*
* Copyright 2010-2020 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.builtins.functions
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
enum class FunctionClassKind(
val packageFqName: FqName,
val classNamePrefix: String,
val isSuspendType: Boolean,
val isReflectType: Boolean
) {
Function(StandardNames.BUILT_INS_PACKAGE_FQ_NAME, "Function", isSuspendType = false, isReflectType = false),
SuspendFunction(StandardNames.COROUTINES_PACKAGE_FQ_NAME, "SuspendFunction", isSuspendType = true, isReflectType = false),
KFunction(StandardNames.KOTLIN_REFLECT_FQ_NAME, "KFunction", isSuspendType = false, isReflectType = true),
KSuspendFunction(StandardNames.KOTLIN_REFLECT_FQ_NAME, "KSuspendFunction", isSuspendType = true, isReflectType = true);
fun numberedClassName(arity: Int) = Name.identifier("$classNamePrefix$arity")
companion object {
fun byClassNamePrefix(packageFqName: FqName, className: String): FunctionClassKind? =
values().firstOrNull { it.packageFqName == packageFqName && className.startsWith(it.classNamePrefix) }
data class KindWithArity(val kind: FunctionClassKind, val arity: Int)
fun parseClassName(className: String, packageFqName: FqName): KindWithArity? {
val kind = byClassNamePrefix(packageFqName, className) ?: return null
val prefix = kind.classNamePrefix
val arity = toInt(className.substring(prefix.length)) ?: return null
// TODO: validate arity, should be <= 255
return KindWithArity(kind, arity)
}
@JvmStatic
fun getFunctionalClassKind(className: String, packageFqName: FqName) =
parseClassName(className, packageFqName)?.kind
fun hasArityAtTheEnd(prefix: String, className: String): Boolean {
return toInt(className.substring(prefix.length)) != null
}
private fun toInt(s: String): Int? {
if (s.isEmpty()) return null
var result = 0
for (c in s) {
val d = c - '0'
if (d !in 0..9) return null
result = result * 10 + d
}
return result
}
}
}
@@ -3,7 +3,7 @@
* 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.types
package org.jetbrains.kotlin.builtins.functions
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.name.ClassId
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
/**
* [ConeFunctionalTypeKind] describes a family of various similar functional types (like kotlin.FunctionN)
* [FunctionalTypeKind] describes a family of various similar functional types (like kotlin.FunctionN)
* All types in the same family have corresponding shape of classId: [packageFqName].[classNamePrefix]N,
* where `N` is an arity of function
*
@@ -38,7 +38,7 @@ import org.jetbrains.kotlin.name.Name
* Note that if you provide some new functional type kind it's your responsibility to handle all references to it in backend
* with [IrGenerationExtension] implementation
*/
abstract class ConeFunctionalTypeKind internal constructor(
abstract class FunctionalTypeKind internal constructor(
val packageFqName: FqName,
val classNamePrefix: String,
val isReflectType: Boolean,
@@ -69,7 +69,7 @@ abstract class ConeFunctionalTypeKind internal constructor(
*
* Should be overridden for reflect kinds
*/
open fun nonReflectKind(): ConeFunctionalTypeKind {
open fun nonReflectKind(): FunctionalTypeKind {
return if (isReflectType) error("Should be overridden explicitly") else this
}
@@ -79,7 +79,7 @@ abstract class ConeFunctionalTypeKind internal constructor(
*
* Should be overridden for non reflect kinds
*/
open fun reflectKind(): ConeFunctionalTypeKind {
open fun reflectKind(): FunctionalTypeKind {
return if (isReflectType) this else error("Should be overridden explicitly")
}
@@ -91,16 +91,16 @@ abstract class ConeFunctionalTypeKind internal constructor(
// ------------------------------------------- Builtin functional kinds -------------------------------------------
object Function : ConeFunctionalTypeKind(
object Function : FunctionalTypeKind(
StandardNames.BUILT_INS_PACKAGE_FQ_NAME,
"Function",
isReflectType = false,
annotationOnInvokeClassId = null
) {
override fun reflectKind(): ConeFunctionalTypeKind = KFunction
override fun reflectKind(): FunctionalTypeKind = KFunction
}
object SuspendFunction : ConeFunctionalTypeKind(
object SuspendFunction : FunctionalTypeKind(
StandardNames.COROUTINES_PACKAGE_FQ_NAME,
"SuspendFunction",
isReflectType = false,
@@ -109,33 +109,37 @@ abstract class ConeFunctionalTypeKind internal constructor(
override val prefixForTypeRender: String
get() = "suspend"
override fun reflectKind(): ConeFunctionalTypeKind = KSuspendFunction
override fun reflectKind(): FunctionalTypeKind = KSuspendFunction
}
object KFunction : ConeFunctionalTypeKind(
object KFunction : FunctionalTypeKind(
StandardNames.KOTLIN_REFLECT_FQ_NAME,
"KFunction",
isReflectType = true,
annotationOnInvokeClassId = null
) {
override fun nonReflectKind(): ConeFunctionalTypeKind = Function
override fun nonReflectKind(): FunctionalTypeKind = Function
}
object KSuspendFunction : ConeFunctionalTypeKind(
object KSuspendFunction : FunctionalTypeKind(
StandardNames.KOTLIN_REFLECT_FQ_NAME,
"KSuspendFunction",
isReflectType = true,
annotationOnInvokeClassId = null
) {
override fun nonReflectKind(): ConeFunctionalTypeKind = SuspendFunction
override fun nonReflectKind(): FunctionalTypeKind = SuspendFunction
}
}
val ConeFunctionalTypeKind.isBuiltin: Boolean
val FunctionalTypeKind.isBuiltin: Boolean
get() = when (this) {
ConeFunctionalTypeKind.Function,
ConeFunctionalTypeKind.KFunction,
ConeFunctionalTypeKind.SuspendFunction,
ConeFunctionalTypeKind.KSuspendFunction -> true
FunctionalTypeKind.Function,
FunctionalTypeKind.SuspendFunction,
FunctionalTypeKind.KFunction,
FunctionalTypeKind.KSuspendFunction -> true
else -> false
}
val FunctionalTypeKind.isSuspendType: Boolean
get() = this == FunctionalTypeKind.SuspendFunction || this == FunctionalTypeKind.KSuspendFunction
@@ -0,0 +1,65 @@
/*
* 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.builtins.functions
import org.jetbrains.kotlin.name.FqName
@RequiresOptIn
annotation class AllowedToUsedOnlyInK1
class FunctionalTypeKindExtractor(kinds: List<FunctionalTypeKind>) {
companion object {
/**
* This instance should be used only in:
* - FE 1.0, since it does not support custom functional kinds from plugins
* - places in FIR where session is not accessible by design (like in renderer of FIR elements)
*/
@JvmStatic
@AllowedToUsedOnlyInK1
val Default = FunctionalTypeKindExtractor(
listOf(
FunctionalTypeKind.Function,
FunctionalTypeKind.SuspendFunction,
FunctionalTypeKind.KFunction,
FunctionalTypeKind.KSuspendFunction,
)
)
}
private val knownKindsByPackageFqName = kinds.groupBy { it.packageFqName }
fun getFunctionalClassKind(packageFqName: FqName, className: String): FunctionalTypeKind? {
return getFunctionalClassKindWithArity(packageFqName, className)?.kind
}
fun getFunctionalClassKindWithArity(packageFqName: FqName, className: String): KindWithArity? {
val kinds = knownKindsByPackageFqName[packageFqName] ?: return null
for (kind in kinds) {
if (!className.startsWith(kind.classNamePrefix)) continue
val arity = toInt(className.substring(kind.classNamePrefix.length)) ?: continue
return KindWithArity(kind, arity)
}
return null
}
fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
return packageFqName in knownKindsByPackageFqName
}
data class KindWithArity(val kind: FunctionalTypeKind, val arity: Int)
private fun toInt(s: String): Int? {
if (s.isEmpty()) return null
var result = 0
for (c in s) {
val d = c - '0'
if (d !in 0..9) return null
result = result * 10 + d
}
return result
}
}
@@ -10,7 +10,7 @@ import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind;
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider;
@@ -33,8 +33,8 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import java.util.*;
import static org.jetbrains.kotlin.builtins.StandardNames.*;
import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
import static org.jetbrains.kotlin.builtins.StandardNames.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
public abstract class KotlinBuiltIns {
@@ -315,7 +315,7 @@ public abstract class KotlinBuiltIns {
@NotNull
public ClassDescriptor getKSuspendFunction(int parameterCount) {
Name name = Name.identifier(FunctionClassKind.KSuspendFunction.getClassNamePrefix() + parameterCount);
Name name = Name.identifier(FunctionalTypeKind.KSuspendFunction.INSTANCE.getClassNamePrefix() + parameterCount);
return getBuiltInClassByFqName(COROUTINES_PACKAGE_FQ_NAME.child(name));
}
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.builtins
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_NAME
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
import org.jetbrains.kotlin.builtins.functions.AllowedToUsedOnlyInK1
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -24,7 +26,6 @@ import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
private fun KotlinType.isTypeOrSubtypeOf(predicate: (KotlinType) -> Boolean): Boolean =
predicate(this) ||
@@ -59,16 +60,16 @@ fun KotlinType.isFunctionTypeOrSubtype(predicate: (KotlinType) -> Boolean): Bool
isTypeOrSubtypeOf { it.isFunctionType && predicate(it) }
val KotlinType.isFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassKind.Function
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.Function
val KotlinType.isKFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassKind.KFunction
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.KFunction
val KotlinType.isSuspendFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassKind.SuspendFunction
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.SuspendFunction
val KotlinType.isKSuspendFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassKind.KSuspendFunction
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.KSuspendFunction
val KotlinType.isFunctionOrSuspendFunctionType: Boolean
get() = isFunctionType || isSuspendFunctionType
@@ -82,16 +83,16 @@ val KotlinType.isBuiltinFunctionalType: Boolean
val DeclarationDescriptor.isBuiltinFunctionalClassDescriptor: Boolean
get() {
val functionalClassKind = getFunctionalClassKind()
return functionalClassKind == FunctionClassKind.Function ||
functionalClassKind == FunctionClassKind.SuspendFunction
return functionalClassKind == FunctionalTypeKind.Function ||
functionalClassKind == FunctionalTypeKind.SuspendFunction
}
fun isBuiltinFunctionClass(classId: ClassId): Boolean {
if (!classId.startsWith(StandardNames.BUILT_INS_PACKAGE_NAME)) return false
val kind = classId.asSingleFqName().toUnsafe().getFunctionalClassKind()
return kind == FunctionClassKind.Function ||
kind == FunctionClassKind.SuspendFunction
return kind == FunctionalTypeKind.Function ||
kind == FunctionalTypeKind.SuspendFunction
}
val KotlinType.isNonExtensionFunctionType: Boolean
@@ -112,20 +113,21 @@ private val KotlinType.isTypeAnnotatedWithExtensionFunctionType: Boolean
*/
fun isNumberedFunctionClassFqName(fqName: FqNameUnsafe): Boolean {
return fqName.startsWith(BUILT_INS_PACKAGE_NAME) &&
fqName.getFunctionalClassKind() == FunctionClassKind.Function
fqName.getFunctionalClassKind() == FunctionalTypeKind.Function
}
fun DeclarationDescriptor.getFunctionalClassKind(): FunctionClassKind? {
fun DeclarationDescriptor.getFunctionalClassKind(): FunctionalTypeKind? {
if (this !is ClassDescriptor) return null
if (!KotlinBuiltIns.isUnderKotlinPackage(this)) return null
return fqNameUnsafe.getFunctionalClassKind()
}
private fun FqNameUnsafe.getFunctionalClassKind(): FunctionClassKind? {
@OptIn(AllowedToUsedOnlyInK1::class)
private fun FqNameUnsafe.getFunctionalClassKind(): FunctionalTypeKind? {
if (!isSafe || isRoot) return null
return FunctionClassKind.getFunctionalClassKind(shortName().asString(), toSafe().parent())
return FunctionalTypeKindExtractor.Default.getFunctionalClassKind(toSafe().parent(), shortName().asString())
}
fun KotlinType.contextFunctionTypeParamsCount(): Int {
@@ -33,13 +33,15 @@ class BuiltInFictitiousFunctionClassFactory(
private val storageManager: StorageManager,
private val module: ModuleDescriptor
) : ClassDescriptorFactory {
@OptIn(AllowedToUsedOnlyInK1::class)
override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean {
val string = name.asString()
return (string.startsWith("Function") || string.startsWith("KFunction") ||
string.startsWith("SuspendFunction") || string.startsWith("KSuspendFunction")) // an optimization
&& FunctionClassKind.parseClassName(string, packageFqName) != null
&& FunctionalTypeKindExtractor.Default.getFunctionalClassKindWithArity(packageFqName, string) != null
}
@OptIn(AllowedToUsedOnlyInK1::class)
override fun createClass(classId: ClassId): ClassDescriptor? {
if (classId.isLocal || classId.isNestedClass) return null
@@ -47,7 +49,7 @@ class BuiltInFictitiousFunctionClassFactory(
if ("Function" !in className) return null // An optimization
val packageFqName = classId.packageFqName
val (kind, arity) = FunctionClassKind.parseClassName(className, packageFqName) ?: return null
val (kind, arity) = FunctionalTypeKindExtractor.Default.getFunctionalClassKindWithArity(packageFqName, className) ?: return null
val builtInsFragments = module.getPackage(packageFqName).fragments.filterIsInstance<BuiltInsPackageFragment>()
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
/**
* A [ClassDescriptor] representing the fictitious class for a function type, such as kotlin.Function1 or kotlin.reflect.KFunction2.
@@ -30,7 +31,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
class FunctionClassDescriptor(
private val storageManager: StorageManager,
private val containingDeclaration: PackageFragmentDescriptor,
val functionKind: FunctionClassKind,
val functionKind: FunctionalTypeKind,
val arity: Int
) : AbstractClassDescriptor(storageManager, functionKind.numberedClassName(arity)) {
@@ -95,14 +96,15 @@ class FunctionClassDescriptor(
override fun computeSupertypes(): Collection<KotlinType> {
// For K{Suspend}Function{n}, add corresponding numbered {Suspend}Function{n} class, e.g. {Suspend}Function2 for K{Suspend}Function2
val supertypes = when (functionKind) {
FunctionClassKind.Function -> // Function$N <: Function
FunctionalTypeKind.Function -> // Function$N <: Function
listOf(functionClassId)
FunctionClassKind.KFunction -> // KFunction$N <: KFunction
listOf(kFunctionClassId, ClassId(BUILT_INS_PACKAGE_FQ_NAME, FunctionClassKind.Function.numberedClassName(arity)))
FunctionClassKind.SuspendFunction -> // SuspendFunction$N<...> <: Function
FunctionalTypeKind.KFunction -> // KFunction$N <: KFunction
listOf(kFunctionClassId, ClassId(BUILT_INS_PACKAGE_FQ_NAME, FunctionalTypeKind.Function.numberedClassName(arity)))
FunctionalTypeKind.SuspendFunction -> // SuspendFunction$N<...> <: Function
listOf(functionClassId)
FunctionClassKind.KSuspendFunction -> // KSuspendFunction$N<...> <: KFunction
listOf(kFunctionClassId, ClassId(COROUTINES_PACKAGE_FQ_NAME, FunctionClassKind.SuspendFunction.numberedClassName(arity)))
FunctionalTypeKind.KSuspendFunction -> // KSuspendFunction$N<...> <: KFunction
listOf(kFunctionClassId, ClassId(COROUTINES_PACKAGE_FQ_NAME, FunctionalTypeKind.SuspendFunction.numberedClassName(arity)))
else -> shouldNotBeCalled()
}
val moduleDescriptor = containingDeclaration.containingDeclaration
@@ -26,8 +26,8 @@ class FunctionClassScope(
) : GivenFunctionsMemberScope(storageManager, containingClass) {
override fun computeDeclaredFunctions(): List<FunctionDescriptor> =
when ((containingClass as FunctionClassDescriptor).functionKind) {
FunctionClassKind.Function -> listOf(FunctionInvokeDescriptor.create(containingClass, isSuspend = false))
FunctionClassKind.SuspendFunction -> listOf(FunctionInvokeDescriptor.create(containingClass, isSuspend = true))
FunctionalTypeKind.Function -> listOf(FunctionInvokeDescriptor.create(containingClass, isSuspend = false))
FunctionalTypeKind.SuspendFunction -> listOf(FunctionInvokeDescriptor.create(containingClass, isSuspend = true))
else -> emptyList()
}
}
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind;
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind;
import org.jetbrains.kotlin.config.LanguageVersion;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
@@ -338,7 +338,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
default: {
if (descriptor instanceof FunctionClassDescriptor) {
FunctionClassDescriptor functionClassDescriptor = (FunctionClassDescriptor) descriptor;
if (functionClassDescriptor.getFunctionKind() == FunctionClassKind.Function) {
if (functionClassDescriptor.getFunctionKind() == FunctionalTypeKind.Function.INSTANCE) {
ClassDescriptor primitivesObject = findPrimitiveClassesObject(context);
assert primitivesObject != null;
FunctionDescriptor function = DescriptorUtils.getFunctionByName(
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.builtins.FunctionInterfacePackageFragment
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.declarations.*
@@ -168,7 +168,7 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
val builtFunctionNClasses get() = builtClassesMap.entries.mapNotNull { (descriptor, irClass) ->
with(descriptor) {
if (functionKind == FunctionClassKind.Function)
if (functionKind == FunctionalTypeKind.Function)
FunctionalInterface(irClass, descriptor, arity)
else null
}
@@ -5,10 +5,8 @@
package org.jetbrains.kotlin.backend.konan.objcexport
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId
@@ -18,7 +16,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
internal fun ClassDescriptor.isMappedFunctionClass() =
this.getFunctionalClassKind() == FunctionClassKind.Function &&
this.getFunctionalClassKind() == FunctionalTypeKind.Function &&
// Type parameters include return type.
declaredTypeParameters.size - 1 < CustomTypeMappers.functionTypeMappersArityLimit