[FIR] Properly set type of constants for java declarations
This commit is contained in:
@@ -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 <T> List<T>.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 {
|
||||
|
||||
+31
-1
@@ -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 <reified T : FirElement> 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)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-30
@@ -627,7 +627,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
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 <T> transformConstExpression(
|
||||
constExpression: FirConstExpression<T>,
|
||||
data: ResolutionMode,
|
||||
@@ -718,7 +690,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
integerLiteralType
|
||||
}
|
||||
}
|
||||
else -> kind.expectedConeType()
|
||||
else -> kind.expectedConeType(session)
|
||||
}
|
||||
|
||||
dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)
|
||||
|
||||
Reference in New Issue
Block a user