[FIR] Support unsigned integer literals
This commit is contained in:
@@ -221,6 +221,7 @@ class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLoo
|
|||||||
|
|
||||||
abstract class ConeIntegerLiteralType(
|
abstract class ConeIntegerLiteralType(
|
||||||
val value: Long,
|
val value: Long,
|
||||||
|
val isUnsigned: Boolean,
|
||||||
override val nullability: ConeNullability
|
override val nullability: ConeNullability
|
||||||
) : ConeSimpleKotlinType(), TypeConstructorMarker {
|
) : ConeSimpleKotlinType(), TypeConstructorMarker {
|
||||||
abstract val possibleTypes: Collection<ConeClassLikeType>
|
abstract val possibleTypes: Collection<ConeClassLikeType>
|
||||||
|
|||||||
@@ -784,6 +784,10 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
|||||||
+value.toString()
|
+value.toString()
|
||||||
keyword("L")
|
keyword("L")
|
||||||
}
|
}
|
||||||
|
FirConstKind.UnsignedLong -> {
|
||||||
|
+value.toString()
|
||||||
|
keyword("UL")
|
||||||
|
}
|
||||||
FirConstKind.Float -> {
|
FirConstKind.Float -> {
|
||||||
+value.toString()
|
+value.toString()
|
||||||
keyword("F")
|
keyword("F")
|
||||||
|
|||||||
@@ -145,14 +145,21 @@ private fun FirConstKind<*>.toIrConstKind(): IrConstKind<*> = when (this) {
|
|||||||
FirConstKind.Null -> IrConstKind.Null
|
FirConstKind.Null -> IrConstKind.Null
|
||||||
FirConstKind.Boolean -> IrConstKind.Boolean
|
FirConstKind.Boolean -> IrConstKind.Boolean
|
||||||
FirConstKind.Char -> IrConstKind.Char
|
FirConstKind.Char -> IrConstKind.Char
|
||||||
|
|
||||||
FirConstKind.Byte -> IrConstKind.Byte
|
FirConstKind.Byte -> IrConstKind.Byte
|
||||||
FirConstKind.Short -> IrConstKind.Short
|
FirConstKind.Short -> IrConstKind.Short
|
||||||
FirConstKind.Int -> IrConstKind.Int
|
FirConstKind.Int -> IrConstKind.Int
|
||||||
FirConstKind.Long -> IrConstKind.Long
|
FirConstKind.Long -> IrConstKind.Long
|
||||||
|
|
||||||
|
FirConstKind.UnsignedByte -> IrConstKind.Byte
|
||||||
|
FirConstKind.UnsignedShort -> IrConstKind.Short
|
||||||
|
FirConstKind.UnsignedInt -> IrConstKind.Int
|
||||||
|
FirConstKind.UnsignedLong -> IrConstKind.Long
|
||||||
|
|
||||||
FirConstKind.String -> IrConstKind.String
|
FirConstKind.String -> IrConstKind.String
|
||||||
FirConstKind.Float -> IrConstKind.Float
|
FirConstKind.Float -> IrConstKind.Float
|
||||||
FirConstKind.Double -> IrConstKind.Double
|
FirConstKind.Double -> IrConstKind.Double
|
||||||
FirConstKind.IntegerLiteral -> throw IllegalArgumentException()
|
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> throw IllegalArgumentException()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun FirClass<*>.collectCallableNamesFromSupertypes(session: FirSession, result: MutableList<Name> = mutableListOf()): List<Name> {
|
internal fun FirClass<*>.collectCallableNamesFromSupertypes(session: FirSession, result: MutableList<Name> = mutableListOf()): List<Name> {
|
||||||
|
|||||||
@@ -224,9 +224,15 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
hasLongSuffix(text) || hasUnsignedSuffix(text) || hasUnsignedLongSuffix(text) -> {
|
hasUnsignedLongSuffix(text) -> {
|
||||||
|
FirConstKind.UnsignedLong
|
||||||
|
}
|
||||||
|
hasLongSuffix(text) -> {
|
||||||
FirConstKind.Long
|
FirConstKind.Long
|
||||||
}
|
}
|
||||||
|
hasUnsignedSuffix(text) -> {
|
||||||
|
FirConstKind.UnsignedIntegerLiteral
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
FirConstKind.IntegerLiteral
|
FirConstKind.IntegerLiteral
|
||||||
|
|||||||
@@ -58,10 +58,13 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
|||||||
|
|
||||||
@Suppress("USELESS_CAST") // TODO: remove once fixed: https://youtrack.jetbrains.com/issue/KT-35635
|
@Suppress("USELESS_CAST") // TODO: remove once fixed: https://youtrack.jetbrains.com/issue/KT-35635
|
||||||
scopeSession.getOrBuild(
|
scopeSession.getOrBuild(
|
||||||
FirIntegerLiteralTypeScope.ILT_SYMBOL,
|
when {
|
||||||
|
isUnsigned -> FirIntegerLiteralTypeScope.ILTKey.Unsigned
|
||||||
|
else -> FirIntegerLiteralTypeScope.ILTKey.Signed
|
||||||
|
},
|
||||||
FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY
|
FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY
|
||||||
) {
|
) {
|
||||||
FirIntegerLiteralTypeScope(useSiteSession)
|
FirIntegerLiteralTypeScope(useSiteSession, isUnsigned)
|
||||||
} as FirScope
|
} as FirScope
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+3
-12
@@ -116,16 +116,6 @@ class IntegerLiteralTypeApproximationTransformer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeClassLikeType.toConstKind(): FirConstKind<*> {
|
|
||||||
return when (classId) {
|
|
||||||
StandardClassIds.Int -> FirConstKind.Int
|
|
||||||
StandardClassIds.Long -> FirConstKind.Long
|
|
||||||
StandardClassIds.Short -> FirConstKind.Short
|
|
||||||
StandardClassIds.Byte -> FirConstKind.Byte
|
|
||||||
else -> throw IllegalStateException()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration<*>? {
|
fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration<*>? {
|
||||||
val symbol: AbstractFirBasedSymbol<*>? = when (val reference = calleeReference) {
|
val symbol: AbstractFirBasedSymbol<*>? = when (val reference = calleeReference) {
|
||||||
is FirResolvedNamedReference -> reference.resolvedSymbol
|
is FirResolvedNamedReference -> reference.resolvedSymbol
|
||||||
@@ -148,7 +138,8 @@ class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximat
|
|||||||
return functionCall.transformExplicitReceiver(approximator, expectedType).compose()
|
return functionCall.transformExplicitReceiver(approximator, expectedType).compose()
|
||||||
}
|
}
|
||||||
// TODO: maybe unsafe?
|
// TODO: maybe unsafe?
|
||||||
val receiverValue = functionCall.explicitReceiver!!.typeRef.coneTypeSafe<ConeIntegerLiteralType>()?.value ?: return functionCall.compose()
|
val receiverType = functionCall.explicitReceiver!!.typeRef.coneTypeSafe<ConeIntegerLiteralType>() ?: return functionCall.compose()
|
||||||
|
val receiverValue = receiverType.value
|
||||||
val kind = function.kind
|
val kind = function.kind
|
||||||
val resultValue = when {
|
val resultValue = when {
|
||||||
kind.unary -> when (kind) {
|
kind.unary -> when (kind) {
|
||||||
@@ -193,7 +184,7 @@ class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(ConeIntegerLiteralTypeImpl(resultValue)))
|
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(ConeIntegerLiteralTypeImpl(resultValue, isUnsigned = receiverType.isUnsigned)))
|
||||||
return functionCall.toOperatorCall().compose()
|
return functionCall.toOperatorCall().compose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-32
@@ -504,44 +504,51 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
constExpression.annotations.forEach { it.accept(this, data) }
|
constExpression.annotations.forEach { it.accept(this, data) }
|
||||||
val kind = constExpression.kind
|
fun constructLiteralType(classId: ClassId, isNullable: Boolean = false): ConeKotlinType {
|
||||||
val symbol = when (kind) {
|
val symbol = symbolProvider.getClassLikeSymbolByFqName(classId) ?: return ConeClassErrorType("Missing stdlib class: ${classId}")
|
||||||
FirConstKind.Null -> StandardClassIds.Nothing(symbolProvider)
|
return symbol.toLookupTag().constructClassType(emptyArray(), isNullable)
|
||||||
FirConstKind.Boolean -> StandardClassIds.Boolean(symbolProvider)
|
|
||||||
FirConstKind.Char -> StandardClassIds.Char(symbolProvider)
|
|
||||||
FirConstKind.Byte -> StandardClassIds.Byte(symbolProvider)
|
|
||||||
FirConstKind.Short -> StandardClassIds.Short(symbolProvider)
|
|
||||||
FirConstKind.Int -> StandardClassIds.Int(symbolProvider)
|
|
||||||
FirConstKind.Long -> StandardClassIds.Long(symbolProvider)
|
|
||||||
FirConstKind.String -> StandardClassIds.String(symbolProvider)
|
|
||||||
FirConstKind.Float -> StandardClassIds.Float(symbolProvider)
|
|
||||||
FirConstKind.Double -> StandardClassIds.Double(symbolProvider)
|
|
||||||
FirConstKind.IntegerLiteral -> null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val type = if (symbol != null) {
|
val kind = constExpression.kind
|
||||||
ConeClassLikeTypeImpl(symbol.toLookupTag(), emptyArray(), isNullable = kind == FirConstKind.Null)
|
val type = when (kind) {
|
||||||
} else {
|
FirConstKind.Null -> session.builtinTypes.nullableNothingType.type
|
||||||
val integerLiteralType = ConeIntegerLiteralTypeImpl(constExpression.value as Long)
|
FirConstKind.Boolean -> session.builtinTypes.booleanType.type
|
||||||
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
FirConstKind.Char -> constructLiteralType(StandardClassIds.Char)
|
||||||
if (expectedType != null) {
|
FirConstKind.Byte -> constructLiteralType(StandardClassIds.Byte)
|
||||||
val approximatedType = integerLiteralType.getApproximatedType(expectedType)
|
FirConstKind.Short -> constructLiteralType(StandardClassIds.Short)
|
||||||
val newConstKind = approximatedType.toConstKind()
|
FirConstKind.Int -> constructLiteralType(StandardClassIds.Int)
|
||||||
if (newConstKind == null) {
|
FirConstKind.Long -> constructLiteralType(StandardClassIds.Long)
|
||||||
constExpression.replaceKind(FirConstKind.Int as FirConstKind<T>)
|
FirConstKind.String -> constructLiteralType(StandardClassIds.String)
|
||||||
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
|
FirConstKind.Float -> constructLiteralType(StandardClassIds.Float)
|
||||||
constExpression.resultType = buildErrorTypeRef {
|
FirConstKind.Double -> constructLiteralType(StandardClassIds.Double)
|
||||||
source = constExpression.source
|
FirConstKind.IntegerLiteral, FirConstKind.UnsignedIntegerLiteral -> {
|
||||||
diagnostic = FirTypeMismatchError(expectedType, integerLiteralType.getApproximatedType())
|
val integerLiteralType = ConeIntegerLiteralTypeImpl(constExpression.value as Long, isUnsigned = kind == FirConstKind.UnsignedIntegerLiteral)
|
||||||
|
val expectedType = data.expectedType?.coneTypeSafe<ConeKotlinType>()
|
||||||
|
if (expectedType != null) {
|
||||||
|
val approximatedType = integerLiteralType.getApproximatedType(expectedType)
|
||||||
|
val newConstKind = approximatedType.toConstKind()
|
||||||
|
if (newConstKind == null) {
|
||||||
|
constExpression.replaceKind(FirConstKind.Int as FirConstKind<T>)
|
||||||
|
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
|
||||||
|
constExpression.resultType = buildErrorTypeRef {
|
||||||
|
source = constExpression.source
|
||||||
|
diagnostic = FirTypeMismatchError(expectedType, integerLiteralType.getApproximatedType())
|
||||||
|
}
|
||||||
|
return constExpression.compose()
|
||||||
}
|
}
|
||||||
return constExpression.compose()
|
constExpression.replaceKind(newConstKind as FirConstKind<T>)
|
||||||
|
approximatedType
|
||||||
|
} else {
|
||||||
|
integerLiteralType
|
||||||
}
|
}
|
||||||
constExpression.replaceKind(newConstKind as FirConstKind<T>)
|
|
||||||
approximatedType
|
|
||||||
} else {
|
|
||||||
integerLiteralType
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FirConstKind.UnsignedByte -> constructLiteralType(StandardClassIds.UByte)
|
||||||
|
FirConstKind.UnsignedShort -> constructLiteralType(StandardClassIds.UShort)
|
||||||
|
FirConstKind.UnsignedInt -> constructLiteralType(StandardClassIds.UInt)
|
||||||
|
FirConstKind.UnsignedLong -> constructLiteralType(StandardClassIds.ULong)
|
||||||
}
|
}
|
||||||
|
|
||||||
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
|
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
|
||||||
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(type)
|
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(type)
|
||||||
return constExpression.compose()
|
return constExpression.compose()
|
||||||
|
|||||||
+9
-37
@@ -19,9 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||||
import org.jetbrains.kotlin.fir.resolve.scopeSessionKey
|
import org.jetbrains.kotlin.fir.resolve.scopeSessionKey
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.CallableId
|
import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl
|
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl
|
||||||
@@ -32,45 +30,19 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
private object FirIntegerLiteralTypeClassifierSymbol : FirClassifierSymbol<FirIntegerLiteralTypeClassifier>() {
|
|
||||||
override fun toLookupTag(): ConeClassifierLookupTag {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object FirIntegerLiteralTypeClassifier : FirDeclaration, FirSymbolOwner<FirIntegerLiteralTypeClassifier> {
|
class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned: Boolean) : FirScope() {
|
||||||
override val symbol: AbstractFirBasedSymbol<FirIntegerLiteralTypeClassifier>
|
sealed class ILTKey {
|
||||||
get() = FirIntegerLiteralTypeClassifierSymbol
|
object Signed : ILTKey()
|
||||||
|
object Unsigned : ILTKey()
|
||||||
override val source: FirSourceElement? get() = throw IllegalStateException("Should not be called")
|
|
||||||
override val session: FirSession get() = throw IllegalStateException("Should not be called")
|
|
||||||
override val resolvePhase: FirResolvePhase get() = throw IllegalStateException("Should not be called")
|
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
|
||||||
throw IllegalStateException("Should not be called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FirIntegerLiteralTypeScope(private val session: FirSession) : FirScope() {
|
|
||||||
companion object {
|
companion object {
|
||||||
val BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filterNot { it.unary }.map { it.operatorName }
|
val BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filterNot { it.unary }.map { it.operatorName }
|
||||||
val UNARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filter { it.unary }.map { it.operatorName }
|
val UNARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filter { it.unary }.map { it.operatorName }
|
||||||
private val ALL_OPERATORS = FirIntegerOperator.Kind.values().map { it.operatorName to it }.toMap()
|
private val ALL_OPERATORS = FirIntegerOperator.Kind.values().map { it.operatorName to it }.toMap()
|
||||||
|
|
||||||
val ILT_SYMBOL: FirClassifierSymbol<*> = FirIntegerLiteralTypeClassifierSymbol
|
val SCOPE_SESSION_KEY = scopeSessionKey<ILTKey, FirIntegerLiteralTypeScope>()
|
||||||
val SCOPE_SESSION_KEY = scopeSessionKey<FirClassifierSymbol<*>, FirIntegerLiteralTypeScope>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val BINARY_OPERATOR_SYMBOLS = BINARY_OPERATOR_NAMES.map { name ->
|
private val BINARY_OPERATOR_SYMBOLS = BINARY_OPERATOR_NAMES.map { name ->
|
||||||
@@ -80,7 +52,7 @@ class FirIntegerLiteralTypeScope(private val session: FirSession) : FirScope() {
|
|||||||
valueParameters += buildValueParameter {
|
valueParameters += buildValueParameter {
|
||||||
source = null
|
source = null
|
||||||
session = this@FirIntegerLiteralTypeScope.session
|
session = this@FirIntegerLiteralTypeScope.session
|
||||||
returnTypeRef = FirILTTypeRefPlaceHolder()
|
returnTypeRef = FirILTTypeRefPlaceHolder(isUnsigned)
|
||||||
this.name = valueParameterName
|
this.name = valueParameterName
|
||||||
symbol = FirVariableSymbol(valueParameterName)
|
symbol = FirVariableSymbol(valueParameterName)
|
||||||
defaultValue = null
|
defaultValue = null
|
||||||
@@ -100,7 +72,7 @@ class FirIntegerLiteralTypeScope(private val session: FirSession) : FirScope() {
|
|||||||
private fun createFirFunction(name: Name, symbol: FirNamedFunctionSymbol): FirSimpleFunctionImpl = FirIntegerOperator(
|
private fun createFirFunction(name: Name, symbol: FirNamedFunctionSymbol): FirSimpleFunctionImpl = FirIntegerOperator(
|
||||||
source = null,
|
source = null,
|
||||||
session,
|
session,
|
||||||
FirILTTypeRefPlaceHolder(),
|
FirILTTypeRefPlaceHolder(isUnsigned),
|
||||||
receiverTypeRef = null,
|
receiverTypeRef = null,
|
||||||
ALL_OPERATORS.getValue(name),
|
ALL_OPERATORS.getValue(name),
|
||||||
FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, FirEffectiveVisibility.Public, Modality.FINAL),
|
FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, FirEffectiveVisibility.Public, Modality.FINAL),
|
||||||
@@ -166,10 +138,10 @@ class FirIntegerOperator @FirImplementationDetail constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FirILTTypeRefPlaceHolder : FirResolvedTypeRef() {
|
class FirILTTypeRefPlaceHolder(isUnsigned: Boolean) : FirResolvedTypeRef() {
|
||||||
override val source: FirSourceElement? get() = null
|
override val source: FirSourceElement? get() = null
|
||||||
override val annotations: List<FirAnnotationCall> get() = emptyList()
|
override val annotations: List<FirAnnotationCall> get() = emptyList()
|
||||||
override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0)
|
override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0, isUnsigned)
|
||||||
override val delegatedTypeRef: FirTypeRef? get() = null
|
override val delegatedTypeRef: FirTypeRef? get() = null
|
||||||
|
|
||||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability, typeCon
|
|||||||
ConeNullability.NULLABLE -> original.withNullability(nullability)
|
ConeNullability.NULLABLE -> original.withNullability(nullability)
|
||||||
ConeNullability.UNKNOWN -> original.withNullability(nullability)
|
ConeNullability.UNKNOWN -> original.withNullability(nullability)
|
||||||
}
|
}
|
||||||
is ConeIntegerLiteralType -> ConeIntegerLiteralTypeImpl(value, nullability)
|
is ConeIntegerLiteralType -> ConeIntegerLiteralTypeImpl(value, isUnsigned, nullability)
|
||||||
else -> error("sealed: ${this::class}")
|
else -> error("sealed: ${this::class}")
|
||||||
} as T
|
} as T
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,23 @@ sealed class FirConstKind<T>(val asString: kotlin.String) {
|
|||||||
object Null : FirConstKind<Nothing?>("Null")
|
object Null : FirConstKind<Nothing?>("Null")
|
||||||
object Boolean : FirConstKind<kotlin.Boolean>("Boolean")
|
object Boolean : FirConstKind<kotlin.Boolean>("Boolean")
|
||||||
object Char : FirConstKind<kotlin.Char>("Char")
|
object Char : FirConstKind<kotlin.Char>("Char")
|
||||||
|
|
||||||
object Byte : FirConstKind<kotlin.Byte>("Byte")
|
object Byte : FirConstKind<kotlin.Byte>("Byte")
|
||||||
|
object UnsignedByte : FirConstKind<kotlin.Byte>("UByte")
|
||||||
object Short : FirConstKind<kotlin.Short>("Short")
|
object Short : FirConstKind<kotlin.Short>("Short")
|
||||||
|
object UnsignedShort : FirConstKind<kotlin.Short>("UShort")
|
||||||
object Int : FirConstKind<kotlin.Int>("Int")
|
object Int : FirConstKind<kotlin.Int>("Int")
|
||||||
|
object UnsignedInt : FirConstKind<kotlin.Int>("UInt")
|
||||||
object Long : FirConstKind<kotlin.Long>("Long")
|
object Long : FirConstKind<kotlin.Long>("Long")
|
||||||
|
object UnsignedLong : FirConstKind<kotlin.Long>("ULong")
|
||||||
|
|
||||||
object String : FirConstKind<kotlin.String>("String")
|
object String : FirConstKind<kotlin.String>("String")
|
||||||
|
|
||||||
object Float : FirConstKind<kotlin.Float>("Float")
|
object Float : FirConstKind<kotlin.Float>("Float")
|
||||||
object Double : FirConstKind<kotlin.Double>("Double")
|
object Double : FirConstKind<kotlin.Double>("Double")
|
||||||
|
|
||||||
object IntegerLiteral : FirConstKind<kotlin.Long>("IntegerLiteral")
|
object IntegerLiteral : FirConstKind<kotlin.Long>("IntegerLiteral")
|
||||||
|
object UnsignedIntegerLiteral : FirConstKind<kotlin.Long>("UnsignedIntegerLiteral")
|
||||||
|
|
||||||
override fun toString() = asString
|
override fun toString() = asString
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
|||||||
class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
|
class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
|
||||||
override val possibleTypes: Collection<ConeClassLikeType>
|
override val possibleTypes: Collection<ConeClassLikeType>
|
||||||
|
|
||||||
constructor(value: Long, nullability: ConeNullability = ConeNullability.NOT_NULL) : super(value, nullability) {
|
constructor(value: Long, isUnsigned: Boolean, nullability: ConeNullability = ConeNullability.NOT_NULL) : super(value, isUnsigned, nullability) {
|
||||||
possibleTypes = mutableListOf()
|
possibleTypes = mutableListOf()
|
||||||
|
|
||||||
fun checkBoundsAndAddPossibleType(classId: ClassId, range: LongRange) {
|
fun checkBoundsAndAddPossibleType(classId: ClassId, range: LongRange) {
|
||||||
@@ -30,15 +30,26 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
|
|||||||
checkBoundsAndAddPossibleType(StandardClassIds.Short, SHORT_RANGE)
|
checkBoundsAndAddPossibleType(StandardClassIds.Short, SHORT_RANGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
addSignedPossibleTypes()
|
fun addUnsignedPossibleType() {
|
||||||
// TODO: add support of unsigned types
|
checkBoundsAndAddPossibleType(StandardClassIds.UInt, UINT_RANGE)
|
||||||
|
possibleTypes += createType(StandardClassIds.ULong)
|
||||||
|
checkBoundsAndAddPossibleType(StandardClassIds.UByte, UBYTE_RANGE)
|
||||||
|
checkBoundsAndAddPossibleType(StandardClassIds.UShort, USHORT_RANGE)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUnsigned) {
|
||||||
|
addUnsignedPossibleType()
|
||||||
|
} else {
|
||||||
|
addSignedPossibleTypes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(
|
private constructor(
|
||||||
value: Long,
|
value: Long,
|
||||||
possibleTypes: Collection<ConeClassLikeType>,
|
possibleTypes: Collection<ConeClassLikeType>,
|
||||||
|
isUnsigned: Boolean,
|
||||||
nullability: ConeNullability = ConeNullability.NOT_NULL
|
nullability: ConeNullability = ConeNullability.NOT_NULL
|
||||||
) : super(value, nullability) {
|
) : super(value, isUnsigned, nullability) {
|
||||||
this.possibleTypes = possibleTypes
|
this.possibleTypes = possibleTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +79,10 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
|
|||||||
private val BYTE_RANGE = Byte.MIN_VALUE.toLong()..Byte.MAX_VALUE.toLong()
|
private val BYTE_RANGE = Byte.MIN_VALUE.toLong()..Byte.MAX_VALUE.toLong()
|
||||||
private val SHORT_RANGE = Short.MIN_VALUE.toLong()..Short.MAX_VALUE.toLong()
|
private val SHORT_RANGE = Short.MIN_VALUE.toLong()..Short.MAX_VALUE.toLong()
|
||||||
|
|
||||||
|
private val UBYTE_RANGE = UByte.MIN_VALUE.toLong()..UByte.MAX_VALUE.toLong()
|
||||||
|
private val USHORT_RANGE = UShort.MIN_VALUE.toLong()..UShort.MAX_VALUE.toLong()
|
||||||
|
private val UINT_RANGE = UInt.MIN_VALUE.toLong()..UInt.MAX_VALUE.toLong()
|
||||||
|
|
||||||
private val COMPARABLE_TAG = ConeClassLikeLookupTagImpl(StandardClassIds.Comparable)
|
private val COMPARABLE_TAG = ConeClassLikeLookupTagImpl(StandardClassIds.Comparable)
|
||||||
|
|
||||||
fun findCommonSuperType(types: Collection<SimpleTypeMarker>): SimpleTypeMarker? {
|
fun findCommonSuperType(types: Collection<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||||
@@ -114,7 +129,7 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
|
|||||||
Mode.COMMON_SUPER_TYPE -> left.possibleTypes intersect right.possibleTypes
|
Mode.COMMON_SUPER_TYPE -> left.possibleTypes intersect right.possibleTypes
|
||||||
Mode.INTERSECTION_TYPE -> left.possibleTypes union right.possibleTypes
|
Mode.INTERSECTION_TYPE -> left.possibleTypes union right.possibleTypes
|
||||||
}
|
}
|
||||||
return ConeIntegerLiteralTypeImpl(left.value, possibleTypes)
|
return ConeIntegerLiteralTypeImpl(left.value, possibleTypes, left.isUnsigned)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fold(left: ConeIntegerLiteralType, right: SimpleTypeMarker): SimpleTypeMarker? =
|
private fun fold(left: ConeIntegerLiteralType, right: SimpleTypeMarker): SimpleTypeMarker? =
|
||||||
|
|||||||
@@ -59,5 +59,10 @@ fun ConeClassLikeType.toConstKind(): FirConstKind<*>? = when (lookupTag.classId)
|
|||||||
StandardClassIds.Short -> FirConstKind.Short
|
StandardClassIds.Short -> FirConstKind.Short
|
||||||
StandardClassIds.Int -> FirConstKind.Int
|
StandardClassIds.Int -> FirConstKind.Int
|
||||||
StandardClassIds.Long -> FirConstKind.Long
|
StandardClassIds.Long -> FirConstKind.Long
|
||||||
|
|
||||||
|
StandardClassIds.UInt -> FirConstKind.UnsignedInt
|
||||||
|
StandardClassIds.ULong -> FirConstKind.UnsignedLong
|
||||||
|
StandardClassIds.UShort -> FirConstKind.UnsignedShort
|
||||||
|
StandardClassIds.UByte -> FirConstKind.UnsignedByte
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user