[FIR] Support IntegerLiteralTypes

This commit is contained in:
Dmitriy Novozhilov
2019-12-09 15:02:55 +03:00
parent 5577f0f8cb
commit b76c984b26
145 changed files with 1815 additions and 585 deletions
@@ -48,6 +48,8 @@ abstract class FirField : FirPureAbstractElement(), FirVariable<FirField>, FirCa
abstract override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirField
abstract override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirField
abstract override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirField
abstract override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirField
@@ -54,6 +54,8 @@ abstract class FirProperty : FirPureAbstractElement(), FirVariable<FirProperty>,
abstract override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirProperty
abstract override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirProperty
abstract override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirProperty
abstract override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirProperty
@@ -48,6 +48,8 @@ abstract class FirValueParameter : FirPureAbstractElement(), FirVariable<FirValu
abstract override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirValueParameter
abstract override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirValueParameter
abstract override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirValueParameter
abstract override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirValueParameter
@@ -44,6 +44,8 @@ interface FirVariable<F : FirVariable<F>> : FirCallableDeclaration<F>, FirNamedD
override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirVariable<F>
fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirVariable<F>
fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirVariable<F>
fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirVariable<F>
@@ -65,6 +65,7 @@ class FirDefaultSetterValueParameter(
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirDefaultSetterValueParameter {
transformReturnTypeRef(transformer, data)
transformReceiverTypeRef(transformer, data)
transformInitializer(transformer, data)
transformGetter(transformer, data)
transformSetter(transformer, data)
transformOtherChildren(transformer, data)
@@ -81,6 +82,11 @@ class FirDefaultSetterValueParameter(
return this
}
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirDefaultSetterValueParameter {
initializer = initializer?.transformSingle(transformer, data)
return this
}
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirDefaultSetterValueParameter {
getter = getter?.transformSingle(transformer, data)
return this
@@ -92,7 +98,6 @@ class FirDefaultSetterValueParameter(
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirDefaultSetterValueParameter {
initializer = initializer?.transformSingle(transformer, data)
delegate = delegate?.transformSingle(transformer, data)
annotations.transformInplace(transformer, data)
defaultValue = defaultValue?.transformSingle(transformer, data)
@@ -76,6 +76,10 @@ class FirFieldImpl(
return this
}
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirFieldImpl {
return this
}
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirFieldImpl {
return this
}
@@ -46,6 +46,8 @@ interface FirModifiableVariable<F : FirVariable<F>> : FirVariable<F>, FirAbstra
override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirModifiableVariable<F>
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirModifiableVariable<F>
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirModifiableVariable<F>
override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirModifiableVariable<F>
@@ -76,6 +76,7 @@ class FirPropertyImpl(
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirPropertyImpl {
transformReturnTypeRef(transformer, data)
transformReceiverTypeRef(transformer, data)
transformInitializer(transformer, data)
transformGetter(transformer, data)
transformSetter(transformer, data)
transformControlFlowGraphReference(transformer, data)
@@ -94,6 +95,11 @@ class FirPropertyImpl(
return this
}
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirPropertyImpl {
initializer = initializer?.transformSingle(transformer, data)
return this
}
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirPropertyImpl {
getter = getter?.transformSingle(transformer, data)
return this
@@ -115,7 +121,6 @@ class FirPropertyImpl(
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirPropertyImpl {
initializer = initializer?.transformSingle(transformer, data)
delegate = delegate?.transformSingle(transformer, data)
annotations.transformInplace(transformer, data)
typeParameters.transformInplace(transformer, data)
@@ -65,6 +65,7 @@ open class FirValueParameterImpl(
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirValueParameterImpl {
transformReturnTypeRef(transformer, data)
transformReceiverTypeRef(transformer, data)
transformInitializer(transformer, data)
transformGetter(transformer, data)
transformSetter(transformer, data)
transformOtherChildren(transformer, data)
@@ -81,6 +82,11 @@ open class FirValueParameterImpl(
return this
}
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirValueParameterImpl {
initializer = initializer?.transformSingle(transformer, data)
return this
}
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirValueParameterImpl {
getter = getter?.transformSingle(transformer, data)
return this
@@ -92,7 +98,6 @@ open class FirValueParameterImpl(
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirValueParameterImpl {
initializer = initializer?.transformSingle(transformer, data)
delegate = delegate?.transformSingle(transformer, data)
annotations.transformInplace(transformer, data)
defaultValue = defaultValue?.transformSingle(transformer, data)
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -20,8 +19,10 @@ abstract class FirConstExpression<T> : FirPureAbstractElement(), FirExpression {
abstract override val source: FirSourceElement?
abstract override val typeRef: FirTypeRef
abstract override val annotations: List<FirAnnotationCall>
abstract val kind: IrConstKind<T>
abstract val kind: FirConstKind<T>
abstract val value: T
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitConstExpression(this, data)
abstract fun replaceKind(newKind: FirConstKind<T>)
}
@@ -25,4 +25,8 @@ abstract class FirReturnExpression : FirPureAbstractElement(), FirJump<FirFuncti
abstract val result: FirExpression
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitReturnExpression(this, data)
abstract fun <D> transformResult(transformer: FirTransformer<D>, data: D): FirReturnExpression
abstract fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirReturnExpression
}
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.fir.expressions.impl
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.expressions.FirConstKind
import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.visitors.*
class FirConstExpressionImpl<T> (
override val source: FirSourceElement?,
override val kind: IrConstKind<T>,
override var kind: FirConstKind<T>,
override val value: T
) : FirConstExpression<T>(), FirAbstractAnnotatedElement {
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
@@ -41,4 +41,8 @@ class FirConstExpressionImpl<T> (
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
typeRef = newTypeRef
}
override fun replaceKind(newKind: FirConstKind<T>) {
kind = newKind
}
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY
*/
class FirFunctionCallImpl(
open class FirFunctionCallImpl(
override val source: FirSourceElement?
) : FirFunctionCall(), FirModifiableQualifiedAccess, FirCallWithArgumentList, FirAbstractAnnotatedElement {
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
@@ -36,9 +36,19 @@ class FirReturnExpressionImpl(
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirReturnExpressionImpl {
transformResult(transformer, data)
transformOtherChildren(transformer, data)
return this
}
override fun <D> transformResult(transformer: FirTransformer<D>, data: D): FirReturnExpressionImpl {
result = result.transformSingle(transformer, data)
return this
}
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirReturnExpressionImpl {
typeRef = typeRef.transformSingle(transformer, data)
annotations.transformInplace(transformer, data)
result = result.transformSingle(transformer, data)
return this
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.expressions
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.toConstKind
import org.jetbrains.kotlin.ir.expressions.IrConstKind
sealed class FirConstKind<T>(val asString: kotlin.String) {
object Null : FirConstKind<Nothing?>("Null")
object Boolean : FirConstKind<kotlin.Boolean>("Boolean")
object Char : FirConstKind<kotlin.Char>("Char")
object Byte : FirConstKind<kotlin.Byte>("Byte")
object Short : FirConstKind<kotlin.Short>("Short")
object Int : FirConstKind<kotlin.Int>("Int")
object Long : FirConstKind<kotlin.Long>("Long")
object String : FirConstKind<kotlin.String>("String")
object Float : FirConstKind<kotlin.Float>("Float")
object Double : FirConstKind<kotlin.Double>("Double")
object IntegerLiteral : FirConstKind<kotlin.Long>("IntegerLiteral")
override fun toString() = asString
}
fun FirConstExpression<*>.getIrConstKind(): IrConstKind<*> = when (kind) {
FirConstKind.IntegerLiteral -> {
val type = typeRef.coneTypeUnsafe<ConeIntegerLiteralType>()
type.getApproximatedType().toConstKind()!!.toIrConstKind()
}
else -> kind.toIrConstKind()
}
private fun FirConstKind<*>.toIrConstKind(): IrConstKind<*> = when (this) {
FirConstKind.Null -> IrConstKind.Null
FirConstKind.Boolean -> IrConstKind.Boolean
FirConstKind.Char -> IrConstKind.Char
FirConstKind.Byte -> IrConstKind.Byte
FirConstKind.Short -> IrConstKind.Short
FirConstKind.Int -> IrConstKind.Int
FirConstKind.Long -> IrConstKind.Long
FirConstKind.String -> IrConstKind.String
FirConstKind.Float -> IrConstKind.Float
FirConstKind.Double -> IrConstKind.Double
FirConstKind.IntegerLiteral -> throw IllegalArgumentException()
}
@@ -23,7 +23,7 @@ inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType?
inline val FirAnnotationCall.classId: ClassId?
get() = coneClassLikeType?.lookupTag?.classId
fun <T> FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind<T>, value: T?, diagnostic: FirDiagnostic): FirExpression =
fun <T> FirConstExpressionImpl(source: FirSourceElement?, kind: FirConstKind<T>, value: T?, diagnostic: FirDiagnostic): FirExpression =
value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, diagnostic)
inline val FirTypeOperatorCall.argument: FirExpression get() = arguments.first()
@@ -0,0 +1,127 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
override val possibleTypes: Collection<ConeClassLikeType>
constructor(value: Long) : super(value) {
possibleTypes = mutableListOf()
fun checkBoundsAndAddPossibleType(type: ConeClassLikeType, range: LongRange) {
if (value in range) {
possibleTypes.add(type)
}
}
fun addSignedPossibleTypes() {
checkBoundsAndAddPossibleType(INT_TYPE, INT_RANGE)
possibleTypes += LONG_TYPE
checkBoundsAndAddPossibleType(BYTE_TYPE, BYTE_RANGE)
checkBoundsAndAddPossibleType(SHORT_TYPE, SHORT_RANGE)
}
addSignedPossibleTypes()
// TODO: add support of unsigned types
}
private constructor(value: Long, possibleTypes: Collection<ConeClassLikeType>) : super(value) {
this.possibleTypes = possibleTypes
}
override val supertypes: List<ConeClassLikeType> by lazy {
listOf(
NUMBER_TYPE,
ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(StandardClassIds.Comparable), arrayOf(ConeKotlinTypeProjectionOut(this)), false)
)
}
override fun getApproximatedType(expectedType: ConeKotlinType?): ConeClassLikeType {
return when (expectedType) {
null, !in possibleTypes -> possibleTypes.first()
else -> expectedType as ConeClassLikeType
}
}
companion object {
private fun createType(classId: ClassId): ConeClassLikeType {
return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(classId), emptyArray(), false)
}
val INT_TYPE = createType(StandardClassIds.Int)
val LONG_TYPE = createType(StandardClassIds.Long)
val SHORT_TYPE = createType(StandardClassIds.Short)
val BYTE_TYPE = createType(StandardClassIds.Byte)
private val NUMBER_TYPE = createType(StandardClassIds.Number)
private val INT_RANGE = Int.MIN_VALUE.toLong()..Int.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()
fun findCommonSuperType(types: Collection<SimpleTypeMarker>): SimpleTypeMarker? {
return findCommonSuperTypeOrIntersectionType(types, Mode.COMMON_SUPER_TYPE)
}
fun findIntersectionType(types: Collection<SimpleTypeMarker>): SimpleTypeMarker? {
return findCommonSuperTypeOrIntersectionType(types, Mode.INTERSECTION_TYPE)
}
private enum class Mode {
COMMON_SUPER_TYPE, INTERSECTION_TYPE
}
/**
* intersection(ILT(types), PrimitiveType) = commonSuperType(ILT(types), PrimitiveType) =
* PrimitiveType in types -> PrimitiveType
* PrimitiveType !in types -> null
*
* intersection(ILT(types_1), ILT(types_2)) = ILT(types_1 union types_2)
*
* commonSuperType(ILT(types_1), ILT(types_2)) = ILT(types_1 intersect types_2)
*/
private fun findCommonSuperTypeOrIntersectionType(types: Collection<SimpleTypeMarker>, mode: Mode): SimpleTypeMarker? {
if (types.isEmpty()) return null
@Suppress("UNCHECKED_CAST")
return types.reduce { left: SimpleTypeMarker?, right: SimpleTypeMarker? -> fold(left, right, mode) }
}
private fun fold(left: SimpleTypeMarker?, right: SimpleTypeMarker?, mode: Mode): SimpleTypeMarker? {
if (left == null || right == null) return null
return when {
left is ConeIntegerLiteralType && right is ConeIntegerLiteralType ->
fold(left, right, mode)
left is ConeIntegerLiteralType -> fold(left, right)
right is ConeIntegerLiteralType -> fold(right, left)
else -> null
}
}
private fun fold(left: ConeIntegerLiteralType, right: ConeIntegerLiteralType, mode: Mode): ConeIntegerLiteralType? {
val possibleTypes = when (mode) {
Mode.COMMON_SUPER_TYPE -> left.possibleTypes intersect right.possibleTypes
Mode.INTERSECTION_TYPE -> left.possibleTypes union right.possibleTypes
}
return ConeIntegerLiteralTypeImpl(left.value, possibleTypes)
}
private fun fold(left: ConeIntegerLiteralType, right: SimpleTypeMarker): SimpleTypeMarker? =
if (right in left.possibleTypes) right else null
}
}
fun ConeKotlinType.approximateIntegerLiteralType(expectedType: ConeKotlinType? = null): ConeKotlinType =
(this as? ConeIntegerLiteralType)?.getApproximatedType(expectedType) ?: this
fun ConeKotlinType.approximateIntegerLiteralTypeOrNull(expectedType: ConeKotlinType? = null): ConeKotlinType? =
(this as? ConeIntegerLiteralType)?.getApproximatedType(expectedType)
@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirConstKind
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
import org.jetbrains.kotlin.name.ClassId
@@ -56,4 +56,12 @@ val FirAnnotationCall.isExtensionFunctionAnnotationCall: Boolean
fun List<FirAnnotationCall>.dropExtensionFunctionAnnotation(): List<FirAnnotationCall> {
return filterNot { it.isExtensionFunctionAnnotationCall }
}
fun ConeClassLikeType.toConstKind(): FirConstKind<*>? = when (lookupTag.classId) {
StandardClassIds.Byte -> FirConstKind.Byte
StandardClassIds.Short -> FirConstKind.Short
StandardClassIds.Int -> FirConstKind.Int
StandardClassIds.Long -> FirConstKind.Long
else -> null
}
@@ -235,6 +235,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
defaultFalse("safe")
lateinit("calleeReference")
defaultNoReceivers()
kind = OpenClass
}
impl(qualifiedAccessExpression) {
@@ -138,7 +138,8 @@ object NodeConfigurator : AbstractFieldConfigurator() {
returnExpression.configure {
parentArg(jump, "E", function.withArgs("F" to "*"))
+field("result", expression)
+field("result", expression).withTransform()
needTransformOtherChildren()
}
label.configure {
@@ -178,7 +179,7 @@ object NodeConfigurator : AbstractFieldConfigurator() {
constExpression.configure {
withArg("T")
+field("kind", constKindType.withArgs("T"))
+field("kind", constKindType.withArgs("T"), withReplace = true)
+field("value", "T", null)
}
@@ -335,7 +336,7 @@ object NodeConfigurator : AbstractFieldConfigurator() {
withArg("F", variable)
parentArg(callableDeclaration, "F", "F")
+symbol("FirVariableSymbol", "F")
+initializer
+initializer.withTransform()
+field("delegate", expression, nullable = true)
+field("delegateFieldSymbol", delegateFieldSymbolType, "F", nullable = true)
generateBooleanFields("var", "val")
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.tree.generator.context.generatedType
import org.jetbrains.kotlin.fir.tree.generator.context.type
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -23,7 +22,7 @@ import org.jetbrains.kotlin.types.Variance
val sourceElementType = type("fir", "FirSourceElement")
val jumpTargetType = type("fir", "FirTarget")
val constKindType = type(IrConstKind::class)
val constKindType = generatedType("expressions", "FirConstKind")
val operationType = type("fir.expressions", "FirOperation")
val classKindType = type(ClassKind::class)
val invocationKindType = type(InvocationKind::class)