[FIR] Add useful util extensions for cone type
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -55,3 +56,22 @@ fun ConeClassLikeType.replaceArgumentsWithStarProjections(): ConeClassLikeType {
|
||||
val newArguments = Array(typeArguments.size) { ConeStarProjection }
|
||||
return withArguments(newArguments)
|
||||
}
|
||||
|
||||
val ConeKotlinType.isAny: Boolean get() = isBuiltinType(StandardClassIds.Any, false)
|
||||
val ConeKotlinType.isNullableAny: Boolean get() = isBuiltinType(StandardClassIds.Any, true)
|
||||
val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, false)
|
||||
val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true)
|
||||
val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false)
|
||||
val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false)
|
||||
val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false)
|
||||
val ConeKotlinType.isArrayType: Boolean
|
||||
get() {
|
||||
return isBuiltinType(StandardClassIds.Array, false) ||
|
||||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
|
||||
|
||||
if (this !is ConeClassLikeType) return false
|
||||
return lookupTag.classId == classId && type.isNullable == isNullable
|
||||
}
|
||||
|
||||
+2
-2
@@ -226,7 +226,7 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation(
|
||||
}
|
||||
}
|
||||
|
||||
val coercionStrategy = if (returnExpectedType.isUnit && !function.returnTypeRef.isUnit)
|
||||
val coercionStrategy = if (returnExpectedType.isUnitOrFlexibleUnit && !function.returnTypeRef.isUnit)
|
||||
CoercionStrategy.COERCION_TO_UNIT
|
||||
else
|
||||
CoercionStrategy.NO_COERCION
|
||||
@@ -288,7 +288,7 @@ private enum class VarargMappingState {
|
||||
|
||||
private fun FirFunction<*>.indexOf(valueParameter: FirValueParameter): Int = valueParameters.indexOf(valueParameter)
|
||||
|
||||
val ConeKotlinType.isUnit: Boolean
|
||||
val ConeKotlinType.isUnitOrFlexibleUnit: Boolean
|
||||
get() {
|
||||
val type = this.lowerBoundIfFlexible()
|
||||
if (type.isNullable) return false
|
||||
|
||||
+2
-2
@@ -168,14 +168,14 @@ class PostponedArgumentsAnalyzer(
|
||||
val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression
|
||||
var hasExpressionInReturnArguments = false
|
||||
// No constraint for return expressions of lambda if it has Unit return type.
|
||||
val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnit }
|
||||
val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnitOrFlexibleUnit }
|
||||
returnArguments.forEach {
|
||||
if (it !is FirExpression) return@forEach
|
||||
hasExpressionInReturnArguments = true
|
||||
// If it is the last expression, and the expected type is Unit, that expression will be coerced to Unit.
|
||||
// If the last expression is of Unit type, of course it's not coercion-to-Unit case.
|
||||
val lastExpressionCoercedToUnit =
|
||||
it == lastExpression && expectedReturnType?.isUnit == true && !it.typeRef.coneType.isUnit
|
||||
it == lastExpression && expectedReturnType?.isUnitOrFlexibleUnit == true && !it.typeRef.coneType.isUnitOrFlexibleUnit
|
||||
// No constraint for the last expression of lambda if it will be coerced to Unit.
|
||||
if (!lastExpressionCoercedToUnit) {
|
||||
candidate.resolveArgumentExpression(
|
||||
|
||||
@@ -7,13 +7,12 @@ package org.jetbrains.kotlin.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.Visibility
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.classId
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.fakeElement
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
@@ -184,6 +183,10 @@ fun ConeKotlinType.isUnsafeVarianceType(session: FirSession): Boolean {
|
||||
return type.attributes.unsafeVarianceType != null
|
||||
}
|
||||
|
||||
fun ConeKotlinType.toSymbol(session: FirSession): AbstractFirBasedSymbol<*>? {
|
||||
return (this as? ConeLookupTagBasedType)?.lookupTag?.toSymbol(session)
|
||||
}
|
||||
|
||||
fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean {
|
||||
return coneTypeSafe<ConeKotlinType>()?.isUnsafeVarianceType(session) == true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user