[FIR] Support unsigned integer literals

This commit is contained in:
simon.ogorodnik
2020-03-24 02:22:53 +03:00
parent 0afbf25943
commit 27136ef8be
12 changed files with 111 additions and 91 deletions
@@ -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
@@ -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()
} }
} }
@@ -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()
@@ -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
} }