[FIR] Support IntegerLiteralTypes
This commit is contained in:
@@ -37,6 +37,9 @@ object StandardClassIds {
|
||||
|
||||
val KProperty = "KProperty".reflectId()
|
||||
|
||||
val Comparable = "Comparable".baseId()
|
||||
val Number = "Number".baseId()
|
||||
|
||||
fun byName(name: String) = name.baseId()
|
||||
fun reflectByName(name: String) = name.reflectId()
|
||||
|
||||
|
||||
@@ -5,10 +5,14 @@
|
||||
|
||||
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.ConeClassifierLookupTag
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
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.*
|
||||
|
||||
sealed class ConeKotlinTypeProjection : TypeArgumentMarker {
|
||||
@@ -230,3 +234,33 @@ open class ConeTypeVariable(name: String) : TypeVariableMarker {
|
||||
class ConeTypeVariableTypeConstructor(val debugName: String) : ConeClassifierLookupTag(), TypeVariableTypeConstructorMarker {
|
||||
override val name: Name get() = Name.identifier(debugName)
|
||||
}
|
||||
|
||||
abstract class ConeIntegerLiteralType(val value: Long) : ConeKotlinType(), SimpleTypeMarker, TypeConstructorMarker {
|
||||
abstract val possibleTypes: Collection<ConeClassLikeType>
|
||||
abstract val supertypes: List<ConeClassLikeType>
|
||||
|
||||
override val typeArguments: Array<out ConeKotlinTypeProjection> = emptyArray()
|
||||
override val nullability: ConeNullability = ConeNullability.NOT_NULL
|
||||
|
||||
abstract fun getApproximatedType(expectedType: ConeKotlinType? = null): ConeClassLikeType
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ConeIntegerLiteralType
|
||||
|
||||
if (possibleTypes != other.possibleTypes) return false
|
||||
if (nullability != other.nullability) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return 31 * possibleTypes.hashCode() + nullability.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeIntegerLiteralType.canBeInt(): Boolean {
|
||||
return value in Int.MIN_VALUE..Int.MAX_VALUE
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ fun ConeKotlinType.render(): String {
|
||||
)
|
||||
}
|
||||
is ConeStubType -> "stub type: $variable"
|
||||
is ConeIntegerLiteralType -> "ILT: $value"
|
||||
} + nullabilitySuffix
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypePlaceholderProjection
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
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
|
||||
@@ -728,38 +727,38 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
|
||||
private fun FlowContent.generate(expression: FirConstExpression<*>) {
|
||||
val value = expression.value
|
||||
if (value == null && expression.kind != IrConstKind.Null) {
|
||||
if (value == null && expression.kind != FirConstKind.Null) {
|
||||
return error {
|
||||
+"null value"
|
||||
}
|
||||
}
|
||||
|
||||
when (expression.kind) {
|
||||
IrConstKind.Null -> keyword("null")
|
||||
IrConstKind.Boolean -> keyword(value.toString())
|
||||
IrConstKind.String, IrConstKind.Char ->
|
||||
FirConstKind.Null -> keyword("null")
|
||||
FirConstKind.Boolean -> keyword(value.toString())
|
||||
FirConstKind.String, FirConstKind.Char ->
|
||||
stringLiteral(value)
|
||||
IrConstKind.Byte -> {
|
||||
FirConstKind.Byte -> {
|
||||
+value.toString()
|
||||
keyword("B")
|
||||
}
|
||||
IrConstKind.Short -> {
|
||||
FirConstKind.Short -> {
|
||||
+value.toString()
|
||||
keyword("S")
|
||||
}
|
||||
IrConstKind.Int -> {
|
||||
FirConstKind.Int -> {
|
||||
+value.toString()
|
||||
keyword("I")
|
||||
}
|
||||
IrConstKind.Long -> {
|
||||
FirConstKind.Long -> {
|
||||
+value.toString()
|
||||
keyword("L")
|
||||
}
|
||||
IrConstKind.Float -> {
|
||||
FirConstKind.Float -> {
|
||||
+value.toString()
|
||||
keyword("F")
|
||||
}
|
||||
IrConstKind.Double -> {
|
||||
FirConstKind.Double -> {
|
||||
+value.toString()
|
||||
keyword("D")
|
||||
}
|
||||
@@ -784,6 +783,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver
|
||||
+"!!"
|
||||
}
|
||||
is ConeIntersectionType -> resolved { generate(type) }
|
||||
is ConeIntegerLiteralType -> inlineUnsupported(type)
|
||||
}
|
||||
if (type.typeArguments.isNotEmpty()) {
|
||||
+"<"
|
||||
|
||||
@@ -73,6 +73,7 @@ fun ConeKotlinType.toIrType(session: FirSession, declarationStorage: Fir2IrDecla
|
||||
intersectedTypes.first().toIrType(session, declarationStorage, definitelyNotNull)
|
||||
}
|
||||
is ConeStubType -> createErrorType()
|
||||
is ConeIntegerLiteralType -> getApproximatedType().toIrType(session, declarationStorage, definitelyNotNull)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,12 +23,16 @@ import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.SyntheticPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.symbols.AccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -71,6 +75,8 @@ class Fir2IrVisitor(
|
||||
private val UNARY_OPERATIONS: Set<FirOperation> = EnumSet.of(FirOperation.EXCL)
|
||||
}
|
||||
|
||||
private val integerApproximator = IntegerLiteralTypeApproximationTransformer(session.firSymbolProvider, session.typeContext)
|
||||
|
||||
private val typeContext = session.typeContext
|
||||
|
||||
private val declarationStorage = Fir2IrDeclarationStorage(session, symbolTable, moduleDescriptor)
|
||||
@@ -822,6 +828,11 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrElement {
|
||||
val functionCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) {
|
||||
functionCall.copy().transformSingle(integerApproximator, null)
|
||||
} else {
|
||||
functionCall
|
||||
}
|
||||
return functionCall.toIrExpression(functionCall.typeRef).applyCallArguments(functionCall).applyTypeArguments(functionCall)
|
||||
.applyReceivers(functionCall)
|
||||
}
|
||||
@@ -916,10 +927,23 @@ class Fir2IrVisitor(
|
||||
|
||||
override fun <T> visitConstExpression(constExpression: FirConstExpression<T>, data: Any?): IrElement {
|
||||
return constExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val kind = constExpression.getIrConstKind() as IrConstKind<T>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val value = (constExpression.value as? Long)?.let {
|
||||
when (kind) {
|
||||
IrConstKind.Byte -> it.toByte()
|
||||
IrConstKind.Short -> it.toShort()
|
||||
IrConstKind.Int -> it.toInt()
|
||||
IrConstKind.Float -> it.toFloat()
|
||||
IrConstKind.Double -> it.toDouble()
|
||||
else -> it
|
||||
}
|
||||
} as T ?: constExpression.value
|
||||
IrConstImpl(
|
||||
startOffset, endOffset,
|
||||
constExpression.typeRef.toIrType(session, declarationStorage),
|
||||
constExpression.kind, constExpression.value
|
||||
kind, value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
||||
return when (this) {
|
||||
is ConeClassLikeType -> mapToCanonicalString(session)
|
||||
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType,
|
||||
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType ->
|
||||
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType, is ConeIntegerLiteralType ->
|
||||
error("Unexpected type: $this [${this::class}]")
|
||||
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ private fun ConeKotlinType.mapToCanonicalString(session: FirSession): String {
|
||||
return when (this) {
|
||||
is ConeClassLikeType -> mapToCanonicalString(session)
|
||||
is ConeTypeVariableType, is ConeFlexibleType, is ConeCapturedType,
|
||||
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType ->
|
||||
is ConeDefinitelyNotNullType, is ConeIntersectionType, is ConeStubType, is ConeIntegerLiteralType ->
|
||||
error("Unexpected type: $this [${this::class}]")
|
||||
is ConeLookupTagBasedType -> lookupTag.name.asString()
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -275,7 +275,7 @@ private fun JavaAnnotationArgument.toFirExpression(
|
||||
}
|
||||
|
||||
// TODO: use kind here
|
||||
private fun <T> List<T>.createArrayOfCall(session: FirSession, @Suppress("UNUSED_PARAMETER") kind: IrConstKind<T>): FirArrayOfCall {
|
||||
private fun <T> List<T>.createArrayOfCall(session: FirSession, @Suppress("UNUSED_PARAMETER") kind: FirConstKind<T>): FirArrayOfCall {
|
||||
return FirArrayOfCallImpl(null).apply {
|
||||
for (element in this@createArrayOfCall) {
|
||||
arguments += element.createConstant(session)
|
||||
@@ -285,24 +285,24 @@ private fun <T> List<T>.createArrayOfCall(session: FirSession, @Suppress("UNUSED
|
||||
|
||||
internal fun Any?.createConstant(session: FirSession): FirExpression {
|
||||
return when (this) {
|
||||
is Byte -> FirConstExpressionImpl(null, IrConstKind.Byte, this)
|
||||
is Short -> FirConstExpressionImpl(null, IrConstKind.Short, this)
|
||||
is Int -> FirConstExpressionImpl(null, IrConstKind.Int, this)
|
||||
is Long -> FirConstExpressionImpl(null, IrConstKind.Long, this)
|
||||
is Char -> FirConstExpressionImpl(null, IrConstKind.Char, this)
|
||||
is Float -> FirConstExpressionImpl(null, IrConstKind.Float, this)
|
||||
is Double -> FirConstExpressionImpl(null, IrConstKind.Double, this)
|
||||
is Boolean -> FirConstExpressionImpl(null, IrConstKind.Boolean, this)
|
||||
is String -> FirConstExpressionImpl(null, IrConstKind.String, this)
|
||||
is ByteArray -> toList().createArrayOfCall(session, IrConstKind.Byte)
|
||||
is ShortArray -> toList().createArrayOfCall(session, IrConstKind.Short)
|
||||
is IntArray -> toList().createArrayOfCall(session, IrConstKind.Int)
|
||||
is LongArray -> toList().createArrayOfCall(session, IrConstKind.Long)
|
||||
is CharArray -> toList().createArrayOfCall(session, IrConstKind.Char)
|
||||
is FloatArray -> toList().createArrayOfCall(session, IrConstKind.Float)
|
||||
is DoubleArray -> toList().createArrayOfCall(session, IrConstKind.Double)
|
||||
is BooleanArray -> toList().createArrayOfCall(session, IrConstKind.Boolean)
|
||||
null -> FirConstExpressionImpl(null, IrConstKind.Null, null)
|
||||
is Byte -> FirConstExpressionImpl(null, FirConstKind.Byte, this)
|
||||
is Short -> FirConstExpressionImpl(null, FirConstKind.Short, this)
|
||||
is Int -> FirConstExpressionImpl(null, FirConstKind.Int, this)
|
||||
is Long -> FirConstExpressionImpl(null, FirConstKind.Long, this)
|
||||
is Char -> FirConstExpressionImpl(null, FirConstKind.Char, this)
|
||||
is Float -> FirConstExpressionImpl(null, FirConstKind.Float, this)
|
||||
is Double -> FirConstExpressionImpl(null, FirConstKind.Double, this)
|
||||
is Boolean -> FirConstExpressionImpl(null, FirConstKind.Boolean, this)
|
||||
is String -> FirConstExpressionImpl(null, FirConstKind.String, this)
|
||||
is ByteArray -> toList().createArrayOfCall(session, FirConstKind.Byte)
|
||||
is ShortArray -> toList().createArrayOfCall(session, FirConstKind.Short)
|
||||
is IntArray -> toList().createArrayOfCall(session, FirConstKind.Int)
|
||||
is LongArray -> toList().createArrayOfCall(session, FirConstKind.Long)
|
||||
is CharArray -> toList().createArrayOfCall(session, FirConstKind.Char)
|
||||
is FloatArray -> toList().createArrayOfCall(session, FirConstKind.Float)
|
||||
is DoubleArray -> toList().createArrayOfCall(session, FirConstKind.Double)
|
||||
is BooleanArray -> toList().createArrayOfCall(session, FirConstKind.Boolean)
|
||||
null -> FirConstExpressionImpl(null, FirConstKind.Null, null)
|
||||
|
||||
else -> FirErrorExpressionImpl(null, FirSimpleDiagnostic("Unknown value in JavaLiteralAnnotationArgument: $this", DiagnosticKind.Java))
|
||||
}
|
||||
|
||||
@@ -111,4 +111,8 @@ class FirJavaField(
|
||||
get() = null
|
||||
|
||||
override var containerSource: DeserializedContainerSource? = null
|
||||
|
||||
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirField {
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
@@ -35,7 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_NULL_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
|
||||
@@ -391,15 +387,15 @@ internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String):
|
||||
|
||||
val (number, radix) = extractRadix(value)
|
||||
return when (classId.relativeClassName.asString()) {
|
||||
"Boolean" -> FirConstExpressionImpl(null, IrConstKind.Boolean, value.toBoolean())
|
||||
"Char" -> FirConstExpressionImpl(null, IrConstKind.Char, value.singleOrNull() ?: return null)
|
||||
"Byte" -> FirConstExpressionImpl(null, IrConstKind.Byte, number.toByteOrNull(radix) ?: return null)
|
||||
"Short" -> FirConstExpressionImpl(null, IrConstKind.Short, number.toShortOrNull(radix) ?: return null)
|
||||
"Int" -> FirConstExpressionImpl(null, IrConstKind.Int, number.toIntOrNull(radix) ?: return null)
|
||||
"Long" -> FirConstExpressionImpl(null, IrConstKind.Long, number.toLongOrNull(radix) ?: return null)
|
||||
"Float" -> FirConstExpressionImpl(null, IrConstKind.Float, value.toFloatOrNull() ?: return null)
|
||||
"Double" -> FirConstExpressionImpl(null, IrConstKind.Double, value.toDoubleOrNull() ?: return null)
|
||||
"String" -> FirConstExpressionImpl(null, IrConstKind.String, value)
|
||||
"Boolean" -> FirConstExpressionImpl(null, FirConstKind.Boolean, value.toBoolean())
|
||||
"Char" -> FirConstExpressionImpl(null, FirConstKind.Char, value.singleOrNull() ?: return null)
|
||||
"Byte" -> FirConstExpressionImpl(null, FirConstKind.Byte, number.toByteOrNull(radix) ?: return null)
|
||||
"Short" -> FirConstExpressionImpl(null, FirConstKind.Short, number.toShortOrNull(radix) ?: return null)
|
||||
"Int" -> FirConstExpressionImpl(null, FirConstKind.Int, number.toIntOrNull(radix) ?: return null)
|
||||
"Long" -> FirConstExpressionImpl(null, FirConstKind.Long, number.toLongOrNull(radix) ?: return null)
|
||||
"Float" -> FirConstExpressionImpl(null, FirConstKind.Float, value.toFloatOrNull() ?: return null)
|
||||
"Double" -> FirConstExpressionImpl(null, FirConstKind.Double, value.toDoubleOrNull() ?: return null)
|
||||
"String" -> FirConstExpressionImpl(null, FirConstKind.String, value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
|
||||
@@ -24,7 +25,6 @@ import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
@@ -276,7 +276,7 @@ class JavaClassEnhancementScope(
|
||||
).enhance(session, jsr305State, predefinedEnhancementInfo?.parametersInfo?.getOrNull(index))
|
||||
val firResolvedTypeRef = signatureParts.type
|
||||
val defaultValueExpression = when (val defaultValue = ownerParameter.getDefaultValueFromAnnotation()) {
|
||||
NullDefaultValue -> FirConstExpressionImpl(null, IrConstKind.Null, null)
|
||||
NullDefaultValue -> FirConstExpressionImpl(null, FirConstKind.Null, null)
|
||||
is StringDefaultValue -> firResolvedTypeRef.type.lexicalCastFrom(session, defaultValue.value)
|
||||
null -> null
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.CLOSING_QUOTE
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.OPEN_QUOTE
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -224,40 +223,50 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
|
||||
else -> null
|
||||
}
|
||||
return when (type) {
|
||||
INTEGER_CONSTANT ->
|
||||
if (convertedText is Long &&
|
||||
(hasLongSuffix(text) || hasUnsignedLongSuffix(text) || hasUnsignedSuffix(text) ||
|
||||
convertedText > Int.MAX_VALUE || convertedText < Int.MIN_VALUE)
|
||||
) {
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(), IrConstKind.Long, convertedText, FirSimpleDiagnostic("Incorrect long: $text", DiagnosticKind.Syntax)
|
||||
INTEGER_CONSTANT -> {
|
||||
val kind = when {
|
||||
convertedText !is Long -> return FirErrorExpressionImpl(
|
||||
expression.getSourceOrNull(),
|
||||
FirSimpleDiagnostic(
|
||||
"Incorrect constant expression: $text",
|
||||
DiagnosticKind.IllegalConstExpression
|
||||
)
|
||||
)
|
||||
} else if (convertedText is Number) {
|
||||
// TODO: support byte / short
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(), IrConstKind.Int, convertedText.toInt(), FirSimpleDiagnostic("Incorrect int: $text", DiagnosticKind.Syntax)
|
||||
)
|
||||
} else {
|
||||
FirErrorExpressionImpl(expression.getSourceOrNull(), FirSimpleDiagnostic("Incorrect constant expression: $text", DiagnosticKind.IllegalConstExpression))
|
||||
|
||||
hasLongSuffix(text) || hasUnsignedSuffix(text) || hasUnsignedLongSuffix(text) -> {
|
||||
FirConstKind.Long
|
||||
}
|
||||
|
||||
else -> {
|
||||
FirConstKind.IntegerLiteral
|
||||
}
|
||||
}
|
||||
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(),
|
||||
kind,
|
||||
convertedText,
|
||||
FirSimpleDiagnostic("Incorrect integer literal: $text", DiagnosticKind.Syntax)
|
||||
)
|
||||
}
|
||||
FLOAT_CONSTANT ->
|
||||
if (convertedText is Float) {
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(), IrConstKind.Float, convertedText, FirSimpleDiagnostic("Incorrect float: $text", DiagnosticKind.Syntax)
|
||||
expression.getSourceOrNull(), FirConstKind.Float, convertedText, FirSimpleDiagnostic("Incorrect float: $text", DiagnosticKind.Syntax)
|
||||
)
|
||||
} else {
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(), IrConstKind.Double, convertedText as Double, FirSimpleDiagnostic("Incorrect double: $text", DiagnosticKind.Syntax)
|
||||
expression.getSourceOrNull(), FirConstKind.Double, convertedText as Double, FirSimpleDiagnostic("Incorrect double: $text", DiagnosticKind.Syntax)
|
||||
)
|
||||
}
|
||||
CHARACTER_CONSTANT ->
|
||||
FirConstExpressionImpl(
|
||||
expression.getSourceOrNull(), IrConstKind.Char, text.parseCharacter(), FirSimpleDiagnostic("Incorrect character: $text", DiagnosticKind.Syntax)
|
||||
expression.getSourceOrNull(), FirConstKind.Char, text.parseCharacter(), FirSimpleDiagnostic("Incorrect character: $text", DiagnosticKind.Syntax)
|
||||
)
|
||||
BOOLEAN_CONSTANT ->
|
||||
FirConstExpressionImpl(expression.getSourceOrNull(), IrConstKind.Boolean, convertedText as Boolean)
|
||||
FirConstExpressionImpl(expression.getSourceOrNull(), FirConstKind.Boolean, convertedText as Boolean)
|
||||
NULL ->
|
||||
FirConstExpressionImpl(expression.getSourceOrNull(), IrConstKind.Null, null)
|
||||
FirConstExpressionImpl(expression.getSourceOrNull(), FirConstKind.Null, null)
|
||||
else ->
|
||||
throw AssertionError("Unknown literal type: $type, $text")
|
||||
}
|
||||
@@ -277,11 +286,11 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
|
||||
OPEN_QUOTE, CLOSING_QUOTE -> continue@L
|
||||
LITERAL_STRING_TEMPLATE_ENTRY -> {
|
||||
sb.append(entry.asText)
|
||||
FirConstExpressionImpl(entry.getSourceOrNull(), IrConstKind.String, entry.asText)
|
||||
FirConstExpressionImpl(entry.getSourceOrNull(), FirConstKind.String, entry.asText)
|
||||
}
|
||||
ESCAPE_STRING_TEMPLATE_ENTRY -> {
|
||||
sb.append(entry.unescapedValue)
|
||||
FirConstExpressionImpl(entry.getSourceOrNull(), IrConstKind.String, entry.unescapedValue)
|
||||
FirConstExpressionImpl(entry.getSourceOrNull(), FirConstKind.String, entry.unescapedValue)
|
||||
}
|
||||
SHORT_STRING_TEMPLATE_ENTRY, LONG_STRING_TEMPLATE_ENTRY -> {
|
||||
hasExpressions = true
|
||||
@@ -313,7 +322,7 @@ abstract class BaseFirBuilder<T>(val session: FirSession, val context: Context =
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (hasExpressions) result!! else FirConstExpressionImpl(base?.toFirSourceElement(), IrConstKind.String, sb.toString())
|
||||
return if (hasExpressions) result!! else FirConstExpressionImpl(base?.toFirSourceElement(), FirConstKind.String, sb.toString())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.types.ConeStarProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitKPropertyTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -149,7 +148,7 @@ fun FirExpression.generateNotNullOrOther(
|
||||
baseSource,
|
||||
FirOperatorCallImpl(baseSource, FirOperation.EQ).apply {
|
||||
arguments += subjectExpression
|
||||
arguments += FirConstExpressionImpl(baseSource, IrConstKind.Null, null)
|
||||
arguments += FirConstExpressionImpl(baseSource, FirConstKind.Null, null)
|
||||
},
|
||||
FirSingleExpressionBlock(other)
|
||||
)
|
||||
@@ -326,7 +325,7 @@ fun FirModifiableVariable<*>.generateAccessorsByDelegate(session: FirSession, me
|
||||
if (member) FirQualifiedAccessExpressionImpl(null).apply {
|
||||
calleeReference = FirExplicitThisReference(null, null)
|
||||
}
|
||||
else FirConstExpressionImpl(null, IrConstKind.Null, null)
|
||||
else FirConstExpressionImpl(null, FirConstKind.Null, null)
|
||||
|
||||
fun propertyRef() = FirCallableReferenceAccessImpl(null).apply {
|
||||
calleeReference = FirResolvedNamedReferenceImpl(null, variable.name, variable.symbol)
|
||||
|
||||
@@ -17,5 +17,5 @@ FILE: expectActual.kt
|
||||
public? final? actual fun foo(): <implicit> {
|
||||
^foo String(Hello)
|
||||
}
|
||||
public? final? actual val x: <implicit> = Int(42)
|
||||
public? final? actual val x: <implicit> = IntegerLiteral(42)
|
||||
public? get(): <implicit>
|
||||
|
||||
@@ -11,7 +11,7 @@ FILE: simpleClass.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
private final? val baz: <implicit> = Int(42)
|
||||
private final? val baz: <implicit> = IntegerLiteral(42)
|
||||
private get(): <implicit>
|
||||
|
||||
public? open? override fun foo(x: Int, y: String): String {
|
||||
|
||||
@@ -19,7 +19,7 @@ FILE: typeParameters.kt
|
||||
}
|
||||
|
||||
public? open? override fun get(index: Int): Int {
|
||||
^get Int(42)
|
||||
^get IntegerLiteral(42)
|
||||
}
|
||||
|
||||
public? open? override fun concat(other: List<Int>): List<Int> {
|
||||
|
||||
@@ -7,18 +7,18 @@ FILE: annotated.kt
|
||||
}
|
||||
public? final? fun foo(arg: Int): Int {
|
||||
when () {
|
||||
==(@Ann() arg#, Int(0)) -> {
|
||||
@Ann() ^foo Int(1)
|
||||
==(@Ann() arg#, IntegerLiteral(0)) -> {
|
||||
@Ann() ^foo IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@Ann() when () {
|
||||
==(arg#, Int(1)) -> {
|
||||
^foo @Ann() Int(1)
|
||||
==(arg#, IntegerLiteral(1)) -> {
|
||||
^foo @Ann() IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
^foo Int(42)
|
||||
^foo IntegerLiteral(42)
|
||||
}
|
||||
public? final? data class Two : R|kotlin/Any| {
|
||||
public? constructor(x: Int, y: Int): R|Two| {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FILE: arrayAccess.kt
|
||||
public? final? val p: <implicit> = Int(0)
|
||||
public? final? val p: <implicit> = IntegerLiteral(0)
|
||||
public? get(): <implicit>
|
||||
public? final? fun foo(): <implicit> {
|
||||
^foo Int(1)
|
||||
^foo IntegerLiteral(1)
|
||||
}
|
||||
public? final? class Wrapper : R|kotlin/Any| {
|
||||
public? constructor(v: IntArray): R|Wrapper| {
|
||||
@@ -14,5 +14,5 @@ FILE: arrayAccess.kt
|
||||
|
||||
}
|
||||
public? final? fun test(a: IntArray, w: Wrapper): <implicit> {
|
||||
^test a#.get#(Int(0)).plus#(a#.get#(p#)).plus#(a#.get#(foo#())).plus#(w#.v#.get#(Int(0)))
|
||||
^test a#.get#(IntegerLiteral(0)).plus#(a#.get#(p#)).plus#(a#.get#(foo#())).plus#(w#.v#.get#(IntegerLiteral(0)))
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
FILE: arrayAssignment.kt
|
||||
public? final? fun test(): R|kotlin/Unit| {
|
||||
lval x: <implicit> = intArrayOf#(Int(1), Int(2), Int(3))
|
||||
x#.set#(Int(1), Int(0))
|
||||
lval x: <implicit> = intArrayOf#(IntegerLiteral(1), IntegerLiteral(2), IntegerLiteral(3))
|
||||
x#.set#(IntegerLiteral(1), IntegerLiteral(0))
|
||||
}
|
||||
public? final? fun foo(): <implicit> {
|
||||
^foo Int(1)
|
||||
^foo IntegerLiteral(1)
|
||||
}
|
||||
public? final? fun test2(): R|kotlin/Unit| {
|
||||
intArrayOf#(Int(1), Int(2), Int(3)).set#(foo#(), Int(1))
|
||||
intArrayOf#(IntegerLiteral(1), IntegerLiteral(2), IntegerLiteral(3)).set#(foo#(), IntegerLiteral(1))
|
||||
}
|
||||
|
||||
@@ -37,19 +37,19 @@ FILE: branches.kt
|
||||
}
|
||||
public? final? fun grade(g: Int): String {
|
||||
^grade when (g#) {
|
||||
==($subj$, Int(6)) || ==($subj$, Int(7)) -> {
|
||||
==($subj$, IntegerLiteral(6)) || ==($subj$, IntegerLiteral(7)) -> {
|
||||
String(Outstanding)
|
||||
}
|
||||
==($subj$, Int(5)) -> {
|
||||
==($subj$, IntegerLiteral(5)) -> {
|
||||
String(Excellent)
|
||||
}
|
||||
==($subj$, Int(4)) -> {
|
||||
==($subj$, IntegerLiteral(4)) -> {
|
||||
String(Good)
|
||||
}
|
||||
==($subj$, Int(3)) -> {
|
||||
==($subj$, IntegerLiteral(3)) -> {
|
||||
String(Mediocre)
|
||||
}
|
||||
Int(1).rangeTo#(Int(2)).contains#($subj$) -> {
|
||||
IntegerLiteral(1).rangeTo#(IntegerLiteral(2)).contains#($subj$) -> {
|
||||
String(Fail)
|
||||
}
|
||||
($subj$ is Number) -> {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ FILE: callableReferences.kt
|
||||
public? final? fun foo(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? val bar: <implicit> = Int(0)
|
||||
public? final? val bar: <implicit> = IntegerLiteral(0)
|
||||
public? get(): <implicit>
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ FILE: calls.kt
|
||||
^distance x#.plus#(y#)
|
||||
}
|
||||
public? final? fun test(): Int {
|
||||
^test Int(3).distance#(Int(4))
|
||||
^test IntegerLiteral(3).distance#(IntegerLiteral(4))
|
||||
}
|
||||
public? final? fun testRegular(): Int {
|
||||
^testRegular distance#(Int(3), Int(4))
|
||||
^testRegular distance#(IntegerLiteral(3), IntegerLiteral(4))
|
||||
}
|
||||
public? final? class My : R|kotlin/Any| {
|
||||
public? constructor(x: Int): R|My| {
|
||||
@@ -30,7 +30,7 @@ FILE: calls.kt
|
||||
|
||||
}
|
||||
public? final? fun testInvoke(): Int {
|
||||
^testInvoke My#(Int(13)).invoke#()
|
||||
^testInvoke My#(IntegerLiteral(13)).invoke#()
|
||||
}
|
||||
public? final? fun testQualified(first: My, second: My?): R|kotlin/Unit| {
|
||||
println#(first#.x#)
|
||||
@@ -38,5 +38,5 @@ FILE: calls.kt
|
||||
first#.foo#()
|
||||
second#?.foo#()
|
||||
first#.copy#().foo#()
|
||||
first#.x# = Int(42)
|
||||
first#.x# = IntegerLiteral(42)
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ FILE: collectionLiterals.kt
|
||||
}
|
||||
|
||||
}
|
||||
@Ann1(<implicitArrayOf>(Int(1), Int(2))) public? final? class First : R|kotlin/Any| {
|
||||
@Ann1(<implicitArrayOf>(IntegerLiteral(1), IntegerLiteral(2))) public? final? class First : R|kotlin/Any| {
|
||||
public? constructor(): R|First| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FILE: for.kt
|
||||
public? final? fun foo(): R|kotlin/Unit| {
|
||||
lval <range>: <implicit> = Int(1).rangeTo#(Int(10))
|
||||
lval <range>: <implicit> = IntegerLiteral(1).rangeTo#(IntegerLiteral(10))
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval i: <implicit> = R|<local>/<iterator>|.next#()
|
||||
@@ -9,14 +9,14 @@ FILE: for.kt
|
||||
|
||||
}
|
||||
public? final? fun bar(list: List<String>): R|kotlin/Unit| {
|
||||
lval <range>: <implicit> = list#.subList#(Int(0), Int(10))
|
||||
lval <range>: <implicit> = list#.subList#(IntegerLiteral(0), IntegerLiteral(10))
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval element: <implicit> = R|<local>/<iterator>|.next#()
|
||||
println#(element#)
|
||||
}
|
||||
|
||||
lval <range>: <implicit> = list#.subList#(Int(10), Int(20))
|
||||
lval <range>: <implicit> = list#.subList#(IntegerLiteral(10), IntegerLiteral(20))
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval element: <implicit> = R|<local>/<iterator>|.next#()
|
||||
|
||||
@@ -23,7 +23,7 @@ FILE: lambda.kt
|
||||
|
||||
}
|
||||
public? final? inline fun use(f: ( (Tuple) -> Int )): <implicit> {
|
||||
^use f#(Tuple#(Int(1), Int(2)))
|
||||
^use f#(Tuple#(IntegerLiteral(1), IntegerLiteral(2)))
|
||||
}
|
||||
public? final? fun foo(): Int {
|
||||
lval l1: <implicit> = fun <implicit>.<anonymous>(t: Tuple): <implicit> {
|
||||
@@ -40,8 +40,8 @@ FILE: lambda.kt
|
||||
)
|
||||
^foo use#(<L> = use@fun <implicit>.<anonymous>(): <implicit> {
|
||||
when () {
|
||||
==(it#.x#, Int(0)) -> {
|
||||
^foo Int(0)
|
||||
==(it#.x#, IntegerLiteral(0)) -> {
|
||||
^foo IntegerLiteral(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ FILE: lambda.kt
|
||||
public? final? fun bar(): Int {
|
||||
^bar use#(<L> = lambda@fun <implicit>.<anonymous>(): <implicit> {
|
||||
when () {
|
||||
==(it#.x#, Int(0)) -> {
|
||||
^bar Int(0)
|
||||
==(it#.x#, IntegerLiteral(0)) -> {
|
||||
^bar IntegerLiteral(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ FILE: lambda.kt
|
||||
|
||||
public? get(): <implicit>
|
||||
public? final? val another: <implicit> = fun <implicit>.<anonymous>(): <implicit> {
|
||||
Int(42)
|
||||
IntegerLiteral(42)
|
||||
}
|
||||
|
||||
public? get(): <implicit>
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ FILE: lambdaAndAnonymousFunction.kt
|
||||
}
|
||||
public? final? fun test_2(): R|kotlin/Unit| {
|
||||
run#(fun <anonymous>(): Int {
|
||||
^ Int(1)
|
||||
^ IntegerLiteral(1)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ FILE: locals.kt
|
||||
|
||||
}
|
||||
|
||||
lval x: <implicit> = Local#(Int(42)).diff#()
|
||||
lval x: <implicit> = Local#(IntegerLiteral(42)).diff#()
|
||||
local final? fun sum(y: Int, z: Int, f: ( (Int, Int) -> Int )): Int {
|
||||
^sum x#.plus#(f#(y#.plus#(z#)))
|
||||
}
|
||||
@@ -30,7 +30,7 @@ FILE: locals.kt
|
||||
|
||||
}
|
||||
.foo#()
|
||||
^withLocals sum#(code#, Local#(Int(1)).diff#(), fun <anonymous>(x: Int, y: Int): <implicit> {
|
||||
^withLocals sum#(code#, Local#(IntegerLiteral(1)).diff#(), fun <anonymous>(x: Int, y: Int): <implicit> {
|
||||
^ x#.plus#(y#)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
FILE: modifications.kt
|
||||
public? final? fun simple(): R|kotlin/Unit| {
|
||||
lvar x: <implicit> = Int(10)
|
||||
+=(x#, Int(20))
|
||||
-=(x#, Int(5))
|
||||
/=(x#, Int(5))
|
||||
*=(x#, Int(10))
|
||||
lvar x: <implicit> = IntegerLiteral(10)
|
||||
+=(x#, IntegerLiteral(20))
|
||||
-=(x#, IntegerLiteral(5))
|
||||
/=(x#, IntegerLiteral(5))
|
||||
*=(x#, IntegerLiteral(10))
|
||||
}
|
||||
public? final? fun List<String>.modify(): R|kotlin/Unit| {
|
||||
+=(this#, String(Alpha))
|
||||
+=(this#, String(Omega))
|
||||
}
|
||||
public? final? fun Any.modify(): R|kotlin/Unit| {
|
||||
+=((this# as List<Int>), Int(42))
|
||||
+=((this# as List<Int>), IntegerLiteral(42))
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: nullability.kt
|
||||
public? final? fun orFourtyTwo(arg: Int?): <implicit> {
|
||||
^orFourtyTwo when (lval <elvis>: <implicit> = arg#) {
|
||||
==($subj$, Null(null)) -> {
|
||||
Int(42)
|
||||
IntegerLiteral(42)
|
||||
}
|
||||
else -> {
|
||||
R|<local>/<elvis>|
|
||||
|
||||
@@ -5,7 +5,7 @@ FILE: these.kt
|
||||
}
|
||||
|
||||
public? final? fun foo(): Int {
|
||||
^foo Int(1)
|
||||
^foo IntegerLiteral(1)
|
||||
}
|
||||
|
||||
public? final? fun bar(): Int {
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
FILE: unary.kt
|
||||
public? final? fun test(): R|kotlin/Unit| {
|
||||
lvar x: <implicit> = Int(0)
|
||||
lvar x: <implicit> = IntegerLiteral(0)
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
@@ -26,7 +26,7 @@ FILE: unary.kt
|
||||
}
|
||||
|
||||
when () {
|
||||
==(x#, Int(0)).not#() -> {
|
||||
==(x#, IntegerLiteral(0)).not#() -> {
|
||||
println#(String(000))
|
||||
}
|
||||
}
|
||||
@@ -58,15 +58,15 @@ FILE: unary.kt
|
||||
}
|
||||
public? final? fun test3(arr: Array<Int>): R|kotlin/Unit| {
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = arr#.get#(Int(0))
|
||||
arr#.set#(Int(0), R|<local>/<unary>|.inc#())
|
||||
lval <unary>: <implicit> = arr#.get#(IntegerLiteral(0))
|
||||
arr#.set#(IntegerLiteral(0), R|<local>/<unary>|.inc#())
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = arr#.get#(Int(1))
|
||||
lval <unary>: <implicit> = arr#.get#(IntegerLiteral(1))
|
||||
lval <unary-result>: <implicit> = R|<local>/<unary>|.inc#()
|
||||
arr#.set#(Int(1), R|<local>/<unary-result>|)
|
||||
arr#.set#(IntegerLiteral(1), R|<local>/<unary-result>|)
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
@@ -82,15 +82,15 @@ FILE: unary.kt
|
||||
}
|
||||
public? final? fun test4(y: Y): R|kotlin/Unit| {
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = y#.arr#.get#(Int(0))
|
||||
y#.arr#.set#(Int(0), R|<local>/<unary>|.inc#())
|
||||
lval <unary>: <implicit> = y#.arr#.get#(IntegerLiteral(0))
|
||||
y#.arr#.set#(IntegerLiteral(0), R|<local>/<unary>|.inc#())
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = y#.arr#.get#(Int(1))
|
||||
lval <unary>: <implicit> = y#.arr#.get#(IntegerLiteral(1))
|
||||
lval <unary-result>: <implicit> = R|<local>/<unary>|.inc#()
|
||||
y#.arr#.set#(Int(1), R|<local>/<unary-result>|)
|
||||
y#.arr#.set#(IntegerLiteral(1), R|<local>/<unary-result>|)
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FILE: variables.kt
|
||||
public? final? fun foo(): R|kotlin/Unit| {
|
||||
lval x: <implicit> = Int(1)
|
||||
lvar y: <implicit> = x#.plus#(Int(1))
|
||||
lval z: <implicit> = y#.times#(Int(2))
|
||||
lval x: <implicit> = IntegerLiteral(1)
|
||||
lvar y: <implicit> = x#.plus#(IntegerLiteral(1))
|
||||
lval z: <implicit> = y#.times#(IntegerLiteral(2))
|
||||
y# = y#.plus#(z#)
|
||||
lval w: <implicit> = y#.minus#(x#)
|
||||
^foo w#
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
FILE: while.kt
|
||||
public? final? fun foo(limit: Int): R|kotlin/Unit| {
|
||||
lvar k: <implicit> = Int(0)
|
||||
lvar k: <implicit> = IntegerLiteral(0)
|
||||
some@while(<(k#, limit#)) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
println#(k#)
|
||||
while(==(k#, Int(13))) {
|
||||
while(==(k#, IntegerLiteral(13))) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
@@ -18,7 +18,7 @@ FILE: while.kt
|
||||
|
||||
when () {
|
||||
>(k#, limit#) -> {
|
||||
continue@@@[==(k#, Int(13))]
|
||||
continue@@@[==(k#, IntegerLiteral(13))]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ FILE: while.kt
|
||||
R|<local>/<unary>|
|
||||
println#(k#)
|
||||
}
|
||||
while(>=(k#, Int(0)))
|
||||
while(>=(k#, IntegerLiteral(0)))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirWhenExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
@@ -36,7 +37,11 @@ fun FirFunctionCall.copy(
|
||||
typeArguments: List<FirTypeProjection> = this.typeArguments,
|
||||
resultType: FirTypeRef = this.typeRef
|
||||
): FirFunctionCall {
|
||||
return FirFunctionCallImpl(source).apply {
|
||||
return if (this is FirIntegerOperatorCall) {
|
||||
FirIntegerOperatorCall(source)
|
||||
} else {
|
||||
FirFunctionCallImpl(source)
|
||||
}.apply {
|
||||
this.safe = safe
|
||||
this.annotations.addAll(annotations)
|
||||
this.arguments.addAll(arguments)
|
||||
|
||||
@@ -35,9 +35,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.symbols.invoke
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -74,15 +72,56 @@ class FirCallResolver(
|
||||
fun resolveCallAndSelectCandidate(functionCall: FirFunctionCall, file: FirFile): FirFunctionCall {
|
||||
qualifiedResolver.reset()
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val functionCall = functionCall.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent)
|
||||
var functionCall = functionCall.transformExplicitReceiver(transformer, ResolutionMode.ContextIndependent)
|
||||
.also { dataFlowAnalyzer.enterQualifiedAccessExpression(functionCall) }
|
||||
.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||
|
||||
val name = functionCall.calleeReference.name
|
||||
var result = collectCandidates(functionCall)
|
||||
|
||||
if (
|
||||
(result.candidates.isEmpty() || result.applicability < CandidateApplicability.SYNTHETIC_RESOLVED) &&
|
||||
functionCall.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
) {
|
||||
functionCall = functionCall.transformExplicitReceiver(integerLiteralTypeApproximator, null)
|
||||
result = collectCandidates(functionCall)
|
||||
}
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
functionCall.calleeReference.name,
|
||||
result.candidates,
|
||||
result.applicability
|
||||
)
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||
val candidate = resultExpression.candidate()
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
|
||||
functionCall.copy(
|
||||
explicitReceiver = candidate.callInfo.explicitReceiver,
|
||||
dispatchReceiver = candidate.dispatchReceiverExpression(),
|
||||
extensionReceiver = candidate.extensionReceiverExpression(),
|
||||
arguments = candidate.callInfo.arguments,
|
||||
safe = candidate.callInfo.isSafeCall
|
||||
)
|
||||
} else {
|
||||
resultExpression
|
||||
}
|
||||
val typeRef = typeFromCallee(resultFunctionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
resultFunctionCall.resultType = typeRef
|
||||
}
|
||||
return resultFunctionCall
|
||||
}
|
||||
|
||||
private data class ResolutionResult(val info: CallInfo, val applicability: CandidateApplicability, val candidates: Collection<Candidate>)
|
||||
|
||||
private fun collectCandidates(functionCall: FirFunctionCall): ResolutionResult {
|
||||
val explicitReceiver = functionCall.explicitReceiver
|
||||
val arguments = functionCall.arguments
|
||||
val typeArguments = functionCall.typeArguments
|
||||
val name = functionCall.calleeReference.name
|
||||
|
||||
val info = CallInfo(
|
||||
CallKind.Function,
|
||||
@@ -108,34 +147,7 @@ class FirCallResolver(
|
||||
} else {
|
||||
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = true)
|
||||
}
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
functionCall.calleeReference,
|
||||
name,
|
||||
reducedCandidates,
|
||||
result.currentApplicability
|
||||
)
|
||||
|
||||
val resultExpression = functionCall.transformCalleeReference(StoreNameReference, nameReference)
|
||||
val candidate = resultExpression.candidate()
|
||||
|
||||
// We need desugaring
|
||||
val resultFunctionCall = if (candidate != null && candidate.callInfo != info) {
|
||||
functionCall.copy(
|
||||
explicitReceiver = candidate.callInfo.explicitReceiver,
|
||||
dispatchReceiver = candidate.dispatchReceiverExpression(),
|
||||
extensionReceiver = candidate.extensionReceiverExpression(),
|
||||
arguments = candidate.callInfo.arguments,
|
||||
safe = candidate.callInfo.isSafeCall
|
||||
)
|
||||
} else {
|
||||
resultExpression
|
||||
}
|
||||
val typeRef = typeFromCallee(resultFunctionCall)
|
||||
if (typeRef.type is ConeKotlinErrorType) {
|
||||
resultFunctionCall.resultType = typeRef
|
||||
}
|
||||
return resultFunctionCall
|
||||
return ResolutionResult(info, result.currentApplicability, reducedCandidates)
|
||||
}
|
||||
|
||||
fun <T : FirQualifiedAccess> resolveVariableAccessAndSelectCandidate(qualifiedAccess: T, file: FirFile): FirStatement {
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeContext
|
||||
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
|
||||
|
||||
private class SessionBasedTypeContext(override val session: FirSession) : ConeTypeContext {
|
||||
private class SessionBasedTypeContext(override val session: FirSession) : ConeInferenceContext {
|
||||
override fun newBaseTypeCheckerContext(
|
||||
errorTypesEqualToAnything: Boolean,
|
||||
stubTypesEqualToAnything: Boolean
|
||||
@@ -18,4 +19,4 @@ private class SessionBasedTypeContext(override val session: FirSession) : ConeTy
|
||||
}
|
||||
}
|
||||
|
||||
val FirSession.typeContext: ConeTypeContext get() = SessionBasedTypeContext(this)
|
||||
val FirSession.typeContext: ConeInferenceContext get() = SessionBasedTypeContext(this)
|
||||
+11
-11
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf.Annotation.Argument.Value.Type.*
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||
@@ -111,15 +111,15 @@ abstract class AbstractAnnotationDeserializer(
|
||||
// TODO: val isUnsigned = Flags.IS_UNSIGNED.get(value.flags)
|
||||
|
||||
val result: FirExpression = when (value.type) {
|
||||
BYTE -> const(IrConstKind.Byte, value.intValue.toByte())
|
||||
CHAR -> const(IrConstKind.Char, value.intValue.toChar())
|
||||
SHORT -> const(IrConstKind.Short, value.intValue.toShort())
|
||||
INT -> const(IrConstKind.Int, value.intValue.toInt())
|
||||
LONG -> const(IrConstKind.Long, value.intValue)
|
||||
FLOAT -> const(IrConstKind.Float, value.floatValue)
|
||||
DOUBLE -> const(IrConstKind.Double, value.doubleValue)
|
||||
BOOLEAN -> const(IrConstKind.Boolean, (value.intValue != 0L))
|
||||
STRING -> const(IrConstKind.String, nameResolver.getString(value.stringValue))
|
||||
BYTE -> const(FirConstKind.Byte, value.intValue.toByte())
|
||||
CHAR -> const(FirConstKind.Char, value.intValue.toChar())
|
||||
SHORT -> const(FirConstKind.Short, value.intValue.toShort())
|
||||
INT -> const(FirConstKind.Int, value.intValue.toInt())
|
||||
LONG -> const(FirConstKind.Long, value.intValue)
|
||||
FLOAT -> const(FirConstKind.Float, value.floatValue)
|
||||
DOUBLE -> const(FirConstKind.Double, value.doubleValue)
|
||||
BOOLEAN -> const(FirConstKind.Boolean, (value.intValue != 0L))
|
||||
STRING -> const(FirConstKind.String, nameResolver.getString(value.stringValue))
|
||||
ANNOTATION -> deserializeAnnotation(value.annotation, nameResolver)
|
||||
CLASS -> FirGetClassCallImpl(null).apply {
|
||||
val classId = nameResolver.getClassId(value.classId)
|
||||
@@ -152,5 +152,5 @@ abstract class AbstractAnnotationDeserializer(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <T> const(kind: IrConstKind<T>, value: T) = FirConstExpressionImpl(null, kind, value)
|
||||
private fun <T> const(kind: FirConstKind<T>, value: T) = FirConstExpressionImpl(null, kind, value)
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ fun <T : ConeKotlinType> T.withNullability(nullability: ConeNullability): T {
|
||||
ConeNullability.NULLABLE -> original.withNullability(nullability)
|
||||
ConeNullability.UNKNOWN -> original.withNullability(nullability)
|
||||
} as T
|
||||
is ConeIntegerLiteralType -> this
|
||||
else -> error("sealed: ${this::class}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@ class FirSamResolverImpl(
|
||||
is ConeClassErrorType, is ConeStubType -> null
|
||||
// TODO: support those types as well
|
||||
is ConeTypeParameterType, is ConeTypeVariableType,
|
||||
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType -> null
|
||||
is ConeCapturedType, is ConeDefinitelyNotNullType, is ConeIntersectionType,
|
||||
is ConeIntegerLiteralType -> null
|
||||
// TODO: Thing of getting rid of this branch since ConeLookupTagBasedType should be a sealed class
|
||||
is ConeLookupTagBasedType -> null
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
@@ -45,6 +45,14 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession)
|
||||
}
|
||||
)
|
||||
is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession)
|
||||
is ConeIntegerLiteralType -> {
|
||||
scopeSession.getOrBuild(
|
||||
FirIntegerLiteralTypeScope.ILT_SYMBOL,
|
||||
FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY
|
||||
) {
|
||||
FirIntegerLiteralTypeScope(useSiteSession)
|
||||
}
|
||||
}
|
||||
else -> error("Failed type $this")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.InferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionStageRunner
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.phasedFir
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
|
||||
@@ -39,6 +37,8 @@ interface BodyResolveComponents : SessionHolder {
|
||||
val doubleColonExpressionResolver: FirDoubleColonExpressionResolver
|
||||
val syntheticCallGenerator: FirSyntheticCallGenerator
|
||||
val dataFlowAnalyzer: FirDataFlowAnalyzer
|
||||
val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer
|
||||
val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater
|
||||
|
||||
val <D> AbstractFirBasedSymbol<D>.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner<D>
|
||||
get() = phasedFir(session, FirResolvePhase.DECLARATIONS)
|
||||
|
||||
+33
-6
@@ -6,14 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.arrayElementType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.resolve.OverloadabilitySpecificityCallbacks
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
|
||||
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.calls.results.isSignatureNotLessSpecific
|
||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||
import org.jetbrains.kotlin.types.checker.requireOrDescribe
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
|
||||
abstract class AbstractConeCallConflictResolver(
|
||||
private val specificityComparator: TypeSpecificityComparator,
|
||||
@@ -50,11 +49,39 @@ abstract class AbstractConeCallConflictResolver(
|
||||
return createEmptyConstraintSystem().isSignatureNotLessSpecific(
|
||||
call1,
|
||||
call2,
|
||||
OverloadabilitySpecificityCallbacks,
|
||||
SpecificityComparisonWithNumerics,
|
||||
specificityComparator
|
||||
)
|
||||
}
|
||||
|
||||
private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks {
|
||||
override fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean {
|
||||
requireOrDescribe(specific is ConeKotlinType, specific)
|
||||
requireOrDescribe(general is ConeKotlinType, general)
|
||||
|
||||
// TODO: support unsigned types
|
||||
// see OverloadingConflictResolver.kt:294
|
||||
|
||||
val int = ConeIntegerLiteralTypeImpl.INT_TYPE
|
||||
val long = ConeIntegerLiteralTypeImpl.LONG_TYPE
|
||||
val byte = ConeIntegerLiteralTypeImpl.BYTE_TYPE
|
||||
val short = ConeIntegerLiteralTypeImpl.SHORT_TYPE
|
||||
|
||||
when {
|
||||
//TypeUtils.equalTypes(specific, _double) && TypeUtils.equalTypes(general, _float) -> return true
|
||||
specific == int -> {
|
||||
when {
|
||||
general == long -> return true
|
||||
general == byte -> return true
|
||||
general == short -> return true
|
||||
}
|
||||
}
|
||||
specific == short && general == byte -> return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
protected fun createFlatSignature(call: Candidate): FlatSignature<Candidate> {
|
||||
return when (val declaration = call.symbol.fir) {
|
||||
is FirSimpleFunction -> createFlatSignature(call, declaration)
|
||||
|
||||
@@ -12,8 +12,12 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||
import org.jetbrains.kotlin.fir.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirILTTypeRefPlaceHolder
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||
@@ -165,7 +169,15 @@ fun Candidate.resolveSubCallArgument(
|
||||
isSafeCall,
|
||||
typeProvider
|
||||
)
|
||||
val type = sink.components.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).coneTypeUnsafe<ConeKotlinType>()
|
||||
/*
|
||||
* It's important to extract type from argument neither from symbol, because of symbol contains
|
||||
* placeholder type with value 0, but argument contains type with proper literal value
|
||||
*/
|
||||
val type: ConeKotlinType = if (candidate.symbol.fir is FirIntegerOperator) {
|
||||
(argument as FirFunctionCall).resultType.coneTypeUnsafe()
|
||||
} else {
|
||||
sink.components.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).coneTypeUnsafe()
|
||||
}
|
||||
val argumentType = candidate.substitutor.substituteOrSelf(type)
|
||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, isReceiver, isDispatch, isSafeCall)
|
||||
}
|
||||
@@ -183,6 +195,14 @@ fun Candidate.resolvePlainExpressionArgument(
|
||||
if (expectedType == null) return
|
||||
val argumentType = typeProvider(argument)?.coneTypeSafe<ConeKotlinType>() ?: return
|
||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, isReceiver, isDispatch, isSafeCall)
|
||||
checkApplicabilityForIntegerOperatorCall(sink, argument)
|
||||
}
|
||||
|
||||
private fun Candidate.checkApplicabilityForIntegerOperatorCall(sink: CheckerSink, argument: FirExpression) {
|
||||
if (symbol.fir !is FirIntegerOperator) return
|
||||
if (argument !is FirConstExpression<*> && argument !is FirIntegerOperatorCall) {
|
||||
sink.reportApplicability(CandidateApplicability.INAPPLICABLE)
|
||||
}
|
||||
}
|
||||
|
||||
fun Candidate.resolvePlainArgumentType(
|
||||
@@ -273,6 +293,7 @@ internal fun Candidate.resolveArgument(
|
||||
}
|
||||
|
||||
private fun Candidate.prepareExpectedType(session: FirSession, argument: FirExpression, parameter: FirValueParameter): ConeKotlinType {
|
||||
if (parameter.returnTypeRef is FirILTTypeRefPlaceHolder) return argument.resultType.coneTypeUnsafe()
|
||||
val basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/)
|
||||
val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType) ?: basicExpectedType
|
||||
return this.substitutor.substituteOrSelf(expectedType)
|
||||
|
||||
+7
-7
@@ -260,7 +260,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
val new = map[type.typeConstructor()] ?: return null
|
||||
return makeNullableIfNeed(type.isMarkedNullable, new as ConeKotlinType)
|
||||
return makeNullableIfNeed(type.isMarkedNullable, (new as ConeKotlinType).approximateIntegerLiteralType())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,10 +299,6 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
return this is ConeCapturedTypeConstructor
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker {
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||
// TODO
|
||||
return this
|
||||
@@ -314,7 +310,11 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
}
|
||||
|
||||
override fun findCommonIntegerLiteralTypesSuperType(explicitSupertypes: List<SimpleTypeMarker>): SimpleTypeMarker? {
|
||||
// TODO: implement
|
||||
return null
|
||||
return ConeIntegerLiteralTypeImpl.findCommonSuperType(explicitSupertypes)
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker {
|
||||
require(this is ConeIntegerLiteralType)
|
||||
return this.getApproximatedType()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
||||
import org.jetbrains.kotlin.fir.returnExpressions
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||
@@ -33,7 +34,8 @@ fun Candidate.computeCompletionMode(
|
||||
if (expectedType != null) return KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL
|
||||
|
||||
// This is questionable as null return type can be only for error call
|
||||
if (currentReturnType == null) return KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
||||
if (currentReturnType == null || currentReturnType is ConeIntegerLiteralType)
|
||||
return KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
||||
|
||||
return when {
|
||||
// Consider call foo(bar(x)), if return type of bar is a proper one, then we can complete resolve for bar => full completion mode
|
||||
|
||||
+8
-4
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.fir.symbols.CallableId
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -51,6 +50,8 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
|
||||
private val variablesForWhenConditions = mutableMapOf<WhenBranchConditionExitNode, DataFlowVariable>()
|
||||
|
||||
private var contractDescriptionVisitingMode = false
|
||||
|
||||
/*
|
||||
* If there is no types from smartcasts function returns null
|
||||
*
|
||||
@@ -211,8 +212,8 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
val rightConst = rightOperand as? FirConstExpression<*>
|
||||
|
||||
when {
|
||||
leftConst?.kind == IrConstKind.Null -> processEqNull(node, rightOperand, operation)
|
||||
rightConst?.kind == IrConstKind.Null -> processEqNull(node, leftOperand, operation)
|
||||
leftConst?.kind == FirConstKind.Null -> processEqNull(node, rightOperand, operation)
|
||||
rightConst?.kind == FirConstKind.Null -> processEqNull(node, leftOperand, operation)
|
||||
leftConst != null -> processEqWithConst(node, rightOperand, leftConst, operation)
|
||||
rightConst != null -> processEqWithConst(node, leftOperand, rightConst, operation)
|
||||
operation != FirOperation.EQ && operation != FirOperation.IDENTITY -> return
|
||||
@@ -248,7 +249,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
|
||||
// propagating facts for (... == true) and (... == false)
|
||||
variableStorage[operand]?.let { operandVariable ->
|
||||
if (const.kind != IrConstKind.Boolean) return@let
|
||||
if (const.kind != FirConstKind.Boolean) return@let
|
||||
|
||||
val constValue = (const.value as Boolean)
|
||||
val shouldInvert = isEq xor constValue
|
||||
@@ -556,6 +557,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
val conditionalEffects = contractDescription.effects.filterIsInstance<ConeConditionalEffectDeclaration>()
|
||||
if (conditionalEffects.isEmpty()) return
|
||||
val argumentsMapping = createArgumentsMapping(functionCall) ?: return
|
||||
contractDescriptionVisitingMode = true
|
||||
graphBuilder.enterContract(functionCall).mergeIncomingFlow()
|
||||
val functionCallVariable = getOrCreateVariable(functionCall)
|
||||
for (conditionalEffect in conditionalEffects) {
|
||||
@@ -594,6 +596,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
}
|
||||
}
|
||||
graphBuilder.exitContract(functionCall).mergeIncomingFlow()
|
||||
contractDescriptionVisitingMode = true
|
||||
}
|
||||
|
||||
|
||||
@@ -622,6 +625,7 @@ class FirDataFlowAnalyzer(private val components: FirAbstractBodyResolveTransfor
|
||||
}
|
||||
|
||||
fun exitConstExpresion(constExpression: FirConstExpression<*>) {
|
||||
if (constExpression.resultType is FirResolvedTypeRef && !contractDescriptionVisitingMode) return
|
||||
graphBuilder.exitConstExpresion(constExpression).mergeIncomingFlow()
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
private object ConeConditionalEffectToFirVisitor : ConeContractDescriptionVisitor<FirExpression?, Map<Int, FirExpression>>() {
|
||||
@@ -21,8 +21,8 @@ private object ConeConditionalEffectToFirVisitor : ConeContractDescriptionVisito
|
||||
|
||||
override fun visitConstantDescriptor(constantReference: ConeConstantReference, data: Map<Int, FirExpression>): FirExpression? {
|
||||
return when (constantReference) {
|
||||
ConeBooleanConstantReference.TRUE -> FirConstExpressionImpl(null, IrConstKind.Boolean, true)
|
||||
ConeBooleanConstantReference.FALSE -> FirConstExpressionImpl(null, IrConstKind.Boolean, false)
|
||||
ConeBooleanConstantReference.TRUE -> FirConstExpressionImpl(null, FirConstKind.Boolean, true)
|
||||
ConeBooleanConstantReference.FALSE -> FirConstExpressionImpl(null, FirConstKind.Boolean, false)
|
||||
ConeConstantReference.NULL -> createConstNull()
|
||||
else -> null
|
||||
}
|
||||
@@ -71,7 +71,7 @@ private object ConeConditionalEffectToFirVisitor : ConeContractDescriptionVisito
|
||||
return data[valueParameterReference.parameterIndex]
|
||||
}
|
||||
|
||||
private fun createConstNull(): FirConstExpression<*> = FirConstExpressionImpl(null, IrConstKind.Null, null)
|
||||
private fun createConstNull(): FirConstExpression<*> = FirConstExpressionImpl(null, FirConstKind.Null, null)
|
||||
}
|
||||
|
||||
fun ConeConditionalEffectDeclaration.buildContractFir(argumentMapping: Map<Int, FirExpression>): FirExpression? {
|
||||
|
||||
+6
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.CandidateApplicability
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||
@@ -47,6 +48,11 @@ class FirVariableExpectedError : FirDiagnostic() {
|
||||
override val reason: String get() = "Variable expected"
|
||||
}
|
||||
|
||||
class FirTypeMismatchError(val expectedType: ConeKotlinType, val actualType: ConeKotlinType) : FirDiagnostic() {
|
||||
override val reason: String
|
||||
get() = "Type mismatch. Expected: $expectedType, Actual: $actualType"
|
||||
}
|
||||
|
||||
private fun describeSymbol(symbol: AbstractFirBasedSymbol<*>): String {
|
||||
return when (symbol) {
|
||||
is FirClassLikeSymbol<*> -> symbol.classId.asString()
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.Severity.*
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
@@ -27,6 +28,7 @@ object FirErrors {
|
||||
val RECURSION_IN_IMPLICIT_TYPES = DiagnosticFactory0.create<KtElement>(ERROR)
|
||||
val ERROR_FROM_JAVA_RESOLUTION = DiagnosticFactory0.create<KtElement>(ERROR)
|
||||
val OTHER_ERROR = DiagnosticFactory0.create<KtElement>(ERROR)
|
||||
val TYPE_MISMATCH = DiagnosticFactory2.create<KtElement, ConeKotlinType, ConeKotlinType>(ERROR)
|
||||
|
||||
init {
|
||||
val klass = FirErrors::class
|
||||
|
||||
+1
@@ -57,6 +57,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
||||
is FirAmbiguityError -> FirErrors.AMBIGUITY.onSource(source, diagnostic.candidates)
|
||||
is FirOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.onSource(source, diagnostic.candidates)
|
||||
is FirVariableExpectedError -> Errors.VARIABLE_EXPECTED.onSource(source)
|
||||
is FirTypeMismatchError -> FirErrors.TYPE_MISMATCH.onSource(source, diagnostic.expectedType, diagnostic.actualType)
|
||||
is FirSimpleDiagnostic -> diagnostic.getFactory().onSource(source)
|
||||
is FirStubDiagnostic -> null
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${diagnostic.javaClass}")
|
||||
|
||||
+5
-5
@@ -16,10 +16,8 @@ import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.MapArguments
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreType
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
@@ -98,12 +96,14 @@ class FirCallCompleter(
|
||||
return call.transformSingle(
|
||||
FirCallCompletionResultsWriterTransformer(
|
||||
session, finalSubstitutor, returnTypeCalculator,
|
||||
inferenceComponents.approximator
|
||||
inferenceComponents.approximator,
|
||||
integerOperatorsTypeUpdater,
|
||||
integerLiteralTypeApproximator
|
||||
),
|
||||
null
|
||||
)
|
||||
}
|
||||
return call
|
||||
return call.transformSingle(integerOperatorsTypeUpdater, null)
|
||||
}
|
||||
|
||||
private inner class LambdaAnalyzerImpl(
|
||||
|
||||
+1
@@ -70,6 +70,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||
is ConeDefinitelyNotNullType -> this.substituteOriginal()
|
||||
is ConeIntersectionType -> this.substituteIntersectedTypes()
|
||||
is ConeStubType -> return null
|
||||
is ConeIntegerLiteralType -> return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+106
-34
@@ -16,11 +16,14 @@ import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substituteOrNull
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.withNullability
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
@@ -29,6 +32,7 @@ import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirTypeProjectionWithVarianceImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -37,12 +41,14 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
override val session: FirSession,
|
||||
private val finalSubstitutor: ConeSubstitutor,
|
||||
private val typeCalculator: ReturnTypeCalculator,
|
||||
private val typeApproximator: AbstractTypeApproximator
|
||||
) : FirAbstractTreeTransformer<Nothing?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
||||
private val typeApproximator: AbstractTypeApproximator,
|
||||
private val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater,
|
||||
private val integerApproximator: IntegerLiteralTypeApproximationTransformer
|
||||
) : FirAbstractTreeTransformer<ExpectedArgumentType?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
||||
|
||||
override fun transformQualifiedAccessExpression(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression,
|
||||
data: Nothing?
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference =
|
||||
qualifiedAccessExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return qualifiedAccessExpression.compose()
|
||||
@@ -92,9 +98,8 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
override fun transformCallableReferenceAccess(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
data: Nothing?
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
|
||||
val calleeReference =
|
||||
callableReferenceAccess.calleeReference as? FirNamedReferenceWithCandidate ?: return callableReferenceAccess.compose()
|
||||
|
||||
@@ -120,7 +125,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
override fun transformVariableAssignment(
|
||||
variableAssignment: FirVariableAssignment,
|
||||
data: Nothing?
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference = variableAssignment.calleeReference as? FirNamedReferenceWithCandidate
|
||||
?: return variableAssignment.compose()
|
||||
@@ -134,9 +139,8 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
).compose()
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference = functionCall.calleeReference as? FirNamedReferenceWithCandidate ?: return functionCall.compose()
|
||||
val functionCall = functionCall.transformArguments(this, data) as FirFunctionCall
|
||||
|
||||
val subCandidate = calleeReference.candidate
|
||||
val declaration = subCandidate.symbol.phasedFir as FirCallableMemberDeclaration<*>
|
||||
@@ -170,35 +174,62 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
val resultType = typeRef.substituteTypeRef(subCandidate)
|
||||
var result = functionCall.transformSingle(integerOperatorsTypeUpdater, null)
|
||||
.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
FirResolvedNamedReferenceImpl(
|
||||
calleeReference.source,
|
||||
calleeReference.name,
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
)
|
||||
.transformDispatchReceiver(StoreReceiver, subCandidate.dispatchReceiverExpression())
|
||||
.transformExtensionReceiver(StoreReceiver, subCandidate.extensionReceiverExpression())
|
||||
val resultType: FirTypeRef
|
||||
result = when (result) {
|
||||
is FirIntegerOperatorCall -> {
|
||||
val expectedType = data?.getExpectedType(functionCall)
|
||||
resultType = typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().getApproximatedType(expectedType))
|
||||
result.transformSingle(integerApproximator, expectedType)
|
||||
}
|
||||
else -> {
|
||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||
result.transformArguments(this, subCandidate.createArgumentsMapping()).transformExplicitReceiver(integerApproximator, null)
|
||||
}
|
||||
}
|
||||
|
||||
return functionCall.copy(
|
||||
return result.copy(
|
||||
resultType = resultType,
|
||||
typeArguments = typeArguments,
|
||||
calleeReference = FirResolvedNamedReferenceImpl(
|
||||
calleeReference.source,
|
||||
calleeReference.name,
|
||||
calleeReference.candidateSymbol
|
||||
),
|
||||
dispatchReceiver = subCandidate.dispatchReceiverExpression(),
|
||||
extensionReceiver = subCandidate.extensionReceiverExpression()
|
||||
typeArguments = typeArguments
|
||||
).compose()
|
||||
}
|
||||
|
||||
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType? {
|
||||
return argumentMapping?.map { (argument, valueParameter) ->
|
||||
val expectedType = valueParameter.returnTypeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||
.let { substitutor.substituteOrSelf(it) }
|
||||
.let { finalSubstitutor.substituteOrSelf(it) }
|
||||
|
||||
argument.expandArgument() to expectedType
|
||||
}
|
||||
?.toMap()?.toExpectedType()
|
||||
}
|
||||
|
||||
override fun transformDelegatedConstructorCall(
|
||||
delegatedConstructorCall: FirDelegatedConstructorCall,
|
||||
data: Nothing?
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference = delegatedConstructorCall.calleeReference as? FirNamedReferenceWithCandidate ?: return delegatedConstructorCall.compose()
|
||||
|
||||
val subCandidate = calleeReference.candidate
|
||||
val result = delegatedConstructorCall.transformArguments(this, data)
|
||||
return result.transformCalleeReference(StoreCalleeReference, FirResolvedNamedReferenceImpl(
|
||||
calleeReference.source,
|
||||
calleeReference.name,
|
||||
calleeReference.candidateSymbol
|
||||
)).compose()
|
||||
val result = delegatedConstructorCall.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
||||
return result.transformCalleeReference(
|
||||
StoreCalleeReference,
|
||||
FirResolvedNamedReferenceImpl(
|
||||
calleeReference.source,
|
||||
calleeReference.name,
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
).compose()
|
||||
}
|
||||
|
||||
private fun computeTypeArguments(
|
||||
@@ -213,11 +244,15 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
override fun transformAnonymousFunction(
|
||||
anonymousFunction: FirAnonymousFunction,
|
||||
data: Nothing?
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val expectedReturnType = data?.getExpectedType(anonymousFunction)
|
||||
?.takeIf { it.isBuiltinFunctionalType }
|
||||
?.let { it.typeArguments.last() as? ConeClassLikeType }
|
||||
|
||||
val initialType = anonymousFunction.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
if (initialType != null) {
|
||||
val finalType = finalSubstitutor.substituteOrNull(initialType)
|
||||
val finalType = expectedReturnType ?: finalSubstitutor.substituteOrNull(initialType)
|
||||
|
||||
val resultType = anonymousFunction.returnTypeRef.withReplacedConeType(finalType)
|
||||
|
||||
@@ -225,23 +260,26 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
anonymousFunction.replaceTypeRef(anonymousFunction.constructFunctionalTypeRef(session))
|
||||
}
|
||||
return transformElement(anonymousFunction, data)
|
||||
return transformElement(anonymousFunction, null)
|
||||
}
|
||||
|
||||
override fun transformBlock(block: FirBlock, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
override fun transformBlock(block: FirBlock, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||
val initialType = block.resultType.coneTypeSafe<ConeKotlinType>()
|
||||
if (initialType != null) {
|
||||
val finalType = finalSubstitutor.substituteOrNull(initialType)
|
||||
val resultType = block.resultType.withReplacedConeType(finalType)
|
||||
var resultType = block.resultType.withReplacedConeType(finalType)
|
||||
resultType.coneTypeSafe<ConeIntegerLiteralType>()?.let {
|
||||
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)))
|
||||
}
|
||||
block.replaceTypeRef(resultType)
|
||||
}
|
||||
return transformElement(block, data)
|
||||
}
|
||||
|
||||
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference = whenExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return whenExpression.compose()
|
||||
|
||||
val whenExpression = whenExpression.transformChildren(this, data) as FirWhenExpression
|
||||
val whenExpression = whenExpression.transformChildren(this, data?.getExpectedType(whenExpression)?.toExpectedType()) as FirWhenExpression
|
||||
|
||||
val declaration = whenExpression.candidate()?.symbol?.fir as? FirMemberFunction<*> ?: return whenExpression.compose()
|
||||
|
||||
@@ -261,7 +299,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
).compose()
|
||||
}
|
||||
|
||||
override fun transformTryExpression(tryExpression: FirTryExpression, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
override fun transformTryExpression(tryExpression: FirTryExpression, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||
val calleeReference = tryExpression.calleeReference as? FirNamedReferenceWithCandidate ?: return tryExpression.compose()
|
||||
|
||||
val tryExpression = tryExpression.transformChildren(this, data) as FirTryExpression
|
||||
@@ -281,6 +319,40 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
calleeReference.candidateSymbol
|
||||
)
|
||||
).compose()
|
||||
}
|
||||
|
||||
override fun <T> transformConstExpression(
|
||||
constExpression: FirConstExpression<T>,
|
||||
data: ExpectedArgumentType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
if (data == ExpectedArgumentType.NoApproximation) return constExpression.compose()
|
||||
val expectedType = data?.getExpectedType(constExpression)
|
||||
return constExpression.transform(integerApproximator, expectedType)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ExpectedArgumentType {
|
||||
class ArgumentsMap(val map: Map<FirExpression, ConeKotlinType>) : ExpectedArgumentType()
|
||||
class ExpectedType(val type: ConeKotlinType) : ExpectedArgumentType()
|
||||
object NoApproximation : ExpectedArgumentType()
|
||||
}
|
||||
|
||||
private fun ExpectedArgumentType.getExpectedType(argument: FirExpression): ConeKotlinType? = when (this) {
|
||||
is ExpectedArgumentType.ArgumentsMap -> map[argument]
|
||||
is ExpectedArgumentType.ExpectedType -> type
|
||||
ExpectedArgumentType.NoApproximation -> null
|
||||
}
|
||||
|
||||
private fun Map<FirExpression, ConeKotlinType>.toExpectedType(): ExpectedArgumentType = ExpectedArgumentType.ArgumentsMap(this)
|
||||
fun ConeKotlinType.toExpectedType(): ExpectedArgumentType = ExpectedArgumentType.ExpectedType(this)
|
||||
|
||||
private fun FirExpression.expandArgument(): FirExpression = when (this) {
|
||||
is FirWrappedArgumentExpression -> expression
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.approximateIfPossible(expectedType: ConeKotlinType?) = if (this is ConeIntegerLiteralType) {
|
||||
getApproximatedType(expectedType)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirResolvedNamedReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
|
||||
class IntegerLiteralTypeApproximationTransformer(
|
||||
private val symbolProvider: FirSymbolProvider,
|
||||
private val inferenceContext: ConeInferenceContext
|
||||
) : FirTransformer<ConeKotlinType?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun <T> transformConstExpression(
|
||||
constExpression: FirConstExpression<T>,
|
||||
data: ConeKotlinType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val type = constExpression.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression.compose()
|
||||
val approximatedType = type.getApproximatedType(data)
|
||||
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(approximatedType)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val kind = approximatedType.toConstKind() as FirConstKind<T>
|
||||
constExpression.replaceKind(kind)
|
||||
return constExpression.compose()
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ConeKotlinType?): CompositeTransformResult<FirStatement> {
|
||||
val operator = functionCall.toResolvedCallableSymbol()?.fir as? FirIntegerOperator ?: return functionCall.compose()
|
||||
functionCall.transformChildren(this, data)
|
||||
val argumentType = functionCall.arguments.firstOrNull()?.resultType?.coneTypeUnsafe<ConeClassLikeType>()
|
||||
val receiverClassId = functionCall.dispatchReceiver.typeRef.coneTypeUnsafe<ConeClassLikeType>().lookupTag.classId
|
||||
val scope = symbolProvider.getClassDeclaredMemberScope(receiverClassId)!!
|
||||
var resultSymbol: FirFunctionSymbol<*>? = null
|
||||
scope.processFunctionsByName(operator.name) { symbol ->
|
||||
if (operator.kind.unary) {
|
||||
resultSymbol = symbol
|
||||
return@processFunctionsByName ProcessorAction.STOP
|
||||
}
|
||||
val function = symbol.fir
|
||||
val valueParameterType = function.valueParameters.first().returnTypeRef.coneTypeUnsafe<ConeClassLikeType>()
|
||||
if (AbstractTypeChecker.isSubtypeOf(inferenceContext, argumentType!!, valueParameterType)) {
|
||||
resultSymbol = symbol
|
||||
return@processFunctionsByName ProcessorAction.STOP
|
||||
}
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
// TODO: Maybe resultType = data?
|
||||
// check black box tests
|
||||
// e.g. Byte doesn't have `and` in member scope. It's an extension
|
||||
if (resultSymbol == null) return functionCall.compose()
|
||||
functionCall.resultType = data?.let { functionCall.resultType.resolvedTypeFromPrototype(it) } ?: resultSymbol.fir.returnTypeRef
|
||||
return functionCall.transformCalleeReference(StoreCalleeReference, FirResolvedNamedReferenceImpl(null, operator.name, resultSymbol!!)).compose()
|
||||
}
|
||||
|
||||
override fun transformOperatorCall(operatorCall: FirOperatorCall, data: ConeKotlinType?): CompositeTransformResult<FirStatement> {
|
||||
if (operatorCall.operation !in FirOperation.BOOLEANS) return operatorCall.compose()
|
||||
val leftArgument = operatorCall.arguments[0]
|
||||
val rightArgument = operatorCall.arguments[1]
|
||||
|
||||
val leftIsIlt = leftArgument.typeRef.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
val rightIsIlt = rightArgument.typeRef.coneTypeSafe<ConeIntegerLiteralType>() != null
|
||||
|
||||
val expectedType: ConeKotlinType? = when {
|
||||
!leftIsIlt && !rightIsIlt -> return operatorCall.compose()
|
||||
leftIsIlt && rightIsIlt -> null
|
||||
leftIsIlt -> rightArgument.typeRef.coneTypeUnsafe()
|
||||
rightIsIlt -> leftArgument.typeRef.coneTypeUnsafe()
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
|
||||
return operatorCall.transformArguments(this, expectedType).compose()
|
||||
}
|
||||
|
||||
// TODO: call outside
|
||||
override fun transformTypeOperatorCall(
|
||||
typeOperatorCall: FirTypeOperatorCall,
|
||||
data: ConeKotlinType?
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
return typeOperatorCall.transformArguments(this, null).compose()
|
||||
}
|
||||
}
|
||||
|
||||
fun ConeClassLikeType.toConstKind(): FirConstKind<*> {
|
||||
return when (this) {
|
||||
ConeIntegerLiteralTypeImpl.INT_TYPE -> FirConstKind.Int
|
||||
ConeIntegerLiteralTypeImpl.LONG_TYPE -> FirConstKind.Long
|
||||
ConeIntegerLiteralTypeImpl.SHORT_TYPE -> FirConstKind.Short
|
||||
ConeIntegerLiteralTypeImpl.BYTE_TYPE -> FirConstKind.Byte
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
fun FirFunctionCall.getOriginalFunction(): FirCallableDeclaration<*>? {
|
||||
val symbol: AbstractFirBasedSymbol<*>? = when (val reference = calleeReference) {
|
||||
is FirResolvedNamedReference -> reference.resolvedSymbol
|
||||
is FirNamedReferenceWithCandidate -> reference.candidateSymbol
|
||||
else -> null
|
||||
}
|
||||
return symbol?.fir as? FirCallableDeclaration<*>
|
||||
}
|
||||
|
||||
class IntegerOperatorsTypeUpdater(val approximator: IntegerLiteralTypeApproximationTransformer) : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
return element.compose()
|
||||
}
|
||||
|
||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
|
||||
val function: FirCallableDeclaration<*> = functionCall.getOriginalFunction() ?: return functionCall.compose()
|
||||
|
||||
if (function !is FirIntegerOperator) {
|
||||
val expectedType = function.receiverTypeRef?.coneTypeSafe<ConeKotlinType>()
|
||||
return functionCall.transformExplicitReceiver(approximator, expectedType).compose()
|
||||
}
|
||||
// TODO: maybe unsafe?
|
||||
val receiverValue = functionCall.explicitReceiver!!.typeRef.coneTypeSafe<ConeIntegerLiteralType>()?.value ?: return functionCall.compose()
|
||||
val kind = function.kind
|
||||
val resultValue = when {
|
||||
kind.unary -> when (kind) {
|
||||
FirIntegerOperator.Kind.UNARY_PLUS -> receiverValue
|
||||
FirIntegerOperator.Kind.UNARY_MINUS -> -receiverValue
|
||||
FirIntegerOperator.Kind.INV -> receiverValue.inv()
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
else -> {
|
||||
val argumentType = functionCall.arguments.first().typeRef.coneTypeUnsafe<ConeKotlinType>()
|
||||
// TODO: handle overflow
|
||||
when (argumentType) {
|
||||
is ConeIntegerLiteralType -> {
|
||||
val argumentValue = argumentType.value
|
||||
val divisionByZero = argumentValue == 0L
|
||||
when (kind) {
|
||||
FirIntegerOperator.Kind.PLUS -> receiverValue + argumentValue
|
||||
FirIntegerOperator.Kind.MINUS -> receiverValue - argumentValue
|
||||
FirIntegerOperator.Kind.TIMES -> receiverValue * argumentValue
|
||||
// TODO: maybe add some error reporting (e.g. in userdata)
|
||||
FirIntegerOperator.Kind.DIV -> if (divisionByZero) receiverValue else receiverValue / argumentValue
|
||||
FirIntegerOperator.Kind.REM -> if (divisionByZero) receiverValue else receiverValue % argumentValue
|
||||
// TODO: check that argument can be int
|
||||
FirIntegerOperator.Kind.SHL -> receiverValue shl argumentValue.toInt()
|
||||
FirIntegerOperator.Kind.SHR -> receiverValue shr argumentValue.toInt()
|
||||
FirIntegerOperator.Kind.USHR -> receiverValue ushr argumentValue.toInt()
|
||||
FirIntegerOperator.Kind.XOR -> receiverValue xor argumentValue
|
||||
FirIntegerOperator.Kind.AND -> receiverValue and argumentValue
|
||||
FirIntegerOperator.Kind.OR -> receiverValue or argumentValue
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val expectedType = when (argumentType) {
|
||||
ConeIntegerLiteralTypeImpl.LONG_TYPE -> argumentType
|
||||
else -> ConeIntegerLiteralTypeImpl.INT_TYPE
|
||||
}
|
||||
functionCall.transformSingle(approximator, expectedType)
|
||||
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(expectedType))
|
||||
return functionCall.compose()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(ConeIntegerLiteralTypeImpl(resultValue)))
|
||||
return functionCall.toOperatorCall().compose()
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirFunctionCall.toOperatorCall(): FirIntegerOperatorCall {
|
||||
if (this is FirIntegerOperatorCall) return this
|
||||
return FirIntegerOperatorCall(source).also {
|
||||
it.typeRef = typeRef
|
||||
it.annotations += annotations
|
||||
it.safe = safe
|
||||
it.typeArguments += typeArguments
|
||||
it.explicitReceiver = explicitReceiver
|
||||
it.dispatchReceiver = dispatchReceiver
|
||||
it.extensionReceiver = extensionReceiver
|
||||
it.arguments += arguments
|
||||
it.calleeReference = calleeReference
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -79,6 +79,9 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
||||
protected inline val dataFlowAnalyzer: FirDataFlowAnalyzer get() = components.dataFlowAnalyzer
|
||||
protected inline val scopeSession: ScopeSession get() = components.scopeSession
|
||||
protected inline val file: FirFile get() = components.file
|
||||
protected inline val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer get() = components.integerLiteralTypeApproximator
|
||||
protected inline val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater get() = components.integerOperatorsTypeUpdater
|
||||
|
||||
|
||||
val ResolutionMode.expectedType: FirTypeRef?
|
||||
get() = when (this) {
|
||||
@@ -122,7 +125,9 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
||||
val callCompleter: FirCallCompleter = FirCallCompleter(transformer, this)
|
||||
override val dataFlowAnalyzer: FirDataFlowAnalyzer = FirDataFlowAnalyzer(this)
|
||||
override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this, callCompleter)
|
||||
|
||||
override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer =
|
||||
IntegerLiteralTypeApproximationTransformer(symbolProvider, inferenceComponents.ctx)
|
||||
override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator)
|
||||
internal var containerIfAny: FirDeclaration? = null
|
||||
private set
|
||||
|
||||
|
||||
+9
-2
@@ -15,9 +15,12 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirErrorTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
@@ -168,9 +171,13 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
||||
// ------------------------------- Jumps -------------------------------
|
||||
|
||||
override fun <E : FirTargetElement> transformJump(jump: FirJump<E>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
val result = transformer.transformExpression(jump, data)
|
||||
var result = transformer.transformExpression(jump, data).single
|
||||
if (result is FirReturnExpression) {
|
||||
val expectedType = result.target.labeledElement.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||
result = result.transformResult(integerLiteralTypeApproximator, expectedType)
|
||||
}
|
||||
dataFlowAnalyzer.exitJump(jump)
|
||||
return result
|
||||
return result.compose()
|
||||
}
|
||||
|
||||
override fun transformThrowExpression(throwExpression: FirThrowExpression, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
|
||||
+12
-6
@@ -19,8 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.ImplicitExtensionReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.extractLambdaInfoFromFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ControlFlowGraphReferenceTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolveTransformer.Companion.resolveStatus
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreType
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayType
|
||||
@@ -104,6 +103,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
localScopes.addIfNotNull(primaryConstructorParametersScope)
|
||||
components.withContainer(property) {
|
||||
property.transformChildrenWithoutAccessors(returnTypeRef)
|
||||
property.transformInitializer(integerLiteralTypeApproximator, null)
|
||||
if (property.initializer != null) {
|
||||
storeVariableReturnType(property)
|
||||
}
|
||||
@@ -125,7 +125,10 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
|
||||
private fun transformLocalVariable(variable: FirProperty): CompositeTransformResult<FirDeclaration> {
|
||||
assert(variable.isLocal)
|
||||
variable.transformOtherChildren(transformer, withExpectedType(variable.returnTypeRef))
|
||||
val resolutionMode = withExpectedType(variable.returnTypeRef)
|
||||
variable.transformOtherChildren(transformer, resolutionMode)
|
||||
.transformInitializer(transformer, resolutionMode)
|
||||
.transformInitializer(integerLiteralTypeApproximator, null)
|
||||
if (variable.initializer != null) {
|
||||
storeVariableReturnType(variable)
|
||||
}
|
||||
@@ -138,7 +141,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
|
||||
private fun FirProperty.transformChildrenWithoutAccessors(returnTypeRef: FirTypeRef): FirProperty {
|
||||
val data = withExpectedType(returnTypeRef)
|
||||
return transformReturnTypeRef(transformer, data).transformOtherChildren(transformer, data)
|
||||
return transformInitializer(transformer, data).transformOtherChildren(transformer, data)
|
||||
}
|
||||
|
||||
private fun <F : FirVariable<F>> FirVariable<F>.transformAccessors() {
|
||||
@@ -380,6 +383,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
valueParameter.replaceResolvePhase(transformerPhase)
|
||||
return valueParameter.compose() // TODO
|
||||
}
|
||||
val valueParameter = valueParameter.transformInitializer(integerLiteralTypeApproximator, valueParameter.returnTypeRef.coneTypeSafe())
|
||||
return (transformDeclaration(valueParameter, withExpectedType(valueParameter.returnTypeRef)).single as FirStatement).compose()
|
||||
}
|
||||
|
||||
@@ -464,9 +468,11 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
|
||||
session,
|
||||
ConeSubstitutor.Empty,
|
||||
returnTypeCalculator,
|
||||
inferenceComponents.approximator
|
||||
inferenceComponents.approximator,
|
||||
integerOperatorsTypeUpdater,
|
||||
integerLiteralTypeApproximator
|
||||
)
|
||||
af.transformSingle(writer, null)
|
||||
af.transformSingle(writer, data.expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.toExpectedType())
|
||||
val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(af).mapNotNull { (it as? FirExpression)?.resultType?.coneTypeUnsafe() }
|
||||
af.replaceReturnTypeRef(af.returnTypeRef.resolvedTypeFromPrototype(inferenceComponents.ctx.commonSuperTypeOrNull(returnTypes) ?: session.builtinTypes.unitType.coneTypeUnsafe()))
|
||||
af.replaceTypeRef(af.constructFunctionalTypeRef(session))
|
||||
|
||||
+52
-28
@@ -5,10 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||
|
||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||
import org.jetbrains.kotlin.fir.FirCallResolver
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParametersOwner
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.FirSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl
|
||||
@@ -21,14 +22,14 @@ import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirExplicitThisReference
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirOperatorAmbiguityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirTypeMismatchError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.FirVariableExpectedError
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
@@ -40,7 +41,6 @@ import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -192,9 +192,10 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||
|
||||
override fun transformOperatorCall(operatorCall: FirOperatorCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
if (operatorCall.operation in FirOperation.BOOLEANS) {
|
||||
// TODO: add approximation of integer literals
|
||||
val result = (operatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirOperatorCall).also {
|
||||
it.resultType = operatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
|
||||
}
|
||||
}.transformSingle(integerLiteralTypeApproximator, null)
|
||||
dataFlowAnalyzer.exitOperatorCall(result)
|
||||
return result.compose()
|
||||
}
|
||||
@@ -259,8 +260,9 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||
data: ResolutionMode
|
||||
): CompositeTransformResult<FirStatement> {
|
||||
val symbolProvider = session.firSymbolProvider
|
||||
val resolved = transformExpression(typeOperatorCall, data).single
|
||||
when ((resolved as FirTypeOperatorCall).operation) {
|
||||
val resolved = (transformExpression(typeOperatorCall, data).single as FirTypeOperatorCall)
|
||||
.transformArguments(integerLiteralTypeApproximator, null)
|
||||
when (resolved.operation) {
|
||||
FirOperation.IS, FirOperation.NOT_IS -> {
|
||||
resolved.resultType = FirResolvedTypeRefImpl(
|
||||
null,
|
||||
@@ -279,7 +281,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||
else -> error("Unknown type operator")
|
||||
}
|
||||
dataFlowAnalyzer.exitTypeOperatorCall(typeOperatorCall)
|
||||
return resolved.compose()
|
||||
return resolved.transform(integerLiteralTypeApproximator, null)
|
||||
}
|
||||
|
||||
override fun transformBinaryLogicExpression(
|
||||
@@ -313,6 +315,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||
val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType) // TODO: check
|
||||
val expectedType = components.typeFromCallee(completeAssignment)
|
||||
completeAssignment.transformRValue(transformer, withExpectedType(expectedType))
|
||||
.transformRValue(integerLiteralTypeApproximator, expectedType.coneTypeSafe())
|
||||
} else {
|
||||
// This can happen in erroneous code only
|
||||
resolvedAssignment
|
||||
@@ -396,36 +399,57 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
||||
}
|
||||
|
||||
override fun <T> transformConstExpression(constExpression: FirConstExpression<T>, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
// TODO: add support of IntegerLiteralType
|
||||
|
||||
constExpression.annotations.forEach { it.accept(this, data) }
|
||||
val kind = constExpression.kind
|
||||
val symbol = when (kind) {
|
||||
IrConstKind.Null -> StandardClassIds.Nothing(symbolProvider)
|
||||
IrConstKind.Boolean -> StandardClassIds.Boolean(symbolProvider)
|
||||
IrConstKind.Char -> StandardClassIds.Char(symbolProvider)
|
||||
IrConstKind.Byte -> StandardClassIds.Byte(symbolProvider)
|
||||
IrConstKind.Short -> StandardClassIds.Short(symbolProvider)
|
||||
IrConstKind.Int -> StandardClassIds.Int(symbolProvider)
|
||||
IrConstKind.Long -> StandardClassIds.Long(symbolProvider)
|
||||
IrConstKind.String -> StandardClassIds.String(symbolProvider)
|
||||
IrConstKind.Float -> StandardClassIds.Float(symbolProvider)
|
||||
IrConstKind.Double -> StandardClassIds.Double(symbolProvider)
|
||||
FirConstKind.Null -> StandardClassIds.Nothing(symbolProvider)
|
||||
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 = ConeClassLikeTypeImpl(symbol.toLookupTag(), emptyArray(), isNullable = kind == IrConstKind.Null)
|
||||
|
||||
constExpression.resultType = FirResolvedTypeRefImpl(null, type)
|
||||
val type = if (symbol != null) {
|
||||
ConeClassLikeTypeImpl(symbol.toLookupTag(), emptyArray(), isNullable = kind == FirConstKind.Null)
|
||||
} else {
|
||||
val integerLiteralType = ConeIntegerLiteralTypeImpl(constExpression.value as Long)
|
||||
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 = FirErrorTypeRefImpl(
|
||||
constExpression.source,
|
||||
FirTypeMismatchError(expectedType, integerLiteralType.getApproximatedType())
|
||||
)
|
||||
return constExpression.compose()
|
||||
}
|
||||
constExpression.replaceKind(newConstKind as FirConstKind<T>)
|
||||
approximatedType
|
||||
} else {
|
||||
integerLiteralType
|
||||
}
|
||||
}
|
||||
dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>)
|
||||
|
||||
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(type)
|
||||
return constExpression.compose()
|
||||
}
|
||||
|
||||
override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): CompositeTransformResult<FirStatement> {
|
||||
dataFlowAnalyzer.enterAnnotationCall(annotationCall)
|
||||
return (annotationCall.transformChildren(transformer, data) as FirAnnotationCall).also {
|
||||
dataFlowAnalyzer.exitAnnotationCall(it)
|
||||
}.compose()
|
||||
return (annotationCall.transformChildren(transformer, data) as FirAnnotationCall)
|
||||
// TODO: it's temporary incorrect solution until we design resolve and completion for annotation calls
|
||||
.transformArguments(integerLiteralTypeApproximator, null).also {
|
||||
dataFlowAnalyzer.exitAnnotationCall(it)
|
||||
}.compose()
|
||||
}
|
||||
|
||||
private fun ConeKotlinTypeProjection.toFirTypeProjection(): FirTypeProjection = when (this) {
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.scopes.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirValueParameterImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirFunctionCallImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.resolve.scopeSessionKey
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
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.types.ConeIntegerLiteralType
|
||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
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> {
|
||||
override val symbol: AbstractFirBasedSymbol<FirIntegerLiteralTypeClassifier>
|
||||
get() = FirIntegerLiteralTypeClassifierSymbol
|
||||
|
||||
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 {
|
||||
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 }
|
||||
private val ALL_OPERATORS = FirIntegerOperator.Kind.values().map { it.operatorName to it }.toMap()
|
||||
|
||||
val ILT_SYMBOL: FirClassifierSymbol<*> = FirIntegerLiteralTypeClassifierSymbol
|
||||
val SCOPE_SESSION_KEY = scopeSessionKey<FirIntegerLiteralTypeScope>()
|
||||
}
|
||||
|
||||
private val BINARY_OPERATOR_SYMBOLS = BINARY_OPERATOR_NAMES.map { name ->
|
||||
name to FirNamedFunctionSymbol(CallableId(name)).apply {
|
||||
createFirFunction(name, this).apply {
|
||||
val valueParameterName = Name.identifier("arg")
|
||||
valueParameters += FirValueParameterImpl(
|
||||
source = null,
|
||||
session,
|
||||
FirILTTypeRefPlaceHolder(),
|
||||
valueParameterName,
|
||||
FirVariableSymbol(name),
|
||||
defaultValue = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
isVararg = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
private val UNARY_OPERATOR_SYMBOLS = UNARY_OPERATOR_NAMES.map { name ->
|
||||
name to FirNamedFunctionSymbol(CallableId(name)).apply { createFirFunction(name, this) }
|
||||
}.toMap()
|
||||
|
||||
private fun createFirFunction(name: Name, symbol: FirNamedFunctionSymbol): FirSimpleFunctionImpl = FirIntegerOperator(
|
||||
source = null,
|
||||
session,
|
||||
FirILTTypeRefPlaceHolder(),
|
||||
receiverTypeRef = null,
|
||||
ALL_OPERATORS.getValue(name),
|
||||
FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, Modality.FINAL),
|
||||
symbol
|
||||
).apply {
|
||||
resolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||
}
|
||||
|
||||
override fun processClassifiersByName(name: Name, processor: (FirClassifierSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
return ProcessorAction.NONE
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
val symbol = BINARY_OPERATOR_SYMBOLS[name]
|
||||
?: UNARY_OPERATOR_SYMBOLS[name]
|
||||
?: return ProcessorAction.NONE
|
||||
return processor(symbol)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirCallableSymbol<*>) -> ProcessorAction): ProcessorAction {
|
||||
return ProcessorAction.NONE
|
||||
}
|
||||
}
|
||||
|
||||
class FirIntegerOperator(
|
||||
source: FirSourceElement?,
|
||||
session: FirSession,
|
||||
returnTypeRef: FirTypeRef,
|
||||
receiverTypeRef: FirTypeRef?,
|
||||
val kind: Kind,
|
||||
status: FirDeclarationStatus,
|
||||
symbol: FirFunctionSymbol<FirSimpleFunction>
|
||||
) : FirSimpleFunctionImpl(source, session, returnTypeRef, receiverTypeRef, kind.operatorName, status, symbol) {
|
||||
enum class Kind(val unary: Boolean, val operatorName: Name) {
|
||||
PLUS(false, OperatorNameConventions.PLUS),
|
||||
MINUS(false, OperatorNameConventions.MINUS),
|
||||
TIMES(false, OperatorNameConventions.TIMES),
|
||||
DIV(false, OperatorNameConventions.DIV),
|
||||
REM(false, OperatorNameConventions.REM),
|
||||
SHL(false, Name.identifier("shl")),
|
||||
SHR(false, Name.identifier("shr")),
|
||||
USHR(false, Name.identifier("ushr")),
|
||||
XOR(false, Name.identifier("xor")),
|
||||
AND(false, Name.identifier("and")),
|
||||
OR(false, Name.identifier("or")),
|
||||
UNARY_PLUS(true, OperatorNameConventions.UNARY_PLUS),
|
||||
UNARY_MINUS(true, OperatorNameConventions.UNARY_MINUS),
|
||||
INV(true, Name.identifier("inv"))
|
||||
}
|
||||
}
|
||||
|
||||
class FirILTTypeRefPlaceHolder : FirResolvedTypeRef() {
|
||||
override val source: FirSourceElement? get() = null
|
||||
override val annotations: List<FirAnnotationCall> get() = emptyList()
|
||||
override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0)
|
||||
override val delegatedTypeRef: FirTypeRef? get() = null
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
class FirIntegerOperatorCall(source: FirSourceElement?) : FirFunctionCallImpl(source)
|
||||
@@ -38,21 +38,24 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
val session: FirSession
|
||||
|
||||
override fun TypeConstructorMarker.isIntegerLiteralTypeConstructor(): Boolean {
|
||||
// TODO()
|
||||
return false
|
||||
return this is ConeIntegerLiteralType
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.possibleIntegerTypes(): Collection<KotlinTypeMarker> {
|
||||
TODO("not implemented")
|
||||
return (this as? ConeIntegerLiteralType)?.possibleTypes ?: emptyList()
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List<SimpleTypeMarker>? {
|
||||
require(this is ConeKotlinType)
|
||||
return session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor)
|
||||
return if (this is ConeIntegerLiteralType) {
|
||||
supertypes
|
||||
} else {
|
||||
session.correspondingSupertypesCache.getCorrespondingSupertypes(this, constructor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isIntegerLiteralType(): Boolean {
|
||||
return false
|
||||
return this is ConeIntegerLiteralType
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.asSimpleType(): SimpleTypeMarker? {
|
||||
@@ -65,6 +68,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeIntersectionType -> this
|
||||
is ConeFlexibleType -> null
|
||||
is ConeStubType -> this
|
||||
is ConeIntegerLiteralType -> this
|
||||
else -> error("Unknown simpleType: $this")
|
||||
}
|
||||
}
|
||||
@@ -134,6 +138,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeIntersectionType -> this
|
||||
is ConeStubType -> variable.typeConstructor
|
||||
is ConeDefinitelyNotNullType -> original.typeConstructor()
|
||||
is ConeIntegerLiteralType -> this
|
||||
else -> error("?: $this")
|
||||
}
|
||||
}
|
||||
@@ -210,6 +215,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is ConeIntersectionType -> 0
|
||||
is FirRegularClassSymbol -> fir.typeParameters.size
|
||||
is FirTypeAliasSymbol -> fir.typeParameters.size
|
||||
is ConeIntegerLiteralType -> 0
|
||||
else -> error("?!:10")
|
||||
}
|
||||
}
|
||||
@@ -234,6 +240,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
is FirTypeAliasSymbol -> listOfNotNull(fir.expandedConeType)
|
||||
is ConeCapturedTypeConstructor -> supertypes!!
|
||||
is ConeIntersectionType -> intersectedTypes
|
||||
is ConeIntegerLiteralType -> supertypes
|
||||
else -> error("?!:13")
|
||||
}
|
||||
}
|
||||
@@ -280,7 +287,8 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
return when (this) {
|
||||
is ConeCapturedTypeConstructor,
|
||||
is ConeTypeVariableTypeConstructor,
|
||||
is ConeIntersectionType -> false
|
||||
is ConeIntersectionType,
|
||||
is ConeIntegerLiteralType -> false
|
||||
is AbstractFirBasedSymbol<*> -> true
|
||||
else -> true
|
||||
}
|
||||
@@ -363,6 +371,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
if (this is ConeCapturedType) return true
|
||||
if (this is ConeTypeVariableType) return false
|
||||
if (this is ConeIntersectionType) return false
|
||||
if (this is ConeIntegerLiteralType) return true
|
||||
if (this is ConeStubType) return true
|
||||
if (this is ConeDefinitelyNotNullType) return true
|
||||
require(this is ConeLookupTagBasedType)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
fun takeInt(x: Int) {}
|
||||
fun takeLong(x: Long) {}
|
||||
fun takeByte(x: Byte) {}
|
||||
fun takeAny(x: Any) {}
|
||||
fun takeString(x: String) {}
|
||||
|
||||
fun test_0() {
|
||||
1l
|
||||
1
|
||||
10000000000
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
takeInt(1)
|
||||
takeByte(1)
|
||||
takeLong(1)
|
||||
}
|
||||
|
||||
fun test_2() {
|
||||
<!INAPPLICABLE_CANDIDATE!>takeInt<!>(10000000000)
|
||||
takeLong(10000000000)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(1000)
|
||||
}
|
||||
|
||||
fun test_3() {
|
||||
takeInt(run { 1 })
|
||||
takeByte(run { 1 })
|
||||
takeLong(run { 1 })
|
||||
}
|
||||
|
||||
|
||||
fun test_4() {
|
||||
takeAny(1)
|
||||
takeAny(run { 1 })
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
<!INAPPLICABLE_CANDIDATE!>takeString<!>(1)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeString<!>(run { 1 })
|
||||
}
|
||||
|
||||
annotation class Ann(val x: Byte)
|
||||
|
||||
@Ann(10)
|
||||
fun test_6() {
|
||||
@Ann(300)
|
||||
val x = ""
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
FILE: integerLiteralTypes.kt
|
||||
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeLong(x: R|kotlin/Long|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeByte(x: R|kotlin/Byte|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeAny(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun takeString(x: R|kotlin/String|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_0(): R|kotlin/Unit| {
|
||||
Long(1)
|
||||
Int(1)
|
||||
Long(10000000000)
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
R|/takeInt|(Int(1))
|
||||
R|/takeByte|(Byte(1))
|
||||
R|/takeLong|(Long(1))
|
||||
}
|
||||
public final fun test_2(): R|kotlin/Unit| {
|
||||
<Inapplicable(INAPPLICABLE): [/takeInt]>#(Long(10000000000))
|
||||
R|/takeLong|(Long(10000000000))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(1000))
|
||||
}
|
||||
public final fun test_3(): R|kotlin/Unit| {
|
||||
R|/takeInt|(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
R|/takeByte|(R|kotlin/run|<R|kotlin/Byte|>(<L> = run@fun <anonymous>(): R|kotlin/Byte| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
R|/takeLong|(R|kotlin/run|<R|kotlin/Long|>(<L> = run@fun <anonymous>(): R|kotlin/Long| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
}
|
||||
public final fun test_4(): R|kotlin/Unit| {
|
||||
R|/takeAny|(Int(1))
|
||||
R|/takeAny|(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
}
|
||||
public final fun test_5(): R|kotlin/Unit| {
|
||||
<Inapplicable(INAPPLICABLE): [/takeString]>#(Int(1))
|
||||
<Inapplicable(INAPPLICABLE): [/takeString]>#(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
}
|
||||
public final annotation class Ann : R|kotlin/Annotation| {
|
||||
public constructor(x: R|kotlin/Byte|): R|Ann| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val x: R|kotlin/Byte| = R|<local>/x|
|
||||
public get(): R|kotlin/Byte|
|
||||
|
||||
}
|
||||
@R|Ann|(Int(10)) public final fun test_6(): R|kotlin/Unit| {
|
||||
@R|Ann|(Int(300)) lval x: R|kotlin/String| = String()
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
fun foo(x: Int) {}
|
||||
fun foo(x: Byte) {}
|
||||
|
||||
fun test_0() {
|
||||
foo(1)
|
||||
}
|
||||
|
||||
fun test_1() {
|
||||
val x1 = 1 + 1
|
||||
val x2 = 1.plus(1)
|
||||
1 + 1
|
||||
127 + 1
|
||||
val x3 = 2000000000 * 4
|
||||
}
|
||||
|
||||
fun test_2(n: Int) {
|
||||
val x = 1 + n
|
||||
val y = n + 1
|
||||
}
|
||||
|
||||
fun Int.bar(): Int {}
|
||||
|
||||
fun Int.baz(): Int
|
||||
fun Byte.baz(): Byte {}
|
||||
|
||||
fun test_3() {
|
||||
val x = 1.bar()
|
||||
val y = 1.baz()
|
||||
}
|
||||
|
||||
fun takeByte(b: Byte) {}
|
||||
|
||||
fun test_4() {
|
||||
takeByte(1 + 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(1 + 127)
|
||||
takeByte(1 - 1)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(-100 - 100)
|
||||
takeByte(10 * 10)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(100 * 100)
|
||||
<!UNRESOLVED_REFERENCE!>taleByte<!>(10 / 10)
|
||||
takeByte(100 % 10)
|
||||
takeByte(1000 % 10)
|
||||
takeByte(1000 and 100)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(128 and 511)
|
||||
takeByte(100 or 100)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(1000 or 0)
|
||||
takeByte(511 xor 511)
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(512 xor 511)
|
||||
}
|
||||
|
||||
fun test_5() {
|
||||
takeByte(-1)
|
||||
takeByte(+1)
|
||||
takeByte(1.inv())
|
||||
}
|
||||
|
||||
fun test_6() {
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(run { 127 + 1 })
|
||||
<!INAPPLICABLE_CANDIDATE!>takeByte<!>(1 <!INAPPLICABLE_CANDIDATE!>+<!> run { 1 })
|
||||
takeByte(run { 1 + 1 })
|
||||
1 + 1
|
||||
run { 1 }
|
||||
1 + run { 1 }
|
||||
}
|
||||
|
||||
fun test_7(d: Double) {
|
||||
val x1 = 1 + d
|
||||
val x2 = d + 1
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
FILE: operatorsOverLiterals.kt
|
||||
public final fun foo(x: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun foo(x: R|kotlin/Byte|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_0(): R|kotlin/Unit| {
|
||||
R|/foo|(Int(1))
|
||||
}
|
||||
public final fun test_1(): R|kotlin/Unit| {
|
||||
lval x1: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
|
||||
lval x2: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(Int(1))
|
||||
Int(1).R|kotlin/Int.plus|(Int(1))
|
||||
Int(127).R|kotlin/Int.plus|(Int(1))
|
||||
lval x3: R|kotlin/Int| = Int(2000000000).R|kotlin/Int.times|(Int(4))
|
||||
}
|
||||
public final fun test_2(n: R|kotlin/Int|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int| = Int(1).R|kotlin/Int.plus|(R|<local>/n|)
|
||||
lval y: R|kotlin/Int| = R|<local>/n|.R|kotlin/Int.plus|(Int(1))
|
||||
}
|
||||
public final fun R|kotlin/Int|.bar(): R|kotlin/Int| {
|
||||
}
|
||||
public final fun R|kotlin/Int|.baz(): R|kotlin/Int|
|
||||
public final fun R|kotlin/Byte|.baz(): R|kotlin/Byte| {
|
||||
}
|
||||
public final fun test_3(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int| = Int(1).R|/bar|()
|
||||
lval y: R|kotlin/Int| = Int(1).R|/baz|()
|
||||
}
|
||||
public final fun takeByte(b: R|kotlin/Byte|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test_4(): R|kotlin/Unit| {
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.plus|(Byte(1)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(1).R|kotlin/Int.plus|(Int(127)))
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.minus|(Byte(1)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(100).R|kotlin/Int.unaryMinus|().R|kotlin/Int.minus|(Int(100)))
|
||||
R|/takeByte|(Byte(10).R|kotlin/Byte.times|(Byte(10)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(100).R|kotlin/Int.times|(Int(100)))
|
||||
<Unresolved name: taleByte>#(Int(10).R|kotlin/Int.div|(Int(10)))
|
||||
R|/takeByte|(Byte(100).R|kotlin/Byte.rem|(Byte(10)))
|
||||
R|/takeByte|(Int(1000).R|kotlin/Int.rem|(Byte(10)))
|
||||
R|/takeByte|(Int(1000).R|<local>/and|(Byte(100)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(128).R|kotlin/Int.and|(Int(511)))
|
||||
R|/takeByte|(Byte(100).R|<local>/or|(Byte(100)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(1000).R|kotlin/Int.or|(Int(0)))
|
||||
R|/takeByte|(Int(511).R|kotlin/Int.xor|(Int(511)))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(512).R|kotlin/Int.xor|(Int(511)))
|
||||
}
|
||||
public final fun test_5(): R|kotlin/Unit| {
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.unaryMinus|())
|
||||
R|/takeByte|(Byte(1).R|kotlin/Byte.unaryPlus|())
|
||||
R|/takeByte|(Byte(1).R|<local>/inv|())
|
||||
}
|
||||
public final fun test_6(): R|kotlin/Unit| {
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(127).R|kotlin/Int.plus|(Int(1))
|
||||
}
|
||||
))
|
||||
<Inapplicable(INAPPLICABLE): [/takeByte]>#(Int(1).<Inapplicable(INAPPLICABLE): [kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus, kotlin/Int.plus]>#(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
)))
|
||||
R|/takeByte|(R|kotlin/run|<R|kotlin/Byte|>(<L> = run@fun <anonymous>(): R|kotlin/Byte| <kind=EXACTLY_ONCE> {
|
||||
Int(1).R|kotlin/Int.plus|(Int(1))
|
||||
}
|
||||
))
|
||||
Int(1).R|kotlin/Int.plus|(Int(1))
|
||||
R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
)
|
||||
Int(1).R|<local>/plus|(R|kotlin/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
Int(1)
|
||||
}
|
||||
))
|
||||
}
|
||||
public final fun test_7(d: R|kotlin/Double|): R|kotlin/Unit| {
|
||||
lval x1: R|kotlin/Double| = Int(1).R|kotlin/Int.plus|(R|<local>/d|)
|
||||
lval x2: R|kotlin/Double| = R|<local>/d|.R|kotlin/Double.plus|(Int(1))
|
||||
}
|
||||
@@ -28,7 +28,7 @@ digraph binaryOperations_kt {
|
||||
subgraph cluster_4 {
|
||||
color=blue
|
||||
12 [label="Enter block"];
|
||||
13 [label="Const: Int(1)"];
|
||||
13 [label="Const: IntegerLiteral(1)"];
|
||||
14 [label="Exit block"];
|
||||
}
|
||||
15 [label="Exit when branch result"];
|
||||
@@ -80,7 +80,7 @@ digraph binaryOperations_kt {
|
||||
subgraph cluster_9 {
|
||||
color=blue
|
||||
30 [label="Enter block"];
|
||||
31 [label="Const: Int(1)"];
|
||||
31 [label="Const: IntegerLiteral(1)"];
|
||||
32 [label="Exit block"];
|
||||
}
|
||||
33 [label="Exit when branch result"];
|
||||
@@ -140,7 +140,7 @@ digraph binaryOperations_kt {
|
||||
subgraph cluster_15 {
|
||||
color=blue
|
||||
53 [label="Enter block"];
|
||||
54 [label="Const: Int(1)"];
|
||||
54 [label="Const: IntegerLiteral(1)"];
|
||||
55 [label="Exit block"];
|
||||
}
|
||||
56 [label="Exit when branch result"];
|
||||
@@ -205,7 +205,7 @@ digraph binaryOperations_kt {
|
||||
subgraph cluster_21 {
|
||||
color=blue
|
||||
76 [label="Enter block"];
|
||||
77 [label="Const: Int(1)"];
|
||||
77 [label="Const: IntegerLiteral(1)"];
|
||||
78 [label="Exit block"];
|
||||
}
|
||||
79 [label="Exit when branch result"];
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: binaryOperations.kt
|
||||
public final fun test_1(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b1| || R|<local>/b2| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ FILE: binaryOperations.kt
|
||||
public final fun test_2(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b1| && R|<local>/b2| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ FILE: binaryOperations.kt
|
||||
public final fun test_3(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|, b3: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b1| && R|<local>/b2| || R|<local>/b3| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ FILE: binaryOperations.kt
|
||||
public final fun test_4(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|, b3: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b1| || R|<local>/b2| && R|<local>/b3| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_4 {
|
||||
color=blue
|
||||
12 [label="Enter block"];
|
||||
13 [label="Const: Int(1)"];
|
||||
13 [label="Const: IntegerLiteral(1)"];
|
||||
14 [label="Exit block"];
|
||||
}
|
||||
15 [label="Exit when branch result"];
|
||||
@@ -81,7 +81,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_9 {
|
||||
color=blue
|
||||
31 [label="Enter block"];
|
||||
32 [label="Const: Int(1)"];
|
||||
32 [label="Const: IntegerLiteral(1)"];
|
||||
33 [label="Exit block"];
|
||||
}
|
||||
34 [label="Exit when branch result"];
|
||||
@@ -135,7 +135,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_14 {
|
||||
color=blue
|
||||
49 [label="Enter block"];
|
||||
50 [label="Const: Int(1)"];
|
||||
50 [label="Const: IntegerLiteral(1)"];
|
||||
51 [label="Exit block"];
|
||||
}
|
||||
52 [label="Exit when branch result"];
|
||||
@@ -188,7 +188,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_19 {
|
||||
color=blue
|
||||
68 [label="Enter block"];
|
||||
69 [label="Const: Int(1)"];
|
||||
69 [label="Const: IntegerLiteral(1)"];
|
||||
70 [label="Exit block"];
|
||||
}
|
||||
71 [label="Exit when branch result"];
|
||||
@@ -242,7 +242,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_24 {
|
||||
color=blue
|
||||
86 [label="Enter block"];
|
||||
87 [label="Const: Int(1)"];
|
||||
87 [label="Const: IntegerLiteral(1)"];
|
||||
88 [label="Exit block"];
|
||||
}
|
||||
89 [label="Exit when branch result"];
|
||||
@@ -295,7 +295,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_29 {
|
||||
color=blue
|
||||
105 [label="Enter block"];
|
||||
106 [label="Const: Int(1)"];
|
||||
106 [label="Const: IntegerLiteral(1)"];
|
||||
107 [label="Exit block"];
|
||||
}
|
||||
108 [label="Exit when branch result"];
|
||||
@@ -349,7 +349,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_34 {
|
||||
color=blue
|
||||
123 [label="Enter block"];
|
||||
124 [label="Const: Int(1)"];
|
||||
124 [label="Const: IntegerLiteral(1)"];
|
||||
125 [label="Exit block"];
|
||||
}
|
||||
126 [label="Exit when branch result"];
|
||||
@@ -402,7 +402,7 @@ digraph booleanOperatorsWithConsts_kt {
|
||||
subgraph cluster_39 {
|
||||
color=blue
|
||||
142 [label="Enter block"];
|
||||
143 [label="Const: Int(1)"];
|
||||
143 [label="Const: IntegerLiteral(1)"];
|
||||
144 [label="Exit block"];
|
||||
}
|
||||
145 [label="Exit when branch result"];
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b| || Boolean(false) -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_2(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
Boolean(false) || R|<local>/b| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_3(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b| || Boolean(true) -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_4(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
Boolean(true) || R|<local>/b| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_5(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b| && Boolean(false) -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_6(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
Boolean(false) && R|<local>/b| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_7(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
R|<local>/b| && Boolean(true) -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ FILE: booleanOperatorsWithConsts.kt
|
||||
public final fun test_8(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
when () {
|
||||
Boolean(true) && R|<local>/b| -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+172
-176
@@ -28,7 +28,7 @@ digraph complex_kt {
|
||||
14 [label="Access variable R|<local>/url|"];
|
||||
15 [label="Access variable R|<local>/url|"];
|
||||
16 [label="Function call: <Unresolved name: HttpRequests>#.<Unresolved name: request>#(R|<local>/url|)"];
|
||||
17 [label="Function call: <Unresolved name: HttpRequests>#.<Unresolved name: request>#(R|<local>/url|).<Unresolved name: connect>#(<L> = connect@fun <anonymous>(): <ERROR TYPE REF: Unresolved name: fromJson> {
|
||||
17 [label="Function call: <Unresolved name: HttpRequests>#.<Unresolved name: request>#(R|<local>/url|).<Unresolved name: connect>#(<L> = connect@fun <anonymous>(): R|class error: Unresolved name: fromJson| {
|
||||
<Unresolved name: GsonBuilder>#().<Unresolved name: create>#().<Unresolved name: fromJson>#(<Unresolved name: it>#.<Unresolved name: inputStream>#.<Ambiguity: reader, [kotlin/io/reader, kotlin/io/reader, kotlin/io/reader]>#(), <getClass>(Q|kotlin/Array|).R|kotlin/jvm/java|)
|
||||
}
|
||||
)"];
|
||||
@@ -44,44 +44,42 @@ digraph complex_kt {
|
||||
21 [label="Enter block"];
|
||||
22 [label="Const: String(Can't parse json response)"];
|
||||
23 [label="Access variable R|<local>/syntaxException|"];
|
||||
24 [label="Const: String(Can't parse json response)"];
|
||||
24 [label="Access variable R|<local>/syntaxException|"];
|
||||
25 [label="Access variable R|<local>/syntaxException|"];
|
||||
26 [label="Const: String(Can't parse json response)"];
|
||||
27 [label="Access variable R|<local>/syntaxException|"];
|
||||
28 [label="Function call: <Unresolved name: ResponseParseException>#(String(Can't parse json response), R|<local>/syntaxException|)"];
|
||||
29 [label="Throw: throw <Unresolved name: ResponseParseException>#(String(Can't parse json response), R|<local>/syntaxException|)"];
|
||||
30 [label="Stub" style="filled" fillcolor=gray];
|
||||
31 [label="Exit block" style="filled" fillcolor=gray];
|
||||
26 [label="Function call: <Unresolved name: ResponseParseException>#(String(Can't parse json response), R|<local>/syntaxException|)"];
|
||||
27 [label="Throw: throw <Unresolved name: ResponseParseException>#(String(Can't parse json response), R|<local>/syntaxException|)"];
|
||||
28 [label="Stub" style="filled" fillcolor=gray];
|
||||
29 [label="Exit block" style="filled" fillcolor=gray];
|
||||
}
|
||||
32 [label="Catch exit" style="filled" fillcolor=gray];
|
||||
30 [label="Catch exit" style="filled" fillcolor=gray];
|
||||
}
|
||||
subgraph cluster_6 {
|
||||
color=blue
|
||||
33 [label="Catch enter"];
|
||||
31 [label="Catch enter"];
|
||||
subgraph cluster_7 {
|
||||
color=blue
|
||||
34 [label="Enter block"];
|
||||
32 [label="Enter block"];
|
||||
33 [label="Access variable R|<local>/ioException|"];
|
||||
34 [label="Access variable R|<local>/ioException|"];
|
||||
35 [label="Access variable R|<local>/ioException|"];
|
||||
36 [label="Access variable R|<local>/ioException|"];
|
||||
37 [label="Access variable R|<local>/ioException|"];
|
||||
38 [label="Function call: <Unresolved name: IOException>#(R|<local>/ioException|)"];
|
||||
39 [label="Throw: throw <Unresolved name: IOException>#(R|<local>/ioException|)"];
|
||||
40 [label="Stub" style="filled" fillcolor=gray];
|
||||
41 [label="Exit block" style="filled" fillcolor=gray];
|
||||
36 [label="Function call: <Unresolved name: IOException>#(R|<local>/ioException|)"];
|
||||
37 [label="Throw: throw <Unresolved name: IOException>#(R|<local>/ioException|)"];
|
||||
38 [label="Stub" style="filled" fillcolor=gray];
|
||||
39 [label="Exit block" style="filled" fillcolor=gray];
|
||||
}
|
||||
42 [label="Catch exit" style="filled" fillcolor=gray];
|
||||
40 [label="Catch exit" style="filled" fillcolor=gray];
|
||||
}
|
||||
43 [label="Try expression exit"];
|
||||
41 [label="Try expression exit"];
|
||||
}
|
||||
44 [label="Variable declaration: lval pluginDTOs: R|kotlin/Array<class error: Symbol not found, for `PluginDTO`>|"];
|
||||
45 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red];
|
||||
42 [label="Variable declaration: lval pluginDTOs: R|kotlin/Array<class error: Symbol not found, for `PluginDTO`>|"];
|
||||
43 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red];
|
||||
}
|
||||
subgraph cluster_8 {
|
||||
color=blue
|
||||
46 [label="Enter annotation"];
|
||||
47 [label="Access variable <Unresolved name: IOException>#"];
|
||||
48 [label="Access variable <Unresolved name: ResponseParseException>#"];
|
||||
49 [label="Exit annotation"];
|
||||
44 [label="Enter annotation"];
|
||||
45 [label="Access variable <Unresolved name: IOException>#"];
|
||||
46 [label="Access variable <Unresolved name: ResponseParseException>#"];
|
||||
47 [label="Exit annotation"];
|
||||
}
|
||||
|
||||
0 -> {1};
|
||||
@@ -94,7 +92,7 @@ digraph complex_kt {
|
||||
7 -> {8};
|
||||
8 -> {9};
|
||||
9 -> {10};
|
||||
10 -> {45 33 20 11};
|
||||
10 -> {43 31 20 11};
|
||||
11 -> {12};
|
||||
12 -> {13};
|
||||
13 -> {14};
|
||||
@@ -103,54 +101,54 @@ digraph complex_kt {
|
||||
16 -> {17};
|
||||
17 -> {18};
|
||||
18 -> {19};
|
||||
19 -> {43};
|
||||
20 -> {45 21};
|
||||
19 -> {41};
|
||||
20 -> {43 21};
|
||||
21 -> {22};
|
||||
22 -> {23};
|
||||
23 -> {24};
|
||||
24 -> {25};
|
||||
25 -> {26};
|
||||
26 -> {27};
|
||||
27 -> {28};
|
||||
28 -> {29};
|
||||
29 -> {45};
|
||||
27 -> {43};
|
||||
27 -> {28} [style=dotted];
|
||||
28 -> {29} [style=dotted];
|
||||
29 -> {30} [style=dotted];
|
||||
30 -> {31} [style=dotted];
|
||||
31 -> {32} [style=dotted];
|
||||
32 -> {43} [style=dotted];
|
||||
33 -> {45 34};
|
||||
30 -> {41} [style=dotted];
|
||||
31 -> {43 32};
|
||||
32 -> {33};
|
||||
33 -> {34};
|
||||
34 -> {35};
|
||||
35 -> {36};
|
||||
36 -> {37};
|
||||
37 -> {38};
|
||||
38 -> {39};
|
||||
39 -> {45};
|
||||
37 -> {43};
|
||||
37 -> {38} [style=dotted];
|
||||
38 -> {39} [style=dotted];
|
||||
39 -> {40} [style=dotted];
|
||||
40 -> {41} [style=dotted];
|
||||
41 -> {42} [style=dotted];
|
||||
42 -> {43} [style=dotted];
|
||||
41 -> {42};
|
||||
42 -> {43};
|
||||
43 -> {44};
|
||||
44 -> {45};
|
||||
45 -> {46};
|
||||
46 -> {47};
|
||||
47 -> {48};
|
||||
48 -> {49};
|
||||
|
||||
subgraph cluster_9 {
|
||||
color=red
|
||||
50 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
51 [label="Function call: <Unresolved name: GsonBuilder>#()"];
|
||||
52 [label="Function call: <Unresolved name: GsonBuilder>#().<Unresolved name: create>#()"];
|
||||
53 [label="Access variable <Unresolved name: it>#"];
|
||||
54 [label="Access variable <Unresolved name: inputStream>#"];
|
||||
55 [label="Function call: <Unresolved name: it>#.<Unresolved name: inputStream>#.<Ambiguity: reader, [kotlin/io/reader, kotlin/io/reader, kotlin/io/reader]>#()"];
|
||||
48 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
|
||||
49 [label="Function call: <Unresolved name: GsonBuilder>#()"];
|
||||
50 [label="Function call: <Unresolved name: GsonBuilder>#().<Unresolved name: create>#()"];
|
||||
51 [label="Access variable <Unresolved name: it>#"];
|
||||
52 [label="Access variable <Unresolved name: inputStream>#"];
|
||||
53 [label="Function call: <Unresolved name: it>#.<Unresolved name: inputStream>#.<Ambiguity: reader, [kotlin/io/reader, kotlin/io/reader, kotlin/io/reader]>#()"];
|
||||
54 [label="Access variable R|kotlin/jvm/java|"];
|
||||
55 [label="Access variable R|kotlin/jvm/java|"];
|
||||
56 [label="Access variable R|kotlin/jvm/java|"];
|
||||
57 [label="Access variable R|kotlin/jvm/java|"];
|
||||
58 [label="Access variable R|kotlin/jvm/java|"];
|
||||
59 [label="Function call: <Unresolved name: GsonBuilder>#().<Unresolved name: create>#().<Unresolved name: fromJson>#(<Unresolved name: it>#.<Unresolved name: inputStream>#.<Ambiguity: reader, [kotlin/io/reader, kotlin/io/reader, kotlin/io/reader]>#(), <getClass>(Q|kotlin/Array|).R|kotlin/jvm/java|)"];
|
||||
60 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
57 [label="Function call: <Unresolved name: GsonBuilder>#().<Unresolved name: create>#().<Unresolved name: fromJson>#(<Unresolved name: it>#.<Unresolved name: inputStream>#.<Ambiguity: reader, [kotlin/io/reader, kotlin/io/reader, kotlin/io/reader]>#(), <getClass>(Q|kotlin/Array|).R|kotlin/jvm/java|)"];
|
||||
58 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
48 -> {49};
|
||||
49 -> {50};
|
||||
50 -> {51};
|
||||
51 -> {52};
|
||||
52 -> {53};
|
||||
@@ -159,98 +157,96 @@ digraph complex_kt {
|
||||
55 -> {56};
|
||||
56 -> {57};
|
||||
57 -> {58};
|
||||
58 -> {59};
|
||||
59 -> {60};
|
||||
|
||||
subgraph cluster_10 {
|
||||
color=red
|
||||
61 [label="Enter function close" style="filled" fillcolor=red];
|
||||
62 [label="Exit function close" style="filled" fillcolor=red];
|
||||
59 [label="Enter function close" style="filled" fillcolor=red];
|
||||
60 [label="Exit function close" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
61 -> {62};
|
||||
59 -> {60};
|
||||
|
||||
subgraph cluster_11 {
|
||||
color=red
|
||||
63 [label="Enter function closeFinally" style="filled" fillcolor=red];
|
||||
61 [label="Enter function closeFinally" style="filled" fillcolor=red];
|
||||
subgraph cluster_12 {
|
||||
color=blue
|
||||
64 [label="Enter when"];
|
||||
62 [label="Enter when"];
|
||||
subgraph cluster_13 {
|
||||
color=blue
|
||||
65 [label="Enter when branch condition "];
|
||||
66 [label="Access variable this@R|/closeFinally|"];
|
||||
67 [label="Const: Null(null)"];
|
||||
68 [label="Operator =="];
|
||||
69 [label="Exit when branch condition"];
|
||||
63 [label="Enter when branch condition "];
|
||||
64 [label="Access variable this@R|/closeFinally|"];
|
||||
65 [label="Const: Null(null)"];
|
||||
66 [label="Operator =="];
|
||||
67 [label="Exit when branch condition"];
|
||||
}
|
||||
subgraph cluster_14 {
|
||||
color=blue
|
||||
70 [label="Enter when branch condition "];
|
||||
71 [label="Access variable R|<local>/cause|"];
|
||||
72 [label="Const: Null(null)"];
|
||||
73 [label="Operator =="];
|
||||
74 [label="Exit when branch condition"];
|
||||
68 [label="Enter when branch condition "];
|
||||
69 [label="Access variable R|<local>/cause|"];
|
||||
70 [label="Const: Null(null)"];
|
||||
71 [label="Operator =="];
|
||||
72 [label="Exit when branch condition"];
|
||||
}
|
||||
subgraph cluster_15 {
|
||||
color=blue
|
||||
75 [label="Enter when branch condition else"];
|
||||
76 [label="Exit when branch condition"];
|
||||
73 [label="Enter when branch condition else"];
|
||||
74 [label="Exit when branch condition"];
|
||||
}
|
||||
77 [label="Enter when branch result"];
|
||||
75 [label="Enter when branch result"];
|
||||
subgraph cluster_16 {
|
||||
color=blue
|
||||
78 [label="Enter block"];
|
||||
76 [label="Enter block"];
|
||||
subgraph cluster_17 {
|
||||
color=blue
|
||||
79 [label="Try expression enter"];
|
||||
77 [label="Try expression enter"];
|
||||
subgraph cluster_18 {
|
||||
color=blue
|
||||
80 [label="Try main block enter"];
|
||||
78 [label="Try main block enter"];
|
||||
subgraph cluster_19 {
|
||||
color=blue
|
||||
81 [label="Enter block"];
|
||||
82 [label="Function call: this@R|/AutoCloseable|.R|/AutoCloseable.close|()"];
|
||||
83 [label="Exit block"];
|
||||
79 [label="Enter block"];
|
||||
80 [label="Function call: this@R|/AutoCloseable|.R|/AutoCloseable.close|()"];
|
||||
81 [label="Exit block"];
|
||||
}
|
||||
84 [label="Try main block exit"];
|
||||
82 [label="Try main block exit"];
|
||||
}
|
||||
subgraph cluster_20 {
|
||||
color=blue
|
||||
85 [label="Catch enter"];
|
||||
83 [label="Catch enter"];
|
||||
subgraph cluster_21 {
|
||||
color=blue
|
||||
86 [label="Enter block"];
|
||||
87 [label="Access variable R|<local>/cause|"];
|
||||
88 [label="Access variable R|<local>/closeException|"];
|
||||
89 [label="Function call: R|<local>/cause|.R|kotlin/addSuppressed|(R|<local>/closeException|)"];
|
||||
90 [label="Exit block"];
|
||||
84 [label="Enter block"];
|
||||
85 [label="Access variable R|<local>/cause|"];
|
||||
86 [label="Access variable R|<local>/closeException|"];
|
||||
87 [label="Function call: R|<local>/cause|.R|kotlin/addSuppressed|(R|<local>/closeException|)"];
|
||||
88 [label="Exit block"];
|
||||
}
|
||||
91 [label="Catch exit"];
|
||||
89 [label="Catch exit"];
|
||||
}
|
||||
92 [label="Try expression exit"];
|
||||
90 [label="Try expression exit"];
|
||||
}
|
||||
93 [label="Exit block"];
|
||||
91 [label="Exit block"];
|
||||
}
|
||||
94 [label="Exit when branch result"];
|
||||
95 [label="Enter when branch result"];
|
||||
92 [label="Exit when branch result"];
|
||||
93 [label="Enter when branch result"];
|
||||
subgraph cluster_22 {
|
||||
color=blue
|
||||
96 [label="Enter block"];
|
||||
97 [label="Function call: this@R|/AutoCloseable|.R|/AutoCloseable.close|()"];
|
||||
98 [label="Exit block"];
|
||||
94 [label="Enter block"];
|
||||
95 [label="Function call: this@R|/AutoCloseable|.R|/AutoCloseable.close|()"];
|
||||
96 [label="Exit block"];
|
||||
}
|
||||
99 [label="Exit when branch result"];
|
||||
100 [label="Enter when branch result"];
|
||||
97 [label="Exit when branch result"];
|
||||
98 [label="Enter when branch result"];
|
||||
subgraph cluster_23 {
|
||||
color=blue
|
||||
101 [label="Enter block"];
|
||||
102 [label="Exit block"];
|
||||
99 [label="Enter block"];
|
||||
100 [label="Exit block"];
|
||||
}
|
||||
103 [label="Exit when branch result"];
|
||||
104 [label="Exit when"];
|
||||
101 [label="Exit when branch result"];
|
||||
102 [label="Exit when"];
|
||||
}
|
||||
105 [label="Jump: ^closeFinally when () {
|
||||
103 [label="Jump: ^closeFinally when () {
|
||||
==(this@R|/closeFinally|, Null(null)) -> {
|
||||
}
|
||||
==(R|<local>/cause|, Null(null)) -> {
|
||||
@@ -267,118 +263,120 @@ digraph complex_kt {
|
||||
}
|
||||
}
|
||||
"];
|
||||
106 [label="Stub" style="filled" fillcolor=gray];
|
||||
107 [label="Exit function closeFinally" style="filled" fillcolor=red];
|
||||
104 [label="Stub" style="filled" fillcolor=gray];
|
||||
105 [label="Exit function closeFinally" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
61 -> {62};
|
||||
62 -> {63};
|
||||
63 -> {64};
|
||||
64 -> {65};
|
||||
65 -> {66};
|
||||
66 -> {67};
|
||||
67 -> {68};
|
||||
67 -> {98 68};
|
||||
68 -> {69};
|
||||
69 -> {100 70};
|
||||
69 -> {70};
|
||||
70 -> {71};
|
||||
71 -> {72};
|
||||
72 -> {73};
|
||||
72 -> {93 73};
|
||||
73 -> {74};
|
||||
74 -> {95 75};
|
||||
74 -> {75};
|
||||
75 -> {76};
|
||||
76 -> {77};
|
||||
77 -> {78};
|
||||
78 -> {79};
|
||||
78 -> {105 83 79};
|
||||
79 -> {80};
|
||||
80 -> {107 85 81};
|
||||
80 -> {81};
|
||||
81 -> {82};
|
||||
82 -> {83};
|
||||
83 -> {84};
|
||||
84 -> {92};
|
||||
85 -> {107 86};
|
||||
82 -> {90};
|
||||
83 -> {105 84};
|
||||
84 -> {85};
|
||||
85 -> {86};
|
||||
86 -> {87};
|
||||
87 -> {88};
|
||||
88 -> {89};
|
||||
89 -> {90};
|
||||
90 -> {91};
|
||||
91 -> {92};
|
||||
92 -> {93};
|
||||
92 -> {102};
|
||||
93 -> {94};
|
||||
94 -> {104};
|
||||
94 -> {95};
|
||||
95 -> {96};
|
||||
96 -> {97};
|
||||
97 -> {98};
|
||||
97 -> {102};
|
||||
98 -> {99};
|
||||
99 -> {104};
|
||||
99 -> {100};
|
||||
100 -> {101};
|
||||
101 -> {102};
|
||||
102 -> {103};
|
||||
103 -> {104};
|
||||
104 -> {105};
|
||||
105 -> {107};
|
||||
105 -> {106} [style=dotted];
|
||||
106 -> {107} [style=dotted];
|
||||
103 -> {105};
|
||||
103 -> {104} [style=dotted];
|
||||
104 -> {105} [style=dotted];
|
||||
|
||||
subgraph cluster_24 {
|
||||
color=red
|
||||
108 [label="Enter function firstIsInstanceOrNull" style="filled" fillcolor=red];
|
||||
109 [label="Access variable this@R|/firstIsInstanceOrNull|"];
|
||||
110 [label="Variable declaration: lval <range>: R|kotlin/sequences/Sequence<*>|"];
|
||||
111 [label="Access variable R|<local>/<range>|"];
|
||||
112 [label="Function call: R|<local>/<range>|.R|FakeOverride<kotlin/sequences/Sequence.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()"];
|
||||
113 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>|"];
|
||||
106 [label="Enter function firstIsInstanceOrNull" style="filled" fillcolor=red];
|
||||
107 [label="Access variable this@R|/firstIsInstanceOrNull|"];
|
||||
108 [label="Variable declaration: lval <range>: R|kotlin/sequences/Sequence<*>|"];
|
||||
109 [label="Access variable R|<local>/<range>|"];
|
||||
110 [label="Function call: R|<local>/<range>|.R|FakeOverride<kotlin/sequences/Sequence.iterator: R|kotlin/collections/Iterator<kotlin/Any?>|>|()"];
|
||||
111 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>|"];
|
||||
subgraph cluster_25 {
|
||||
color=blue
|
||||
114 [label="Enter while loop"];
|
||||
112 [label="Enter while loop"];
|
||||
subgraph cluster_26 {
|
||||
color=blue
|
||||
115 [label="Enter loop condition"];
|
||||
116 [label="Access variable R|<local>/<iterator>|"];
|
||||
117 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
|
||||
118 [label="Exit loop condition"];
|
||||
113 [label="Enter loop condition"];
|
||||
114 [label="Access variable R|<local>/<iterator>|"];
|
||||
115 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
|
||||
116 [label="Exit loop condition"];
|
||||
}
|
||||
subgraph cluster_27 {
|
||||
color=blue
|
||||
119 [label="Enter loop block"];
|
||||
117 [label="Enter loop block"];
|
||||
subgraph cluster_28 {
|
||||
color=blue
|
||||
120 [label="Enter block"];
|
||||
121 [label="Access variable R|<local>/<iterator>|"];
|
||||
122 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()"];
|
||||
123 [label="Variable declaration: lval element: R|kotlin/Any?|"];
|
||||
118 [label="Enter block"];
|
||||
119 [label="Access variable R|<local>/<iterator>|"];
|
||||
120 [label="Function call: R|<local>/<iterator>|.R|FakeOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()"];
|
||||
121 [label="Variable declaration: lval element: R|kotlin/Any?|"];
|
||||
subgraph cluster_29 {
|
||||
color=blue
|
||||
124 [label="Enter when"];
|
||||
122 [label="Enter when"];
|
||||
subgraph cluster_30 {
|
||||
color=blue
|
||||
125 [label="Enter when branch condition "];
|
||||
126 [label="Access variable R|<local>/element|"];
|
||||
127 [label="Type operator: element is T"];
|
||||
128 [label="Exit when branch condition"];
|
||||
123 [label="Enter when branch condition "];
|
||||
124 [label="Access variable R|<local>/element|"];
|
||||
125 [label="Type operator: element is T"];
|
||||
126 [label="Exit when branch condition"];
|
||||
}
|
||||
129 [label="Synthetic else branch"];
|
||||
130 [label="Enter when branch result"];
|
||||
127 [label="Synthetic else branch"];
|
||||
128 [label="Enter when branch result"];
|
||||
subgraph cluster_31 {
|
||||
color=blue
|
||||
131 [label="Enter block"];
|
||||
132 [label="Access variable R|<local>/element|"];
|
||||
133 [label="Jump: ^firstIsInstanceOrNull R|<local>/element|"];
|
||||
134 [label="Stub" style="filled" fillcolor=gray];
|
||||
135 [label="Exit block" style="filled" fillcolor=gray];
|
||||
129 [label="Enter block"];
|
||||
130 [label="Access variable R|<local>/element|"];
|
||||
131 [label="Jump: ^firstIsInstanceOrNull R|<local>/element|"];
|
||||
132 [label="Stub" style="filled" fillcolor=gray];
|
||||
133 [label="Exit block" style="filled" fillcolor=gray];
|
||||
}
|
||||
136 [label="Exit when branch result" style="filled" fillcolor=gray];
|
||||
137 [label="Exit when"];
|
||||
134 [label="Exit when branch result" style="filled" fillcolor=gray];
|
||||
135 [label="Exit when"];
|
||||
}
|
||||
138 [label="Exit block"];
|
||||
136 [label="Exit block"];
|
||||
}
|
||||
139 [label="Exit loop block"];
|
||||
137 [label="Exit loop block"];
|
||||
}
|
||||
140 [label="Exit whileloop"];
|
||||
138 [label="Exit whileloop"];
|
||||
}
|
||||
141 [label="Const: Null(null)"];
|
||||
142 [label="Jump: ^firstIsInstanceOrNull Null(null)"];
|
||||
143 [label="Stub" style="filled" fillcolor=gray];
|
||||
144 [label="Exit function firstIsInstanceOrNull" style="filled" fillcolor=red];
|
||||
139 [label="Const: Null(null)"];
|
||||
140 [label="Jump: ^firstIsInstanceOrNull Null(null)"];
|
||||
141 [label="Stub" style="filled" fillcolor=gray];
|
||||
142 [label="Exit function firstIsInstanceOrNull" style="filled" fillcolor=red];
|
||||
}
|
||||
|
||||
106 -> {107};
|
||||
107 -> {108};
|
||||
108 -> {109};
|
||||
109 -> {110};
|
||||
110 -> {111};
|
||||
@@ -387,9 +385,9 @@ digraph complex_kt {
|
||||
113 -> {114};
|
||||
114 -> {115};
|
||||
115 -> {116};
|
||||
116 -> {117};
|
||||
116 -> {138 117};
|
||||
117 -> {118};
|
||||
118 -> {140 119};
|
||||
118 -> {119};
|
||||
119 -> {120};
|
||||
120 -> {121};
|
||||
121 -> {122};
|
||||
@@ -397,25 +395,23 @@ digraph complex_kt {
|
||||
123 -> {124};
|
||||
124 -> {125};
|
||||
125 -> {126};
|
||||
126 -> {127};
|
||||
127 -> {128};
|
||||
128 -> {130 129};
|
||||
129 -> {137};
|
||||
126 -> {128 127};
|
||||
127 -> {135};
|
||||
128 -> {129};
|
||||
129 -> {130};
|
||||
130 -> {131};
|
||||
131 -> {132};
|
||||
132 -> {133};
|
||||
133 -> {144};
|
||||
131 -> {142};
|
||||
131 -> {132} [style=dotted];
|
||||
132 -> {133} [style=dotted];
|
||||
133 -> {134} [style=dotted];
|
||||
134 -> {135} [style=dotted];
|
||||
135 -> {136} [style=dotted];
|
||||
136 -> {137} [style=dotted];
|
||||
137 -> {138};
|
||||
135 -> {136};
|
||||
136 -> {137};
|
||||
137 -> {113};
|
||||
138 -> {139};
|
||||
139 -> {115};
|
||||
140 -> {141};
|
||||
141 -> {142};
|
||||
142 -> {144};
|
||||
142 -> {143} [style=dotted];
|
||||
143 -> {144} [style=dotted];
|
||||
139 -> {140};
|
||||
140 -> {142};
|
||||
140 -> {141} [style=dotted];
|
||||
141 -> {142} [style=dotted];
|
||||
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ digraph propertiesAndInitBlocks_kt {
|
||||
subgraph cluster_18 {
|
||||
color=blue
|
||||
53 [label="Enter block"];
|
||||
54 [label="Const: Int(0)"];
|
||||
54 [label="Const: IntegerLiteral(0)"];
|
||||
55 [label="Exit block"];
|
||||
}
|
||||
56 [label="Exit finally"];
|
||||
|
||||
@@ -52,7 +52,7 @@ FILE: propertiesAndInitBlocks.kt
|
||||
Int(2)
|
||||
}
|
||||
finally {
|
||||
Int(0)
|
||||
IntegerLiteral(0)
|
||||
}
|
||||
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
@@ -50,7 +50,7 @@ digraph returnValuesFromLambda_kt {
|
||||
19 [label="Function call: R|/C.C|()"];
|
||||
20 [label="Exit function anonymousFunction"];
|
||||
}
|
||||
21 [label="Function call: R|kotlin/run|<R|A|>(<L> = run@fun <anonymous>(): R|C| <kind=EXACTLY_ONCE> {
|
||||
21 [label="Function call: R|kotlin/run|<R|A|>(<L> = run@fun <anonymous>(): R|A| <kind=EXACTLY_ONCE> {
|
||||
when () {
|
||||
R|<local>/b| -> {
|
||||
^@run R|/B.B|()
|
||||
@@ -124,7 +124,7 @@ digraph returnValuesFromLambda_kt {
|
||||
36 [label="Stub" style="filled" fillcolor=gray];
|
||||
37 [label="Exit function anonymousFunction" style="filled" fillcolor=gray];
|
||||
}
|
||||
38 [label="Function call: R|kotlin/run|<R|kotlin/Nothing|>(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
38 [label="Function call: R|kotlin/run|<R|kotlin/Nothing|>(<L> = run@fun <anonymous>(): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
|
||||
^test_3 Unit
|
||||
}
|
||||
)" style="filled" fillcolor=gray];
|
||||
|
||||
@@ -14,7 +14,7 @@ FILE: returnValuesFromLambda.kt
|
||||
|
||||
}
|
||||
public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
lval x: R|A| = R|kotlin/run|<R|A|>(<L> = run@fun <anonymous>(): R|C| <kind=EXACTLY_ONCE> {
|
||||
lval x: R|A| = R|kotlin/run|<R|A|>(<L> = run@fun <anonymous>(): R|A| <kind=EXACTLY_ONCE> {
|
||||
when () {
|
||||
R|<local>/b| -> {
|
||||
^@run R|/B.B|()
|
||||
@@ -32,7 +32,7 @@ FILE: returnValuesFromLambda.kt
|
||||
)
|
||||
}
|
||||
public final fun test_3(): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Nothing| = R|kotlin/run|<R|kotlin/Nothing|>(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
lval x: R|kotlin/Nothing| = R|kotlin/run|<R|kotlin/Nothing|>(<L> = run@fun <anonymous>(): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
|
||||
^test_3 Unit
|
||||
}
|
||||
)
|
||||
|
||||
@@ -14,3 +14,14 @@ class B3_1 : <!AMBIGUITY!>A3<!>("")
|
||||
class B3_2 : A3("", "asas")
|
||||
class B3_3 : A3("", true)
|
||||
class B3_4 : <!INAPPLICABLE_CANDIDATE!>A3<!>("", Unit)
|
||||
|
||||
open class A4(val x: Byte)
|
||||
class B4 : A4( 1 + 1)
|
||||
|
||||
open class A5 {
|
||||
constructor(x: Byte)
|
||||
constructor(x: Short)
|
||||
}
|
||||
|
||||
class B5_1 : A5(1 + 1)
|
||||
class B5_2 : A5(100 * 2)
|
||||
@@ -74,3 +74,40 @@ FILE: delegatingConstructorCall.kt
|
||||
}
|
||||
|
||||
}
|
||||
public open class A4 : R|kotlin/Any| {
|
||||
public constructor(x: R|kotlin/Byte|): R|A4| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val x: R|kotlin/Byte| = R|<local>/x|
|
||||
public get(): R|kotlin/Byte|
|
||||
|
||||
}
|
||||
public final class B4 : R|A4| {
|
||||
public constructor(): R|B4| {
|
||||
super<R|A4|>(Byte(1).R|kotlin/Byte.plus|(Byte(1)))
|
||||
}
|
||||
|
||||
}
|
||||
public open class A5 : R|kotlin/Any| {
|
||||
public constructor(x: R|kotlin/Byte|): R|A5| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public constructor(x: R|kotlin/Short|): R|A5| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public final class B5_1 : R|A5| {
|
||||
public constructor(): R|B5_1| {
|
||||
super<R|A5|>(Short(1).R|kotlin/Short.plus|(Short(1)))
|
||||
}
|
||||
|
||||
}
|
||||
public final class B5_2 : R|A5| {
|
||||
public constructor(): R|B5_2| {
|
||||
super<R|A5|>(Short(100).R|kotlin/Short.times|(Short(2)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ FILE: exhaustiveness_boolean.kt
|
||||
public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Unit| = when (R|<local>/b|) {
|
||||
==($subj$, Boolean(true)) -> {
|
||||
Int(1)
|
||||
IntegerLiteral(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class TestProperty {
|
||||
return intConst + 1
|
||||
}
|
||||
}
|
||||
1
|
||||
return 1
|
||||
}
|
||||
|
||||
val z = run {
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ FILE: localObject.kt
|
||||
|
||||
}
|
||||
|
||||
Int(1)
|
||||
^ Int(1)
|
||||
}
|
||||
|
||||
public final val z: R|kotlin/Int| = R|/run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| {
|
||||
|
||||
@@ -69,9 +69,9 @@ FILE: main.kt
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
@R|annotations/WithString|(String(xyz)) public final class Second : @R|annotations/WithInt|(Int(0)) R|test/First| {
|
||||
@R|annotations/WithString|(String(xyz)) public final class Second : @R|annotations/WithInt|(IntegerLiteral(0)) R|test/First| {
|
||||
public constructor(y: R|kotlin/Char|): R|test/Second| {
|
||||
super<@R|annotations/WithInt|(Int(0)) R|test/First|>()
|
||||
super<@R|annotations/WithInt|(IntegerLiteral(0)) R|test/First|>()
|
||||
}
|
||||
|
||||
public final val y: R|kotlin/Char| = R|<local>/y|
|
||||
|
||||
@@ -199,7 +199,7 @@ digraph safeCalls_kt {
|
||||
73 [label="Stub" style="filled" fillcolor=gray];
|
||||
74 [label="Exit function anonymousFunction" style="filled" fillcolor=gray];
|
||||
}
|
||||
75 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
75 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
|
||||
^test_5 Unit
|
||||
}
|
||||
)" style="filled" fillcolor=gray];
|
||||
@@ -207,7 +207,7 @@ digraph safeCalls_kt {
|
||||
77 [label="Enter safe call" style="filled" fillcolor=gray];
|
||||
78 [label="Access variable R|<local>/x|" style="filled" fillcolor=gray];
|
||||
79 [label="Function call: R|<local>/x|.R|/A.bool|()" style="filled" fillcolor=gray];
|
||||
80 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
80 [label="Function call: R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
|
||||
^test_5 Unit
|
||||
}
|
||||
)?.R|/boo|(R|<local>/x|.R|/A.bool|())" style="filled" fillcolor=gray];
|
||||
|
||||
@@ -32,7 +32,7 @@ FILE: safeCalls.kt
|
||||
}
|
||||
public final fun R|kotlin/Any?|.boo(b: R|kotlin/Boolean|): R|kotlin/Unit|
|
||||
public final fun test_5(x: R|A?|): R|kotlin/Unit| {
|
||||
R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|<local>/x|?.R|kotlin/let|<R|A|, R|kotlin/Nothing|>(<L> = let@fun <anonymous>(it: R|A|): R|kotlin/Nothing| <kind=EXACTLY_ONCE> {
|
||||
^test_5 Unit
|
||||
}
|
||||
)?.R|/boo|(R|<local>/x|.R|/A.bool|())
|
||||
|
||||
@@ -28,16 +28,16 @@ FILE: implicitReceiverOrder.kt
|
||||
|
||||
}
|
||||
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
|
||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
this@R|/A|.R|/A.foo|()
|
||||
(this@R|/B|, this@R|special/anonymous|).R|/B.bar|()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(R|<local>/a|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|B|, R|kotlin/Int|>(R|<local>/b|, <L> = with@fun R|B|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
this@R|/B|.R|/B.foo|()
|
||||
(this@R|/A|, this@R|special/anonymous|).R|/A.bar|()
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ fun main(k: KSub, vString: SuperClass<String>.NestedInSuperClass, vInt: SuperCla
|
||||
// TODO: Support parametrisized inner classes
|
||||
k.getImpl().nestedI(vInt)
|
||||
k.getNestedSubClass().<!INAPPLICABLE_CANDIDATE!>nested<!>("")
|
||||
k.getNestedSubClass().<!INAPPLICABLE_CANDIDATE!>nested<!>(1)
|
||||
k.getNestedSubClass().nested(1)
|
||||
}
|
||||
|
||||
// FILE: J1.java
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ FILE: K1.kt
|
||||
R|<local>/k|.R|/J1.getImpl|().R|FakeOverride</SuperI.NestedInI.nestedI: R|kotlin/Unit|>|(R|<local>/vString|)
|
||||
R|<local>/k|.R|/J1.getImpl|().R|FakeOverride</SuperI.NestedInI.nestedI: R|kotlin/Unit|>|(R|<local>/vInt|)
|
||||
R|<local>/k|.R|/J1.getNestedSubClass|().<Inapplicable(INAPPLICABLE): [/SuperClass.NestedInSuperClass.nested]>#(String())
|
||||
R|<local>/k|.R|/J1.getNestedSubClass|().<Inapplicable(INAPPLICABLE): [/SuperClass.NestedInSuperClass.nested]>#(Int(1))
|
||||
R|<local>/k|.R|/J1.getNestedSubClass|().R|/SuperClass.NestedInSuperClass.nested|(Int(1))
|
||||
}
|
||||
FILE: K2.kt
|
||||
public open class KFirst : R|SuperClass<kotlin/String>|, R|SuperI<kotlin/Int>| {
|
||||
|
||||
@@ -25,10 +25,10 @@ FILE: multipleImplicitReceivers.kt
|
||||
|
||||
}
|
||||
public final fun test(fooImpl: R|IFoo|, invokeImpl: R|IInvoke|): R|kotlin/Unit| {
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|IFoo|, R|kotlin/Int|>(R|<local>/fooImpl|, <L> = with@fun R|IFoo|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|A|, R|kotlin/Int|>(Q|A|, <L> = with@fun R|A|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|IFoo|, R|kotlin/Int|>(R|<local>/fooImpl|, <L> = with@fun R|IFoo|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
(this@R|/IFoo|, this@R|special/anonymous|).R|/IFoo.foo|
|
||||
R|kotlin/with|<R|IInvoke|, R|kotlin/Int|>(R|<local>/invokeImpl|, <L> = with@fun R|IInvoke|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||
R|kotlin/with|<R|IInvoke|, R|kotlin/Int|>(R|<local>/invokeImpl|, <L> = with@fun R|IInvoke|.<anonymous>(): R|kotlin/Int| <kind=EXACTLY_ONCE> {
|
||||
(this@R|/IInvoke|, (this@R|/IFoo|, this@R|special/anonymous|).R|/IFoo.foo|).R|/IInvoke.invoke|()
|
||||
}
|
||||
)
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ FILE: tryWithLambdaInside.kt
|
||||
public final fun bar(): R|kotlin/collections/List<kotlin/String>| {
|
||||
^bar try {
|
||||
R|/foo|().R|kotlin/collections/filter|<R|kotlin/String|>(<L> = filter@fun <implicit>.<anonymous>(): <implicit> <kind=UNKNOWN> {
|
||||
>(it#.length#, Int(2))
|
||||
>(it#.length#, IntegerLiteral(2))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fun test(b: Byte, s: Short, i: Int, l: Long) {
|
||||
val x1 = 1.rangeTo(b)
|
||||
val x2 = 1.rangeTo(s)
|
||||
val x3 = 1.rangeTo(i)
|
||||
val x4 = 1.rangeTo(l)
|
||||
|
||||
val x5 = b.rangeTo(1)
|
||||
val x6 = s.rangeTo(1)
|
||||
val x7 = i.rangeTo(1)
|
||||
val x8 = l.rangeTo(1)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
FILE: rangeTo.kt
|
||||
public final fun test(b: R|kotlin/Byte|, s: R|kotlin/Short|, i: R|kotlin/Int|, l: R|kotlin/Long|): R|kotlin/Unit| {
|
||||
lval x1: R|kotlin/ranges/IntRange| = Int(1).R|kotlin/Int.rangeTo|(R|<local>/b|)
|
||||
lval x2: R|kotlin/ranges/IntRange| = Int(1).R|kotlin/Int.rangeTo|(R|<local>/s|)
|
||||
lval x3: R|kotlin/ranges/IntRange| = Int(1).R|kotlin/Int.rangeTo|(R|<local>/i|)
|
||||
lval x4: R|kotlin/ranges/LongRange| = Int(1).R|kotlin/Int.rangeTo|(R|<local>/l|)
|
||||
lval x5: R|kotlin/ranges/IntRange| = R|<local>/b|.R|kotlin/Byte.rangeTo|(Int(1))
|
||||
lval x6: R|kotlin/ranges/IntRange| = R|<local>/s|.R|kotlin/Short.rangeTo|(Int(1))
|
||||
lval x7: R|kotlin/ranges/IntRange| = R|<local>/i|.R|kotlin/Int.rangeTo|(Int(1))
|
||||
lval x8: R|kotlin/ranges/LongRange| = R|<local>/l|.R|kotlin/Long.rangeTo|(Int(1))
|
||||
}
|
||||
+10
@@ -275,6 +275,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/incorrectFunctionalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("integerLiteralTypes.kt")
|
||||
public void testIntegerLiteralTypes() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invoke.kt")
|
||||
public void testInvoke() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/invoke.kt");
|
||||
@@ -305,6 +310,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/lambdaInUnresolvedCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("operatorsOverLiterals.kt")
|
||||
public void testOperatorsOverLiterals() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overloadByReceiver.kt")
|
||||
public void testOverloadByReceiver() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/arguments/overloadByReceiver.kt");
|
||||
|
||||
Generated
+5
@@ -158,6 +158,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/problems.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("rangeTo.kt")
|
||||
public void testRangeTo() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/rangeTo.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveBug.kt")
|
||||
public void testRecursiveBug() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/resolve/stdlib/recursiveBug.kt");
|
||||
|
||||
@@ -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>
|
||||
|
||||
+6
-1
@@ -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
|
||||
}
|
||||
|
||||
+2
@@ -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)
|
||||
|
||||
+6
-1
@@ -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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user