diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 3a6a027f4a8..54bb1411839 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.expectedConeType import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl @@ -519,6 +520,9 @@ private fun List.createArrayOfCall(session: FirSession, @Suppress("UNUSED arguments += element.createConstantOrError(session) } } + typeRef = buildResolvedTypeRef { + type = kind.expectedConeType(session).createArrayType() + } } } @@ -530,15 +534,15 @@ internal fun Any?.createConstantOrError(session: FirSession): FirExpression { internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? { return when (this) { - is Byte -> buildConstExpression(null, FirConstKind.Byte, this) - is Short -> buildConstExpression(null, FirConstKind.Short, this) - is Int -> buildConstExpression(null, FirConstKind.Int, this) - is Long -> buildConstExpression(null, FirConstKind.Long, this) - is Char -> buildConstExpression(null, FirConstKind.Char, this) - is Float -> buildConstExpression(null, FirConstKind.Float, this) - is Double -> buildConstExpression(null, FirConstKind.Double, this) - is Boolean -> buildConstExpression(null, FirConstKind.Boolean, this) - is String -> buildConstExpression(null, FirConstKind.String, this) + is Byte -> buildConstExpression(null, FirConstKind.Byte, this).setProperType(session) + is Short -> buildConstExpression(null, FirConstKind.Short, this).setProperType(session) + is Int -> buildConstExpression(null, FirConstKind.Int, this).setProperType(session) + is Long -> buildConstExpression(null, FirConstKind.Long, this).setProperType(session) + is Char -> buildConstExpression(null, FirConstKind.Char, this).setProperType(session) + is Float -> buildConstExpression(null, FirConstKind.Float, this).setProperType(session) + is Double -> buildConstExpression(null, FirConstKind.Double, this).setProperType(session) + is Boolean -> buildConstExpression(null, FirConstKind.Boolean, this).setProperType(session) + is String -> buildConstExpression(null, FirConstKind.String, this).setProperType(session) is ByteArray -> toList().createArrayOfCall(session, FirConstKind.Byte) is ShortArray -> toList().createArrayOfCall(session, FirConstKind.Short) is IntArray -> toList().createArrayOfCall(session, FirConstKind.Int) @@ -547,12 +551,20 @@ internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? { is FloatArray -> toList().createArrayOfCall(session, FirConstKind.Float) is DoubleArray -> toList().createArrayOfCall(session, FirConstKind.Double) is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean) - null -> buildConstExpression(null, FirConstKind.Null, null) + null -> buildConstExpression(null, FirConstKind.Null, null).setProperType(session) else -> null } } +private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstExpression<*> { + val typeRef = buildResolvedTypeRef { + type = kind.expectedConeType(session) + } + replaceTypeRef(typeRef) + return this +} + private fun JavaType.toFirResolvedTypeRef( session: FirSession, javaTypeParameterStack: JavaTypeParameterStack ): FirResolvedTypeRef { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index d30bd31d831..a2d37f71aa2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -11,11 +11,13 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression +import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import kotlin.math.min +import org.jetbrains.kotlin.name.ClassId inline fun FirBasedSymbol<*>.firUnsafe(): T { val fir = this.fir @@ -98,3 +100,31 @@ fun FirBlock.writeResultType(session: FirSession) { } } } + +fun FirConstKind<*>.expectedConeType(session: FirSession): ConeKotlinType { + fun constructLiteralType(classId: ClassId, isNullable: Boolean = false): ConeKotlinType { + val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) + ?: return ConeClassErrorType(ConeSimpleDiagnostic("Missing stdlib class: $classId", DiagnosticKind.MissingStdlibClass)) + return symbol.toLookupTag().constructClassType(emptyArray(), isNullable) + } + return when (this) { + FirConstKind.Null -> session.builtinTypes.nullableNothingType.type + FirConstKind.Boolean -> session.builtinTypes.booleanType.type + FirConstKind.Char -> constructLiteralType(StandardClassIds.Char) + FirConstKind.Byte -> constructLiteralType(StandardClassIds.Byte) + FirConstKind.Short -> constructLiteralType(StandardClassIds.Short) + FirConstKind.Int -> constructLiteralType(StandardClassIds.Int) + FirConstKind.Long -> constructLiteralType(StandardClassIds.Long) + FirConstKind.String -> constructLiteralType(StandardClassIds.String) + 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) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index de400e5793d..fbaaf7358b1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -627,7 +627,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult { val arg = getClassCall.argument val dataWithExpectedType = if (arg is FirConstExpression<*>) { - withExpectedType(arg.typeRef.resolvedTypeFromPrototype(arg.kind.expectedConeType())) + withExpectedType(arg.typeRef.resolvedTypeFromPrototype(arg.kind.expectedConeType(session))) } else { data } @@ -670,34 +670,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform return transformedGetClassCall.compose() } - private fun FirConstKind<*>.expectedConeType(): ConeKotlinType { - fun constructLiteralType(classId: ClassId, isNullable: Boolean = false): ConeKotlinType { - val symbol = symbolProvider.getClassLikeSymbolByFqName(classId) - ?: return ConeClassErrorType(ConeSimpleDiagnostic("Missing stdlib class: $classId", DiagnosticKind.MissingStdlibClass)) - return symbol.toLookupTag().constructClassType(emptyArray(), isNullable) - } - return when (this) { - FirConstKind.Null -> session.builtinTypes.nullableNothingType.type - FirConstKind.Boolean -> session.builtinTypes.booleanType.type - FirConstKind.Char -> constructLiteralType(StandardClassIds.Char) - FirConstKind.Byte -> constructLiteralType(StandardClassIds.Byte) - FirConstKind.Short -> constructLiteralType(StandardClassIds.Short) - FirConstKind.Int -> constructLiteralType(StandardClassIds.Int) - FirConstKind.Long -> constructLiteralType(StandardClassIds.Long) - FirConstKind.String -> constructLiteralType(StandardClassIds.String) - 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 transformConstExpression( constExpression: FirConstExpression, data: ResolutionMode, @@ -718,7 +690,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform integerLiteralType } } - else -> kind.expectedConeType() + else -> kind.expectedConeType(session) } dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)