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 f520ee62e36..77460fa3292 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 @@ -22,17 +22,13 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirStubStatement import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.references.FirReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.isIteratorNext import org.jetbrains.kotlin.fir.resolve.scope import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer -import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol 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.UNDEFINED_OFFSET @@ -60,12 +56,6 @@ class Fir2IrVisitor( private val annotationGenerator = AnnotationGenerator(this) - private val integerApproximator = IntegerLiteralTypeApproximationTransformer( - session.firSymbolProvider, - session.typeContext, - session - ) - private val memberGenerator = ClassMemberGenerator(components, this, conversionScope) private val operatorGenerator = OperatorExpressionGenerator(components, this, conversionScope) @@ -342,12 +332,7 @@ class Fir2IrVisitor( } override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression { - val convertibleCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) { - functionCall.copy().transformSingle(integerApproximator, null) - } else { - functionCall - } - return convertToIrCall(functionCall = convertibleCall, annotationMode = false) + return convertToIrCall(functionCall = functionCall, annotationMode = false) } override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement { 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 cbd42589fa0..72f0bf16e35 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -157,14 +157,6 @@ class FirCallResolver( bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference ) } - if ((reducedCandidates.isEmpty() || !result.currentApplicability.isSuccess) && - explicitReceiver?.typeRef?.coneTypeSafe() != null - ) { - val approximatedQualifiedAccess = qualifiedAccess.transformExplicitReceiver(components.integerLiteralTypeApproximator, null) - if (approximatedQualifiedAccess.explicitReceiver?.typeRef?.coneTypeSafe() == null) { - return collectCandidates(approximatedQualifiedAccess, name) - } - } return ResolutionResult(info, result.currentApplicability, reducedCandidates) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt index 6beb9d63559..266d0c8b5bf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/BodyResolveComponents.kt @@ -18,8 +18,6 @@ import org.jetbrains.kotlin.fir.resolve.dfa.FirDataFlowAnalyzer import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator -import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer -import org.jetbrains.kotlin.fir.resolve.transformers.IntegerOperatorsTypeUpdater import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope @@ -54,8 +52,6 @@ abstract class BodyResolveComponents : SessionHolder { abstract val doubleColonExpressionResolver: FirDoubleColonExpressionResolver abstract val syntheticCallGenerator: FirSyntheticCallGenerator abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*> - abstract val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer - abstract val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater abstract val outerClassManager: FirOuterClassManager } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt index e344158242d..1a0fd79c973 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDoubleColonExpressionResolver.kt @@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.declarations.expandedConeType import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirNamedReference -import org.jetbrains.kotlin.fir.resolve.transformers.IntegerLiteralTypeApproximationTransformer import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.types.Variance @@ -41,10 +40,7 @@ sealed class DoubleColonLHS(val type: ConeKotlinType) { internal val FirFunctionCall.hasExplicitValueArguments: Boolean get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments -class FirDoubleColonExpressionResolver( - private val session: FirSession, - private val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer -) { +class FirDoubleColonExpressionResolver(private val session: FirSession) { // Returns true if the expression is not a call expression without value arguments (such as "A") or a qualified expression // which contains such call expression as one of its parts. @@ -80,9 +76,6 @@ class FirDoubleColonExpressionResolver( } internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? { - if (doubleColonExpression.explicitReceiver is FirConstExpression<*>) { - doubleColonExpression.transformExplicitReceiver(integerLiteralTypeApproximator, null) - } val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS) if (resultForExpr != null && !resultForExpr.isObjectQualifier) { return resultForExpr 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 0eee965dd54..d5e180df070 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 @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerLiteralTypeScope import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope import org.jetbrains.kotlin.fir.scopes.scope @@ -56,18 +55,7 @@ fun ConeKotlinType.scope(useSiteSession: FirSession, scopeSession: ScopeSession) } ) is ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession) - is ConeIntegerLiteralType -> { - @Suppress("USELESS_CAST") // TODO: remove once fixed: https://youtrack.jetbrains.com/issue/KT-35635 - scopeSession.getOrBuild( - when { - isUnsigned -> FirIntegerLiteralTypeScope.ILTKey.Unsigned - else -> FirIntegerLiteralTypeScope.ILTKey.Signed - }, - FirIntegerLiteralTypeScope.SCOPE_SESSION_KEY - ) { - FirIntegerLiteralTypeScope(useSiteSession, isUnsigned) - } as FirTypeScope - } + is ConeIntegerLiteralType -> error("ILT should not be in receiver position") else -> null } } 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 d0b4333312a..c3ca6a18e5a 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 @@ -18,9 +18,6 @@ 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.transformers.ensureResolvedTypeDeclaration 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.symbols.StandardClassIds import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* @@ -185,11 +182,7 @@ fun Candidate.resolveSubCallArgument( * 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.coneType - } else { - context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).type - } + val type: ConeKotlinType = context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).type val argumentType = candidate.substitutor.substituteOrSelf(type) resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, context, isReceiver, isDispatch, useNullableArgumentType) } @@ -207,14 +200,6 @@ fun Candidate.resolvePlainExpressionArgument( if (expectedType == null) return val argumentType = argument.typeRef.coneTypeSafe() ?: return resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, context, isReceiver, isDispatch, useNullableArgumentType) - 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.reportDiagnostic(InapplicableCandidate) - } } fun Candidate.resolvePlainArgumentType( @@ -346,9 +331,6 @@ private fun Candidate.prepareExpectedType( context: ResolutionContext ): ConeKotlinType? { if (parameter == null) return null - val parameterReturnTypeRef = parameter.returnTypeRef - if (parameterReturnTypeRef is FirILTTypeRefPlaceHolder && argument.resultType is FirResolvedTypeRef) - return argument.resultType.coneType.takeIf { it in parameterReturnTypeRef.type.possibleTypes } ?: session.builtinTypes.intType.type val basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/) val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType, context) ?: basicExpectedType return this.substitutor.substituteOrSelf(expectedType) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt index 8249e71f1ef..7a40f780220 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirTowerResolveTask.kt @@ -233,13 +233,6 @@ internal open class FirTowerResolveTask( explicitReceiverValue.toMemberScopeTowerLevel(), info, parentGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER ) - val shouldProcessExplicitReceiverScopeOnly = - info.callKind == CallKind.Function && info.explicitReceiver?.typeRef?.coneTypeSafe() != null - if (shouldProcessExplicitReceiverScopeOnly) { - // Special case (integer literal type) - return - } - enumerateTowerLevels( parentGroup = parentGroup, onScope = { scope, group -> @@ -412,4 +405,4 @@ internal open class FirTowerResolveTask( parentGroup.TopPrioritized(index).let { if (depth != null) it.Implicit(depth) else it }, explicitReceiverKind, ) -} \ No newline at end of file +} 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 c765cb3ab5b..729665c5102 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 @@ -72,17 +72,21 @@ class FirCallCompleter( return when (completionMode) { ConstraintSystemCompletionMode.FULL -> { if (inferenceSession.shouldRunCompletion(call)) { - completer.complete(candidate.system.asConstraintSystemCompleterContext(), completionMode, listOf(call), initialType, transformer.resolutionContext) { + completer.complete( + candidate.system.asConstraintSystemCompleterContext(), + completionMode, + listOf(call), + initialType, + transformer.resolutionContext + ) { analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate) } - val finalSubstitutor = - candidate.system.asReadOnlyStorage().buildAbstractResultingSubstitutor(session.inferenceComponents.ctx) as ConeSubstitutor + val finalSubstitutor = candidate.system.asReadOnlyStorage() + .buildAbstractResultingSubstitutor(session.inferenceComponents.ctx) as ConeSubstitutor val completedCall = call.transformSingle( FirCallCompletionResultsWriterTransformer( session, finalSubstitutor, components.returnTypeCalculator, - session.inferenceComponents.approximator, - components.integerOperatorsTypeUpdater, - components.integerLiteralTypeApproximator + session.inferenceComponents.approximator ), null ) @@ -104,9 +108,8 @@ class FirCallCompleter( ) { analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate) } - val approximatedCall = call.transformSingle(components.integerOperatorsTypeUpdater, null) - inferenceSession.addPartiallyResolvedCall(approximatedCall) - CompletionResult(approximatedCall, false) + inferenceSession.addPartiallyResolvedCall(call) + CompletionResult(call, false) } ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException() @@ -120,8 +123,6 @@ class FirCallCompleter( return FirCallCompletionResultsWriterTransformer( session, substitutor, components.returnTypeCalculator, session.inferenceComponents.approximator, - components.integerOperatorsTypeUpdater, - components.integerLiteralTypeApproximator, mode ) } @@ -189,9 +190,7 @@ class FirCallCompleter( FirBuilderInferenceSession(transformer.resolutionContext, stubsForPostponedVariables as Map) } - val localContext = components.towerDataContextForAnonymousFunctions.get(lambdaArgument.symbol) ?: error( - "" - ) + val localContext = components.towerDataContextForAnonymousFunctions[lambdaArgument.symbol] ?: error("") transformer.context.withTowerDataContext(localContext) { if (builderInferenceSession != null) { transformer.context.withInferenceSession(builderInferenceSession) { 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 ab4ae4309ec..da5f1c648b3 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 @@ -48,8 +48,6 @@ class FirCallCompletionResultsWriterTransformer( private val finalSubstitutor: ConeSubstitutor, private val typeCalculator: ReturnTypeCalculator, private val typeApproximator: AbstractTypeApproximator, - private val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater, - private val integerApproximator: IntegerLiteralTypeApproximationTransformer, private val mode: Mode = Mode.Normal ) : FirAbstractTreeTransformer(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) { @@ -105,14 +103,8 @@ class FirCallCompletionResultsWriterTransformer( } } - val updatedQualifiedAccess = if (qualifiedAccessExpression is FirFunctionCall) { - qualifiedAccessExpression.transformSingle(integerOperatorsTypeUpdater, null) - } else { - qualifiedAccessExpression - } - @Suppress("UNCHECKED_CAST") - val result = updatedQualifiedAccess + val result = qualifiedAccessExpression .transformCalleeReference( StoreCalleeReference, calleeReference.toResolvedReference(), @@ -137,7 +129,6 @@ class FirCallCompletionResultsWriterTransformer( qualifiedAccessExpression.compose() } val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference) - .transformExplicitReceiver(integerApproximator, null) val typeRef = result.typeRef as FirResolvedTypeRef val subCandidate = calleeReference.candidate @@ -154,13 +145,6 @@ class FirCallCompletionResultsWriterTransformer( return result.compose() } - override fun transformCheckedSafeCallSubject( - checkedSafeCallSubject: FirCheckedSafeCallSubject, - data: ExpectedArgumentType? - ): CompositeTransformResult { - return checkedSafeCallSubject.transform(integerApproximator, data?.getExpectedType(checkedSafeCallSubject)) - } - override fun transformFunctionCall(functionCall: FirFunctionCall, data: ExpectedArgumentType?): CompositeTransformResult { val calleeReference = functionCall.calleeReference as? FirNamedReferenceWithCandidate ?: return functionCall.compose() @@ -174,7 +158,7 @@ class FirCallCompletionResultsWriterTransformer( resultType = typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe().getApproximatedType(expectedType)) result.argumentList.transformArguments(this, expectedType?.toExpectedType()) - result.transformSingle(integerApproximator, expectedType) + result } else -> { resultType = typeRef.substituteTypeRef(subCandidate) @@ -186,7 +170,7 @@ class FirCallCompletionResultsWriterTransformer( result.replaceArgumentList(buildResolvedArgumentList(it)) } } - result.transformExplicitReceiver(integerApproximator, null) + result } } @@ -325,7 +309,7 @@ class FirCallCompletionResultsWriterTransformer( return variableAssignment.transformCalleeReference( StoreCalleeReference, calleeReference.toResolvedReference(), - ).transformExplicitReceiver(integerApproximator, null).apply { + ).apply { replaceTypeArguments(typeArguments) }.compose() } @@ -565,8 +549,7 @@ class FirCallCompletionResultsWriterTransformer( data: ExpectedArgumentType?, ): CompositeTransformResult { if (data == ExpectedArgumentType.NoApproximation) return constExpression.compose() - val expectedType = data?.getExpectedType(constExpression) - return constExpression.transform(integerApproximator, expectedType) + return constExpression.approximateIfIsIntegerConst(data?.getExpectedType(constExpression)).compose() } override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ExpectedArgumentType?): CompositeTransformResult { 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 index 8bdac8a57c9..f93156db43a 100644 --- 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 @@ -6,36 +6,26 @@ package org.jetbrains.kotlin.fir.resolve.transformers import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirImplementationDetail -import org.jetbrains.kotlin.fir.FirSession -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.builder.buildResolvedNamedReference -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate -import org.jetbrains.kotlin.fir.resolve.propagateTypeFromOriginalReceiver +import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.expressions.FirConstKind +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype -import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator -import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall -import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.StandardClassIds -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.fir.types.toConstKind 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, - private val session: FirSession -) : FirTransformer() { +fun FirExpression.approximateIfIsIntegerConst(expectedType: ConeKotlinType? = null): FirExpression { + return transformSingle(IntegerLiteralTypeApproximationTransformer, expectedType) +} + +private object IntegerLiteralTypeApproximationTransformer : FirTransformer() { override fun transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult { return element.compose() } @@ -52,207 +42,4 @@ class IntegerLiteralTypeApproximationTransformer( constExpression.replaceKind(kind) return constExpression.compose() } - - override fun transformFunctionCall(functionCall: FirFunctionCall, data: ConeKotlinType?): CompositeTransformResult { - val operator = functionCall.toResolvedCallableSymbol()?.fir as? FirIntegerOperator - if (operator == null) { - if (functionCall is FirIntegerOperatorCall) { - // functionCall _was_ a named call whose candidate symbol was an integer operator, but has been transformed to an integer - // operator call (by [IntegerOperatorsTypeUpdater]). So, technically, this _was_ a call that this transformer was looking - // for, i.e., a call with ILT, but in a resolved form already. Here we just adapt to the expected type if any. - // - // Note that such inequality can happen to the resolved call, since the call completer doesn't complete the call with the - // given, expected type: see [FirCallCompleter#completeCall]. One reason _not_ to propagate the expected type to the call - // completing transformation is to handle integer overflow naturally. E.g., if a property with Long, a bigger type, is - // intentionally set with an integer operator that overflows, knowing the expected type will hide the overflow. Rather, we - // have a second chance here to sort of wrap such overflowed integer with type conversion, like `n.toLong()`. - data?.let { - functionCall.resultType = functionCall.resultType.resolvedTypeFromPrototype(it) - } - } - return functionCall.compose() - } - functionCall.transformChildren(this, data) - val argumentType = functionCall.arguments.firstOrNull()?.resultType?.coneTypeUnsafe() - val receiverClassId = functionCall.dispatchReceiver.typeRef.coneTypeUnsafe().lookupTag.classId - val scope = declaredMemberScope((symbolProvider.getClassLikeSymbolByFqName(receiverClassId) as FirRegularClassSymbol).fir) - var resultSymbol: FirFunctionSymbol<*>? = null - scope.processFunctionsByName(operator.name) { symbol -> - if (resultSymbol != null) { - return@processFunctionsByName - } - if (operator.kind.unary) { - resultSymbol = symbol - return@processFunctionsByName - } - val function = symbol.fir - val valueParameterType = function.valueParameters.first().returnTypeRef.coneTypeUnsafe() - if (AbstractTypeChecker.isSubtypeOf(inferenceContext, argumentType!!, valueParameterType)) { - resultSymbol = symbol - return@processFunctionsByName - } - } - // TODO: Maybe resultType = data? - // check black box tests - // e.g. Byte doesn't have `and` in member scope. It's an extension. See also: FirBlackBoxCodegenTestGenerated.testIntrinsics - if (resultSymbol == null) return functionCall.compose() - functionCall.resultType = data?.let { functionCall.resultType.resolvedTypeFromPrototype(it) } ?: resultSymbol!!.fir.returnTypeRef - // If the original call has argument mapping, values in that mapping refer to value parameters in that original symbol. We should - // map those original value parameters back to indices, and then renew the argument mapping with new value parameters in the result - // symbol. Otherwise, while putting the value argument to the converted IR call, it will encounter an unknown value parameter, - // resulting in an out-of-bound error. - val newArgumentMapping = - functionCall.argumentMapping?.mapValues { (_, oldValueParameter) -> - val index = operator.valueParameters.indexOf(oldValueParameter) - if (index != -1) resultSymbol!!.fir.valueParameters[index] else oldValueParameter - } - return functionCall.transformCalleeReference( - StoreCalleeReference, - buildResolvedNamedReference { - name = operator.name - resolvedSymbol = resultSymbol!! - } - ).apply { - newArgumentMapping?.let { - replaceArgumentList(buildResolvedArgumentList(it)) - } - }.compose() - } - - // TODO: call outside - override fun transformTypeOperatorCall( - typeOperatorCall: FirTypeOperatorCall, - data: ConeKotlinType? - ): CompositeTransformResult { - typeOperatorCall.argumentList.transformArguments(this, null) - return typeOperatorCall.compose() - } - - override fun transformEqualityOperatorCall( - equalityOperatorCall: FirEqualityOperatorCall, - data: ConeKotlinType? - ): CompositeTransformResult { - val leftArgument = equalityOperatorCall.arguments[0] - val rightArgument = equalityOperatorCall.arguments[1] - - val leftIsIlt = leftArgument.typeRef.coneTypeSafe() != null - val rightIsIlt = rightArgument.typeRef.coneTypeSafe() != null - - val expectedType: ConeKotlinType? = when { - !leftIsIlt && !rightIsIlt -> return equalityOperatorCall.compose() - leftIsIlt && rightIsIlt -> null - leftIsIlt -> rightArgument.typeRef.coneType - rightIsIlt -> leftArgument.typeRef.coneType - else -> throw IllegalStateException() - } - - equalityOperatorCall.argumentList.transformArguments(this, expectedType) - return equalityOperatorCall.compose() - } - - override fun transformCheckedSafeCallSubject( - checkedSafeCallSubject: FirCheckedSafeCallSubject, - data: ConeKotlinType? - ): CompositeTransformResult { - val newReceiver = - checkedSafeCallSubject.originalReceiverRef.value.transform(this, data).single - checkedSafeCallSubject.propagateTypeFromOriginalReceiver(newReceiver, session) - return super.transformCheckedSafeCallSubject(checkedSafeCallSubject, data) - } -} - -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(private 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?.coneType - return functionCall.transformExplicitReceiver(approximator, expectedType).compose() - } - // TODO: maybe unsafe? - val receiverType = functionCall.explicitReceiver!!.typeRef.coneTypeSafe() ?: return functionCall.compose() - val receiverValue = receiverType.value - 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 -> { - // TODO: handle overflow - when (val argumentType = functionCall.argument.typeRef.coneType) { - 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.classId) { - StandardClassIds.Long, - StandardClassIds.Float, - StandardClassIds.Double -> argumentType - else -> ConeIntegerLiteralTypeImpl.createType(StandardClassIds.Int) - } - functionCall.transformSingle(approximator, expectedType) - functionCall.replaceTypeRef(functionCall.resultType.resolvedTypeFromPrototype(expectedType)) - return functionCall.compose() - } - } - } - } - val newTypeRef = functionCall.resultType.resolvedTypeFromPrototype( - ConeIntegerLiteralTypeImpl( - resultValue, - isUnsigned = receiverType.isUnsigned - ) - ) - functionCall.replaceTypeRef(newTypeRef) - return functionCall.toOperatorCall().compose() - } -} - -@OptIn(FirImplementationDetail::class) -private fun FirFunctionCall.toOperatorCall(): FirIntegerOperatorCall { - if (this is FirIntegerOperatorCall) return this - return FirIntegerOperatorCall( - source, - typeRef, - annotations.toMutableList(), - typeArguments.toMutableList(), - explicitReceiver, - dispatchReceiver, - extensionReceiver, - argumentList, - calleeReference, - ) } 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 9b630ecfdc3..9d3cb58deff 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 @@ -20,7 +20,10 @@ import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.transformers.* +import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractPhaseTransformer +import org.jetbrains.kotlin.fir.resolve.transformers.FirSpecificTypeResolverTransformer +import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator +import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.types.FirTypeRef @@ -88,8 +91,6 @@ 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) { @@ -134,11 +135,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val dataFlowAnalyzer: FirDataFlowAnalyzer<*> = FirDataFlowAnalyzer.createFirDataFlowAnalyzer(this, context.dataFlowAnalyzerContext) override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this) - override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer = - IntegerLiteralTypeApproximationTransformer(symbolProvider, session.inferenceComponents.ctx, session) - override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = - FirDoubleColonExpressionResolver(session, integerLiteralTypeApproximator) - override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator) + override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session) override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt index 55b1aa79cb6..18d9b8885c8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirArrayOfCallTransformer.kt @@ -10,7 +10,9 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall -import org.jetbrains.kotlin.fir.resolve.transformers.getOriginalFunction +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.types.isArrayType /** @@ -64,3 +66,12 @@ internal class FirArrayOfCallTransformer { } } } + +private 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<*> +} 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 ab70600c345..248be29f27e 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 @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransf import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef -import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.transformSingle @@ -191,10 +190,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran } else { ResolutionMode.ContextIndependent } - var result = transformer.transformExpression(jump, mode).single - if (result is FirReturnExpression) { - result = result.transformResult(integerLiteralTypeApproximator, expectedTypeRef!!.coneTypeSafe()) - } + val result = transformer.transformExpression(jump, mode).single dataFlowAnalyzer.exitJump(jump) return result.compose() } 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 e93f9d78fe5..e300cbe41a1 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 @@ -138,7 +138,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor withLocalScopeCleanup { addLocalScope(context.getPrimaryConstructorParametersScope()) property.transformChildrenWithoutAccessors(returnTypeRef) - property.transformInitializer(integerLiteralTypeApproximator, property.returnTypeRef.coneTypeSafe()) } if (property.initializer != null) { storeVariableReturnType(property) @@ -253,7 +252,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor (delegateProvider as? FirFunctionCall)?.let { dataFlowAnalyzer.dropSubgraphFromCall(it) } return wrappedDelegateExpression.expression .transformSingle(transformer, ResolutionMode.ContextDependent) - .transform(integerLiteralTypeApproximator, null) + .approximateIfIsIntegerConst() + .compose() } finally { dataFlowAnalyzer.exitDelegateExpression() } @@ -269,7 +269,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor .transformDelegate(transformer, resolutionMode) .transformTypeParameters(transformer, resolutionMode) .transformOtherChildren(transformer, resolutionMode) - .transformInitializer(integerLiteralTypeApproximator, null) if (variable.initializer != null) { storeVariableReturnType(variable) } @@ -650,12 +649,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } dataFlowAnalyzer.enterValueParameter(valueParameter) - val transformedValueParameter = - valueParameter.transformInitializer(integerLiteralTypeApproximator, valueParameter.returnTypeRef.coneType) - val result = transformDeclarationContent( - transformedValueParameter, - withExpectedType(transformedValueParameter.returnTypeRef) + valueParameter, + withExpectedType(valueParameter.returnTypeRef) ).single as FirValueParameter dataFlowAnalyzer.exitValueParameter(result)?.let { graph -> @@ -752,8 +748,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor ConeSubstitutor.Empty, components.returnTypeCalculator, inferenceComponents.approximator, - integerOperatorsTypeUpdater, - integerLiteralTypeApproximator ) lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe()?.toExpectedType()) val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda) 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 e3fa222aa48..6d22aa06f4c 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 @@ -309,14 +309,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform transformer.onBeforeStatementResolution(block.statements[index]) TransformData.Data(value) } - if (data == ResolutionMode.ContextIndependent) { - block.transformStatements(integerLiteralTypeApproximator, null) - } else { - block.transformAllStatementsExceptLast( - integerLiteralTypeApproximator, - null - ) - } block.transformOtherChildren(transformer, data) block.writeResultType(session) @@ -336,8 +328,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform ): CompositeTransformResult { return (comparisonExpression.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirComparisonExpression).also { it.resultType = comparisonExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) - }.transformSingle(integerLiteralTypeApproximator, null) - .also(dataFlowAnalyzer::exitComparisonExpressionCall).compose() + dataFlowAnalyzer.exitComparisonExpressionCall(it) + }.compose() } override fun transformAssignmentOperatorStatement( @@ -429,7 +421,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform ): CompositeTransformResult { val result = (equalityOperatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirEqualityOperatorCall) .also { it.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) } - .transformSingle(integerLiteralTypeApproximator, null) dataFlowAnalyzer.exitEqualityOperatorCall(result) return result.compose() } @@ -481,7 +472,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform val resolved = components.typeResolverTransformer.withAllowedBareTypes { typeOperatorCall.transformConversionTypeRef(transformer, ResolutionMode.ContextIndependent) }.transformOtherChildren(transformer, ResolutionMode.ContextIndependent) - resolved.argumentList.transformArguments(integerLiteralTypeApproximator, null) val conversionTypeRef = resolved.conversionTypeRef.withTypeArgumentsForBareType(resolved.argument) resolved.transformChildren(object : FirDefaultTransformer() { @@ -520,7 +510,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform else -> error("Unknown type operator: ${resolved.operation}") } dataFlowAnalyzer.exitTypeOperatorCall(resolved) - return resolved.transform(integerLiteralTypeApproximator, null) + return resolved.compose() } override fun transformCheckNotNullCall( @@ -587,7 +577,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType).result // 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 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 deleted file mode 100644 index c6f9709a3eb..00000000000 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.* -import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription -import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter -import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl -import org.jetbrains.kotlin.fir.declarations.impl.FirSimpleFunctionImpl -import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.resolve.scopeSessionKey -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.symbols.CallableId -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol -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 - -class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned: Boolean) : FirTypeScope() { - sealed class ILTKey { - object Signed : ILTKey() - object Unsigned : ILTKey() - } - - companion object { - val BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filterNot { it.unary }.map { it.operatorName } - val FLOATING_BINARY_OPERATOR_NAMES = FirIntegerOperator.Kind.values().filter { it.withFloatingRhs }.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 SCOPE_SESSION_KEY = scopeSessionKey() - } - - @Suppress("PrivatePropertyName") - private val BINARY_OPERATOR_SYMBOLS = BINARY_OPERATOR_NAMES.map { name -> - name to FirNamedFunctionSymbol(CallableId(name)).apply { - createFirFunction(name, this).apply { - valueParameters += createValueParameter(FirILTTypeRefPlaceHolder(isUnsigned)) - } - } - }.toMap() - - private val FLOATING_BINARY_OPERATOR_SYMBOLS = FLOATING_BINARY_OPERATOR_NAMES.map { name -> - name to listOf(session.builtinTypes.floatType, session.builtinTypes.doubleType).map { typeRef -> - FirNamedFunctionSymbol(CallableId(name)).apply { - createFirFunction(name, this, typeRef).apply { - valueParameters += createValueParameter(typeRef) - } - } - } - }.toMap() - - @Suppress("PrivatePropertyName") - private val UNARY_OPERATOR_SYMBOLS = UNARY_OPERATOR_NAMES.map { name -> - name to FirNamedFunctionSymbol(CallableId(name)).apply { createFirFunction(name, this) } - }.toMap() - - @OptIn(FirImplementationDetail::class) - private fun createFirFunction( - name: Name, - symbol: FirNamedFunctionSymbol, - returnTypeRef: FirResolvedTypeRef = FirILTTypeRefPlaceHolder(isUnsigned) - ): FirSimpleFunctionImpl = FirIntegerOperator( - source = null, - session, - returnTypeRef, - receiverTypeRef = null, - ALL_OPERATORS.getValue(name), - FirResolvedDeclarationStatusImpl(Visibilities.Public, Modality.FINAL), - symbol - ).apply { - resolvePhase = FirResolvePhase.BODY_RESOLVE - } - - private fun createValueParameter(returnTypeRef: FirResolvedTypeRef): FirValueParameter { - return buildValueParameter { - source = null - origin = FirDeclarationOrigin.Synthetic - session = this@FirIntegerLiteralTypeScope.session - this.returnTypeRef = returnTypeRef - name = Name.identifier("arg") - symbol = FirVariableSymbol(name) - defaultValue = null - isCrossinline = false - isNoinline = false - isVararg = false - } - } - - override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { - UNARY_OPERATOR_SYMBOLS[name]?.let { - processor(it) - return - } - val symbol = BINARY_OPERATOR_SYMBOLS[name] ?: return - processor(symbol) - FLOATING_BINARY_OPERATOR_SYMBOLS[name]?.forEach(processor) - } - - override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { - } - - override fun processDirectOverriddenFunctionsWithBaseScope( - functionSymbol: FirFunctionSymbol<*>, - processor: (FirFunctionSymbol<*>, FirTypeScope) -> ProcessorAction - ): ProcessorAction = ProcessorAction.NEXT - - override fun processDirectOverriddenPropertiesWithBaseScope( - propertySymbol: FirPropertySymbol, - processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction - ): ProcessorAction = ProcessorAction.NEXT - - override fun getCallableNames(): Set = ALL_OPERATORS.keys - - override fun getClassifierNames(): Set = emptySet() -} - -@OptIn(FirImplementationDetail::class) -class FirIntegerOperator @FirImplementationDetail constructor( - source: FirSourceElement?, - session: FirSession, - returnTypeRef: FirTypeRef, - receiverTypeRef: FirTypeRef?, - val kind: Kind, - status: FirDeclarationStatus, - symbol: FirFunctionSymbol -) : FirSimpleFunctionImpl( - source, - session, - resolvePhase = FirResolvePhase.BODY_RESOLVE, - FirDeclarationOrigin.Synthetic, - returnTypeRef, - receiverTypeRef, - valueParameters = mutableListOf(), - body = null, - status, - containerSource = null, - contractDescription = FirEmptyContractDescription, - kind.operatorName, - symbol, - annotations = mutableListOf(), - typeParameters = mutableListOf(), -) { - enum class Kind(val operatorName: Name, val unary: Boolean, val withFloatingRhs: Boolean) { - PLUS(OperatorNameConventions.PLUS, unary = false, withFloatingRhs = true), - MINUS(OperatorNameConventions.MINUS, unary = false, withFloatingRhs = true), - TIMES(OperatorNameConventions.TIMES, unary = false, withFloatingRhs = true), - DIV(OperatorNameConventions.DIV, unary = false, withFloatingRhs = true), - REM(OperatorNameConventions.REM, unary = false, withFloatingRhs = true), - SHL(Name.identifier("shl"), unary = false, withFloatingRhs = false), - SHR(Name.identifier("shr"), unary = false, withFloatingRhs = false), - USHR(Name.identifier("ushr"), unary = false, withFloatingRhs = false), - XOR(Name.identifier("xor"), unary = false, withFloatingRhs = false), - AND(Name.identifier("and"), unary = false, withFloatingRhs = false), - OR(Name.identifier("or"), unary = false, withFloatingRhs = false), - UNARY_PLUS(OperatorNameConventions.UNARY_PLUS, unary = true, withFloatingRhs = false), - UNARY_MINUS(OperatorNameConventions.UNARY_MINUS, unary = true, withFloatingRhs = false), - INV(Name.identifier("inv"), unary = true, withFloatingRhs = false), - } -} - -class FirILTTypeRefPlaceHolder(isUnsigned: Boolean) : FirResolvedTypeRef() { - override val source: FirSourceElement? get() = null - override val annotations: List get() = emptyList() - override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0, isUnsigned) - override val delegatedTypeRef: FirTypeRef? get() = null - - override fun acceptChildren(visitor: FirVisitor, data: D) {} - - override fun transformChildren(transformer: FirTransformer, data: D): FirElement { - return this - } - - override fun transformAnnotations(transformer: FirTransformer, data: D): FirResolvedTypeRef { - return this - } -}