From b76c984b2696008f34f02fab13574881a9420aa3 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 9 Dec 2019 15:02:55 +0300 Subject: [PATCH] [FIR] Support IntegerLiteralTypes --- .../kotlin/fir/symbols/StandardClassIds.kt | 3 + .../jetbrains/kotlin/fir/types/ConeTypes.kt | 34 ++ .../kotlin/fir/types/TypeRenderer.kt | 1 + .../jetbrains/kotlin/fir/dump/HtmlFirDump.kt | 22 +- .../kotlin/fir/backend/ConversionUtils.kt | 1 + .../kotlin/fir/backend/Fir2IrVisitor.kt | 26 +- .../kotlin/fir/java/FirJavaElementFinder.kt | 2 +- .../fir/java/FirJavaElementFinder.kt.183 | 2 +- .../jetbrains/kotlin/fir/java/JavaUtils.kt | 40 +- .../fir/java/declarations/FirJavaField.kt | 4 + .../fir/java/enhancement/javaTypeUtils.kt | 24 +- .../java/scopes/JavaClassEnhancementScope.kt | 4 +- .../kotlin/fir/builder/BaseFirBuilder.kt | 55 +-- .../kotlin/fir/builder/ConversionUtils.kt | 5 +- .../rawBuilder/declarations/expectActual.txt | 2 +- .../rawBuilder/declarations/simpleClass.txt | 2 +- .../declarations/typeParameters.txt | 2 +- .../rawBuilder/expressions/annotated.txt | 10 +- .../rawBuilder/expressions/arrayAccess.txt | 6 +- .../expressions/arrayAssignment.txt | 8 +- .../rawBuilder/expressions/branches.txt | 10 +- .../expressions/callableReferences.txt | 2 +- .../testData/rawBuilder/expressions/calls.txt | 8 +- .../expressions/collectionLiterals.txt | 2 +- .../testData/rawBuilder/expressions/for.txt | 6 +- .../rawBuilder/expressions/lambda.txt | 12 +- .../lambdaAndAnonymousFunction.txt | 2 +- .../rawBuilder/expressions/locals.txt | 4 +- .../rawBuilder/expressions/modifications.txt | 12 +- .../rawBuilder/expressions/nullability.txt | 2 +- .../testData/rawBuilder/expressions/these.txt | 2 +- .../testData/rawBuilder/expressions/unary.txt | 20 +- .../rawBuilder/expressions/variables.txt | 6 +- .../testData/rawBuilder/expressions/while.txt | 8 +- .../src/org/jetbrains/kotlin/fir/CopyUtils.kt | 7 +- .../jetbrains/kotlin/fir/FirCallResolver.kt | 78 ++-- .../org/jetbrains/kotlin/fir/SessionUtils.kt | 5 +- .../AbstractAnnotationDeserializer.kt | 22 +- .../kotlin/fir/resolve/ResolveUtils.kt | 1 + .../kotlin/fir/resolve/SamResolution.kt | 3 +- .../kotlin/fir/resolve/ScopeUtils.kt | 10 +- .../kotlin/fir/resolve/SessionHolder.kt | 6 +- .../calls/AbstractConeCallConflictResolver.kt | 39 +- .../kotlin/fir/resolve/calls/Arguments.kt | 23 +- .../fir/resolve/calls/ConeInferenceContext.kt | 14 +- .../fir/resolve/calls/InferenceCompletion.kt | 4 +- .../fir/resolve/dfa/FirDataFlowAnalyzer.kt | 12 +- .../ConeConditionalEffectToFirVisitor.kt | 8 +- .../fir/resolve/diagnostics/FirDiagnostics.kt | 6 + .../fir/resolve/diagnostics/FirErrors.kt | 2 + .../ErrorNodeDiagnosticCollectorComponent.kt | 1 + .../fir/resolve/inference/FirCallCompleter.kt | 10 +- .../resolve/substitution/ConeSubstitutor.kt | 1 + ...rCallCompletionResultsWriterTransformer.kt | 140 +++++-- ...egerLiteralTypeApproximationTransformer.kt | 203 ++++++++++ .../FirAbstractBodyResolveTransformer.kt | 7 +- ...ControlFlowStatementsResolveTransformer.kt | 11 +- .../FirDeclarationsResolveTransformer.kt | 18 +- .../FirExpressionsResolveTransformer.kt | 80 ++-- .../scopes/impl/FirIntegerLiteralTypeScope.kt | 173 +++++++++ .../kotlin/fir/types/ConeTypeContext.kt | 21 +- .../resolve/arguments/integerLiteralTypes.kt | 48 +++ .../resolve/arguments/integerLiteralTypes.txt | 66 ++++ .../arguments/operatorsOverLiterals.kt | 69 ++++ .../arguments/operatorsOverLiterals.txt | 79 ++++ .../testData/resolve/cfg/binaryOperations.dot | 8 +- .../testData/resolve/cfg/binaryOperations.txt | 8 +- .../cfg/booleanOperatorsWithConsts.dot | 16 +- .../cfg/booleanOperatorsWithConsts.txt | 16 +- .../resolve/testData/resolve/cfg/complex.dot | 348 +++++++++--------- .../resolve/cfg/propertiesAndInitBlocks.dot | 2 +- .../resolve/cfg/propertiesAndInitBlocks.txt | 2 +- .../resolve/cfg/returnValuesFromLambda.dot | 4 +- .../resolve/cfg/returnValuesFromLambda.txt | 4 +- .../resolve/delegatingConstructorCall.kt | 11 + .../resolve/delegatingConstructorCall.txt | 37 ++ .../resolve/exhaustiveness_boolean.txt | 2 +- .../resolve/testData/resolve/localObject.kt | 2 +- .../resolve/testData/resolve/localObject.txt | 2 +- .../resolve/multifile/Annotations.txt | 4 +- .../testData/resolve/smartcasts/safeCalls.dot | 4 +- .../testData/resolve/smartcasts/safeCalls.txt | 2 +- .../resolve/stdlib/implicitReceiverOrder.txt | 8 +- .../j+k/KJKComplexHierarchyWithNested.kt | 2 +- .../j+k/KJKComplexHierarchyWithNested.txt | 2 +- .../stdlib/multipleImplicitReceivers.txt | 6 +- .../stdlib/problems/tryWithLambdaInside.txt | 2 +- .../testData/resolve/stdlib/rangeTo.kt | 11 + .../testData/resolve/stdlib/rangeTo.txt | 11 + .../fir/FirDiagnosticsTestGenerated.java | 10 + ...FirDiagnosticsWithStdlibTestGenerated.java | 5 + .../kotlin/fir/declarations/FirField.kt | 2 + .../kotlin/fir/declarations/FirProperty.kt | 2 + .../fir/declarations/FirValueParameter.kt | 2 + .../kotlin/fir/declarations/FirVariable.kt | 2 + .../impl/FirDefaultSetterValueParameter.kt | 7 +- .../fir/declarations/impl/FirFieldImpl.kt | 4 + .../impl/FirModifiableVariable.kt | 2 + .../fir/declarations/impl/FirPropertyImpl.kt | 7 +- .../impl/FirValueParameterImpl.kt | 7 +- .../fir/expressions/FirConstExpression.kt | 5 +- .../fir/expressions/FirReturnExpression.kt | 4 + .../impl/FirConstExpressionImpl.kt | 8 +- .../expressions/impl/FirFunctionCallImpl.kt | 2 +- .../impl/FirReturnExpressionImpl.kt | 12 +- .../kotlin/fir/expressions/FirConstKind.kt | 49 +++ .../fir/expressions/FirExpressionUtil.kt | 2 +- .../fir/types/ConeIntegerLiteralTypeImpl.kt | 127 +++++++ .../kotlin/fir/types/FirTypeUtils.kt | 10 +- .../generator/ImplementationConfigurator.kt | 1 + .../fir/tree/generator/NodeConfigurator.kt | 7 +- .../kotlin/fir/tree/generator/Types.kt | 3 +- .../components/ResultTypeResolver.kt | 11 +- .../codegen/box/boxingOptimization/kt5588.kt | 1 + .../capturedInInlineOnlyAssign.kt | 1 - .../capturedInInlineOnlyCAO.kt | 1 - .../breakContinueInExpressions/popSizes.kt | 1 - .../tryCatchInExpressions/differentTypes.kt | 1 - .../functions/tailRecursion/sum.kt | 1 - .../codegen/box/fullJdk/native/topLevel.kt | 1 - .../lessDouble_properIeeeAndNewInference.kt | 2 +- .../box/innerNested/createNestedClass.kt | 2 +- .../equalityWithObject/whenNullableBoxed.kt | 1 - .../codegen/box/primitiveTypes/kt3078.kt | 1 + .../codegen/box/primitiveTypes/kt665.kt | 2 +- .../box/primitiveTypes/unboxComparable.kt | 1 + .../lateinit/local/localLateinit.kt | 1 - .../lateinit/topLevel/topLevelLateinit.kt | 1 - .../comparisonWithRangeBoundEliminated.kt | 1 - .../testData/codegen/box/strings/kt889.kt | 1 + .../codegen/box/synchronized/changeMonitor.kt | 1 - .../codegen/box/synchronized/finally.kt | 1 - .../synchronized/nestedDifferentObjects.kt | 1 - .../box/synchronized/nestedSameObject.kt | 1 - .../testData/codegen/box/synchronized/wait.kt | 1 - .../testData/codegen/box/when/longInRange.kt | 1 - ...icConstructorCallWithTypeArguments.fir.txt | 13 +- .../ir/irText/expressions/literals.fir.txt | 6 +- .../primitivesImplicitConversions.fir.txt | 8 +- .../expressions/whenUnusedExpression.fir.txt | 4 +- .../lambdas/multipleImplicitReceivers.fir.txt | 12 +- .../compiler/visualizer/FirVisualizer.kt | 2 +- .../fir/lazyResolve/import/bar/bar.txt | 2 +- .../testData/fir/lazyResolve/inLocal/main.txt | 4 +- .../fir/lazyResolve/simple/callMe.txt | 2 +- 145 files changed, 1815 insertions(+), 585 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt create mode 100644 compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.kt create mode 100644 compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.txt create mode 100644 compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.kt create mode 100644 compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.txt create mode 100644 compiler/fir/resolve/testData/resolve/stdlib/rangeTo.kt create mode 100644 compiler/fir/resolve/testData/resolve/stdlib/rangeTo.txt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirConstKind.kt create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt index 739f8b0aa93..62bd6bfffe1 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/symbols/StandardClassIds.kt @@ -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() diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index 10bf997c597..e200e3009ee 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -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 + abstract val supertypes: List + + override val typeArguments: Array = 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 +} diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt index 17ab73f78a2..c8760e2f07a 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt @@ -46,6 +46,7 @@ fun ConeKotlinType.render(): String { ) } is ConeStubType -> "stub type: $variable" + is ConeIntegerLiteralType -> "ILT: $value" } + nullabilitySuffix } diff --git a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt index d0d8308c886..7f7a9566626 100644 --- a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt +++ b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt @@ -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()) { +"<" diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 7bfab4e9383..aa4e3ebefb7 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -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) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 0d1d73b41c5..3a0c0e52890 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -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 = 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 visitConstExpression(constExpression: FirConstExpression, data: Any?): IrElement { return constExpression.convertWithOffsets { startOffset, endOffset -> + @Suppress("UNCHECKED_CAST") + val kind = constExpression.getIrConstKind() as IrConstKind + @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 ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt index d34ecec632d..ab0291912a5 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt @@ -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() } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt.183 b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt.183 index 5f13cdebca7..df7a3aa9283 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt.183 +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/FirJavaElementFinder.kt.183 @@ -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() } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 179d96c91c5..56ab61fb3ae 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -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 List.createArrayOfCall(session: FirSession, @Suppress("UNUSED_PARAMETER") kind: IrConstKind): FirArrayOfCall { +private fun List.createArrayOfCall(session: FirSession, @Suppress("UNUSED_PARAMETER") kind: FirConstKind): FirArrayOfCall { return FirArrayOfCallImpl(null).apply { for (element in this@createArrayOfCall) { arguments += element.createConstant(session) @@ -285,24 +285,24 @@ private fun List.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)) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt index 0af2eead9eb..2f885952a90 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt @@ -111,4 +111,8 @@ class FirJavaField( get() = null override var containerSource: DeserializedContainerSource? = null + + override fun transformInitializer(transformer: FirTransformer, data: D): FirField { + return this + } } \ No newline at end of file diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 3365daf5b3a..da3238678e2 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -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 } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt index 0953942d45f..0108ce3fd87 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassEnhancementScope.kt @@ -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 } diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index fb953c89525..80d21688a4f 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -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(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(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(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()) } /** diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index 53eb282d5b8..31266b6ed70 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -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) diff --git a/compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.txt b/compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.txt index 848d81038e7..e6c02a95fc6 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.txt @@ -17,5 +17,5 @@ FILE: expectActual.kt public? final? actual fun foo(): { ^foo String(Hello) } - public? final? actual val x: = Int(42) + public? final? actual val x: = IntegerLiteral(42) public? get(): diff --git a/compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.txt b/compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.txt index dc4b7568277..9626811746e 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.txt @@ -11,7 +11,7 @@ FILE: simpleClass.kt super() } - private final? val baz: = Int(42) + private final? val baz: = IntegerLiteral(42) private get(): public? open? override fun foo(x: Int, y: String): String { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt b/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt index e2a8e767c7a..65c35350953 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.txt @@ -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): List { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt index 780b7b3eeab..411c53d339a 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt @@ -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| { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt index a4c2fef1518..da15cc1a463 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.txt @@ -1,8 +1,8 @@ FILE: arrayAccess.kt - public? final? val p: = Int(0) + public? final? val p: = IntegerLiteral(0) public? get(): public? final? fun foo(): { - ^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): { - ^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))) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.txt index 4594ef549f9..3957425d5e6 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.txt @@ -1,11 +1,11 @@ FILE: arrayAssignment.kt public? final? fun test(): R|kotlin/Unit| { - lval x: = intArrayOf#(Int(1), Int(2), Int(3)) - x#.set#(Int(1), Int(0)) + lval x: = intArrayOf#(IntegerLiteral(1), IntegerLiteral(2), IntegerLiteral(3)) + x#.set#(IntegerLiteral(1), IntegerLiteral(0)) } public? final? fun foo(): { - ^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)) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/branches.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/branches.txt index 3d7f4d3a8cb..ae6a890c6ea 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/branches.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/branches.txt @@ -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) -> { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/callableReferences.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/callableReferences.txt index ee1b1f931cc..ba46202eb7b 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/callableReferences.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/callableReferences.txt @@ -7,7 +7,7 @@ FILE: callableReferences.kt public? final? fun foo(): R|kotlin/Unit| { } - public? final? val bar: = Int(0) + public? final? val bar: = IntegerLiteral(0) public? get(): } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/calls.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/calls.txt index 367745fc256..b470a8011f6 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/calls.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/calls.txt @@ -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) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt index 753381c75cb..41bb97c524b 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.txt @@ -32,7 +32,7 @@ FILE: collectionLiterals.kt } } - @Ann1((Int(1), Int(2))) public? final? class First : R|kotlin/Any| { + @Ann1((IntegerLiteral(1), IntegerLiteral(2))) public? final? class First : R|kotlin/Any| { public? constructor(): R|First| { super() } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt index d53d208f667..a81070669d8 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt @@ -1,6 +1,6 @@ FILE: for.kt public? final? fun foo(): R|kotlin/Unit| { - lval : = Int(1).rangeTo#(Int(10)) + lval : = IntegerLiteral(1).rangeTo#(IntegerLiteral(10)) lval : = R|/|.iterator#() while(R|/|.hasNext#()) { lval i: = R|/|.next#() @@ -9,14 +9,14 @@ FILE: for.kt } public? final? fun bar(list: List): R|kotlin/Unit| { - lval : = list#.subList#(Int(0), Int(10)) + lval : = list#.subList#(IntegerLiteral(0), IntegerLiteral(10)) lval : = R|/|.iterator#() while(R|/|.hasNext#()) { lval element: = R|/|.next#() println#(element#) } - lval : = list#.subList#(Int(10), Int(20)) + lval : = list#.subList#(IntegerLiteral(10), IntegerLiteral(20)) lval : = R|/|.iterator#() while(R|/|.hasNext#()) { lval element: = R|/|.next#() diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt index 281162e5ca3..e2a128867b8 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt @@ -23,7 +23,7 @@ FILE: lambda.kt } public? final? inline fun use(f: ( (Tuple) -> Int )): { - ^use f#(Tuple#(Int(1), Int(2))) + ^use f#(Tuple#(IntegerLiteral(1), IntegerLiteral(2))) } public? final? fun foo(): Int { lval l1: = fun .(t: Tuple): { @@ -40,8 +40,8 @@ FILE: lambda.kt ) ^foo use#( = use@fun .(): { 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#( = lambda@fun .(): { when () { - ==(it#.x#, Int(0)) -> { - ^bar Int(0) + ==(it#.x#, IntegerLiteral(0)) -> { + ^bar IntegerLiteral(0) } } @@ -77,7 +77,7 @@ FILE: lambda.kt public? get(): public? final? val another: = fun .(): { - Int(42) + IntegerLiteral(42) } public? get(): diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.txt index aa0b3eea139..30f29648689 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.txt @@ -14,7 +14,7 @@ FILE: lambdaAndAnonymousFunction.kt } public? final? fun test_2(): R|kotlin/Unit| { run#(fun (): Int { - ^ Int(1) + ^ IntegerLiteral(1) } ) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/locals.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/locals.txt index 29d6b43549f..c34a0f3148f 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/locals.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/locals.txt @@ -14,7 +14,7 @@ FILE: locals.kt } - lval x: = Local#(Int(42)).diff#() + lval x: = 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 (x: Int, y: Int): { + ^withLocals sum#(code#, Local#(IntegerLiteral(1)).diff#(), fun (x: Int, y: Int): { ^ x#.plus#(y#) } ) diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/modifications.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/modifications.txt index 86b23db054b..0e5169c6d6d 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/modifications.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/modifications.txt @@ -1,15 +1,15 @@ FILE: modifications.kt public? final? fun simple(): R|kotlin/Unit| { - lvar x: = Int(10) - +=(x#, Int(20)) - -=(x#, Int(5)) - /=(x#, Int(5)) - *=(x#, Int(10)) + lvar x: = IntegerLiteral(10) + +=(x#, IntegerLiteral(20)) + -=(x#, IntegerLiteral(5)) + /=(x#, IntegerLiteral(5)) + *=(x#, IntegerLiteral(10)) } public? final? fun List.modify(): R|kotlin/Unit| { +=(this#, String(Alpha)) +=(this#, String(Omega)) } public? final? fun Any.modify(): R|kotlin/Unit| { - +=((this# as List), Int(42)) + +=((this# as List), IntegerLiteral(42)) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt index 077f1c780d6..0a86e2ffa67 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt @@ -2,7 +2,7 @@ FILE: nullability.kt public? final? fun orFourtyTwo(arg: Int?): { ^orFourtyTwo when (lval : = arg#) { ==($subj$, Null(null)) -> { - Int(42) + IntegerLiteral(42) } else -> { R|/| diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt index 7fd039d8852..f2d854922b2 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/these.txt @@ -5,7 +5,7 @@ FILE: these.kt } public? final? fun foo(): Int { - ^foo Int(1) + ^foo IntegerLiteral(1) } public? final? fun bar(): Int { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt index e553661738f..e9f84a112d0 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt @@ -1,6 +1,6 @@ FILE: unary.kt public? final? fun test(): R|kotlin/Unit| { - lvar x: = Int(0) + lvar x: = IntegerLiteral(0) lval x1: = { lval : = x# x# = R|/|.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): R|kotlin/Unit| { lval x1: = { - lval : = arr#.get#(Int(0)) - arr#.set#(Int(0), R|/|.inc#()) + lval : = arr#.get#(IntegerLiteral(0)) + arr#.set#(IntegerLiteral(0), R|/|.inc#()) R|/| } lval x2: = { - lval : = arr#.get#(Int(1)) + lval : = arr#.get#(IntegerLiteral(1)) lval : = R|/|.inc#() - arr#.set#(Int(1), R|/|) + arr#.set#(IntegerLiteral(1), R|/|) R|/| } @@ -82,15 +82,15 @@ FILE: unary.kt } public? final? fun test4(y: Y): R|kotlin/Unit| { lval x1: = { - lval : = y#.arr#.get#(Int(0)) - y#.arr#.set#(Int(0), R|/|.inc#()) + lval : = y#.arr#.get#(IntegerLiteral(0)) + y#.arr#.set#(IntegerLiteral(0), R|/|.inc#()) R|/| } lval x2: = { - lval : = y#.arr#.get#(Int(1)) + lval : = y#.arr#.get#(IntegerLiteral(1)) lval : = R|/|.inc#() - y#.arr#.set#(Int(1), R|/|) + y#.arr#.set#(IntegerLiteral(1), R|/|) R|/| } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/variables.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/variables.txt index 693d9151568..e850a6a385b 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/variables.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/variables.txt @@ -1,8 +1,8 @@ FILE: variables.kt public? final? fun foo(): R|kotlin/Unit| { - lval x: = Int(1) - lvar y: = x#.plus#(Int(1)) - lval z: = y#.times#(Int(2)) + lval x: = IntegerLiteral(1) + lvar y: = x#.plus#(IntegerLiteral(1)) + lval z: = y#.times#(IntegerLiteral(2)) y# = y#.plus#(z#) lval w: = y#.minus#(x#) ^foo w# diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt index 7a6125889fa..b04bb764ed1 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt @@ -1,12 +1,12 @@ FILE: while.kt public? final? fun foo(limit: Int): R|kotlin/Unit| { - lvar k: = Int(0) + lvar k: = IntegerLiteral(0) some@while(<(k#, limit#)) { lval : = k# k# = R|/|.inc#() R|/| println#(k#) - while(==(k#, Int(13))) { + while(==(k#, IntegerLiteral(13))) { lval : = k# k# = R|/|.inc#() R|/| @@ -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|/| println#(k#) } - while(>=(k#, Int(0))) + while(>=(k#, IntegerLiteral(0))) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt index cc2e2b0f3b8..24f3765f694 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt @@ -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 = 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) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index c0df308e4a9..7ec355a763f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -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() != 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) + + 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 resolveVariableAccessAndSelectCandidate(qualifiedAccess: T, file: FirFile): FirStatement { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/SessionUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/SessionUtils.kt index 6becf48253a..b757bf7bbea 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/SessionUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/SessionUtils.kt @@ -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) \ No newline at end of file +val FirSession.typeContext: ConeInferenceContext get() = SessionBasedTypeContext(this) \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt index fea3f0223ab..2dd00d92514 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/AbstractAnnotationDeserializer.kt @@ -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 const(kind: IrConstKind, value: T) = FirConstExpressionImpl(null, kind, value) + private fun const(kind: FirConstKind, value: T) = FirConstExpressionImpl(null, kind, value) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index ddcec92d5af..92daa0b1965 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -224,6 +224,7 @@ fun 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}") } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index c3bd97d0ede..b7491df806c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -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 } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt index df367d932a7..abebb86a378 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ScopeUtils.kt @@ -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") } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt index 1df69e8d11c..cab3b1d0324 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SessionHolder.kt @@ -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 AbstractFirBasedSymbol.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner get() = phasedFir(session, FirResolvePhase.DECLARATIONS) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt index e06189fe364..999edfb98c7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractConeCallConflictResolver.kt @@ -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 { return when (val declaration = call.symbol.fir) { is FirSimpleFunction -> createFlatSignature(call, declaration) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt index 3ba25d6dd5d..a07671c91f7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Arguments.kt @@ -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() + /* + * 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() ?: 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) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt index 4d078f15544..d298091f024 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt @@ -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? { - // TODO: implement - return null + return ConeIntegerLiteralTypeImpl.findCommonSuperType(explicitSupertypes) + } + + override fun TypeConstructorMarker.getApproximatedIntegerLiteralType(): KotlinTypeMarker { + require(this is ConeIntegerLiteralType) + return this.getApproximatedType() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt index 631d80bc0ad..9553c1bce0c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/InferenceCompletion.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 2d88cb065a2..558a49b2bf2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -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() + 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() 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() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/contracts/ConeConditionalEffectToFirVisitor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/contracts/ConeConditionalEffectToFirVisitor.kt index 3060802ca2e..abbc79e83a4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/contracts/ConeConditionalEffectToFirVisitor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/contracts/ConeConditionalEffectToFirVisitor.kt @@ -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>() { @@ -21,8 +21,8 @@ private object ConeConditionalEffectToFirVisitor : ConeContractDescriptionVisito override fun visitConstantDescriptor(constantReference: ConeConstantReference, data: Map): 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): FirExpression? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index e6f6237c5e3..31640509b46 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -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() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirErrors.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirErrors.kt index 8e11b7830a3..b3593e2b591 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirErrors.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirErrors.kt @@ -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(ERROR) val ERROR_FROM_JAVA_RESOLUTION = DiagnosticFactory0.create(ERROR) val OTHER_ERROR = DiagnosticFactory0.create(ERROR) + val TYPE_MISMATCH = DiagnosticFactory2.create(ERROR) init { val klass = FirErrors::class diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 83265a60af9..32d00d50d6c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -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}") diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index 4fef5ca0ff3..b73b605ca0e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -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( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt index 83f3d8bddd2..c8dd9531988 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/substitution/ConeSubstitutor.kt @@ -70,6 +70,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() { is ConeDefinitelyNotNullType -> this.substituteOriginal() is ConeIntersectionType -> this.substituteIntersectedTypes() is ConeStubType -> return null + is ConeIntegerLiteralType -> return null } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 344602e9b83..22fc89692cb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -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(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { + private val typeApproximator: AbstractTypeApproximator, + private val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater, + private val integerApproximator: IntegerLiteralTypeApproximationTransformer +) : FirAbstractTreeTransformer(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { override fun transformQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, - data: Nothing? + data: ExpectedArgumentType? ): CompositeTransformResult { 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 { - 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 { val calleeReference = variableAssignment.calleeReference as? FirNamedReferenceWithCandidate ?: return variableAssignment.compose() @@ -134,9 +139,8 @@ class FirCallCompletionResultsWriterTransformer( ).compose() } - override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult { + override fun transformFunctionCall(functionCall: FirFunctionCall, data: ExpectedArgumentType?): CompositeTransformResult { 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().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() + .let { substitutor.substituteOrSelf(it) } + .let { finalSubstitutor.substituteOrSelf(it) } + + argument.expandArgument() to expectedType + } + ?.toMap()?.toExpectedType() } override fun transformDelegatedConstructorCall( delegatedConstructorCall: FirDelegatedConstructorCall, - data: Nothing? + data: ExpectedArgumentType? ): CompositeTransformResult { 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 { + val expectedReturnType = data?.getExpectedType(anonymousFunction) + ?.takeIf { it.isBuiltinFunctionalType } + ?.let { it.typeArguments.last() as? ConeClassLikeType } + val initialType = anonymousFunction.returnTypeRef.coneTypeSafe() 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 { + override fun transformBlock(block: FirBlock, data: ExpectedArgumentType?): CompositeTransformResult { val initialType = block.resultType.coneTypeSafe() if (initialType != null) { val finalType = finalSubstitutor.substituteOrNull(initialType) - val resultType = block.resultType.withReplacedConeType(finalType) + var resultType = block.resultType.withReplacedConeType(finalType) + resultType.coneTypeSafe()?.let { + resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block))) + } block.replaceTypeRef(resultType) } return transformElement(block, data) } - override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Nothing?): CompositeTransformResult { + override fun transformWhenExpression(whenExpression: FirWhenExpression, data: ExpectedArgumentType?): CompositeTransformResult { 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 { + override fun transformTryExpression(tryExpression: FirTryExpression, data: ExpectedArgumentType?): CompositeTransformResult { 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 transformConstExpression( + constExpression: FirConstExpression, + data: ExpectedArgumentType? + ): CompositeTransformResult { + 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) : 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.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 +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt new file mode 100644 index 00000000000..44dabb0a135 --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/IntegerLiteralTypeApproximationTransformer.kt @@ -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() { + override fun transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult { + return element.compose() + } + + override fun transformConstExpression( + constExpression: FirConstExpression, + data: ConeKotlinType? + ): CompositeTransformResult { + val type = constExpression.resultType.coneTypeSafe() ?: return constExpression.compose() + val approximatedType = type.getApproximatedType(data) + constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(approximatedType) + @Suppress("UNCHECKED_CAST") + val kind = approximatedType.toConstKind() as FirConstKind + constExpression.replaceKind(kind) + return constExpression.compose() + } + + override fun transformFunctionCall(functionCall: FirFunctionCall, data: ConeKotlinType?): CompositeTransformResult { + val operator = functionCall.toResolvedCallableSymbol()?.fir as? FirIntegerOperator ?: return functionCall.compose() + functionCall.transformChildren(this, data) + val argumentType = functionCall.arguments.firstOrNull()?.resultType?.coneTypeUnsafe() + val receiverClassId = functionCall.dispatchReceiver.typeRef.coneTypeUnsafe().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() + 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 { + if (operatorCall.operation !in FirOperation.BOOLEANS) return operatorCall.compose() + val leftArgument = operatorCall.arguments[0] + val rightArgument = operatorCall.arguments[1] + + val leftIsIlt = leftArgument.typeRef.coneTypeSafe() != null + val rightIsIlt = rightArgument.typeRef.coneTypeSafe() != 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 { + 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() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + return element.compose() + } + + override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult { + val function: FirCallableDeclaration<*> = functionCall.getOriginalFunction() ?: return functionCall.compose() + + if (function !is FirIntegerOperator) { + val expectedType = function.receiverTypeRef?.coneTypeSafe() + return functionCall.transformExplicitReceiver(approximator, expectedType).compose() + } + // TODO: maybe unsafe? + val receiverValue = functionCall.explicitReceiver!!.typeRef.coneTypeSafe()?.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() + // 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 + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index beb3cd235cf..065630fb6f4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 1d9ed9a8c64..6b3bfb44fb8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -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 transformJump(jump: FirJump, data: ResolutionMode): CompositeTransformResult { - val result = transformer.transformExpression(jump, data) + var result = transformer.transformExpression(jump, data).single + if (result is FirReturnExpression) { + val expectedType = result.target.labeledElement.returnTypeRef.coneTypeSafe() + result = result.transformResult(integerLiteralTypeApproximator, expectedType) + } dataFlowAnalyzer.exitJump(jump) - return result + return result.compose() } override fun transformThrowExpression(throwExpression: FirThrowExpression, data: ResolutionMode): CompositeTransformResult { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 04b4d4f033e..355bb2e9894 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -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 { 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 > FirVariable.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()?.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)) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 77b3b30f5fa..84a689dace3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -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 { 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 { 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 transformConstExpression(constExpression: FirConstExpression, data: ResolutionMode): CompositeTransformResult { - // 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() + if (expectedType != null) { + val approximatedType = integerLiteralType.getApproximatedType(expectedType) + val newConstKind = approximatedType.toConstKind() + if (newConstKind == null) { + constExpression.replaceKind(FirConstKind.Int as FirConstKind) + dataFlowAnalyzer.exitConstExpresion(constExpression as FirConstExpression<*>) + constExpression.resultType = FirErrorTypeRefImpl( + constExpression.source, + FirTypeMismatchError(expectedType, integerLiteralType.getApproximatedType()) + ) + return constExpression.compose() + } + constExpression.replaceKind(newConstKind as FirConstKind) + 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 { 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) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt new file mode 100644 index 00000000000..59314261acb --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt @@ -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() { + override fun toLookupTag(): ConeClassifierLookupTag { + throw IllegalStateException("Should not be called") + } +} + +private object FirIntegerLiteralTypeClassifier : FirDeclaration, FirSymbolOwner { + override val symbol: AbstractFirBasedSymbol + 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 accept(visitor: FirVisitor, data: D): R { + throw IllegalStateException("Should not be called") + } + + override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { + throw IllegalStateException("Should not be called") + } + + override fun acceptChildren(visitor: FirVisitor, data: D) { + throw IllegalStateException("Should not be called") + } + + override fun transformChildren(transformer: FirTransformer, 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() + } + + 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 +) : 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 get() = emptyList() + override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0) + override val delegatedTypeRef: FirTypeRef? get() = null + + override fun acceptChildren(visitor: FirVisitor, data: D) {} + + override fun transformChildren(transformer: FirTransformer, data: D): FirElement { + return this + } +} + +class FirIntegerOperatorCall(source: FirSourceElement?) : FirFunctionCallImpl(source) \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index fe3ffce2f4d..76042483d57 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -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 { - TODO("not implemented") + return (this as? ConeIntegerLiteralType)?.possibleTypes ?: emptyList() } override fun SimpleTypeMarker.fastCorrespondingSupertypes(constructor: TypeConstructorMarker): List? { 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) diff --git a/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.kt b/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.kt new file mode 100644 index 00000000000..99a2eb9fdc6 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.kt @@ -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() { + takeInt(10000000000) + takeLong(10000000000) + 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() { + takeString(1) + takeString(run { 1 }) +} + +annotation class Ann(val x: Byte) + +@Ann(10) +fun test_6() { + @Ann(300) + val x = "" +} diff --git a/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.txt b/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.txt new file mode 100644 index 00000000000..8c8d83c494e --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/integerLiteralTypes.txt @@ -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| { + #(Long(10000000000)) + R|/takeLong|(Long(10000000000)) + #(Int(1000)) + } + public final fun test_3(): R|kotlin/Unit| { + R|/takeInt|(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(1) + } + )) + R|/takeByte|(R|kotlin/run|( = run@fun (): R|kotlin/Byte| { + Int(1) + } + )) + R|/takeLong|(R|kotlin/run|( = run@fun (): R|kotlin/Long| { + Int(1) + } + )) + } + public final fun test_4(): R|kotlin/Unit| { + R|/takeAny|(Int(1)) + R|/takeAny|(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(1) + } + )) + } + public final fun test_5(): R|kotlin/Unit| { + #(Int(1)) + #(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(1) + } + )) + } + public final annotation class Ann : R|kotlin/Annotation| { + public constructor(x: R|kotlin/Byte|): R|Ann| { + super() + } + + public final val x: R|kotlin/Byte| = R|/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() + } diff --git a/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.kt b/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.kt new file mode 100644 index 00000000000..b8e51b8eaff --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.kt @@ -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) + takeByte(1 + 127) + takeByte(1 - 1) + takeByte(-100 - 100) + takeByte(10 * 10) + takeByte(100 * 100) + taleByte(10 / 10) + takeByte(100 % 10) + takeByte(1000 % 10) + takeByte(1000 and 100) + takeByte(128 and 511) + takeByte(100 or 100) + takeByte(1000 or 0) + takeByte(511 xor 511) + takeByte(512 xor 511) +} + +fun test_5() { + takeByte(-1) + takeByte(+1) + takeByte(1.inv()) +} + +fun test_6() { + takeByte(run { 127 + 1 }) + takeByte(1 + 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 +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.txt b/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.txt new file mode 100644 index 00000000000..c02587b777d --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/operatorsOverLiterals.txt @@ -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|/n|) + lval y: R|kotlin/Int| = R|/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))) + #(Int(1).R|kotlin/Int.plus|(Int(127))) + R|/takeByte|(Byte(1).R|kotlin/Byte.minus|(Byte(1))) + #(Int(100).R|kotlin/Int.unaryMinus|().R|kotlin/Int.minus|(Int(100))) + R|/takeByte|(Byte(10).R|kotlin/Byte.times|(Byte(10))) + #(Int(100).R|kotlin/Int.times|(Int(100))) + #(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|/and|(Byte(100))) + #(Int(128).R|kotlin/Int.and|(Int(511))) + R|/takeByte|(Byte(100).R|/or|(Byte(100))) + #(Int(1000).R|kotlin/Int.or|(Int(0))) + R|/takeByte|(Int(511).R|kotlin/Int.xor|(Int(511))) + #(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|/inv|()) + } + public final fun test_6(): R|kotlin/Unit| { + #(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(127).R|kotlin/Int.plus|(Int(1)) + } + )) + #(Int(1).#(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(1) + } + ))) + R|/takeByte|(R|kotlin/run|( = run@fun (): R|kotlin/Byte| { + Int(1).R|kotlin/Int.plus|(Int(1)) + } + )) + Int(1).R|kotlin/Int.plus|(Int(1)) + R|kotlin/run|( = run@fun (): R|kotlin/Int| { + Int(1) + } + ) + Int(1).R|/plus|(R|kotlin/run|( = run@fun (): R|kotlin/Int| { + 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|/d|) + lval x2: R|kotlin/Double| = R|/d|.R|kotlin/Double.plus|(Int(1)) + } diff --git a/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.dot b/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.dot index 6cc77e1bd41..ba61f8f1289 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.dot @@ -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"]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.txt b/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.txt index 180f171f7a4..7e5f7644c45 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/binaryOperations.txt @@ -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|/b1| || R|/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|/b1| && R|/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|/b1| && R|/b2| || R|/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|/b1| || R|/b2| && R|/b3| -> { - Int(1) + IntegerLiteral(1) } } diff --git a/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.dot b/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.dot index ad07c5e717c..80a8ff1c1f4 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.dot @@ -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"]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.txt b/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.txt index 176c8294695..69ea37239be 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/booleanOperatorsWithConsts.txt @@ -2,7 +2,7 @@ FILE: booleanOperatorsWithConsts.kt public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| { when () { R|/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|/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|/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|/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|/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|/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|/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|/b| -> { - Int(1) + IntegerLiteral(1) } } diff --git a/compiler/fir/resolve/testData/resolve/cfg/complex.dot b/compiler/fir/resolve/testData/resolve/cfg/complex.dot index 31f9a629d59..6eab838f8be 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/complex.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/complex.dot @@ -28,7 +28,7 @@ digraph complex_kt { 14 [label="Access variable R|/url|"]; 15 [label="Access variable R|/url|"]; 16 [label="Function call: #.#(R|/url|)"]; - 17 [label="Function call: #.#(R|/url|).#( = connect@fun (): { + 17 [label="Function call: #.#(R|/url|).#( = connect@fun (): R|class error: Unresolved name: fromJson| { #().#().#(#.#.#(), (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|/syntaxException|"]; - 24 [label="Const: String(Can't parse json response)"]; + 24 [label="Access variable R|/syntaxException|"]; 25 [label="Access variable R|/syntaxException|"]; - 26 [label="Const: String(Can't parse json response)"]; - 27 [label="Access variable R|/syntaxException|"]; - 28 [label="Function call: #(String(Can't parse json response), R|/syntaxException|)"]; - 29 [label="Throw: throw #(String(Can't parse json response), R|/syntaxException|)"]; - 30 [label="Stub" style="filled" fillcolor=gray]; - 31 [label="Exit block" style="filled" fillcolor=gray]; + 26 [label="Function call: #(String(Can't parse json response), R|/syntaxException|)"]; + 27 [label="Throw: throw #(String(Can't parse json response), R|/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|/ioException|"]; + 34 [label="Access variable R|/ioException|"]; 35 [label="Access variable R|/ioException|"]; - 36 [label="Access variable R|/ioException|"]; - 37 [label="Access variable R|/ioException|"]; - 38 [label="Function call: #(R|/ioException|)"]; - 39 [label="Throw: throw #(R|/ioException|)"]; - 40 [label="Stub" style="filled" fillcolor=gray]; - 41 [label="Exit block" style="filled" fillcolor=gray]; + 36 [label="Function call: #(R|/ioException|)"]; + 37 [label="Throw: throw #(R|/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|"]; - 45 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red]; + 42 [label="Variable declaration: lval pluginDTOs: R|kotlin/Array|"]; + 43 [label="Exit function fetchPluginReleaseDate" style="filled" fillcolor=red]; } subgraph cluster_8 { color=blue - 46 [label="Enter annotation"]; - 47 [label="Access variable #"]; - 48 [label="Access variable #"]; - 49 [label="Exit annotation"]; + 44 [label="Enter annotation"]; + 45 [label="Access variable #"]; + 46 [label="Access variable #"]; + 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: #()"]; - 52 [label="Function call: #().#()"]; - 53 [label="Access variable #"]; - 54 [label="Access variable #"]; - 55 [label="Function call: #.#.#()"]; + 48 [label="Enter function anonymousFunction" style="filled" fillcolor=red]; + 49 [label="Function call: #()"]; + 50 [label="Function call: #().#()"]; + 51 [label="Access variable #"]; + 52 [label="Access variable #"]; + 53 [label="Function call: #.#.#()"]; + 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: #().#().#(#.#.#(), (Q|kotlin/Array|).R|kotlin/jvm/java|)"]; - 60 [label="Exit function anonymousFunction" style="filled" fillcolor=red]; + 57 [label="Function call: #().#().#(#.#.#(), (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|/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|/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|/cause|"]; - 88 [label="Access variable R|/closeException|"]; - 89 [label="Function call: R|/cause|.R|kotlin/addSuppressed|(R|/closeException|)"]; - 90 [label="Exit block"]; + 84 [label="Enter block"]; + 85 [label="Access variable R|/cause|"]; + 86 [label="Access variable R|/closeException|"]; + 87 [label="Function call: R|/cause|.R|kotlin/addSuppressed|(R|/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|/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 : R|kotlin/sequences/Sequence<*>|"]; - 111 [label="Access variable R|/|"]; - 112 [label="Function call: R|/|.R|FakeOverride|>|()"]; - 113 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; + 106 [label="Enter function firstIsInstanceOrNull" style="filled" fillcolor=red]; + 107 [label="Access variable this@R|/firstIsInstanceOrNull|"]; + 108 [label="Variable declaration: lval : R|kotlin/sequences/Sequence<*>|"]; + 109 [label="Access variable R|/|"]; + 110 [label="Function call: R|/|.R|FakeOverride|>|()"]; + 111 [label="Variable declaration: lval : R|kotlin/collections/Iterator|"]; 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|/|"]; - 117 [label="Function call: R|/|.R|kotlin/collections/Iterator.hasNext|()"]; - 118 [label="Exit loop condition"]; + 113 [label="Enter loop condition"]; + 114 [label="Access variable R|/|"]; + 115 [label="Function call: R|/|.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|/|"]; - 122 [label="Function call: R|/|.R|FakeOverride|()"]; - 123 [label="Variable declaration: lval element: R|kotlin/Any?|"]; + 118 [label="Enter block"]; + 119 [label="Access variable R|/|"]; + 120 [label="Function call: R|/|.R|FakeOverride|()"]; + 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|/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|/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|/element|"]; - 133 [label="Jump: ^firstIsInstanceOrNull R|/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|/element|"]; + 131 [label="Jump: ^firstIsInstanceOrNull R|/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]; } diff --git a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot index bc4ace1851d..43f5e0cc975 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.dot @@ -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"]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.txt b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.txt index 2416514e27b..7b4fc3f05da 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/propertiesAndInitBlocks.txt @@ -52,7 +52,7 @@ FILE: propertiesAndInitBlocks.kt Int(2) } finally { - Int(0) + IntegerLiteral(0) } public get(): R|kotlin/Int| diff --git a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot index 92bd357e2f9..dd463f567ef 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot +++ b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.dot @@ -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|( = run@fun (): R|C| { + 21 [label="Function call: R|kotlin/run|( = run@fun (): R|A| { when () { R|/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|( = run@fun (): R|kotlin/Unit| { + 38 [label="Function call: R|kotlin/run|( = run@fun (): R|kotlin/Nothing| { ^test_3 Unit } )" style="filled" fillcolor=gray]; diff --git a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.txt b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.txt index cbb5a51225c..04c3db6d453 100644 --- a/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.txt +++ b/compiler/fir/resolve/testData/resolve/cfg/returnValuesFromLambda.txt @@ -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|( = run@fun (): R|C| { + lval x: R|A| = R|kotlin/run|( = run@fun (): R|A| { when () { R|/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|( = run@fun (): R|kotlin/Unit| { + lval x: R|kotlin/Nothing| = R|kotlin/run|( = run@fun (): R|kotlin/Nothing| { ^test_3 Unit } ) diff --git a/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.kt b/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.kt index a3a5326a4f5..572fe555b15 100644 --- a/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.kt +++ b/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.kt @@ -14,3 +14,14 @@ class B3_1 : A3("") class B3_2 : A3("", "asas") class B3_3 : A3("", true) class B3_4 : 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) \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.txt b/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.txt index f26f5924f6f..710189d1fbf 100644 --- a/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.txt +++ b/compiler/fir/resolve/testData/resolve/delegatingConstructorCall.txt @@ -74,3 +74,40 @@ FILE: delegatingConstructorCall.kt } } + public open class A4 : R|kotlin/Any| { + public constructor(x: R|kotlin/Byte|): R|A4| { + super() + } + + public final val x: R|kotlin/Byte| = R|/x| + public get(): R|kotlin/Byte| + + } + public final class B4 : R|A4| { + public constructor(): R|B4| { + super(Byte(1).R|kotlin/Byte.plus|(Byte(1))) + } + + } + public open class A5 : R|kotlin/Any| { + public constructor(x: R|kotlin/Byte|): R|A5| { + super() + } + + public constructor(x: R|kotlin/Short|): R|A5| { + super() + } + + } + public final class B5_1 : R|A5| { + public constructor(): R|B5_1| { + super(Short(1).R|kotlin/Short.plus|(Short(1))) + } + + } + public final class B5_2 : R|A5| { + public constructor(): R|B5_2| { + super(Short(100).R|kotlin/Short.times|(Short(2))) + } + + } diff --git a/compiler/fir/resolve/testData/resolve/exhaustiveness_boolean.txt b/compiler/fir/resolve/testData/resolve/exhaustiveness_boolean.txt index 72efeabf878..c1f2c998bc2 100644 --- a/compiler/fir/resolve/testData/resolve/exhaustiveness_boolean.txt +++ b/compiler/fir/resolve/testData/resolve/exhaustiveness_boolean.txt @@ -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|/b|) { ==($subj$, Boolean(true)) -> { - Int(1) + IntegerLiteral(1) } } diff --git a/compiler/fir/resolve/testData/resolve/localObject.kt b/compiler/fir/resolve/testData/resolve/localObject.kt index db4119be3b2..ff144f1d776 100644 --- a/compiler/fir/resolve/testData/resolve/localObject.kt +++ b/compiler/fir/resolve/testData/resolve/localObject.kt @@ -33,7 +33,7 @@ class TestProperty { return intConst + 1 } } - 1 + return 1 } val z = run { diff --git a/compiler/fir/resolve/testData/resolve/localObject.txt b/compiler/fir/resolve/testData/resolve/localObject.txt index 8deefc649e1..87c1b98e1e2 100644 --- a/compiler/fir/resolve/testData/resolve/localObject.txt +++ b/compiler/fir/resolve/testData/resolve/localObject.txt @@ -61,7 +61,7 @@ FILE: localObject.kt } - Int(1) + ^ Int(1) } public final val z: R|kotlin/Int| = R|/run|( = run@fun (): R|kotlin/Int| { diff --git a/compiler/fir/resolve/testData/resolve/multifile/Annotations.txt b/compiler/fir/resolve/testData/resolve/multifile/Annotations.txt index a9c5e19f823..9be8f2fbed9 100644 --- a/compiler/fir/resolve/testData/resolve/multifile/Annotations.txt +++ b/compiler/fir/resolve/testData/resolve/multifile/Annotations.txt @@ -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|/y| diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot index 99190369ed8..0868603d72e 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot +++ b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.dot @@ -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|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Unit| { + 75 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { ^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|/x|" style="filled" fillcolor=gray]; 79 [label="Function call: R|/x|.R|/A.bool|()" style="filled" fillcolor=gray]; - 80 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Unit| { + 80 [label="Function call: R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { ^test_5 Unit } )?.R|/boo|(R|/x|.R|/A.bool|())" style="filled" fillcolor=gray]; diff --git a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.txt b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.txt index 76d250e6eb2..fb80bfb393a 100644 --- a/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.txt +++ b/compiler/fir/resolve/testData/resolve/smartcasts/safeCalls.txt @@ -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|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Unit| { + R|/x|?.R|kotlin/let|( = let@fun (it: R|A|): R|kotlin/Nothing| { ^test_5 Unit } )?.R|/boo|(R|/x|.R|/A.bool|()) diff --git a/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt b/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt index 76e121c35cd..9a91e1a774d 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/implicitReceiverOrder.txt @@ -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|, = with@fun R|B|.(): R|kotlin/Unit| { - R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Unit| { + R|kotlin/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Int| { + R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Int| { this@R|/A|.R|/A.foo|() (this@R|/B|, this@R|special/anonymous|).R|/B.bar|() } ) } ) - R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Unit| { - R|kotlin/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Unit| { + R|kotlin/with|(R|/a|, = with@fun R|A|.(): R|kotlin/Int| { + R|kotlin/with|(R|/b|, = with@fun R|B|.(): R|kotlin/Int| { this@R|/B|.R|/B.foo|() (this@R|/A|, this@R|special/anonymous|).R|/A.bar|() } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.kt b/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.kt index 9c3f2567623..ef7079b02c5 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.kt +++ b/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.kt @@ -7,7 +7,7 @@ fun main(k: KSub, vString: SuperClass.NestedInSuperClass, vInt: SuperCla // TODO: Support parametrisized inner classes k.getImpl().nestedI(vInt) k.getNestedSubClass().nested("") - k.getNestedSubClass().nested(1) + k.getNestedSubClass().nested(1) } // FILE: J1.java diff --git a/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.txt b/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.txt index 9357a5a572d..998d56aeab7 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/j+k/KJKComplexHierarchyWithNested.txt @@ -9,7 +9,7 @@ FILE: K1.kt R|/k|.R|/J1.getImpl|().R|FakeOverride|(R|/vString|) R|/k|.R|/J1.getImpl|().R|FakeOverride|(R|/vInt|) R|/k|.R|/J1.getNestedSubClass|().#(String()) - R|/k|.R|/J1.getNestedSubClass|().#(Int(1)) + R|/k|.R|/J1.getNestedSubClass|().R|/SuperClass.NestedInSuperClass.nested|(Int(1)) } FILE: K2.kt public open class KFirst : R|SuperClass|, R|SuperI| { diff --git a/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt b/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt index ef1167da8b3..96a923bd9d7 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/multipleImplicitReceivers.txt @@ -25,10 +25,10 @@ FILE: multipleImplicitReceivers.kt } public final fun test(fooImpl: R|IFoo|, invokeImpl: R|IInvoke|): R|kotlin/Unit| { - R|kotlin/with|(Q|A|, = with@fun R|A|.(): R|kotlin/Unit| { - R|kotlin/with|(R|/fooImpl|, = with@fun R|IFoo|.(): R|kotlin/Unit| { + R|kotlin/with|(Q|A|, = with@fun R|A|.(): R|kotlin/Int| { + R|kotlin/with|(R|/fooImpl|, = with@fun R|IFoo|.(): R|kotlin/Int| { (this@R|/IFoo|, this@R|special/anonymous|).R|/IFoo.foo| - R|kotlin/with|(R|/invokeImpl|, = with@fun R|IInvoke|.(): R|kotlin/Unit| { + R|kotlin/with|(R|/invokeImpl|, = with@fun R|IInvoke|.(): R|kotlin/Int| { (this@R|/IInvoke|, (this@R|/IFoo|, this@R|special/anonymous|).R|/IFoo.foo|).R|/IInvoke.invoke|() } ) diff --git a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt b/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt index 28e513b050b..59605e78960 100644 --- a/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt +++ b/compiler/fir/resolve/testData/resolve/stdlib/problems/tryWithLambdaInside.txt @@ -8,7 +8,7 @@ FILE: tryWithLambdaInside.kt public final fun bar(): R|kotlin/collections/List| { ^bar try { R|/foo|().R|kotlin/collections/filter|( = filter@fun .(): { - >(it#.length#, Int(2)) + >(it#.length#, IntegerLiteral(2)) } ) } diff --git a/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.kt b/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.kt new file mode 100644 index 00000000000..3bad8f43dcf --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.kt @@ -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) +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.txt b/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.txt new file mode 100644 index 00000000000..f4ecfea536e --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/rangeTo.txt @@ -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|/b|) + lval x2: R|kotlin/ranges/IntRange| = Int(1).R|kotlin/Int.rangeTo|(R|/s|) + lval x3: R|kotlin/ranges/IntRange| = Int(1).R|kotlin/Int.rangeTo|(R|/i|) + lval x4: R|kotlin/ranges/LongRange| = Int(1).R|kotlin/Int.rangeTo|(R|/l|) + lval x5: R|kotlin/ranges/IntRange| = R|/b|.R|kotlin/Byte.rangeTo|(Int(1)) + lval x6: R|kotlin/ranges/IntRange| = R|/s|.R|kotlin/Short.rangeTo|(Int(1)) + lval x7: R|kotlin/ranges/IntRange| = R|/i|.R|kotlin/Int.rangeTo|(Int(1)) + lval x8: R|kotlin/ranges/LongRange| = R|/l|.R|kotlin/Long.rangeTo|(Int(1)) + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index d7c4623035c..283bdeeabdc 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -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"); diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index c9514e6a6f6..796e8a2d945 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -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"); diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt index d313e296b6a..62014191dfb 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt @@ -48,6 +48,8 @@ abstract class FirField : FirPureAbstractElement(), FirVariable, FirCa abstract override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirField + abstract override fun transformInitializer(transformer: FirTransformer, data: D): FirField + abstract override fun transformGetter(transformer: FirTransformer, data: D): FirField abstract override fun transformSetter(transformer: FirTransformer, data: D): FirField diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt index e9fe052e5f8..59ad72714cb 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt @@ -54,6 +54,8 @@ abstract class FirProperty : FirPureAbstractElement(), FirVariable, abstract override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirProperty + abstract override fun transformInitializer(transformer: FirTransformer, data: D): FirProperty + abstract override fun transformGetter(transformer: FirTransformer, data: D): FirProperty abstract override fun transformSetter(transformer: FirTransformer, data: D): FirProperty diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt index d1d4b996a07..5f99eaeaca2 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt @@ -48,6 +48,8 @@ abstract class FirValueParameter : FirPureAbstractElement(), FirVariable transformReceiverTypeRef(transformer: FirTransformer, data: D): FirValueParameter + abstract override fun transformInitializer(transformer: FirTransformer, data: D): FirValueParameter + abstract override fun transformGetter(transformer: FirTransformer, data: D): FirValueParameter abstract override fun transformSetter(transformer: FirTransformer, data: D): FirValueParameter diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt index abf4c081c4d..d7f017420bb 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt @@ -44,6 +44,8 @@ interface FirVariable> : FirCallableDeclaration, FirNamedD override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirVariable + fun transformInitializer(transformer: FirTransformer, data: D): FirVariable + fun transformGetter(transformer: FirTransformer, data: D): FirVariable fun transformSetter(transformer: FirTransformer, data: D): FirVariable diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt index 4c2faa73028..43ab9d6fdff 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt @@ -65,6 +65,7 @@ class FirDefaultSetterValueParameter( override fun transformChildren(transformer: FirTransformer, 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 transformInitializer(transformer: FirTransformer, data: D): FirDefaultSetterValueParameter { + initializer = initializer?.transformSingle(transformer, data) + return this + } + override fun transformGetter(transformer: FirTransformer, data: D): FirDefaultSetterValueParameter { getter = getter?.transformSingle(transformer, data) return this @@ -92,7 +98,6 @@ class FirDefaultSetterValueParameter( } override fun transformOtherChildren(transformer: FirTransformer, data: D): FirDefaultSetterValueParameter { - initializer = initializer?.transformSingle(transformer, data) delegate = delegate?.transformSingle(transformer, data) annotations.transformInplace(transformer, data) defaultValue = defaultValue?.transformSingle(transformer, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt index 7b2a4f04708..a565ea4003f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt @@ -76,6 +76,10 @@ class FirFieldImpl( return this } + override fun transformInitializer(transformer: FirTransformer, data: D): FirFieldImpl { + return this + } + override fun transformGetter(transformer: FirTransformer, data: D): FirFieldImpl { return this } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirModifiableVariable.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirModifiableVariable.kt index 3afd8637a19..07aebe38964 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirModifiableVariable.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirModifiableVariable.kt @@ -46,6 +46,8 @@ interface FirModifiableVariable> : FirVariable, FirAbstra override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirModifiableVariable + override fun transformInitializer(transformer: FirTransformer, data: D): FirModifiableVariable + override fun transformGetter(transformer: FirTransformer, data: D): FirModifiableVariable override fun transformSetter(transformer: FirTransformer, data: D): FirModifiableVariable diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt index ce6d13654a7..850826ea2d3 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt @@ -76,6 +76,7 @@ class FirPropertyImpl( override fun transformChildren(transformer: FirTransformer, 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 transformInitializer(transformer: FirTransformer, data: D): FirPropertyImpl { + initializer = initializer?.transformSingle(transformer, data) + return this + } + override fun transformGetter(transformer: FirTransformer, data: D): FirPropertyImpl { getter = getter?.transformSingle(transformer, data) return this @@ -115,7 +121,6 @@ class FirPropertyImpl( } override fun transformOtherChildren(transformer: FirTransformer, data: D): FirPropertyImpl { - initializer = initializer?.transformSingle(transformer, data) delegate = delegate?.transformSingle(transformer, data) annotations.transformInplace(transformer, data) typeParameters.transformInplace(transformer, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt index 577ca394c9c..b6d1d65f8b0 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt @@ -65,6 +65,7 @@ open class FirValueParameterImpl( override fun transformChildren(transformer: FirTransformer, 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 transformInitializer(transformer: FirTransformer, data: D): FirValueParameterImpl { + initializer = initializer?.transformSingle(transformer, data) + return this + } + override fun transformGetter(transformer: FirTransformer, data: D): FirValueParameterImpl { getter = getter?.transformSingle(transformer, data) return this @@ -92,7 +98,6 @@ open class FirValueParameterImpl( } override fun transformOtherChildren(transformer: FirTransformer, data: D): FirValueParameterImpl { - initializer = initializer?.transformSingle(transformer, data) delegate = delegate?.transformSingle(transformer, data) annotations.transformInplace(transformer, data) defaultValue = defaultValue?.transformSingle(transformer, data) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirConstExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirConstExpression.kt index 00f66084552..feeb66adc65 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirConstExpression.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirConstExpression.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.expressions import org.jetbrains.kotlin.fir.FirPureAbstractElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.fir.visitors.* /* @@ -20,8 +19,10 @@ abstract class FirConstExpression : FirPureAbstractElement(), FirExpression { abstract override val source: FirSourceElement? abstract override val typeRef: FirTypeRef abstract override val annotations: List - abstract val kind: IrConstKind + abstract val kind: FirConstKind abstract val value: T override fun accept(visitor: FirVisitor, data: D): R = visitor.visitConstExpression(this, data) + + abstract fun replaceKind(newKind: FirConstKind) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirReturnExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirReturnExpression.kt index 04996c28d4d..f2d986d3f7b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirReturnExpression.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirReturnExpression.kt @@ -25,4 +25,8 @@ abstract class FirReturnExpression : FirPureAbstractElement(), FirJump accept(visitor: FirVisitor, data: D): R = visitor.visitReturnExpression(this, data) + + abstract fun transformResult(transformer: FirTransformer, data: D): FirReturnExpression + + abstract fun transformOtherChildren(transformer: FirTransformer, data: D): FirReturnExpression } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirConstExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirConstExpressionImpl.kt index 9b3809628a9..98f5cd3d5e1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirConstExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirConstExpressionImpl.kt @@ -8,10 +8,10 @@ package org.jetbrains.kotlin.fir.expressions.impl import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.expressions.FirConstKind import org.jetbrains.kotlin.fir.impl.FirAbstractAnnotatedElement import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl -import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.fir.visitors.* /* @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.visitors.* class FirConstExpressionImpl ( override val source: FirSourceElement?, - override val kind: IrConstKind, + override var kind: FirConstKind, override val value: T ) : FirConstExpression(), FirAbstractAnnotatedElement { override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) @@ -41,4 +41,8 @@ class FirConstExpressionImpl ( override fun replaceTypeRef(newTypeRef: FirTypeRef) { typeRef = newTypeRef } + + override fun replaceKind(newKind: FirConstKind) { + kind = newKind + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt index 6a7891a4e02..114bf378c5b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirFunctionCallImpl.kt @@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.visitors.* * DO NOT MODIFY IT MANUALLY */ -class FirFunctionCallImpl( +open class FirFunctionCallImpl( override val source: FirSourceElement? ) : FirFunctionCall(), FirModifiableQualifiedAccess, FirCallWithArgumentList, FirAbstractAnnotatedElement { override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirReturnExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirReturnExpressionImpl.kt index b4b0a72d30f..d995d6f7a21 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirReturnExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirReturnExpressionImpl.kt @@ -36,9 +36,19 @@ class FirReturnExpressionImpl( } override fun transformChildren(transformer: FirTransformer, data: D): FirReturnExpressionImpl { + transformResult(transformer, data) + transformOtherChildren(transformer, data) + return this + } + + override fun transformResult(transformer: FirTransformer, data: D): FirReturnExpressionImpl { + result = result.transformSingle(transformer, data) + return this + } + + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirReturnExpressionImpl { typeRef = typeRef.transformSingle(transformer, data) annotations.transformInplace(transformer, data) - result = result.transformSingle(transformer, data) return this } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirConstKind.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirConstKind.kt new file mode 100644 index 00000000000..edef463cd53 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirConstKind.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.expressions + +import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType +import org.jetbrains.kotlin.fir.types.coneTypeUnsafe +import org.jetbrains.kotlin.fir.types.toConstKind +import org.jetbrains.kotlin.ir.expressions.IrConstKind + +sealed class FirConstKind(val asString: kotlin.String) { + object Null : FirConstKind("Null") + object Boolean : FirConstKind("Boolean") + object Char : FirConstKind("Char") + object Byte : FirConstKind("Byte") + object Short : FirConstKind("Short") + object Int : FirConstKind("Int") + object Long : FirConstKind("Long") + object String : FirConstKind("String") + object Float : FirConstKind("Float") + object Double : FirConstKind("Double") + object IntegerLiteral : FirConstKind("IntegerLiteral") + + override fun toString() = asString +} + +fun FirConstExpression<*>.getIrConstKind(): IrConstKind<*> = when (kind) { + FirConstKind.IntegerLiteral -> { + val type = typeRef.coneTypeUnsafe() + type.getApproximatedType().toConstKind()!!.toIrConstKind() + } + else -> kind.toIrConstKind() +} + +private fun FirConstKind<*>.toIrConstKind(): IrConstKind<*> = when (this) { + FirConstKind.Null -> IrConstKind.Null + FirConstKind.Boolean -> IrConstKind.Boolean + FirConstKind.Char -> IrConstKind.Char + FirConstKind.Byte -> IrConstKind.Byte + FirConstKind.Short -> IrConstKind.Short + FirConstKind.Int -> IrConstKind.Int + FirConstKind.Long -> IrConstKind.Long + FirConstKind.String -> IrConstKind.String + FirConstKind.Float -> IrConstKind.Float + FirConstKind.Double -> IrConstKind.Double + FirConstKind.IntegerLiteral -> throw IllegalArgumentException() +} \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index 56ffabfb468..1a463e1c9f3 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -23,7 +23,7 @@ inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType? inline val FirAnnotationCall.classId: ClassId? get() = coneClassLikeType?.lookupTag?.classId -fun FirConstExpressionImpl(source: FirSourceElement?, kind: IrConstKind, value: T?, diagnostic: FirDiagnostic): FirExpression = +fun FirConstExpressionImpl(source: FirSourceElement?, kind: FirConstKind, value: T?, diagnostic: FirDiagnostic): FirExpression = value?.let { FirConstExpressionImpl(source, kind, it) } ?: FirErrorExpressionImpl(source, diagnostic) inline val FirTypeOperatorCall.argument: FirExpression get() = arguments.first() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt new file mode 100644 index 00000000000..a1f5062abae --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt @@ -0,0 +1,127 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.types + +import org.jetbrains.kotlin.fir.symbols.StandardClassIds +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.types.model.SimpleTypeMarker + +class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType { + override val possibleTypes: Collection + + constructor(value: Long) : super(value) { + possibleTypes = mutableListOf() + + fun checkBoundsAndAddPossibleType(type: ConeClassLikeType, range: LongRange) { + if (value in range) { + possibleTypes.add(type) + } + } + + fun addSignedPossibleTypes() { + checkBoundsAndAddPossibleType(INT_TYPE, INT_RANGE) + possibleTypes += LONG_TYPE + checkBoundsAndAddPossibleType(BYTE_TYPE, BYTE_RANGE) + checkBoundsAndAddPossibleType(SHORT_TYPE, SHORT_RANGE) + } + + addSignedPossibleTypes() + // TODO: add support of unsigned types + } + + private constructor(value: Long, possibleTypes: Collection) : super(value) { + this.possibleTypes = possibleTypes + } + + override val supertypes: List by lazy { + listOf( + NUMBER_TYPE, + ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(StandardClassIds.Comparable), arrayOf(ConeKotlinTypeProjectionOut(this)), false) + ) + } + + override fun getApproximatedType(expectedType: ConeKotlinType?): ConeClassLikeType { + return when (expectedType) { + null, !in possibleTypes -> possibleTypes.first() + else -> expectedType as ConeClassLikeType + } + } + + companion object { + private fun createType(classId: ClassId): ConeClassLikeType { + return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(classId), emptyArray(), false) + } + + val INT_TYPE = createType(StandardClassIds.Int) + val LONG_TYPE = createType(StandardClassIds.Long) + val SHORT_TYPE = createType(StandardClassIds.Short) + val BYTE_TYPE = createType(StandardClassIds.Byte) + + private val NUMBER_TYPE = createType(StandardClassIds.Number) + + private val INT_RANGE = Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong() + private val BYTE_RANGE = Byte.MIN_VALUE.toLong()..Byte.MAX_VALUE.toLong() + private val SHORT_RANGE = Short.MIN_VALUE.toLong()..Short.MAX_VALUE.toLong() + + fun findCommonSuperType(types: Collection): SimpleTypeMarker? { + return findCommonSuperTypeOrIntersectionType(types, Mode.COMMON_SUPER_TYPE) + } + + fun findIntersectionType(types: Collection): SimpleTypeMarker? { + return findCommonSuperTypeOrIntersectionType(types, Mode.INTERSECTION_TYPE) + } + + private enum class Mode { + COMMON_SUPER_TYPE, INTERSECTION_TYPE + } + + /** + * intersection(ILT(types), PrimitiveType) = commonSuperType(ILT(types), PrimitiveType) = + * PrimitiveType in types -> PrimitiveType + * PrimitiveType !in types -> null + * + * intersection(ILT(types_1), ILT(types_2)) = ILT(types_1 union types_2) + * + * commonSuperType(ILT(types_1), ILT(types_2)) = ILT(types_1 intersect types_2) + */ + private fun findCommonSuperTypeOrIntersectionType(types: Collection, mode: Mode): SimpleTypeMarker? { + if (types.isEmpty()) return null + @Suppress("UNCHECKED_CAST") + return types.reduce { left: SimpleTypeMarker?, right: SimpleTypeMarker? -> fold(left, right, mode) } + } + + private fun fold(left: SimpleTypeMarker?, right: SimpleTypeMarker?, mode: Mode): SimpleTypeMarker? { + if (left == null || right == null) return null + return when { + left is ConeIntegerLiteralType && right is ConeIntegerLiteralType -> + fold(left, right, mode) + + left is ConeIntegerLiteralType -> fold(left, right) + right is ConeIntegerLiteralType -> fold(right, left) + else -> null + } + } + + private fun fold(left: ConeIntegerLiteralType, right: ConeIntegerLiteralType, mode: Mode): ConeIntegerLiteralType? { + val possibleTypes = when (mode) { + Mode.COMMON_SUPER_TYPE -> left.possibleTypes intersect right.possibleTypes + Mode.INTERSECTION_TYPE -> left.possibleTypes union right.possibleTypes + } + return ConeIntegerLiteralTypeImpl(left.value, possibleTypes) + } + + private fun fold(left: ConeIntegerLiteralType, right: SimpleTypeMarker): SimpleTypeMarker? = + if (right in left.possibleTypes) right else null + } +} + +fun ConeKotlinType.approximateIntegerLiteralType(expectedType: ConeKotlinType? = null): ConeKotlinType = + (this as? ConeIntegerLiteralType)?.getApproximatedType(expectedType) ?: this + +fun ConeKotlinType.approximateIntegerLiteralTypeOrNull(expectedType: ConeKotlinType? = null): ConeKotlinType? = + (this as? ConeIntegerLiteralType)?.getApproximatedType(expectedType) \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt index 2d2cfa1618e..1fab8a0b049 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt @@ -5,8 +5,8 @@ package org.jetbrains.kotlin.fir.types -import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirConstKind import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.name.ClassId @@ -56,4 +56,12 @@ val FirAnnotationCall.isExtensionFunctionAnnotationCall: Boolean fun List.dropExtensionFunctionAnnotation(): List { return filterNot { it.isExtensionFunctionAnnotationCall } +} + +fun ConeClassLikeType.toConstKind(): FirConstKind<*>? = when (lookupTag.classId) { + StandardClassIds.Byte -> FirConstKind.Byte + StandardClassIds.Short -> FirConstKind.Short + StandardClassIds.Int -> FirConstKind.Int + StandardClassIds.Long -> FirConstKind.Long + else -> null } \ No newline at end of file diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index 534b6e3f8b9..8d079324377 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -235,6 +235,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() defaultFalse("safe") lateinit("calleeReference") defaultNoReceivers() + kind = OpenClass } impl(qualifiedAccessExpression) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 4a02df5c254..2d25eaf6914 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -138,7 +138,8 @@ object NodeConfigurator : AbstractFieldConfigurator() { returnExpression.configure { parentArg(jump, "E", function.withArgs("F" to "*")) - +field("result", expression) + +field("result", expression).withTransform() + needTransformOtherChildren() } label.configure { @@ -178,7 +179,7 @@ object NodeConfigurator : AbstractFieldConfigurator() { constExpression.configure { withArg("T") - +field("kind", constKindType.withArgs("T")) + +field("kind", constKindType.withArgs("T"), withReplace = true) +field("value", "T", null) } @@ -335,7 +336,7 @@ object NodeConfigurator : AbstractFieldConfigurator() { withArg("F", variable) parentArg(callableDeclaration, "F", "F") +symbol("FirVariableSymbol", "F") - +initializer + +initializer.withTransform() +field("delegate", expression, nullable = true) +field("delegateFieldSymbol", delegateFieldSymbolType, "F", nullable = true) generateBooleanFields("var", "val") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index 0cd27a7215e..10b6b0e12a2 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.tree.generator.context.generatedType import org.jetbrains.kotlin.fir.tree.generator.context.type import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -23,7 +22,7 @@ import org.jetbrains.kotlin.types.Variance val sourceElementType = type("fir", "FirSourceElement") val jumpTargetType = type("fir", "FirTarget") -val constKindType = type(IrConstKind::class) +val constKindType = generatedType("expressions", "FirConstKind") val operationType = type("fir.expressions", "FirOperation") val classKindType = type(ClassKind::class) val invocationKindType = type(InvocationKind::class) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index 97e2cb4827a..577d68297a7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -18,9 +18,12 @@ package org.jetbrains.kotlin.resolve.calls.inference.components import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator import org.jetbrains.kotlin.resolve.calls.inference.components.TypeVariableDirectionCalculator.ResolveDirection -import org.jetbrains.kotlin.resolve.calls.inference.model.* -import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind +import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints +import org.jetbrains.kotlin.resolve.calls.inference.model.checkConstraint +import org.jetbrains.kotlin.types.AbstractTypeApproximator +import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext @@ -177,7 +180,7 @@ class ResultTypeResolver( if (constraints.isEmpty()) return null val constraintTypes = constraints.map { it.type } - val nonLiteralTypes = constraintTypes.filter { it.typeConstructor() !is IntegerLiteralTypeConstructor } + val nonLiteralTypes = constraintTypes.filter { !it.typeConstructor().isIntegerLiteralTypeConstructor() } return nonLiteralTypes.singleBestRepresentative() ?: constraintTypes.singleBestRepresentative() ?: constraintTypes.first() // seems like constraint system has contradiction diff --git a/compiler/testData/codegen/box/boxingOptimization/kt5588.kt b/compiler/testData/codegen/box/boxingOptimization/kt5588.kt index ece5914c504..d1c0319ee4a 100644 --- a/compiler/testData/codegen/box/boxingOptimization/kt5588.kt +++ b/compiler/testData/codegen/box/boxingOptimization/kt5588.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR fun box() : String { val s = "notA" val id = when (s) { diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt index 216a92b0ea1..5faf6875838 100644 --- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt +++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyAssign.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME fun box(): String { diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt index eeecafca219..0f62af3ed4d 100644 --- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt +++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyCAO.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME fun box(): String { diff --git a/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt index 2228e3f8055..8c736e5952b 100644 --- a/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt +++ b/compiler/testData/codegen/box/controlStructures/breakContinueInExpressions/popSizes.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun foo(x: Long, y: Int, z: Double, s: String) {} fun box(): String { diff --git a/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/differentTypes.kt b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/differentTypes.kt index 5b6ba7dd521..b97999102f7 100644 --- a/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/differentTypes.kt +++ b/compiler/testData/codegen/box/controlStructures/tryCatchInExpressions/differentTypes.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS diff --git a/compiler/testData/codegen/box/diagnostics/functions/tailRecursion/sum.kt b/compiler/testData/codegen/box/diagnostics/functions/tailRecursion/sum.kt index c9a55b03241..8a2ae5e6a68 100644 --- a/compiler/testData/codegen/box/diagnostics/functions/tailRecursion/sum.kt +++ b/compiler/testData/codegen/box/diagnostics/functions/tailRecursion/sum.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TODO: muted automatically, investigate should it be ran for JS or not // DONT_RUN_GENERATED_CODE: JS diff --git a/compiler/testData/codegen/box/fullJdk/native/topLevel.kt b/compiler/testData/codegen/box/fullJdk/native/topLevel.kt index 1301246348e..ef215d03b29 100644 --- a/compiler/testData/codegen/box/fullJdk/native/topLevel.kt +++ b/compiler/testData/codegen/box/fullJdk/native/topLevel.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // FULL_JDK diff --git a/compiler/testData/codegen/box/ieee754/lessDouble_properIeeeAndNewInference.kt b/compiler/testData/codegen/box/ieee754/lessDouble_properIeeeAndNewInference.kt index fc814f16137..249851377b8 100644 --- a/compiler/testData/codegen/box/ieee754/lessDouble_properIeeeAndNewInference.kt +++ b/compiler/testData/codegen/box/ieee754/lessDouble_properIeeeAndNewInference.kt @@ -1,5 +1,5 @@ -// !LANGUAGE: +ProperIeee754Comparisons +NewInference // IGNORE_BACKEND_FIR: JVM_IR +// !LANGUAGE: +ProperIeee754Comparisons +NewInference fun box(): String { if (-0.0 < 0.0) return "Fail 1" diff --git a/compiler/testData/codegen/box/innerNested/createNestedClass.kt b/compiler/testData/codegen/box/innerNested/createNestedClass.kt index 22f299c27aa..2667bc8f97f 100644 --- a/compiler/testData/codegen/box/innerNested/createNestedClass.kt +++ b/compiler/testData/codegen/box/innerNested/createNestedClass.kt @@ -1,4 +1,4 @@ -// IGNORE_BACKEND_FIR: JVM_IR + class A { class B1 class B2(val x: Int) diff --git a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt index 9bafc452a1e..ff03f15417c 100644 --- a/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt +++ b/compiler/testData/codegen/box/primitiveTypes/equalityWithObject/whenNullableBoxed.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR class CInt(val value: Int) val nCInt3: CInt? = CInt(3) diff --git a/compiler/testData/codegen/box/primitiveTypes/kt3078.kt b/compiler/testData/codegen/box/primitiveTypes/kt3078.kt index bf06b256df1..61a5e671193 100644 --- a/compiler/testData/codegen/box/primitiveTypes/kt3078.kt +++ b/compiler/testData/codegen/box/primitiveTypes/kt3078.kt @@ -1,4 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR + fun box(): String { if (1 >= 1.9) return "Fail #1" if (1.compareTo(1.1) >= 0) return "Fail #2" diff --git a/compiler/testData/codegen/box/primitiveTypes/kt665.kt b/compiler/testData/codegen/box/primitiveTypes/kt665.kt index 09198d70e58..b1aeccdb849 100644 --- a/compiler/testData/codegen/box/primitiveTypes/kt665.kt +++ b/compiler/testData/codegen/box/primitiveTypes/kt665.kt @@ -1,4 +1,4 @@ -// IGNORE_BACKEND_FIR: JVM_IR + fun f(x: Long, zzz: Long = 1): Long { return if (x <= 1) zzz diff --git a/compiler/testData/codegen/box/primitiveTypes/unboxComparable.kt b/compiler/testData/codegen/box/primitiveTypes/unboxComparable.kt index 870989087fd..a14f2452688 100644 --- a/compiler/testData/codegen/box/primitiveTypes/unboxComparable.kt +++ b/compiler/testData/codegen/box/primitiveTypes/unboxComparable.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR fun foo(x: Int) = x fun bar(x: Comparable) = if (x is Int) foo(x) else 0 diff --git a/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt b/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt index b30d2416246..619cd6d90de 100644 --- a/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt +++ b/compiler/testData/codegen/box/properties/lateinit/local/localLateinit.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun box(): String { lateinit var ok: String run { diff --git a/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt b/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt index c2cb9fb01f5..23d1104aeba 100644 --- a/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt +++ b/compiler/testData/codegen/box/properties/lateinit/topLevel/topLevelLateinit.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR lateinit var ok: String fun box(): String { diff --git a/compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt b/compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt index 6145314a0e4..949136655a1 100644 --- a/compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt +++ b/compiler/testData/codegen/box/ranges/contains/comparisonWithRangeBoundEliminated.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR fun abs(x: Int) = if (x < 0) -x else x fun abs(x: Long) = if (x < 0) -x else x diff --git a/compiler/testData/codegen/box/strings/kt889.kt b/compiler/testData/codegen/box/strings/kt889.kt index b1ffdc4c7c3..22954f35c5f 100644 --- a/compiler/testData/codegen/box/strings/kt889.kt +++ b/compiler/testData/codegen/box/strings/kt889.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // IGNORE_BACKEND: JS_IR // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS, NATIVE diff --git a/compiler/testData/codegen/box/synchronized/changeMonitor.kt b/compiler/testData/codegen/box/synchronized/changeMonitor.kt index 6b3600f3c94..5c2bab2c36b 100644 --- a/compiler/testData/codegen/box/synchronized/changeMonitor.kt +++ b/compiler/testData/codegen/box/synchronized/changeMonitor.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/synchronized/finally.kt b/compiler/testData/codegen/box/synchronized/finally.kt index 684753ed2e7..2fd42eae717 100644 --- a/compiler/testData/codegen/box/synchronized/finally.kt +++ b/compiler/testData/codegen/box/synchronized/finally.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/synchronized/nestedDifferentObjects.kt b/compiler/testData/codegen/box/synchronized/nestedDifferentObjects.kt index 0d83196b6f1..d5779c1e1bd 100644 --- a/compiler/testData/codegen/box/synchronized/nestedDifferentObjects.kt +++ b/compiler/testData/codegen/box/synchronized/nestedDifferentObjects.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/synchronized/nestedSameObject.kt b/compiler/testData/codegen/box/synchronized/nestedSameObject.kt index 1687907d007..a98bdd48bd0 100644 --- a/compiler/testData/codegen/box/synchronized/nestedSameObject.kt +++ b/compiler/testData/codegen/box/synchronized/nestedSameObject.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/synchronized/wait.kt b/compiler/testData/codegen/box/synchronized/wait.kt index 379a4bcb6d7..56acadd4016 100644 --- a/compiler/testData/codegen/box/synchronized/wait.kt +++ b/compiler/testData/codegen/box/synchronized/wait.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/when/longInRange.kt b/compiler/testData/codegen/box/when/longInRange.kt index d1522ea2cd4..c73169ff600 100644 --- a/compiler/testData/codegen/box/when/longInRange.kt +++ b/compiler/testData/codegen/box/when/longInRange.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR class LongR { operator fun contains(l : Long): Boolean = l == 5.toLong() } diff --git a/compiler/testData/ir/irText/expressions/genericConstructorCallWithTypeArguments.fir.txt b/compiler/testData/ir/irText/expressions/genericConstructorCallWithTypeArguments.fir.txt index f275eb8ef39..856858f9821 100644 --- a/compiler/testData/ir/irText/expressions/genericConstructorCallWithTypeArguments.fir.txt +++ b/compiler/testData/ir/irText/expressions/genericConstructorCallWithTypeArguments.fir.txt @@ -1,11 +1,12 @@ FILE fqName: fileName:/genericConstructorCallWithTypeArguments.kt - FUN name:testSimple visibility:public modality:FINAL <> () returnType:IrErrorType + FUN name:testSimple visibility:public modality:FINAL <> () returnType:.Box BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun testSimple (): IrErrorType declared in ' - ERROR_CALL 'Unresolved reference: #' type=IrErrorType - CALL 'public final fun times (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=2 - other: CONST Int type=kotlin.Int value=3 + RETURN type=kotlin.Nothing from='public final fun testSimple (): .Box declared in ' + CONSTRUCTOR_CALL 'public constructor (value: T of .Box) [primary] declared in .Box' type=.Box origin=null + : kotlin.Long + value: CALL 'public final fun times (other: kotlin.Long): kotlin.Long [operator] declared in kotlin.Long' type=kotlin.Long origin=null + $this: CONST Long type=kotlin.Long value=2 + other: CONST Long type=kotlin.Long value=3 FUN name:testArray visibility:public modality:FINAL (n:kotlin.Int, block:kotlin.Function0.testArray>) returnType:kotlin.Array.testArray> [inline] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] VALUE_PARAMETER name:n index:0 type:kotlin.Int diff --git a/compiler/testData/ir/irText/expressions/literals.fir.txt b/compiler/testData/ir/irText/expressions/literals.fir.txt index 59f3561544d..c3f20bf2c8b 100644 --- a/compiler/testData/ir/irText/expressions/literals.fir.txt +++ b/compiler/testData/ir/irText/expressions/literals.fir.txt @@ -123,7 +123,7 @@ FILE fqName: fileName:/literals.kt PROPERTY name:testB visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:testB type:kotlin.Byte visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=1 + CONST Byte type=kotlin.Byte value=1 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Byte correspondingProperty: PROPERTY name:testB visibility:public modality:FINAL [val] BLOCK_BODY @@ -132,7 +132,7 @@ FILE fqName: fileName:/literals.kt PROPERTY name:testS visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:testS type:kotlin.Short visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=1 + CONST Short type=kotlin.Short value=1 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Short correspondingProperty: PROPERTY name:testS visibility:public modality:FINAL [val] BLOCK_BODY @@ -150,7 +150,7 @@ FILE fqName: fileName:/literals.kt PROPERTY name:testL visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:testL type:kotlin.Long visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=1 + CONST Long type=kotlin.Long value=1 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Long correspondingProperty: PROPERTY name:testL visibility:public modality:FINAL [val] BLOCK_BODY diff --git a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.fir.txt b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.fir.txt index b421d44d4d5..0ff7105e522 100644 --- a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.fir.txt +++ b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.fir.txt @@ -2,7 +2,7 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test1 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Long visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=42 + CONST Long type=kotlin.Long value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Long correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val] BLOCK_BODY @@ -11,7 +11,7 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test2 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Short visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=42 + CONST Short type=kotlin.Short value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Short correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val] BLOCK_BODY @@ -20,7 +20,7 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test3 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test3 type:kotlin.Byte visibility:private [final,static] EXPRESSION_BODY - CONST Int type=kotlin.Int value=42 + CONST Byte type=kotlin.Byte value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Byte correspondingProperty: PROPERTY name:test3 visibility:public modality:FINAL [val] BLOCK_BODY @@ -61,7 +61,7 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt VAR name:test1 type:kotlin.Int? [val] CONST Int type=kotlin.Int value=42 VAR name:test2 type:kotlin.Long [val] - CONST Int type=kotlin.Int value=42 + CONST Long type=kotlin.Long value=42 VAR name:test3 type:kotlin.Long? [val] CONST Int type=kotlin.Int value=42 VAR name:test4 type:kotlin.Long? [val] diff --git a/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt b/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt index 93b136c175f..645e254491f 100644 --- a/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt +++ b/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt @@ -6,10 +6,10 @@ FILE fqName: fileName:/whenUnusedExpression.kt WHEN type=kotlin.Int? origin=IF BRANCH if: GET_VAR 'b: kotlin.Boolean declared in .test' type=kotlin.Boolean origin=null - then: BLOCK type=kotlin.Int? origin=WHEN + then: BLOCK type=kotlin.Int origin=WHEN VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.Int [val] GET_VAR 'i: kotlin.Int declared in .test' type=kotlin.Int origin=null - WHEN type=kotlin.Int? origin=WHEN + WHEN type=kotlin.Int origin=WHEN BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'val tmp_0: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/lambdas/multipleImplicitReceivers.fir.txt b/compiler/testData/ir/irText/lambdas/multipleImplicitReceivers.fir.txt index 33860fee098..26e735ddafe 100644 --- a/compiler/testData/ir/irText/lambdas/multipleImplicitReceivers.fir.txt +++ b/compiler/testData/ir/irText/lambdas/multipleImplicitReceivers.fir.txt @@ -88,22 +88,22 @@ FILE fqName: fileName:/multipleImplicitReceivers.kt : .A : kotlin.Int receiver: GET_OBJECT 'CLASS OBJECT name:A modality:FINAL visibility:public superTypes:[kotlin.Any]' type=.A - block: FUN_EXPR type=kotlin.Function1<.A, kotlin.Unit> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit + block: FUN_EXPR type=kotlin.Function1<.A, kotlin.Int> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Int BLOCK_BODY CALL 'public final fun with (receiver: T of kotlin.with, block: kotlin.Function1): R of kotlin.with [inline] declared in kotlin' type=kotlin.Int origin=null : .IFoo : kotlin.Int receiver: GET_VAR 'fooImpl: .IFoo declared in .test' type=.IFoo origin=null - block: FUN_EXPR type=kotlin.Function1<.IFoo, kotlin.Unit> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit + block: FUN_EXPR type=kotlin.Function1<.IFoo, kotlin.Int> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Int BLOCK_BODY CALL 'public final fun with (receiver: T of kotlin.with, block: kotlin.Function1): R of kotlin.with [inline] declared in kotlin' type=kotlin.Int origin=null : .IInvoke : kotlin.Int receiver: GET_VAR 'invokeImpl: .IInvoke declared in .test' type=.IInvoke origin=null - block: FUN_EXPR type=kotlin.Function1<.IInvoke, kotlin.Unit> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Unit + block: FUN_EXPR type=kotlin.Function1<.IInvoke, kotlin.Int> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:kotlin.Int BLOCK_BODY CALL 'public open fun invoke (): kotlin.Int [operator] declared in .IInvoke' type=kotlin.Int origin=null $this: GET_VAR ': .IInvoke declared in .IInvoke' type=.IInvoke origin=null diff --git a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt index fdf7dcad679..64fc979bf33 100644 --- a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt +++ b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt @@ -425,7 +425,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { } override fun visitConstExpression(constExpression: FirConstExpression, data: StringBuilder) { - if (constExpression.kind != IrConstKind.String) { + if (constExpression.kind != FirConstKind.String) { data.append(constExpression.kind) } } diff --git a/idea/testData/fir/lazyResolve/import/bar/bar.txt b/idea/testData/fir/lazyResolve/import/bar/bar.txt index c5cba1bf37a..108622b2a2f 100644 --- a/idea/testData/fir/lazyResolve/import/bar/bar.txt +++ b/idea/testData/fir/lazyResolve/import/bar/bar.txt @@ -1,4 +1,4 @@ FILE: bar.kt public final fun barbar(): R|kotlin/Int| { - ^barbar Int(13) + ^barbar IntegerLiteral(13) } diff --git a/idea/testData/fir/lazyResolve/inLocal/main.txt b/idea/testData/fir/lazyResolve/inLocal/main.txt index 4570884e8d0..72ef5dd181f 100644 --- a/idea/testData/fir/lazyResolve/inLocal/main.txt +++ b/idea/testData/fir/lazyResolve/inLocal/main.txt @@ -7,6 +7,6 @@ FILE: main.kt R|/foo|() } public final fun bar(): R|kotlin/Int| { - lval x: = Int(4) - ^bar Int(9).times#(x#) + lval x: = IntegerLiteral(4) + ^bar IntegerLiteral(9).times#(x#) } diff --git a/idea/testData/fir/lazyResolve/simple/callMe.txt b/idea/testData/fir/lazyResolve/simple/callMe.txt index c6e72a64dba..68daec3288b 100644 --- a/idea/testData/fir/lazyResolve/simple/callMe.txt +++ b/idea/testData/fir/lazyResolve/simple/callMe.txt @@ -3,5 +3,5 @@ FILE: callMe.kt ^callMe Int(42) } public final fun other(): R|kotlin/Unit| { - lval x: = Int(1) + lval x: = IntegerLiteral(1) }