[FIR] Get rid of FirIntegerLiteralTypeScope and corresponding stuff

This commit is contained in:
Dmitriy Novozhilov
2020-09-18 12:22:31 +03:00
parent 4374c06537
commit da3a676c2a
16 changed files with 61 additions and 568 deletions
@@ -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 {
@@ -157,14 +157,6 @@ class FirCallResolver(
bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference
)
}
if ((reducedCandidates.isEmpty() || !result.currentApplicability.isSuccess) &&
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() != null
) {
val approximatedQualifiedAccess = qualifiedAccess.transformExplicitReceiver(components.integerLiteralTypeApproximator, null)
if (approximatedQualifiedAccess.explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null) {
return collectCandidates(approximatedQualifiedAccess, name)
}
}
return ResolutionResult(info, result.currentApplicability, reducedCandidates)
}
@@ -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
}
@@ -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<B>") 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
@@ -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
}
}
@@ -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<ConeKotlinType>() ?: 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)
@@ -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<ConeIntegerLiteralType>() != 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,
)
}
}
@@ -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<ConeTypeVariable, ConeStubType>)
}
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) {
@@ -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<ExpectedArgumentType?>(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<FirStatement> {
return checkedSafeCallSubject.transform(integerApproximator, data?.getExpectedType(checkedSafeCallSubject))
}
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
val calleeReference = functionCall.calleeReference as? FirNamedReferenceWithCandidate
?: return functionCall.compose()
@@ -174,7 +158,7 @@ class FirCallCompletionResultsWriterTransformer(
resultType =
typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().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<FirStatement> {
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<FirStatement> {
@@ -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<ConeKotlinType?>() {
fun FirExpression.approximateIfIsIntegerConst(expectedType: ConeKotlinType? = null): FirExpression {
return transformSingle(IntegerLiteralTypeApproximationTransformer, expectedType)
}
private object IntegerLiteralTypeApproximationTransformer : FirTransformer<ConeKotlinType?>() {
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult<E> {
return element.compose()
}
@@ -52,207 +42,4 @@ class IntegerLiteralTypeApproximationTransformer(
constExpression.replaceKind(kind)
return constExpression.compose()
}
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ConeKotlinType?): CompositeTransformResult<FirStatement> {
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<ConeClassLikeType>()
val receiverClassId = functionCall.dispatchReceiver.typeRef.coneTypeUnsafe<ConeClassLikeType>().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<ConeClassLikeType>()
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<FirStatement> {
typeOperatorCall.argumentList.transformArguments(this, null)
return typeOperatorCall.compose()
}
override fun transformEqualityOperatorCall(
equalityOperatorCall: FirEqualityOperatorCall,
data: ConeKotlinType?
): CompositeTransformResult<FirStatement> {
val leftArgument = equalityOperatorCall.arguments[0]
val rightArgument = equalityOperatorCall.arguments[1]
val leftIsIlt = leftArgument.typeRef.coneTypeSafe<ConeIntegerLiteralType>() != null
val rightIsIlt = rightArgument.typeRef.coneTypeSafe<ConeIntegerLiteralType>() != 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<FirStatement> {
val newReceiver =
checkedSafeCallSubject.originalReceiverRef.value.transform<FirExpression, ConeKotlinType?>(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<Nothing?>() {
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
return element.compose()
}
override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult<FirStatement> {
val function: FirCallableDeclaration<*> = functionCall.getOriginalFunction() ?: return functionCall.compose()
if (function !is FirIntegerOperator) {
val expectedType = function.receiverTypeRef?.coneType
return functionCall.transformExplicitReceiver(approximator, expectedType).compose()
}
// TODO: maybe unsafe?
val receiverType = functionCall.explicitReceiver!!.typeRef.coneTypeSafe<ConeIntegerLiteralType>() ?: 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,
)
}
@@ -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)
}
}
@@ -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<*>
}
@@ -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()
}
@@ -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<ConeKotlinType>()?.toExpectedType())
val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda)
@@ -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<FirStatement> {
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<FirStatement> {
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<Nothing?>() {
@@ -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
@@ -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<ILTKey, FirTypeScope>()
}
@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<Name> = ALL_OPERATORS.keys
override fun getClassifierNames(): Set<Name> = emptySet()
}
@OptIn(FirImplementationDetail::class)
class FirIntegerOperator @FirImplementationDetail constructor(
source: FirSourceElement?,
session: FirSession,
returnTypeRef: FirTypeRef,
receiverTypeRef: FirTypeRef?,
val kind: Kind,
status: FirDeclarationStatus,
symbol: FirFunctionSymbol<FirSimpleFunction>
) : 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<FirAnnotationCall> get() = emptyList()
override var type: ConeIntegerLiteralType = ConeIntegerLiteralTypeImpl(0, isUnsigned)
override val delegatedTypeRef: FirTypeRef? get() = null
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
return this
}
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirResolvedTypeRef {
return this
}
}