[FIR] Replace static cone types for integers with default classIds in ILT

This commit is contained in:
Dmitriy Novozhilov
2019-12-12 10:33:56 +03:00
parent c6b9593157
commit 4faa2c0c2c
6 changed files with 83 additions and 67 deletions
@@ -0,0 +1,18 @@
/*
* 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
enum class ConeNullability(val suffix: String) {
NULLABLE("?"),
UNKNOWN("!"),
NOT_NULL("");
val isNullable: Boolean get() = this != NOT_NULL
companion object {
fun create(isNullable: Boolean) = if (isNullable) NULLABLE else NOT_NULL
}
}
@@ -0,0 +1,15 @@
/*
* 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.name.ClassId
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
val ConeKotlinType.isNullable: Boolean get() = nullability != ConeNullability.NOT_NULL
val ConeKotlinType.isMarkedNullable: Boolean get() = nullability == ConeNullability.NULLABLE
val ConeKotlinType.classId: ClassId? get() = this.safeAs<ConeClassLikeType>()?.lookupTag?.classId
@@ -5,24 +5,12 @@
package org.jetbrains.kotlin.fir.types package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
abstract val kind: ProjectionKind
companion object {
val EMPTY_ARRAY = arrayOf<ConeKotlinTypeProjection>()
}
}
enum class ProjectionKind { enum class ProjectionKind {
STAR, IN, OUT, INVARIANT; STAR, IN, OUT, INVARIANT;
@@ -37,40 +25,37 @@ enum class ProjectionKind {
} }
} }
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
abstract val kind: ProjectionKind
companion object {
val EMPTY_ARRAY = arrayOf<ConeKotlinTypeProjection>()
}
}
object ConeStarProjection : ConeKotlinTypeProjection() { object ConeStarProjection : ConeKotlinTypeProjection() {
override val kind: ProjectionKind override val kind: ProjectionKind
get() = ProjectionKind.STAR get() = ProjectionKind.STAR
} }
interface ConeTypedProjection { data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection(),
val type: ConeKotlinType ConeTypedProjection {
}
data class ConeKotlinTypeProjectionIn(override val type: ConeKotlinType) : ConeKotlinTypeProjection(), ConeTypedProjection {
override val kind: ProjectionKind override val kind: ProjectionKind
get() = ProjectionKind.IN get() = ProjectionKind.IN
} }
data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotlinTypeProjection(), ConeTypedProjection { data class ConeKotlinTypeProjectionOut(override val type: ConeKotlinType) : ConeKotlinTypeProjection(),
ConeTypedProjection {
override val kind: ProjectionKind override val kind: ProjectionKind
get() = ProjectionKind.OUT get() = ProjectionKind.OUT
} }
enum class ConeNullability(val suffix: String) {
NULLABLE("?"),
UNKNOWN("!"),
NOT_NULL("");
val isNullable: Boolean get() = this != NOT_NULL
companion object {
fun create(isNullable: Boolean) = if (isNullable) NULLABLE else NOT_NULL
}
}
// We assume type IS an invariant type projection to prevent additional wrapper here // We assume type IS an invariant type projection to prevent additional wrapper here
// (more exactly, invariant type projection contains type) // (more exactly, invariant type projection contains type)
sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection, KotlinTypeMarker, TypeArgumentListMarker { sealed class ConeKotlinType : ConeKotlinTypeProjection(),
ConeTypedProjection,
KotlinTypeMarker,
TypeArgumentListMarker {
override val kind: ProjectionKind override val kind: ProjectionKind
get() = ProjectionKind.INVARIANT get() = ProjectionKind.INVARIANT
@@ -86,9 +71,9 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), ConeTypedProjection, K
} }
} }
val ConeKotlinType.isNullable: Boolean get() = nullability != ConeNullability.NOT_NULL interface ConeTypedProjection {
val type: ConeKotlinType
val ConeKotlinType.isMarkedNullable: Boolean get() = nullability == ConeNullability.NULLABLE }
typealias ConeKotlinErrorType = ConeClassErrorType typealias ConeKotlinErrorType = ConeClassErrorType
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.fir.resolve.calls package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl import org.jetbrains.kotlin.fir.declarations.classId
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.arrayElementType import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.resolve.calls.results.*
import org.jetbrains.kotlin.types.checker.requireOrDescribe import org.jetbrains.kotlin.types.checker.requireOrDescribe
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
@@ -62,21 +61,24 @@ abstract class AbstractConeCallConflictResolver(
// TODO: support unsigned types // TODO: support unsigned types
// see OverloadingConflictResolver.kt:294 // see OverloadingConflictResolver.kt:294
val int = ConeIntegerLiteralTypeImpl.INT_TYPE val int = StandardClassIds.Int
val long = ConeIntegerLiteralTypeImpl.LONG_TYPE val long = StandardClassIds.Long
val byte = ConeIntegerLiteralTypeImpl.BYTE_TYPE val byte = StandardClassIds.Byte
val short = ConeIntegerLiteralTypeImpl.SHORT_TYPE val short = StandardClassIds.Short
val specificClassId = specific.classId ?: return false
val generalClassId = general.classId ?: return false
when { when {
//TypeUtils.equalTypes(specific, _double) && TypeUtils.equalTypes(general, _float) -> return true //TypeUtils.equalTypes(specific, _double) && TypeUtils.equalTypes(general, _float) -> return true
specific == int -> { specificClassId == int -> {
when { when {
general == long -> return true generalClassId == long -> return true
general == byte -> return true generalClassId == byte -> return true
general == short -> return true generalClassId == short -> return true
} }
} }
specific == short && general == byte -> return true specificClassId == short && generalClassId == byte -> return true
} }
return false return false
} }
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
@@ -106,11 +107,11 @@ class IntegerLiteralTypeApproximationTransformer(
} }
fun ConeClassLikeType.toConstKind(): FirConstKind<*> { fun ConeClassLikeType.toConstKind(): FirConstKind<*> {
return when (this) { return when (classId) {
ConeIntegerLiteralTypeImpl.INT_TYPE -> FirConstKind.Int StandardClassIds.Int -> FirConstKind.Int
ConeIntegerLiteralTypeImpl.LONG_TYPE -> FirConstKind.Long StandardClassIds.Long -> FirConstKind.Long
ConeIntegerLiteralTypeImpl.SHORT_TYPE -> FirConstKind.Short StandardClassIds.Short -> FirConstKind.Short
ConeIntegerLiteralTypeImpl.BYTE_TYPE -> FirConstKind.Byte StandardClassIds.Byte -> FirConstKind.Byte
else -> throw IllegalStateException() else -> throw IllegalStateException()
} }
} }
@@ -171,9 +172,9 @@ class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximat
} }
} }
else -> { else -> {
val expectedType = when (argumentType) { val expectedType = when (argumentType.classId) {
ConeIntegerLiteralTypeImpl.LONG_TYPE -> argumentType StandardClassIds.Long -> argumentType
else -> ConeIntegerLiteralTypeImpl.INT_TYPE else -> ConeIntegerLiteralTypeImpl.createType(StandardClassIds.Int)
} }
functionCall.transformSingle(approximator, expectedType) functionCall.transformSingle(approximator, expectedType)
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(expectedType)) functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(expectedType))
@@ -17,17 +17,17 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
constructor(value: Long) : super(value) { constructor(value: Long) : super(value) {
possibleTypes = mutableListOf() possibleTypes = mutableListOf()
fun checkBoundsAndAddPossibleType(type: ConeClassLikeType, range: LongRange) { fun checkBoundsAndAddPossibleType(classId: ClassId, range: LongRange) {
if (value in range) { if (value in range) {
possibleTypes.add(type) possibleTypes.add(createType(classId))
} }
} }
fun addSignedPossibleTypes() { fun addSignedPossibleTypes() {
checkBoundsAndAddPossibleType(INT_TYPE, INT_RANGE) checkBoundsAndAddPossibleType(StandardClassIds.Int, INT_RANGE)
possibleTypes += LONG_TYPE possibleTypes += createType(StandardClassIds.Long)
checkBoundsAndAddPossibleType(BYTE_TYPE, BYTE_RANGE) checkBoundsAndAddPossibleType(StandardClassIds.Byte, BYTE_RANGE)
checkBoundsAndAddPossibleType(SHORT_TYPE, SHORT_RANGE) checkBoundsAndAddPossibleType(StandardClassIds.Short, SHORT_RANGE)
} }
addSignedPossibleTypes() addSignedPossibleTypes()
@@ -53,15 +53,10 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType {
} }
companion object { companion object {
private fun createType(classId: ClassId): ConeClassLikeType { fun createType(classId: ClassId): ConeClassLikeType {
return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(classId), emptyArray(), false) 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 NUMBER_TYPE = createType(StandardClassIds.Number)
private val INT_RANGE = Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong() private val INT_RANGE = Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong()