[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.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredCallableSymbols
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
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.resolve.transformers.body.resolve.firUnsafe
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
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)
|
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? {
|
internal fun Any?.createConstantIfAny(session: FirSession): FirExpression? {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Byte -> buildConstExpression(null, FirConstKind.Byte, this)
|
is Byte -> buildConstExpression(null, FirConstKind.Byte, this).setProperType(session)
|
||||||
is Short -> buildConstExpression(null, FirConstKind.Short, this)
|
is Short -> buildConstExpression(null, FirConstKind.Short, this).setProperType(session)
|
||||||
is Int -> buildConstExpression(null, FirConstKind.Int, this)
|
is Int -> buildConstExpression(null, FirConstKind.Int, this).setProperType(session)
|
||||||
is Long -> buildConstExpression(null, FirConstKind.Long, this)
|
is Long -> buildConstExpression(null, FirConstKind.Long, this).setProperType(session)
|
||||||
is Char -> buildConstExpression(null, FirConstKind.Char, this)
|
is Char -> buildConstExpression(null, FirConstKind.Char, this).setProperType(session)
|
||||||
is Float -> buildConstExpression(null, FirConstKind.Float, this)
|
is Float -> buildConstExpression(null, FirConstKind.Float, this).setProperType(session)
|
||||||
is Double -> buildConstExpression(null, FirConstKind.Double, this)
|
is Double -> buildConstExpression(null, FirConstKind.Double, this).setProperType(session)
|
||||||
is Boolean -> buildConstExpression(null, FirConstKind.Boolean, this)
|
is Boolean -> buildConstExpression(null, FirConstKind.Boolean, this).setProperType(session)
|
||||||
is String -> buildConstExpression(null, FirConstKind.String, this)
|
is String -> buildConstExpression(null, FirConstKind.String, this).setProperType(session)
|
||||||
is ByteArray -> toList().createArrayOfCall(session, FirConstKind.Byte)
|
is ByteArray -> toList().createArrayOfCall(session, FirConstKind.Byte)
|
||||||
is ShortArray -> toList().createArrayOfCall(session, FirConstKind.Short)
|
is ShortArray -> toList().createArrayOfCall(session, FirConstKind.Short)
|
||||||
is IntArray -> toList().createArrayOfCall(session, FirConstKind.Int)
|
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 FloatArray -> toList().createArrayOfCall(session, FirConstKind.Float)
|
||||||
is DoubleArray -> toList().createArrayOfCall(session, FirConstKind.Double)
|
is DoubleArray -> toList().createArrayOfCall(session, FirConstKind.Double)
|
||||||
is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean)
|
is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean)
|
||||||
null -> buildConstExpression(null, FirConstKind.Null, null)
|
null -> buildConstExpression(null, FirConstKind.Null, null).setProperType(session)
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstExpression<*> {
|
||||||
|
val typeRef = buildResolvedTypeRef {
|
||||||
|
type = kind.expectedConeType(session)
|
||||||
|
}
|
||||||
|
replaceTypeRef(typeRef)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
private fun JavaType.toFirResolvedTypeRef(
|
private fun JavaType.toFirResolvedTypeRef(
|
||||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack
|
||||||
): FirResolvedTypeRef {
|
): 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.diagnostics.DiagnosticKind
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression
|
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.FirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
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
|
||||||
import kotlin.math.min
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
inline fun <reified T : FirElement> FirBasedSymbol<*>.firUnsafe(): T {
|
inline fun <reified T : FirElement> FirBasedSymbol<*>.firUnsafe(): T {
|
||||||
val fir = this.fir
|
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> {
|
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||||
val arg = getClassCall.argument
|
val arg = getClassCall.argument
|
||||||
val dataWithExpectedType = if (arg is FirConstExpression<*>) {
|
val dataWithExpectedType = if (arg is FirConstExpression<*>) {
|
||||||
withExpectedType(arg.typeRef.resolvedTypeFromPrototype(arg.kind.expectedConeType()))
|
withExpectedType(arg.typeRef.resolvedTypeFromPrototype(arg.kind.expectedConeType(session)))
|
||||||
} else {
|
} else {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
@@ -670,34 +670,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
return transformedGetClassCall.compose()
|
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(
|
override fun <T> transformConstExpression(
|
||||||
constExpression: FirConstExpression<T>,
|
constExpression: FirConstExpression<T>,
|
||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
@@ -718,7 +690,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
integerLiteralType
|
integerLiteralType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> kind.expectedConeType()
|
else -> kind.expectedConeType(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)
|
dataFlowAnalyzer.exitConstExpression(constExpression as FirConstExpression<*>)
|
||||||
|
|||||||
Reference in New Issue
Block a user