Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.builtins.StandardNames
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
/**
* [FunctionTypeKind] 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
*
* Functional type kind may be either reflect type or non-reflect type
* Each non-reflect kind should have corresponding reflect kind and vice-versa (like `kotlin.FunctionN` and `kotlin.reflection.KFunctionN`)
*
* Classes for such functional types are synthetic and generated by compiler itself
* [annotationOnInvokeClassId] is a classId of annotation, which will be added to `invoke` function of generated
* functional interface. This argument is mandatory for non-standard functional kinds
*
* Assume we have `some.CustomFunctionN` and `some.KCustomFunctionN` families with [annotationOnInvokeClassId] = /some.Anno
* Classes for those kinds will look like this:
*
* interface CustomFunctionN : kotlin.Function {
* @some.Anno
* operator fun invoke(p1: P1, p2: P2, ..., pN: PN): R
* }
*
* interface KCustomFunctionN : kotlin.reflect.KFunction, some.CustomFunctionN {
* @some.Anno
* override operator fun invoke(p1: P1, p2: P2, ..., pN: PN): R
* }
*
* 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 FunctionTypeKind internal constructor(
val packageFqName: FqName,
val classNamePrefix: String,
val isReflectType: Boolean,
val annotationOnInvokeClassId: ClassId?
) {
/*
* This constructor is needed to enforce not nullable [annotationOnInvokeClassId] for
* functional kinds provided by compiler plugins
*/
constructor(
packageFqName: FqName,
classNamePrefix: String,
annotationOnInvokeClassId: ClassId,
isReflectType: Boolean
) : this(packageFqName, classNamePrefix, isReflectType, annotationOnInvokeClassId)
/*
* Specifies how corresponding type will be rendered
* E.g. if `prefixForTypeRender = @Some` and type is `some.CustomFunction2`,
* then type will be rendered as `@Some (Int, String) -> Double`
*/
open val prefixForTypeRender: String?
get() = null
/**
* Specifies the first language version for which to serialize custom function types
* into kotlin metadata. Until that version, custom function types will be serialized
* with the legacy scheme: as a FunctionN/KFunctionN with the annotation used for the
* custom function type.
*
* If no version is specified, custom function types are serialized to kotlin metadata.
*
* Serialization using the legacy format allows libraries compiled with K2 with a
* K2 plugin that uses custom function types to be used by clients using a K1 compiler
* with a K1 compiler plugin that understands the custom function types.
*/
open val serializeAsFunctionWithAnnotationUntil: String?
get() = null
/**
* @return corresponding non-reflect kind for reflect kind
* @return [this] if [isReflectType] is false
*
* Should be overridden for reflect kinds
*/
open fun nonReflectKind(): FunctionTypeKind {
return if (isReflectType) error("Should be overridden explicitly") else this
}
/**
* @return corresponding reflect kind for non-reflect kind
* @return [this] if [isReflectType] is true
*
* Should be overridden for non reflect kinds
*/
open fun reflectKind(): FunctionTypeKind {
return if (isReflectType) this else error("Should be overridden explicitly")
}
fun numberedClassName(arity: Int): Name = Name.identifier("$classNamePrefix$arity")
fun numberedClassId(arity: Int): ClassId = ClassId(packageFqName, numberedClassName(arity))
override fun toString(): String {
return "$packageFqName.${classNamePrefix}N"
}
// ------------------------------------------- Builtin functional kinds -------------------------------------------
object Function : FunctionTypeKind(
StandardNames.BUILT_INS_PACKAGE_FQ_NAME,
"Function",
isReflectType = false,
annotationOnInvokeClassId = null
) {
override fun reflectKind(): FunctionTypeKind = KFunction
}
object SuspendFunction : FunctionTypeKind(
StandardNames.COROUTINES_PACKAGE_FQ_NAME,
"SuspendFunction",
isReflectType = false,
annotationOnInvokeClassId = null
) {
override val prefixForTypeRender: String
get() = "suspend"
override fun reflectKind(): FunctionTypeKind = KSuspendFunction
}
object KFunction : FunctionTypeKind(
StandardNames.KOTLIN_REFLECT_FQ_NAME,
"KFunction",
isReflectType = true,
annotationOnInvokeClassId = null
) {
override fun nonReflectKind(): FunctionTypeKind = Function
}
object KSuspendFunction : FunctionTypeKind(
StandardNames.KOTLIN_REFLECT_FQ_NAME,
"KSuspendFunction",
isReflectType = true,
annotationOnInvokeClassId = null
) {
override fun nonReflectKind(): FunctionTypeKind = SuspendFunction
}
}
val FunctionTypeKind.isBuiltin: Boolean
get() = when (this) {
FunctionTypeKind.Function,
FunctionTypeKind.SuspendFunction,
FunctionTypeKind.KFunction,
FunctionTypeKind.KSuspendFunction -> true
else -> false
}
val FunctionTypeKind.isSuspendOrKSuspendFunction: Boolean
get() = this.nonReflectKind() == FunctionTypeKind.SuspendFunction
val FunctionTypeKind.isBasicFunctionOrKFunction: Boolean
get() = this.nonReflectKind() == FunctionTypeKind.Function