[FIR] Generify resolution and inference of arguments of functional types
This commit is contained in:
committed by
Space Team
parent
67aa80562d
commit
d1b797ed97
+1
-2
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirSafe
|
|||||||
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
@@ -114,7 +113,7 @@ internal class KtFirExpressionTypeProvider(
|
|||||||
declaration.toFirAnonymousFunction()
|
declaration.toFirAnonymousFunction()
|
||||||
else
|
else
|
||||||
declaration.getOrBuildFirOfType<FirFunction>(firResolveSession)
|
declaration.getOrBuildFirOfType<FirFunction>(firResolveSession)
|
||||||
return firFunction.constructFunctionalType(firFunction.isSuspend).asKtType()
|
return firFunction.constructFunctionalType(firFunction.specialFunctionalTypeKind(firResolveSession.useSiteFirSession)).asKtType()
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
|||||||
+2
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.scopes.collectAllFunctions
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionOverrideFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
|
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.fir.types.typeContext
|
import org.jetbrains.kotlin.fir.types.typeContext
|
||||||
|
|
||||||
object FirJsInheritanceClassChecker : FirClassChecker() {
|
object FirJsInheritanceClassChecker : FirClassChecker() {
|
||||||
@@ -52,7 +53,7 @@ object FirJsInheritanceClassChecker : FirClassChecker() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeType.isSuspendFunctionTypeOrSubtype(session: FirSession): Boolean {
|
private fun ConeClassLikeType.isSuspendFunctionTypeOrSubtype(session: FirSession): Boolean {
|
||||||
return with(session.typeContext) { isSuspendFunctionTypeOrSubtype() }
|
return with(session.typeContext) { isTypeOrSubtypeOf { it.isSuspendFunctionType(session) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirClass.findFakeMethodOverridingExternalWithOptionalParams(context: CheckerContext): FirNamedFunctionSymbol? {
|
private fun FirClass.findFakeMethodOverridingExternalWithOptionalParams(context: CheckerContext): FirNamedFunctionSymbol? {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
import org.jetbrains.kotlin.fir.declarations.utils.modality
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||||
@@ -466,7 +467,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
return this.isSomeFunctionalType(session)
|
return this.isSomeFunctionalType(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.isTypeOrSubtypeOf(predicate: (ConeKotlinType) -> Boolean): Boolean {
|
fun ConeKotlinType.isTypeOrSubtypeOf(predicate: (ConeKotlinType) -> Boolean): Boolean {
|
||||||
return predicate(this) || DFS.dfsFromNode(
|
return predicate(this) || DFS.dfsFromNode(
|
||||||
this,
|
this,
|
||||||
{
|
{
|
||||||
@@ -489,13 +490,6 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean {
|
|
||||||
require(this is ConeKotlinType)
|
|
||||||
return isTypeOrSubtypeOf {
|
|
||||||
(it.lowerBoundIfFlexible() as ConeKotlinType).isSuspendOrKSuspendFunctionType(session)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return (this.lowerBoundIfFlexible() as? ConeKotlinType)?.isExtensionFunctionType(session) == true
|
return (this.lowerBoundIfFlexible() as? ConeKotlinType)?.isExtensionFunctionType(session) == true
|
||||||
@@ -536,24 +530,17 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
override fun KotlinTypeMarker.functionalTypeKind(): FunctionalTypeKind? {
|
||||||
val classId = if (isSuspend) {
|
require(this is ConeKotlinType)
|
||||||
StandardClassIds.SuspendFunctionN(parametersNumber)
|
return this.functionalTypeKind(session)
|
||||||
} else {
|
|
||||||
StandardClassIds.FunctionN(parametersNumber)
|
|
||||||
}
|
|
||||||
return session.symbolProvider.getClassLikeSymbolByClassId(classId)?.toLookupTag()
|
|
||||||
?: error("Can't find Function type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
override fun getNonReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker {
|
||||||
val classId = if (isSuspend) {
|
return kind.nonReflectKind().numberedClassId(parametersNumber).toLookupTag()
|
||||||
StandardClassIds.KSuspendFunctionN(parametersNumber)
|
}
|
||||||
} else {
|
|
||||||
StandardClassIds.KFunctionN(parametersNumber)
|
override fun getReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker {
|
||||||
}
|
return kind.reflectKind().numberedClassId(parametersNumber).toLookupTag()
|
||||||
return session.symbolProvider.getClassLikeSymbolByClassId(classId)?.toLookupTag()
|
|
||||||
?: error("Can't find KFunction type")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createTypeWithAlternativeForIntersectionResult(
|
override fun createTypeWithAlternativeForIntersectionResult(
|
||||||
|
|||||||
+30
@@ -8,11 +8,15 @@ package org.jetbrains.kotlin.fir.types
|
|||||||
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirFunctionalTypeKindExtension
|
import org.jetbrains.kotlin.fir.extensions.FirFunctionalTypeKindExtension
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.extensions.functionalTypeKindExtensions
|
import org.jetbrains.kotlin.fir.extensions.functionalTypeKindExtensions
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
|
||||||
class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeKindService() {
|
class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeKindService() {
|
||||||
|
private val nonReflectKindsFromExtensions = mutableListOf<FunctionalTypeKind>()
|
||||||
|
|
||||||
override val extractor: FunctionalTypeKindExtractor = run {
|
override val extractor: FunctionalTypeKindExtractor = run {
|
||||||
val kinds = buildList {
|
val kinds = buildList {
|
||||||
add(FunctionalTypeKind.Function)
|
add(FunctionalTypeKind.Function)
|
||||||
@@ -26,6 +30,7 @@ class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeK
|
|||||||
require(reflectKind.nonReflectKind() == nonReflectKind)
|
require(reflectKind.nonReflectKind() == nonReflectKind)
|
||||||
add(nonReflectKind)
|
add(nonReflectKind)
|
||||||
add(reflectKind)
|
add(reflectKind)
|
||||||
|
nonReflectKindsFromExtensions += nonReflectKind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +43,31 @@ class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeK
|
|||||||
"There are clashing functional type kinds: $allNames"
|
"There are clashing functional type kinds: $allNames"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionalTypeKindExtractor(kinds)
|
FunctionalTypeKindExtractor(kinds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun extractSingleSpecialKindForFunction(functionSymbol: FirNamedFunctionSymbol): FunctionalTypeKind? {
|
||||||
|
if (nonReflectKindsFromExtensions.isEmpty()) {
|
||||||
|
return FunctionalTypeKind.SuspendFunction.takeIf { functionSymbol.isSuspend }
|
||||||
|
}
|
||||||
|
return extractAllSpecialKindsForFunction(functionSymbol).singleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractAllSpecialKindsForFunction(functionSymbol: FirNamedFunctionSymbol): List<FunctionalTypeKind> {
|
||||||
|
return buildList {
|
||||||
|
if (functionSymbol.isSuspend) {
|
||||||
|
add(FunctionalTypeKind.SuspendFunction)
|
||||||
|
}
|
||||||
|
if (nonReflectKindsFromExtensions.isNotEmpty()) {
|
||||||
|
for (annotationClassId in functionSymbol.resolvedAnnotationClassIds) {
|
||||||
|
for (kind in nonReflectKindsFromExtensions) {
|
||||||
|
if (kind.annotationOnInvokeClassId == annotationClassId) {
|
||||||
|
add(kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.isRegularFunction
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
import org.jetbrains.kotlin.fir.originalForSubstitutionOverride
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
@@ -82,14 +84,12 @@ fun ConeClassLikeLookupTag.isSomeFunctionalType(session: FirSession): Boolean {
|
|||||||
|
|
||||||
// Function, KFunction
|
// Function, KFunction
|
||||||
private fun ConeKotlinType.isSimpleFunctionalType(session: FirSession, errorOnNotFunctionalType: Boolean): Boolean {
|
private fun ConeKotlinType.isSimpleFunctionalType(session: FirSession, errorOnNotFunctionalType: Boolean): Boolean {
|
||||||
return isFunctionalTypeWithPredicate(session, errorOnNotFunctionalType) {
|
return isFunctionalTypeWithPredicate(session, errorOnNotFunctionalType) { it.isRegularFunction }
|
||||||
it == FunctionalTypeKind.Function || it == FunctionalTypeKind.KFunction
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuspendFunction, [Custom]Function, KSuspendFunction, K[Custom]Function
|
// SuspendFunction, [Custom]Function, KSuspendFunction, K[Custom]Function
|
||||||
private fun ConeKotlinType.isNotSimpleFunctionalType(session: FirSession): Boolean {
|
fun ConeKotlinType.isNotSimpleFunctionalType(session: FirSession): Boolean {
|
||||||
return !isSimpleFunctionalType(session, errorOnNotFunctionalType = false)
|
return isFunctionalTypeWithPredicate(session, errorOnNotFunctionalType = false) { !it.isRegularFunction }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------- functional type conversions ----------------------------------------------
|
// ---------------------------------------------- functional type conversions ----------------------------------------------
|
||||||
@@ -106,7 +106,7 @@ fun ConeKotlinType.customFunctionalTypeToSimpleFunctionalType(session: FirSessio
|
|||||||
} else {
|
} else {
|
||||||
FunctionalTypeKind.Function
|
FunctionalTypeKind.Function
|
||||||
}
|
}
|
||||||
return createFunctionalTypeWithNewKind(newKind)
|
return createFunctionalTypeWithNewKind(session, newKind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -117,12 +117,17 @@ fun ConeKotlinType.customFunctionalTypeToSimpleFunctionalType(session: FirSessio
|
|||||||
fun ConeKotlinType.reflectFunctionalTypeToNonReflectFunctionalType(session: FirSession): ConeClassLikeType {
|
fun ConeKotlinType.reflectFunctionalTypeToNonReflectFunctionalType(session: FirSession): ConeClassLikeType {
|
||||||
val kind = functionalTypeKind(session)
|
val kind = functionalTypeKind(session)
|
||||||
require(kind != null && kind.isReflectType)
|
require(kind != null && kind.isReflectType)
|
||||||
return createFunctionalTypeWithNewKind(kind.nonReflectKind())
|
return createFunctionalTypeWithNewKind(session, kind.nonReflectKind())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeKotlinType.createFunctionalTypeWithNewKind(kind: FunctionalTypeKind): ConeClassLikeType {
|
private fun ConeKotlinType.createFunctionalTypeWithNewKind(session: FirSession, kind: FunctionalTypeKind): ConeClassLikeType {
|
||||||
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(typeArguments.size - 1))
|
val expandedType = fullyExpandedType(session)
|
||||||
return functionalTypeId.toLookupTag().constructClassType(typeArguments, isNullable = false, attributes = attributes)
|
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(expandedType.typeArguments.size - 1))
|
||||||
|
return functionalTypeId.toLookupTag().constructClassType(
|
||||||
|
expandedType.typeArguments,
|
||||||
|
isNullable = false,
|
||||||
|
attributes = expandedType.attributes
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------- functional type subtyping ----------------------------------------------
|
// ---------------------------------------------- functional type subtyping ----------------------------------------------
|
||||||
@@ -139,8 +144,8 @@ private fun ConeKotlinType.findSubtypeOfSimpleFunctionalTypeImpl(
|
|||||||
): ConeKotlinType? {
|
): ConeKotlinType? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeClassLikeType -> {
|
is ConeClassLikeType -> {
|
||||||
// Expect the argument type is a simple functional type.
|
|
||||||
when {
|
when {
|
||||||
|
// Expect the argument type is a simple functional type.
|
||||||
isNotSimpleFunctionalType(session) -> null
|
isNotSimpleFunctionalType(session) -> null
|
||||||
isSubtypeOfFunctionalType(session, expectedFunctionalType) -> this
|
isSubtypeOfFunctionalType(session, expectedFunctionalType) -> this
|
||||||
else -> null
|
else -> null
|
||||||
@@ -247,3 +252,11 @@ private fun ConeTypeProjection.typeOrDefault(default: ConeKotlinType): ConeKotli
|
|||||||
is ConeKotlinTypeProjection -> type
|
is ConeKotlinTypeProjection -> type
|
||||||
is ConeStarProjection -> default
|
is ConeStarProjection -> default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------- TODO fir utils
|
||||||
|
|
||||||
|
fun FirFunction.specialFunctionalTypeKind(session: FirSession): FunctionalTypeKind? {
|
||||||
|
return (symbol as? FirNamedFunctionSymbol)?.let {
|
||||||
|
session.functionalTypeService.extractSingleSpecialKindForFunction(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,15 +60,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
|||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
|
||||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
|
||||||
|
|
||||||
fun FirAnonymousFunction.shouldReturnUnit(returnStatements: Collection<FirExpression>): Boolean =
|
fun FirAnonymousFunction.shouldReturnUnit(returnStatements: Collection<FirExpression>): Boolean =
|
||||||
isLambda && returnStatements.any { it is FirUnitExpression }
|
isLambda && returnStatements.any { it is FirUnitExpression }
|
||||||
|
|
||||||
fun FirAnonymousFunction.isExplicitlySuspend(session: FirSession): Boolean =
|
|
||||||
typeRef.coneTypeSafe<ConeKotlinType>()?.isSuspendOrKSuspendFunctionType(session) == true
|
|
||||||
|
|
||||||
fun FirAnonymousFunction.addReturnToLastStatementIfNeeded() {
|
fun FirAnonymousFunction.addReturnToLastStatementIfNeeded() {
|
||||||
// If this lambda's resolved, expected return type is Unit, we don't need an explicit return statement.
|
// If this lambda's resolved, expected return type is Unit, we don't need an explicit return statement.
|
||||||
// During conversion (to backend IR), the last expression will be coerced to Unit if needed.
|
// During conversion (to backend IR), the last expression will be coerced to Unit if needed.
|
||||||
@@ -96,7 +90,10 @@ fun FirAnonymousFunction.addReturnToLastStatementIfNeeded() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirFunction.constructFunctionalType(isSuspend: Boolean = false): ConeLookupTagBasedType {
|
/**
|
||||||
|
* [kind] == null means that [FunctionalTypeKind.Function] will be used
|
||||||
|
*/
|
||||||
|
fun FirFunction.constructFunctionalType(kind: FunctionalTypeKind? = null): ConeLookupTagBasedType {
|
||||||
val receiverTypeRef = when (this) {
|
val receiverTypeRef = when (this) {
|
||||||
is FirSimpleFunction -> receiverParameter
|
is FirSimpleFunction -> receiverParameter
|
||||||
is FirAnonymousFunction -> receiverParameter
|
is FirAnonymousFunction -> receiverParameter
|
||||||
@@ -114,25 +111,27 @@ fun FirFunction.constructFunctionalType(isSuspend: Boolean = false): ConeLookupT
|
|||||||
val rawReturnType = (this as FirCallableDeclaration).returnTypeRef.coneType
|
val rawReturnType = (this as FirCallableDeclaration).returnTypeRef.coneType
|
||||||
|
|
||||||
return createFunctionalType(
|
return createFunctionalType(
|
||||||
parameters, receiverTypeRef?.coneType, rawReturnType, isSuspend = isSuspend,
|
kind ?: FunctionalTypeKind.Function, parameters, receiverTypeRef?.coneType, rawReturnType,
|
||||||
contextReceivers = contextReceivers.map { it.typeRef.coneType }
|
contextReceivers = contextReceivers.map { it.typeRef.coneType }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun FirFunction.constructFunctionalTypeRef(isSuspend: Boolean = false): FirResolvedTypeRef {
|
/**
|
||||||
|
* [kind] == null means that [FunctionalTypeKind.Function] will be used
|
||||||
|
*/
|
||||||
|
fun FirFunction.constructFunctionalTypeRef(kind: FunctionalTypeKind? = null): FirResolvedTypeRef {
|
||||||
return buildResolvedTypeRef {
|
return buildResolvedTypeRef {
|
||||||
source = this@constructFunctionalTypeRef.source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef)
|
source = this@constructFunctionalTypeRef.source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef)
|
||||||
type = constructFunctionalType(isSuspend)
|
type = constructFunctionalType(kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createFunctionalType(
|
fun createFunctionalType(
|
||||||
|
kind: FunctionalTypeKind,
|
||||||
parameters: List<ConeKotlinType>,
|
parameters: List<ConeKotlinType>,
|
||||||
receiverType: ConeKotlinType?,
|
receiverType: ConeKotlinType?,
|
||||||
rawReturnType: ConeKotlinType,
|
rawReturnType: ConeKotlinType,
|
||||||
isSuspend: Boolean,
|
|
||||||
contextReceivers: List<ConeKotlinType> = emptyList(),
|
contextReceivers: List<ConeKotlinType> = emptyList(),
|
||||||
isKFunctionType: Boolean = false
|
|
||||||
): ConeLookupTagBasedType {
|
): ConeLookupTagBasedType {
|
||||||
val receiverAndParameterTypes =
|
val receiverAndParameterTypes =
|
||||||
buildList {
|
buildList {
|
||||||
@@ -142,12 +141,6 @@ fun createFunctionalType(
|
|||||||
add(rawReturnType)
|
add(rawReturnType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val kind = if (isSuspend) {
|
|
||||||
if (isKFunctionType) FunctionalTypeKind.KSuspendFunction else FunctionalTypeKind.SuspendFunction
|
|
||||||
} else {
|
|
||||||
if (isKFunctionType) FunctionalTypeKind.KFunction else FunctionalTypeKind.Function
|
|
||||||
}
|
|
||||||
|
|
||||||
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(receiverAndParameterTypes.size - 1))
|
val functionalTypeId = ClassId(kind.packageFqName, kind.numberedClassName(receiverAndParameterTypes.size - 1))
|
||||||
val attributes = when {
|
val attributes = when {
|
||||||
contextReceivers.isNotEmpty() -> ConeAttributes.create(
|
contextReceivers.isNotEmpty() -> ConeAttributes.create(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -265,7 +266,7 @@ class FirSamResolver(
|
|||||||
it.getCustomFunctionalTypeForSamConversion(abstractMethod)
|
it.getCustomFunctionalTypeForSamConversion(abstractMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMInfo(abstractMethod.symbol, typeFromExtension ?: abstractMethod.getFunctionTypeForAbstractMethod())
|
SAMInfo(abstractMethod.symbol, typeFromExtension ?: abstractMethod.getFunctionTypeForAbstractMethod(session))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,18 +408,19 @@ fun FirSimpleFunction.isPublicInObject(checkOnlyName: Boolean): Boolean {
|
|||||||
|
|
||||||
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
|
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
|
||||||
|
|
||||||
private fun FirSimpleFunction.getFunctionTypeForAbstractMethod(): ConeLookupTagBasedType {
|
private fun FirSimpleFunction.getFunctionTypeForAbstractMethod(session: FirSession): ConeLookupTagBasedType {
|
||||||
val parameterTypes = valueParameters.map {
|
val parameterTypes = valueParameters.map {
|
||||||
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for parameter $it"))
|
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for parameter $it"))
|
||||||
}
|
}
|
||||||
val contextReceiversTypes = contextReceivers.map {
|
val contextReceiversTypes = contextReceivers.map {
|
||||||
it.typeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for context receiver $it"))
|
it.typeRef.coneTypeSafe<ConeKotlinType>() ?: ConeErrorType(ConeIntermediateDiagnostic("No type for context receiver $it"))
|
||||||
}
|
}
|
||||||
|
val kind = session.functionalTypeService.extractSingleSpecialKindForFunction(symbol) ?: FunctionalTypeKind.Function
|
||||||
return createFunctionalType(
|
return createFunctionalType(
|
||||||
|
kind,
|
||||||
parameterTypes,
|
parameterTypes,
|
||||||
receiverType = receiverParameter?.typeRef?.coneType,
|
receiverType = receiverParameter?.typeRef?.coneType,
|
||||||
rawReturnType = returnTypeRef.coneType,
|
rawReturnType = returnTypeRef.coneType,
|
||||||
isSuspend = this.isSuspend,
|
|
||||||
contextReceivers = contextReceiversTypes
|
contextReceivers = contextReceiversTypes
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.calls
|
package org.jetbrains.kotlin.fir.resolve.calls
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.isRegularFunction
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
@@ -265,12 +266,12 @@ fun Candidate.resolvePlainArgumentType(
|
|||||||
|
|
||||||
// If the argument is of functional type and the expected type is a suspend function type, we need to do "suspend conversion."
|
// If the argument is of functional type and the expected type is a suspend function type, we need to do "suspend conversion."
|
||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
argumentTypeWithSuspendConversion(
|
argumentTypeWithCustomConversion(
|
||||||
session, context.bodyResolveComponents.scopeSession, expectedType, argumentTypeForApplicabilityCheck
|
session, context.bodyResolveComponents.scopeSession, expectedType, argumentTypeForApplicabilityCheck
|
||||||
)?.let {
|
)?.let {
|
||||||
argumentTypeForApplicabilityCheck = it
|
argumentTypeForApplicabilityCheck = it
|
||||||
substitutor.substituteOrSelf(argumentTypeForApplicabilityCheck)
|
substitutor.substituteOrSelf(argumentTypeForApplicabilityCheck)
|
||||||
usesSuspendConversion = true
|
usesFunctionalConversion = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,18 +280,15 @@ fun Candidate.resolvePlainArgumentType(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun argumentTypeWithSuspendConversion(
|
private fun argumentTypeWithCustomConversion(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
scopeSession: ScopeSession,
|
scopeSession: ScopeSession,
|
||||||
expectedType: ConeKotlinType,
|
expectedType: ConeKotlinType,
|
||||||
argumentType: ConeKotlinType
|
argumentType: ConeKotlinType
|
||||||
): ConeKotlinType? {
|
): ConeKotlinType? {
|
||||||
// TODO: should refer to LanguageVersionSettings.SuspendConversion
|
// Expect the expected type to be a not regular functional type (e.g. suspend or custom)
|
||||||
|
val expectedTypeKind = expectedType.functionalTypeKind(session) ?: return null
|
||||||
// Expect the expected type to be a suspend functional type.
|
if (expectedTypeKind.isRegularFunction) return null
|
||||||
if (!expectedType.isSuspendOrKSuspendFunctionType(session)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to check the argument type against non-suspend functional type.
|
// We want to check the argument type against non-suspend functional type.
|
||||||
val expectedFunctionalType = expectedType.customFunctionalTypeToSimpleFunctionalType(session)
|
val expectedFunctionalType = expectedType.customFunctionalTypeToSimpleFunctionalType(session)
|
||||||
@@ -304,11 +302,10 @@ private fun argumentTypeWithSuspendConversion(
|
|||||||
shouldCalculateReturnTypesOfFakeOverrides = false
|
shouldCalculateReturnTypesOfFakeOverrides = false
|
||||||
)?.let { invokeSymbol ->
|
)?.let { invokeSymbol ->
|
||||||
createFunctionalType(
|
createFunctionalType(
|
||||||
|
expectedTypeKind,
|
||||||
invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType },
|
invokeSymbol.fir.valueParameters.map { it.returnTypeRef.coneType },
|
||||||
null,
|
null,
|
||||||
invokeSymbol.fir.returnTypeRef.coneType,
|
invokeSymbol.fir.returnTypeRef.coneType,
|
||||||
isSuspend = true,
|
|
||||||
isKFunctionType = argumentType.isReflectFunctionalType(session)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-13
@@ -7,10 +7,11 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.isRegularFunction
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||||
@@ -26,7 +27,6 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.SuspendConversionStrategy
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
|
import org.jetbrains.kotlin.resolve.calls.inference.runTransaction
|
||||||
@@ -130,14 +130,16 @@ private fun buildReflectionType(
|
|||||||
fir.valueParameters.mapTo(parameters) { it.returnTypeRef.coneType }
|
fir.valueParameters.mapTo(parameters) { it.returnTypeRef.coneType }
|
||||||
}
|
}
|
||||||
|
|
||||||
val isSuspend = (fir as? FirSimpleFunction)?.isSuspend == true ||
|
|
||||||
callableReferenceAdaptation?.suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
val baseFunctionalTypeKind = callableReferenceAdaptation?.suspendConversionStrategy?.kind
|
||||||
|
?: fir.specialFunctionalTypeKind(context.session)
|
||||||
|
?: FunctionalTypeKind.Function
|
||||||
|
|
||||||
return createFunctionalType(
|
return createFunctionalType(
|
||||||
|
baseFunctionalTypeKind.reflectKind(),
|
||||||
parameters,
|
parameters,
|
||||||
receiverType = receiverType.takeIf { fir.receiverParameter != null },
|
receiverType = receiverType.takeIf { fir.receiverParameter != null },
|
||||||
rawReturnType = returnType,
|
rawReturnType = returnType,
|
||||||
isKFunctionType = true,
|
|
||||||
isSuspend = isSuspend,
|
|
||||||
contextReceivers = fir.contextReceivers.map { it.typeRef.coneType }
|
contextReceivers = fir.contextReceivers.map { it.typeRef.coneType }
|
||||||
) to callableReferenceAdaptation
|
) to callableReferenceAdaptation
|
||||||
}
|
}
|
||||||
@@ -151,14 +153,14 @@ internal class CallableReferenceAdaptation(
|
|||||||
val coercionStrategy: CoercionStrategy,
|
val coercionStrategy: CoercionStrategy,
|
||||||
val defaults: Int,
|
val defaults: Int,
|
||||||
val mappedArguments: CallableReferenceMappedArguments,
|
val mappedArguments: CallableReferenceMappedArguments,
|
||||||
val suspendConversionStrategy: SuspendConversionStrategy
|
val suspendConversionStrategy: CallableReferenceConversionStrategy
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun CallableReferenceAdaptation?.needCompatibilityResolveForCallableReference(): Boolean {
|
private fun CallableReferenceAdaptation?.needCompatibilityResolveForCallableReference(): Boolean {
|
||||||
// KT-13934: check containing declaration for companion object
|
// KT-13934: check containing declaration for companion object
|
||||||
if (this == null) return false
|
if (this == null) return false
|
||||||
return defaults != 0 ||
|
return defaults != 0 ||
|
||||||
suspendConversionStrategy != SuspendConversionStrategy.NO_CONVERSION ||
|
suspendConversionStrategy != CallableReferenceConversionStrategy.NoConversion ||
|
||||||
coercionStrategy != CoercionStrategy.NO_COERCION ||
|
coercionStrategy != CoercionStrategy.NO_COERCION ||
|
||||||
mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
||||||
}
|
}
|
||||||
@@ -253,10 +255,14 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
|||||||
else
|
else
|
||||||
mappedArguments
|
mappedArguments
|
||||||
|
|
||||||
val suspendConversionStrategy = if ((function as? FirSimpleFunction)?.isSuspend != true && expectedType.isSuspendOrKSuspendFunctionType(session))
|
val expectedTypeFunctionalKind = expectedType.functionalTypeKind(session)?.takeUnless { it.isRegularFunction }
|
||||||
SuspendConversionStrategy.SUSPEND_CONVERSION
|
val functionKind = function.specialFunctionalTypeKind(session)
|
||||||
else
|
|
||||||
SuspendConversionStrategy.NO_CONVERSION
|
val conversionStrategy = if (expectedTypeFunctionalKind != null && functionKind == null) {
|
||||||
|
CallableReferenceConversionStrategy.CustomConversion(expectedTypeFunctionalKind)
|
||||||
|
} else {
|
||||||
|
CallableReferenceConversionStrategy.NoConversion
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return CallableReferenceAdaptation(
|
return CallableReferenceAdaptation(
|
||||||
@@ -264,10 +270,23 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
|||||||
coercionStrategy,
|
coercionStrategy,
|
||||||
defaults,
|
defaults,
|
||||||
adaptedArguments,
|
adaptedArguments,
|
||||||
suspendConversionStrategy
|
conversionStrategy
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sealed class CallableReferenceConversionStrategy {
|
||||||
|
abstract val kind: FunctionalTypeKind?
|
||||||
|
|
||||||
|
object NoConversion : CallableReferenceConversionStrategy() {
|
||||||
|
override val kind: FunctionalTypeKind?
|
||||||
|
get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomConversion(override val kind: FunctionalTypeKind) : CallableReferenceConversionStrategy()
|
||||||
|
}
|
||||||
|
|
||||||
private fun varargParameterTypeByExpectedParameter(
|
private fun varargParameterTypeByExpectedParameter(
|
||||||
expectedParameterType: ConeKotlinType,
|
expectedParameterType: ConeKotlinType,
|
||||||
substitutedParameter: FirValueParameter,
|
substitutedParameter: FirValueParameter,
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.scopes.FirScope
|
|||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.SuspendConversionStrategy
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError
|
||||||
@@ -63,13 +62,13 @@ class Candidate(
|
|||||||
internal var callableReferenceAdaptation: CallableReferenceAdaptation? = null
|
internal var callableReferenceAdaptation: CallableReferenceAdaptation? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
usesSuspendConversion = value?.suspendConversionStrategy == SuspendConversionStrategy.SUSPEND_CONVERSION
|
usesFunctionalConversion = value?.suspendConversionStrategy is CallableReferenceConversionStrategy.CustomConversion
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
numDefaults = value.defaults
|
numDefaults = value.defaults
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var usesSuspendConversion: Boolean = false
|
var usesFunctionalConversion: Boolean = false
|
||||||
|
|
||||||
var argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>? = null
|
var argumentMapping: LinkedHashMap<FirExpression, FirValueParameter>? = null
|
||||||
var numDefaults: Int = 0
|
var numDefaults: Int = 0
|
||||||
|
|||||||
+1
-2
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
|||||||
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
@@ -95,7 +94,7 @@ class ConeOverloadConflictResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (discriminateSuspendConversions) {
|
if (discriminateSuspendConversions) {
|
||||||
val filtered = candidates.filterTo(mutableSetOf()) { !it.usesSuspendConversion }
|
val filtered = candidates.filterTo(mutableSetOf()) { !it.usesFunctionalConversion }
|
||||||
when (filtered.size) {
|
when (filtered.size) {
|
||||||
1 -> return filtered
|
1 -> return filtered
|
||||||
0, candidates.size -> {
|
0, candidates.size -> {
|
||||||
|
|||||||
+2
-2
@@ -36,7 +36,7 @@ fun extractLambdaInfoFromFunctionalType(
|
|||||||
duringCompletion
|
duringCompletion
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (!expectedType.isSomeFunctionalType(session)) return null
|
val expectedFunctionalKind = expectedType.functionalTypeKind(session) ?: return null
|
||||||
|
|
||||||
val singleStatement = argument.body?.statements?.singleOrNull() as? FirReturnExpression
|
val singleStatement = argument.body?.statements?.singleOrNull() as? FirReturnExpression
|
||||||
if (argument.returnType == null && singleStatement != null &&
|
if (argument.returnType == null && singleStatement != null &&
|
||||||
@@ -100,7 +100,7 @@ fun extractLambdaInfoFromFunctionalType(
|
|||||||
return ResolvedLambdaAtom(
|
return ResolvedLambdaAtom(
|
||||||
argument,
|
argument,
|
||||||
expectedType,
|
expectedType,
|
||||||
expectedType.isSuspendOrKSuspendFunctionType(session),
|
expectedFunctionalKind,
|
||||||
receiverType,
|
receiverType,
|
||||||
contextReceivers,
|
contextReceivers,
|
||||||
parameters,
|
parameters,
|
||||||
|
|||||||
+7
-8
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.inference
|
package org.jetbrains.kotlin.fir.resolve.inference
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
|
import org.jetbrains.kotlin.fir.expressions.FirAnonymousFunctionExpression
|
||||||
@@ -21,6 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
fun Candidate.preprocessLambdaArgument(
|
fun Candidate.preprocessLambdaArgument(
|
||||||
csBuilder: ConstraintSystemBuilder,
|
csBuilder: ConstraintSystemBuilder,
|
||||||
@@ -62,10 +64,10 @@ fun Candidate.preprocessLambdaArgument(
|
|||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
val parameters = resolvedArgument.parameters
|
val parameters = resolvedArgument.parameters
|
||||||
val lambdaType = createFunctionalType(
|
val lambdaType = createFunctionalType(
|
||||||
|
resolvedArgument.expectedFunctionalTypeKind ?: FunctionalTypeKind.Function,
|
||||||
if (resolvedArgument.coerceFirstParameterToExtensionReceiver) parameters.drop(1) else parameters,
|
if (resolvedArgument.coerceFirstParameterToExtensionReceiver) parameters.drop(1) else parameters,
|
||||||
resolvedArgument.receiver,
|
resolvedArgument.receiver,
|
||||||
resolvedArgument.returnType,
|
resolvedArgument.returnType,
|
||||||
isSuspend = resolvedArgument.isSuspend,
|
|
||||||
contextReceivers = resolvedArgument.contextReceivers,
|
contextReceivers = resolvedArgument.contextReceivers,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -105,18 +107,15 @@ private fun extractLambdaInfo(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
candidate: Candidate?
|
candidate: Candidate?
|
||||||
): ResolvedLambdaAtom {
|
): ResolvedLambdaAtom {
|
||||||
val isSuspend = expectedType?.isSuspendOrKSuspendFunctionType(session) ?: false
|
val expectedFunctionalKind = expectedType?.lowerBoundIfFlexible()?.functionalTypeKind(session)
|
||||||
|
val isFunctionSupertype = expectedFunctionalKind != null
|
||||||
val isFunctionSupertype =
|
|
||||||
expectedType != null && expectedType.lowerBoundIfFlexible()
|
|
||||||
.isSomeFunctionalType(session)//isNotNullOrNullableFunctionSupertype(expectedType)
|
|
||||||
|
|
||||||
val typeVariable = ConeTypeVariableForLambdaReturnType(argument, "_L")
|
val typeVariable = ConeTypeVariableForLambdaReturnType(argument, "_L")
|
||||||
|
|
||||||
val receiverType = argument.receiverType
|
val receiverType = argument.receiverType
|
||||||
val returnType =
|
val returnType =
|
||||||
argument.returnType
|
argument.returnType
|
||||||
?: (expectedType?.typeArguments?.singleOrNull() as? ConeKotlinTypeProjection)?.type?.takeIf { isFunctionSupertype }
|
?: runIf(isFunctionSupertype) { (expectedType?.typeArguments?.singleOrNull() as? ConeKotlinTypeProjection)?.type }
|
||||||
?: typeVariable.defaultType
|
?: typeVariable.defaultType
|
||||||
|
|
||||||
val nothingType = session.builtinTypes.nothingType.type
|
val nothingType = session.builtinTypes.nothingType.type
|
||||||
@@ -134,7 +133,7 @@ private fun extractLambdaInfo(
|
|||||||
return ResolvedLambdaAtom(
|
return ResolvedLambdaAtom(
|
||||||
argument,
|
argument,
|
||||||
expectedType,
|
expectedType,
|
||||||
isSuspend,
|
expectedFunctionalKind,
|
||||||
receiverType,
|
receiverType,
|
||||||
contextReceivers,
|
contextReceivers,
|
||||||
parameters,
|
parameters,
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve.inference
|
package org.jetbrains.kotlin.fir.resolve.inference
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
@@ -39,7 +40,7 @@ sealed class PostponedResolvedAtom : PostponedResolvedAtomMarker {
|
|||||||
class ResolvedLambdaAtom(
|
class ResolvedLambdaAtom(
|
||||||
override val atom: FirAnonymousFunction,
|
override val atom: FirAnonymousFunction,
|
||||||
expectedType: ConeKotlinType?,
|
expectedType: ConeKotlinType?,
|
||||||
val isSuspend: Boolean,
|
val expectedFunctionalTypeKind: FunctionalTypeKind?,
|
||||||
val receiver: ConeKotlinType?,
|
val receiver: ConeKotlinType?,
|
||||||
val contextReceivers: List<ConeKotlinType>,
|
val contextReceivers: List<ConeKotlinType>,
|
||||||
val parameters: List<ConeKotlinType>,
|
val parameters: List<ConeKotlinType>,
|
||||||
|
|||||||
+6
-5
@@ -570,12 +570,12 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
firRegularClass?.let answer@{
|
firRegularClass?.let answer@{
|
||||||
val functionType = samResolver.getFunctionTypeForPossibleSamType(firRegularClass.defaultType())
|
val functionType = samResolver.getFunctionTypeForPossibleSamType(firRegularClass.defaultType())
|
||||||
?: return@answer null
|
?: return@answer null
|
||||||
|
val kind = functionType.functionalTypeKind(session) ?: FunctionalTypeKind.Function
|
||||||
createFunctionalType(
|
createFunctionalType(
|
||||||
|
kind,
|
||||||
functionType.typeArguments.dropLast(1).map { it as ConeKotlinType },
|
functionType.typeArguments.dropLast(1).map { it as ConeKotlinType },
|
||||||
null,
|
null,
|
||||||
functionType.typeArguments.last() as ConeKotlinType,
|
functionType.typeArguments.last() as ConeKotlinType
|
||||||
functionType.classId?.relativeClassName?.asString()
|
|
||||||
?.startsWith(FunctionalTypeKind.SuspendFunction.classNamePrefix) == true
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -617,8 +617,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (needUpdateLambdaType) {
|
if (needUpdateLambdaType) {
|
||||||
val isSuspend = expectedType?.isSuspendOrKSuspendFunctionType(session) ?: result.isExplicitlySuspend(session)
|
val kind = expectedType?.functionalTypeKind(session)
|
||||||
result.replaceTypeRef(result.constructFunctionalTypeRef(isSuspend))
|
?: result.typeRef.coneTypeSafe<ConeClassLikeType>()?.functionalTypeKind(session)
|
||||||
|
result.replaceTypeRef(result.constructFunctionalTypeRef(kind))
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(result.typeRef, result.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(result.typeRef, result.source, context.file.source)
|
||||||
}
|
}
|
||||||
// Have to delay this until the type is written to avoid adding a return if the type is Unit.
|
// Have to delay this until the type is written to avoid adding a return if the type is Unit.
|
||||||
|
|||||||
+1
-1
@@ -805,7 +805,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
|
|||||||
session.lookupTracker?.recordTypeResolveAsLookup(lambda.returnTypeRef, lambda.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(lambda.returnTypeRef, lambda.source, context.file.source)
|
||||||
}
|
}
|
||||||
|
|
||||||
lambda.replaceTypeRef(lambda.constructFunctionalTypeRef(resolvedLambdaAtom?.isSuspend == true))
|
lambda.replaceTypeRef(lambda.constructFunctionalTypeRef(resolvedLambdaAtom?.expectedFunctionalTypeKind))
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(lambda.typeRef, lambda.source, context.file.source)
|
session.lookupTracker?.recordTypeResolveAsLookup(lambda.typeRef, lambda.source, context.file.source)
|
||||||
lambda.addReturnToLastStatementIfNeeded()
|
lambda.addReturnToLastStatementIfNeeded()
|
||||||
return lambda
|
return lambda
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
|||||||
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKindExtractor
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
abstract class FirFunctionalTypeKindService : FirSessionComponent {
|
abstract class FirFunctionalTypeKindService : FirSessionComponent {
|
||||||
@@ -21,6 +23,9 @@ abstract class FirFunctionalTypeKindService : FirSessionComponent {
|
|||||||
fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
|
fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean {
|
||||||
return extractor.hasKindWithSpecificPackage(packageFqName)
|
return extractor.hasKindWithSpecificPackage(packageFqName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract fun extractSingleSpecialKindForFunction(functionSymbol: FirNamedFunctionSymbol): FunctionalTypeKind?
|
||||||
|
abstract fun extractAllSpecialKindsForFunction(functionSymbol: FirNamedFunctionSymbol): List<FunctionalTypeKind>
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.functionalTypeService: FirFunctionalTypeKindService by FirSession.sessionComponentAccessor()
|
val FirSession.functionalTypeService: FirFunctionalTypeKindService by FirSession.sessionComponentAccessor()
|
||||||
|
|||||||
+14
-10
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.isRegularFunction
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
@@ -28,7 +30,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
val parametersFromConstraints: Set<List<TypeWithKind>>?,
|
val parametersFromConstraints: Set<List<TypeWithKind>>?,
|
||||||
val annotations: List<AnnotationMarker>?,
|
val annotations: List<AnnotationMarker>?,
|
||||||
val isExtensionFunction: Boolean,
|
val isExtensionFunction: Boolean,
|
||||||
val isSuspend: Boolean,
|
val functionalTypeKind: FunctionalTypeKind,
|
||||||
val isNullable: Boolean
|
val isNullable: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -94,14 +96,16 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
parameterTypesFromDeclaration,
|
parameterTypesFromDeclaration,
|
||||||
)
|
)
|
||||||
|
|
||||||
var isSuspend = false
|
var functionalTypeKind: FunctionalTypeKind? = null
|
||||||
var isNullable = false
|
var isNullable = false
|
||||||
if (!functionalTypesFromConstraints.isNullOrEmpty()) {
|
if (functionalTypesFromConstraints.isNotEmpty()) {
|
||||||
isNullable = true
|
isNullable = true
|
||||||
for (funType in functionalTypesFromConstraints) {
|
for (funType in functionalTypesFromConstraints) {
|
||||||
if (!isSuspend && funType.type.isSuspendFunctionTypeOrSubtype()) isSuspend = true
|
if (functionalTypeKind == null) {
|
||||||
|
funType.type.functionalTypeKind()?.takeUnless { it.isRegularFunction }?.let { functionalTypeKind = it }
|
||||||
|
}
|
||||||
if (isNullable && !funType.type.isMarkedNullable()) isNullable = false
|
if (isNullable && !funType.type.isMarkedNullable()) isNullable = false
|
||||||
if (isSuspend && !isNullable) break
|
if ((functionalTypeKind != null) && !isNullable) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +126,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
parameterTypesFromConstraints,
|
parameterTypesFromConstraints,
|
||||||
annotations = annotations,
|
annotations = annotations,
|
||||||
isExtensionFunction,
|
isExtensionFunction,
|
||||||
isSuspend = isSuspend,
|
functionalTypeKind ?: FunctionalTypeKind.Function,
|
||||||
isNullable = isNullable
|
isNullable = isNullable
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -254,7 +258,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
private fun Context.computeResultingFunctionalConstructor(
|
private fun Context.computeResultingFunctionalConstructor(
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
parametersNumber: Int,
|
parametersNumber: Int,
|
||||||
isSuspend: Boolean,
|
functionalTypeKind: FunctionalTypeKind,
|
||||||
resultTypeResolver: ResultTypeResolver
|
resultTypeResolver: ResultTypeResolver
|
||||||
): TypeConstructorMarker {
|
): TypeConstructorMarker {
|
||||||
val expectedType = argument.expectedType
|
val expectedType = argument.expectedType
|
||||||
@@ -264,7 +268,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
|
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is LambdaWithTypeVariableAsExpectedTypeMarker ->
|
is LambdaWithTypeVariableAsExpectedTypeMarker ->
|
||||||
getFunctionTypeConstructor(parametersNumber, isSuspend)
|
getNonReflectFunctionTypeConstructor(parametersNumber, functionalTypeKind)
|
||||||
is PostponedCallableReferenceMarker -> {
|
is PostponedCallableReferenceMarker -> {
|
||||||
val computedResultType = resultTypeResolver.findResultType(
|
val computedResultType = resultTypeResolver.findResultType(
|
||||||
this@computeResultingFunctionalConstructor,
|
this@computeResultingFunctionalConstructor,
|
||||||
@@ -276,7 +280,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
if (computedResultType.isBuiltinFunctionalTypeOrSubtype() && computedResultType.argumentsCount() > 1) {
|
if (computedResultType.isBuiltinFunctionalTypeOrSubtype() && computedResultType.argumentsCount() > 1) {
|
||||||
computedResultType.typeConstructor()
|
computedResultType.typeConstructor()
|
||||||
} else {
|
} else {
|
||||||
getKFunctionTypeConstructor(parametersNumber, isSuspend)
|
getReflectFunctionTypeConstructor(parametersNumber, functionalTypeKind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||||
@@ -378,7 +382,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
val functionalConstructor = computeResultingFunctionalConstructor(
|
val functionalConstructor = computeResultingFunctionalConstructor(
|
||||||
argument,
|
argument,
|
||||||
variablesForParameterTypes.size,
|
variablesForParameterTypes.size,
|
||||||
parameterTypesInfo.isSuspend,
|
parameterTypesInfo.functionalTypeKind,
|
||||||
resultTypeResolver
|
resultTypeResolver
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Vendored
+3
-3
@@ -44,7 +44,7 @@ FILE fqName:<root> fileName:/adaptedExtensionFunctions.kt
|
|||||||
FUN name:testExtensionVararg visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testExtensionVararg visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
f: FUN_EXPR type=kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
f: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
||||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionVararg visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionVararg visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
||||||
@@ -55,7 +55,7 @@ FILE fqName:<root> fileName:/adaptedExtensionFunctions.kt
|
|||||||
FUN name:testExtensionDefault visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testExtensionDefault visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
f: FUN_EXPR type=kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
f: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
||||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionDefault visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionDefault visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
||||||
@@ -66,7 +66,7 @@ FILE fqName:<root> fileName:/adaptedExtensionFunctions.kt
|
|||||||
FUN name:testExtensionBoth visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
FUN name:testExtensionBoth visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
CALL 'public final fun use (f: @[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||||
f: FUN_EXPR type=kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
f: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function2<<root>.C, kotlin.Int, kotlin.Unit> origin=ADAPTED_FUNCTION_REFERENCE
|
||||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionBoth visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:extensionBoth visibility:local modality:FINAL <> (p0:<root>.C, p1:kotlin.Int) returnType:kotlin.Unit
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.C
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ FILE fqName:<root> fileName:/cannotCastToFunction.kt
|
|||||||
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||||
arg0: GET_VAR 'dumpStrategy: kotlin.String declared in <root>.dump' type=kotlin.String origin=null
|
arg0: GET_VAR 'dumpStrategy: kotlin.String declared in <root>.dump' type=kotlin.String origin=null
|
||||||
arg1: CONST String type=kotlin.String value="KotlinLike"
|
arg1: CONST String type=kotlin.String value="KotlinLike"
|
||||||
then: FUN_EXPR type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
|
then: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
|
||||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dumpKotlinLike visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
|
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dumpKotlinLike visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -56,7 +56,7 @@ FILE fqName:<root> fileName:/cannotCastToFunction.kt
|
|||||||
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dumpKotlinLike' type=<root>.IrElement origin=null
|
$receiver: GET_VAR 'p0: <root>.IrElement declared in <root>.dump.dumpKotlinLike' type=<root>.IrElement origin=null
|
||||||
BRANCH
|
BRANCH
|
||||||
if: CONST Boolean type=kotlin.Boolean value=true
|
if: CONST Boolean type=kotlin.Boolean value=true
|
||||||
then: FUN_EXPR type=kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
|
then: FUN_EXPR type=@[ExtensionFunctionType] kotlin.Function1<<root>.IrElement, kotlin.String> origin=ADAPTED_FUNCTION_REFERENCE
|
||||||
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dump visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
|
FUN ADAPTER_FOR_CALLABLE_REFERENCE name:dump visibility:local modality:FINAL <> (p0:<root>.IrElement) returnType:kotlin.String
|
||||||
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
|
VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p0 index:0 type:<root>.IrElement
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
+5
-1
@@ -85,6 +85,8 @@ abstract class FunctionalTypeKind internal constructor(
|
|||||||
|
|
||||||
fun numberedClassName(arity: Int): Name = Name.identifier("$classNamePrefix$arity")
|
fun numberedClassName(arity: Int): Name = Name.identifier("$classNamePrefix$arity")
|
||||||
|
|
||||||
|
fun numberedClassId(arity: Int): ClassId = ClassId(packageFqName, numberedClassName(arity))
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "$packageFqName.${classNamePrefix}N"
|
return "$packageFqName.${classNamePrefix}N"
|
||||||
}
|
}
|
||||||
@@ -141,5 +143,7 @@ val FunctionalTypeKind.isBuiltin: Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
val FunctionalTypeKind.isSuspendType: Boolean
|
val FunctionalTypeKind.isSuspendType: Boolean
|
||||||
get() = this == FunctionalTypeKind.SuspendFunction || this == FunctionalTypeKind.KSuspendFunction
|
get() = this.nonReflectKind() == FunctionalTypeKind.SuspendFunction
|
||||||
|
|
||||||
|
val FunctionalTypeKind.isRegularFunction: Boolean
|
||||||
|
get() = this.nonReflectKind() == FunctionalTypeKind.Function
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.types.model
|
package org.jetbrains.kotlin.types.model
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.resolve.checkers.EmptyIntersectionTypeChecker
|
import org.jetbrains.kotlin.resolve.checkers.EmptyIntersectionTypeChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.EmptyIntersectionTypeInfo
|
import org.jetbrains.kotlin.resolve.checkers.EmptyIntersectionTypeInfo
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -247,9 +248,11 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
|||||||
|
|
||||||
fun KotlinTypeMarker.isSignedOrUnsignedNumberType(): Boolean
|
fun KotlinTypeMarker.isSignedOrUnsignedNumberType(): Boolean
|
||||||
|
|
||||||
|
// ------------- functional type utils -------------
|
||||||
|
|
||||||
fun KotlinTypeMarker.isFunctionOrKFunctionWithAnySuspendability(): Boolean
|
fun KotlinTypeMarker.isFunctionOrKFunctionWithAnySuspendability(): Boolean
|
||||||
|
|
||||||
fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean
|
fun KotlinTypeMarker.functionalTypeKind(): FunctionalTypeKind?
|
||||||
|
|
||||||
fun KotlinTypeMarker.isExtensionFunctionType(): Boolean
|
fun KotlinTypeMarker.isExtensionFunctionType(): Boolean
|
||||||
|
|
||||||
@@ -257,12 +260,14 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
|||||||
|
|
||||||
fun KotlinTypeMarker.getFunctionalTypeFromSupertypes(): KotlinTypeMarker
|
fun KotlinTypeMarker.getFunctionalTypeFromSupertypes(): KotlinTypeMarker
|
||||||
|
|
||||||
|
fun getNonReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker
|
||||||
|
|
||||||
|
fun getReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
|
||||||
fun StubTypeMarker.getOriginalTypeVariable(): TypeVariableTypeConstructorMarker
|
fun StubTypeMarker.getOriginalTypeVariable(): TypeVariableTypeConstructorMarker
|
||||||
|
|
||||||
fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker
|
|
||||||
|
|
||||||
fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker
|
|
||||||
|
|
||||||
private fun <T> KotlinTypeMarker.extractTypeOf(to: MutableSet<T>, getIfApplicable: (TypeConstructorMarker) -> T?) {
|
private fun <T> KotlinTypeMarker.extractTypeOf(to: MutableSet<T>, getIfApplicable: (TypeConstructorMarker) -> T?) {
|
||||||
for (i in 0 until argumentsCount()) {
|
for (i in 0 until argumentsCount()) {
|
||||||
val argument = getArgument(i)
|
val argument = getArgument(i)
|
||||||
|
|||||||
@@ -59,17 +59,20 @@ val KotlinType.isBuiltinFunctionalTypeOrSubtype: Boolean
|
|||||||
fun KotlinType.isFunctionTypeOrSubtype(predicate: (KotlinType) -> Boolean): Boolean =
|
fun KotlinType.isFunctionTypeOrSubtype(predicate: (KotlinType) -> Boolean): Boolean =
|
||||||
isTypeOrSubtypeOf { it.isFunctionType && predicate(it) }
|
isTypeOrSubtypeOf { it.isFunctionType && predicate(it) }
|
||||||
|
|
||||||
|
val KotlinType.functionalTypeKind: FunctionalTypeKind?
|
||||||
|
get() = constructor.declarationDescriptor?.getFunctionalClassKind()
|
||||||
|
|
||||||
val KotlinType.isFunctionType: Boolean
|
val KotlinType.isFunctionType: Boolean
|
||||||
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.Function
|
get() = functionalTypeKind == FunctionalTypeKind.Function
|
||||||
|
|
||||||
val KotlinType.isKFunctionType: Boolean
|
val KotlinType.isKFunctionType: Boolean
|
||||||
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.KFunction
|
get() = functionalTypeKind == FunctionalTypeKind.KFunction
|
||||||
|
|
||||||
val KotlinType.isSuspendFunctionType: Boolean
|
val KotlinType.isSuspendFunctionType: Boolean
|
||||||
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.SuspendFunction
|
get() = functionalTypeKind == FunctionalTypeKind.SuspendFunction
|
||||||
|
|
||||||
val KotlinType.isKSuspendFunctionType: Boolean
|
val KotlinType.isKSuspendFunctionType: Boolean
|
||||||
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionalTypeKind.KSuspendFunction
|
get() = functionalTypeKind == FunctionalTypeKind.KSuspendFunction
|
||||||
|
|
||||||
val KotlinType.isFunctionOrSuspendFunctionType: Boolean
|
val KotlinType.isFunctionOrSuspendFunctionType: Boolean
|
||||||
get() = isFunctionType || isSuspendFunctionType
|
get() = isFunctionType || isSuspendFunctionType
|
||||||
|
|||||||
+18
-9
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.types.checker
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.*
|
import org.jetbrains.kotlin.builtins.*
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
|
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
@@ -849,11 +850,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this.isFunctionOrKFunctionTypeWithAnySuspendability
|
return this.isFunctionOrKFunctionTypeWithAnySuspendability
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean {
|
|
||||||
require(this is KotlinType, this::errorMessage)
|
|
||||||
return this.isSuspendFunctionTypeOrSubtype
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
||||||
require(this is KotlinType, this::errorMessage)
|
require(this is KotlinType, this::errorMessage)
|
||||||
return this.isBuiltinExtensionFunctionalType
|
return this.isBuiltinExtensionFunctionalType
|
||||||
@@ -869,12 +865,25 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this.extractFunctionalTypeFromSupertypes()
|
return this.extractFunctionalTypeFromSupertypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
override fun KotlinTypeMarker.functionalTypeKind(): FunctionalTypeKind? {
|
||||||
return getFunctionDescriptor(builtIns, parametersNumber, isSuspend).typeConstructor
|
require(this is KotlinType)
|
||||||
|
return this.functionalTypeKind
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
override fun getNonReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker {
|
||||||
return getKFunctionDescriptor(builtIns, parametersNumber, isSuspend).typeConstructor
|
return getFunctionDescriptor(
|
||||||
|
builtIns,
|
||||||
|
parametersNumber,
|
||||||
|
isSuspendFunction = kind.nonReflectKind() == FunctionalTypeKind.SuspendFunction
|
||||||
|
).typeConstructor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getReflectFunctionTypeConstructor(parametersNumber: Int, kind: FunctionalTypeKind): TypeConstructorMarker {
|
||||||
|
return getKFunctionDescriptor(
|
||||||
|
builtIns,
|
||||||
|
parametersNumber,
|
||||||
|
isSuspendFunction = kind.reflectKind() == FunctionalTypeKind.KSuspendFunction
|
||||||
|
).typeConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createSubstitutorForSuperTypes(baseType: KotlinTypeMarker): TypeSubstitutorMarker? {
|
override fun createSubstitutorForSuperTypes(baseType: KotlinTypeMarker): TypeSubstitutorMarker? {
|
||||||
|
|||||||
+5
-3
@@ -5,15 +5,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.samWithReceiver.k2
|
package org.jetbrains.kotlin.samWithReceiver.k2
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSamConversionTransformerExtension
|
import org.jetbrains.kotlin.fir.resolve.FirSamConversionTransformerExtension
|
||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.functionalTypeService
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
class FirSamWithReceiverConventionTransformer(
|
class FirSamWithReceiverConventionTransformer(
|
||||||
@@ -25,11 +26,12 @@ class FirSamWithReceiverConventionTransformer(
|
|||||||
return runIf(containingClassSymbol.resolvedAnnotationClassIds.any { it.asSingleFqName().asString() in annotations }) {
|
return runIf(containingClassSymbol.resolvedAnnotationClassIds.any { it.asSingleFqName().asString() in annotations }) {
|
||||||
val parameterTypes = function.valueParameters.map { it.returnTypeRef.coneType }
|
val parameterTypes = function.valueParameters.map { it.returnTypeRef.coneType }
|
||||||
if (parameterTypes.isEmpty()) return null
|
if (parameterTypes.isEmpty()) return null
|
||||||
|
val kind = session.functionalTypeService.extractSingleSpecialKindForFunction(function.symbol) ?: FunctionalTypeKind.Function
|
||||||
createFunctionalType(
|
createFunctionalType(
|
||||||
|
kind,
|
||||||
parameters = parameterTypes.subList(1, parameterTypes.size),
|
parameters = parameterTypes.subList(1, parameterTypes.size),
|
||||||
receiverType = parameterTypes[0],
|
receiverType = parameterTypes[0],
|
||||||
rawReturnType = function.returnTypeRef.coneType,
|
rawReturnType = function.returnTypeRef.coneType
|
||||||
isSuspend = function.isSuspend
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -8,6 +8,7 @@
|
|||||||
package org.jetbrains.kotlin.scripting.compiler.plugin.impl
|
package org.jetbrains.kotlin.scripting.compiler.plugin.impl
|
||||||
|
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionalTypeKind
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||||
@@ -41,7 +42,6 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.builder.scriptConfigurators
|
import org.jetbrains.kotlin.fir.builder.scriptConfigurators
|
||||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.resolve.FirSamConversionTransformerExtension
|
import org.jetbrains.kotlin.fir.resolve.FirSamConversionTransformerExtension
|
||||||
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
|||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.fir.types.functionalTypeService
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -158,11 +159,12 @@ internal class FirScriptingSamWithReceiverExtensionRegistrar() : FirExtensionReg
|
|||||||
return runIf(containingClassSymbol.resolvedAnnotationClassIds.any { it.asSingleFqName().asString() in knownAnnotations }) {
|
return runIf(containingClassSymbol.resolvedAnnotationClassIds.any { it.asSingleFqName().asString() in knownAnnotations }) {
|
||||||
val parameterTypes = function.valueParameters.map { it.returnTypeRef.coneType }
|
val parameterTypes = function.valueParameters.map { it.returnTypeRef.coneType }
|
||||||
if (parameterTypes.isEmpty()) return null
|
if (parameterTypes.isEmpty()) return null
|
||||||
|
val kind = session.functionalTypeService.extractSingleSpecialKindForFunction(function.symbol) ?: FunctionalTypeKind.Function
|
||||||
createFunctionalType(
|
createFunctionalType(
|
||||||
|
kind,
|
||||||
parameters = parameterTypes.subList(1, parameterTypes.size),
|
parameters = parameterTypes.subList(1, parameterTypes.size),
|
||||||
receiverType = parameterTypes[0],
|
receiverType = parameterTypes[0],
|
||||||
rawReturnType = function.returnTypeRef.coneType,
|
rawReturnType = function.returnTypeRef.coneType
|
||||||
isSuspend = function.isSuspend
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user