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