FIR: handle getClassCall with integer literals

This commit is contained in:
Jinseong Jeon
2020-07-06 23:43:00 -07:00
committed by Mikhail Glukhikh
parent 7f472ba24e
commit 3afc37438e
3 changed files with 27 additions and 15 deletions
@@ -565,7 +565,13 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
}
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
val transformedGetClassCall = transformExpression(getClassCall, data).single as FirGetClassCall
val arg = getClassCall.argument
val dataWithExpectedType = if (arg is FirConstExpression<*>) {
withExpectedType(arg.typeRef.resolvedTypeFromPrototype(arg.kind.expectedConeType()))
} else {
data
}
val transformedGetClassCall = transformExpression(getClassCall, dataWithExpectedType).single as FirGetClassCall
val typeOfExpression = when (val lhs = transformedGetClassCall.argument) {
is FirResolvedQualifier -> {
@@ -604,17 +610,12 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
return transformedGetClassCall.compose()
}
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ResolutionMode,
): CompositeTransformResult<FirStatement> {
constExpression.annotations.forEach { it.accept(this, data) }
private fun FirConstKind<*>.expectedConeType(): ConeKotlinType {
fun constructLiteralType(classId: ClassId, isNullable: Boolean = false): ConeKotlinType {
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId) ?: return ConeClassErrorType("Missing stdlib class: $classId")
return symbol.toLookupTag().constructClassType(emptyArray(), isNullable)
}
val type = when (val kind = constExpression.kind) {
return when (this) {
FirConstKind.Null -> session.builtinTypes.nullableNothingType.type
FirConstKind.Boolean -> session.builtinTypes.booleanType.type
FirConstKind.Char -> constructLiteralType(StandardClassIds.Char)
@@ -626,6 +627,23 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
FirConstKind.Float -> constructLiteralType(StandardClassIds.Float)
FirConstKind.Double -> constructLiteralType(StandardClassIds.Double)
FirConstKind.UnsignedByte -> constructLiteralType(StandardClassIds.UByte)
FirConstKind.UnsignedShort -> constructLiteralType(StandardClassIds.UShort)
FirConstKind.UnsignedInt -> constructLiteralType(StandardClassIds.UInt)
FirConstKind.UnsignedLong -> constructLiteralType(StandardClassIds.ULong)
FirConstKind.IntegerLiteral -> constructLiteralType(StandardClassIds.Int)
FirConstKind.UnsignedIntegerLiteral -> constructLiteralType(StandardClassIds.UInt)
}
}
override fun <T> transformConstExpression(
constExpression: FirConstExpression<T>,
data: ResolutionMode,
): CompositeTransformResult<FirStatement> {
constExpression.annotations.forEach { it.accept(this, data) }
val type = when (val kind = constExpression.kind) {
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> {
val integerLiteralType =
ConeIntegerLiteralTypeImpl(constExpression.value as Long, isUnsigned = kind == FirConstKind.UnsignedIntegerLiteral)
@@ -650,11 +668,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
integerLiteralType
}
}
FirConstKind.UnsignedByte -> constructLiteralType(StandardClassIds.UByte)
FirConstKind.UnsignedShort -> constructLiteralType(StandardClassIds.UShort)
FirConstKind.UnsignedInt -> constructLiteralType(StandardClassIds.UInt)
FirConstKind.UnsignedLong -> constructLiteralType(StandardClassIds.ULong)
else -> kind.expectedConeType()
}
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_REFLECT
// TARGET_BACKEND: JVM
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// TARGET_BACKEND: JVM