[FIR] Get rid of FirIntegerLiteralTypeScope and corresponding stuff
This commit is contained in:
@@ -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.expressions.impl.FirUnitExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
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.isIteratorNext
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
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.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
@@ -60,12 +56,6 @@ class Fir2IrVisitor(
|
|||||||
|
|
||||||
private val annotationGenerator = AnnotationGenerator(this)
|
private val annotationGenerator = AnnotationGenerator(this)
|
||||||
|
|
||||||
private val integerApproximator = IntegerLiteralTypeApproximationTransformer(
|
|
||||||
session.firSymbolProvider,
|
|
||||||
session.typeContext,
|
|
||||||
session
|
|
||||||
)
|
|
||||||
|
|
||||||
private val memberGenerator = ClassMemberGenerator(components, this, conversionScope)
|
private val memberGenerator = ClassMemberGenerator(components, this, conversionScope)
|
||||||
|
|
||||||
private val operatorGenerator = OperatorExpressionGenerator(components, this, conversionScope)
|
private val operatorGenerator = OperatorExpressionGenerator(components, this, conversionScope)
|
||||||
@@ -342,12 +332,7 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression {
|
override fun visitFunctionCall(functionCall: FirFunctionCall, data: Any?): IrExpression {
|
||||||
val convertibleCall = if (functionCall.toResolvedCallableSymbol()?.fir is FirIntegerOperator) {
|
return convertToIrCall(functionCall = functionCall, annotationMode = false)
|
||||||
functionCall.copy().transformSingle(integerApproximator, null)
|
|
||||||
} else {
|
|
||||||
functionCall
|
|
||||||
}
|
|
||||||
return convertToIrCall(functionCall = convertibleCall, annotationMode = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement {
|
override fun visitSafeCallExpression(safeCallExpression: FirSafeCallExpression, data: Any?): IrElement {
|
||||||
|
|||||||
@@ -157,14 +157,6 @@ class FirCallResolver(
|
|||||||
bestCandidates, discriminateGenerics = true, discriminateAbstracts = onSuperReference
|
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)
|
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.inference.FirCallCompleter
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
|
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.resolve.transformers.ReturnTypeCalculator
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
@@ -54,8 +52,6 @@ abstract class BodyResolveComponents : SessionHolder {
|
|||||||
abstract val doubleColonExpressionResolver: FirDoubleColonExpressionResolver
|
abstract val doubleColonExpressionResolver: FirDoubleColonExpressionResolver
|
||||||
abstract val syntheticCallGenerator: FirSyntheticCallGenerator
|
abstract val syntheticCallGenerator: FirSyntheticCallGenerator
|
||||||
abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*>
|
abstract val dataFlowAnalyzer: FirDataFlowAnalyzer<*>
|
||||||
abstract val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer
|
|
||||||
abstract val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater
|
|
||||||
abstract val outerClassManager: FirOuterClassManager
|
abstract val outerClassManager: FirOuterClassManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-8
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
|||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
@@ -41,10 +40,7 @@ sealed class DoubleColonLHS(val type: ConeKotlinType) {
|
|||||||
internal val FirFunctionCall.hasExplicitValueArguments: Boolean
|
internal val FirFunctionCall.hasExplicitValueArguments: Boolean
|
||||||
get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments
|
get() = true // TODO: hasExplicitArgumentList || hasExplicitLambdaArguments
|
||||||
|
|
||||||
class FirDoubleColonExpressionResolver(
|
class FirDoubleColonExpressionResolver(private val session: FirSession) {
|
||||||
private val session: FirSession,
|
|
||||||
private val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer
|
|
||||||
) {
|
|
||||||
|
|
||||||
// Returns true if the expression is not a call expression without value arguments (such as "A<B>") or a qualified expression
|
// 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.
|
// which contains such call expression as one of its parts.
|
||||||
@@ -80,9 +76,6 @@ class FirDoubleColonExpressionResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? {
|
internal fun resolveDoubleColonLHS(doubleColonExpression: FirCallableReferenceAccess): DoubleColonLHS? {
|
||||||
if (doubleColonExpression.explicitReceiver is FirConstExpression<*>) {
|
|
||||||
doubleColonExpression.transformExplicitReceiver(integerLiteralTypeApproximator, null)
|
|
||||||
}
|
|
||||||
val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS)
|
val resultForExpr = tryResolveLHS(doubleColonExpression, this::shouldTryResolveLHSAsExpression, this::resolveExpressionOnLHS)
|
||||||
if (resultForExpr != null && !resultForExpr.isObjectQualifier) {
|
if (resultForExpr != null && !resultForExpr.isObjectQualifier) {
|
||||||
return resultForExpr
|
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.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
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.FirStandardOverrideChecker
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirTypeIntersectionScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.scope
|
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 ConeDefinitelyNotNullType -> original.scope(useSiteSession, scopeSession)
|
||||||
is ConeIntegerLiteralType -> {
|
is ConeIntegerLiteralType -> error("ILT should not be in receiver position")
|
||||||
@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
|
|
||||||
}
|
|
||||||
else -> null
|
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.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedTypeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.returnExpressions
|
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.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
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
|
* 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
|
* placeholder type with value 0, but argument contains type with proper literal value
|
||||||
*/
|
*/
|
||||||
val type: ConeKotlinType = if (candidate.symbol.fir is FirIntegerOperator) {
|
val type: ConeKotlinType = context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).type
|
||||||
(argument as FirFunctionCall).resultType.coneType
|
|
||||||
} else {
|
|
||||||
context.returnTypeCalculator.tryCalculateReturnType(candidate.symbol.firUnsafe()).type
|
|
||||||
}
|
|
||||||
val argumentType = candidate.substitutor.substituteOrSelf(type)
|
val argumentType = candidate.substitutor.substituteOrSelf(type)
|
||||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, context, isReceiver, isDispatch, useNullableArgumentType)
|
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, context, isReceiver, isDispatch, useNullableArgumentType)
|
||||||
}
|
}
|
||||||
@@ -207,14 +200,6 @@ fun Candidate.resolvePlainExpressionArgument(
|
|||||||
if (expectedType == null) return
|
if (expectedType == null) return
|
||||||
val argumentType = argument.typeRef.coneTypeSafe<ConeKotlinType>() ?: return
|
val argumentType = argument.typeRef.coneTypeSafe<ConeKotlinType>() ?: return
|
||||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, context, isReceiver, isDispatch, useNullableArgumentType)
|
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(
|
fun Candidate.resolvePlainArgumentType(
|
||||||
@@ -346,9 +331,6 @@ private fun Candidate.prepareExpectedType(
|
|||||||
context: ResolutionContext
|
context: ResolutionContext
|
||||||
): ConeKotlinType? {
|
): ConeKotlinType? {
|
||||||
if (parameter == null) return null
|
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 basicExpectedType = argument.getExpectedType(session, parameter/*, LanguageVersionSettings*/)
|
||||||
val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType, context) ?: basicExpectedType
|
val expectedType = getExpectedTypeWithSAMConversion(session, argument, basicExpectedType, context) ?: basicExpectedType
|
||||||
return this.substitutor.substituteOrSelf(expectedType)
|
return this.substitutor.substituteOrSelf(expectedType)
|
||||||
|
|||||||
-7
@@ -233,13 +233,6 @@ internal open class FirTowerResolveTask(
|
|||||||
explicitReceiverValue.toMemberScopeTowerLevel(), info, parentGroup.Member, ExplicitReceiverKind.DISPATCH_RECEIVER
|
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(
|
enumerateTowerLevels(
|
||||||
parentGroup = parentGroup,
|
parentGroup = parentGroup,
|
||||||
onScope = { scope, group ->
|
onScope = { scope, group ->
|
||||||
|
|||||||
+13
-14
@@ -72,17 +72,21 @@ class FirCallCompleter(
|
|||||||
return when (completionMode) {
|
return when (completionMode) {
|
||||||
ConstraintSystemCompletionMode.FULL -> {
|
ConstraintSystemCompletionMode.FULL -> {
|
||||||
if (inferenceSession.shouldRunCompletion(call)) {
|
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)
|
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate)
|
||||||
}
|
}
|
||||||
val finalSubstitutor =
|
val finalSubstitutor = candidate.system.asReadOnlyStorage()
|
||||||
candidate.system.asReadOnlyStorage().buildAbstractResultingSubstitutor(session.inferenceComponents.ctx) as ConeSubstitutor
|
.buildAbstractResultingSubstitutor(session.inferenceComponents.ctx) as ConeSubstitutor
|
||||||
val completedCall = call.transformSingle(
|
val completedCall = call.transformSingle(
|
||||||
FirCallCompletionResultsWriterTransformer(
|
FirCallCompletionResultsWriterTransformer(
|
||||||
session, finalSubstitutor, components.returnTypeCalculator,
|
session, finalSubstitutor, components.returnTypeCalculator,
|
||||||
session.inferenceComponents.approximator,
|
session.inferenceComponents.approximator
|
||||||
components.integerOperatorsTypeUpdater,
|
|
||||||
components.integerLiteralTypeApproximator
|
|
||||||
),
|
),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@@ -104,9 +108,8 @@ class FirCallCompleter(
|
|||||||
) {
|
) {
|
||||||
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate)
|
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate)
|
||||||
}
|
}
|
||||||
val approximatedCall = call.transformSingle(components.integerOperatorsTypeUpdater, null)
|
inferenceSession.addPartiallyResolvedCall(call)
|
||||||
inferenceSession.addPartiallyResolvedCall(approximatedCall)
|
CompletionResult(call, false)
|
||||||
CompletionResult(approximatedCall, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException()
|
ConstraintSystemCompletionMode.UNTIL_FIRST_LAMBDA -> throw IllegalStateException()
|
||||||
@@ -120,8 +123,6 @@ class FirCallCompleter(
|
|||||||
return FirCallCompletionResultsWriterTransformer(
|
return FirCallCompletionResultsWriterTransformer(
|
||||||
session, substitutor, components.returnTypeCalculator,
|
session, substitutor, components.returnTypeCalculator,
|
||||||
session.inferenceComponents.approximator,
|
session.inferenceComponents.approximator,
|
||||||
components.integerOperatorsTypeUpdater,
|
|
||||||
components.integerLiteralTypeApproximator,
|
|
||||||
mode
|
mode
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -189,9 +190,7 @@ class FirCallCompleter(
|
|||||||
FirBuilderInferenceSession(transformer.resolutionContext, stubsForPostponedVariables as Map<ConeTypeVariable, ConeStubType>)
|
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) {
|
transformer.context.withTowerDataContext(localContext) {
|
||||||
if (builderInferenceSession != null) {
|
if (builderInferenceSession != null) {
|
||||||
transformer.context.withInferenceSession(builderInferenceSession) {
|
transformer.context.withInferenceSession(builderInferenceSession) {
|
||||||
|
|||||||
+5
-22
@@ -48,8 +48,6 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
private val finalSubstitutor: ConeSubstitutor,
|
private val finalSubstitutor: ConeSubstitutor,
|
||||||
private val typeCalculator: ReturnTypeCalculator,
|
private val typeCalculator: ReturnTypeCalculator,
|
||||||
private val typeApproximator: AbstractTypeApproximator,
|
private val typeApproximator: AbstractTypeApproximator,
|
||||||
private val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater,
|
|
||||||
private val integerApproximator: IntegerLiteralTypeApproximationTransformer,
|
|
||||||
private val mode: Mode = Mode.Normal
|
private val mode: Mode = Mode.Normal
|
||||||
) : FirAbstractTreeTransformer<ExpectedArgumentType?>(phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
) : 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")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val result = updatedQualifiedAccess
|
val result = qualifiedAccessExpression
|
||||||
.transformCalleeReference(
|
.transformCalleeReference(
|
||||||
StoreCalleeReference,
|
StoreCalleeReference,
|
||||||
calleeReference.toResolvedReference(),
|
calleeReference.toResolvedReference(),
|
||||||
@@ -137,7 +129,6 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
qualifiedAccessExpression.compose()
|
qualifiedAccessExpression.compose()
|
||||||
}
|
}
|
||||||
val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference)
|
val result = prepareQualifiedTransform(qualifiedAccessExpression, calleeReference)
|
||||||
.transformExplicitReceiver(integerApproximator, null)
|
|
||||||
val typeRef = result.typeRef as FirResolvedTypeRef
|
val typeRef = result.typeRef as FirResolvedTypeRef
|
||||||
val subCandidate = calleeReference.candidate
|
val subCandidate = calleeReference.candidate
|
||||||
|
|
||||||
@@ -154,13 +145,6 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
return result.compose()
|
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> {
|
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||||
val calleeReference = functionCall.calleeReference as? FirNamedReferenceWithCandidate
|
val calleeReference = functionCall.calleeReference as? FirNamedReferenceWithCandidate
|
||||||
?: return functionCall.compose()
|
?: return functionCall.compose()
|
||||||
@@ -174,7 +158,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
resultType =
|
resultType =
|
||||||
typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().getApproximatedType(expectedType))
|
typeRef.resolvedTypeFromPrototype(typeRef.coneTypeUnsafe<ConeIntegerLiteralType>().getApproximatedType(expectedType))
|
||||||
result.argumentList.transformArguments(this, expectedType?.toExpectedType())
|
result.argumentList.transformArguments(this, expectedType?.toExpectedType())
|
||||||
result.transformSingle(integerApproximator, expectedType)
|
result
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||||
@@ -186,7 +170,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
result.replaceArgumentList(buildResolvedArgumentList(it))
|
result.replaceArgumentList(buildResolvedArgumentList(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.transformExplicitReceiver(integerApproximator, null)
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +309,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
return variableAssignment.transformCalleeReference(
|
return variableAssignment.transformCalleeReference(
|
||||||
StoreCalleeReference,
|
StoreCalleeReference,
|
||||||
calleeReference.toResolvedReference(),
|
calleeReference.toResolvedReference(),
|
||||||
).transformExplicitReceiver(integerApproximator, null).apply {
|
).apply {
|
||||||
replaceTypeArguments(typeArguments)
|
replaceTypeArguments(typeArguments)
|
||||||
}.compose()
|
}.compose()
|
||||||
}
|
}
|
||||||
@@ -565,8 +549,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
data: ExpectedArgumentType?,
|
data: ExpectedArgumentType?,
|
||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
if (data == ExpectedArgumentType.NoApproximation) return constExpression.compose()
|
if (data == ExpectedArgumentType.NoApproximation) return constExpression.compose()
|
||||||
val expectedType = data?.getExpectedType(constExpression)
|
return constExpression.approximateIfIsIntegerConst(data?.getExpectedType(constExpression)).compose()
|
||||||
return constExpression.transform(integerApproximator, expectedType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ExpectedArgumentType?): CompositeTransformResult<FirStatement> {
|
||||||
|
|||||||
+13
-226
@@ -6,36 +6,26 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve.transformers
|
package org.jetbrains.kotlin.fir.resolve.transformers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.expressions.FirConstKind
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
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.resolve.transformers.body.resolve.resultType
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperator
|
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.types.toConstKind
|
||||||
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.visitors.CompositeTransformResult
|
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||||
import org.jetbrains.kotlin.fir.visitors.compose
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
|
||||||
|
|
||||||
class IntegerLiteralTypeApproximationTransformer(
|
fun FirExpression.approximateIfIsIntegerConst(expectedType: ConeKotlinType? = null): FirExpression {
|
||||||
private val symbolProvider: FirSymbolProvider,
|
return transformSingle(IntegerLiteralTypeApproximationTransformer, expectedType)
|
||||||
private val inferenceContext: ConeInferenceContext,
|
}
|
||||||
private val session: FirSession
|
|
||||||
) : FirTransformer<ConeKotlinType?>() {
|
private object IntegerLiteralTypeApproximationTransformer : FirTransformer<ConeKotlinType?>() {
|
||||||
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult<E> {
|
override fun <E : FirElement> transformElement(element: E, data: ConeKotlinType?): CompositeTransformResult<E> {
|
||||||
return element.compose()
|
return element.compose()
|
||||||
}
|
}
|
||||||
@@ -52,207 +42,4 @@ class IntegerLiteralTypeApproximationTransformer(
|
|||||||
constExpression.replaceKind(kind)
|
constExpression.replaceKind(kind)
|
||||||
return constExpression.compose()
|
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,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-8
@@ -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.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
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.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
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 dataFlowAnalyzer: FirDataFlowAnalyzer<*> get() = components.dataFlowAnalyzer
|
||||||
protected inline val scopeSession: ScopeSession get() = components.scopeSession
|
protected inline val scopeSession: ScopeSession get() = components.scopeSession
|
||||||
protected inline val file: FirFile get() = components.file
|
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?
|
val ResolutionMode.expectedType: FirTypeRef?
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
@@ -134,11 +135,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb
|
|||||||
override val dataFlowAnalyzer: FirDataFlowAnalyzer<*> =
|
override val dataFlowAnalyzer: FirDataFlowAnalyzer<*> =
|
||||||
FirDataFlowAnalyzer.createFirDataFlowAnalyzer(this, context.dataFlowAnalyzerContext)
|
FirDataFlowAnalyzer.createFirDataFlowAnalyzer(this, context.dataFlowAnalyzerContext)
|
||||||
override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this)
|
override val syntheticCallGenerator: FirSyntheticCallGenerator = FirSyntheticCallGenerator(this)
|
||||||
override val integerLiteralTypeApproximator: IntegerLiteralTypeApproximationTransformer =
|
override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver = FirDoubleColonExpressionResolver(session)
|
||||||
IntegerLiteralTypeApproximationTransformer(symbolProvider, session.inferenceComponents.ctx, session)
|
|
||||||
override val doubleColonExpressionResolver: FirDoubleColonExpressionResolver =
|
|
||||||
FirDoubleColonExpressionResolver(session, integerLiteralTypeApproximator)
|
|
||||||
override val integerOperatorsTypeUpdater: IntegerOperatorsTypeUpdater = IntegerOperatorsTypeUpdater(integerLiteralTypeApproximator)
|
|
||||||
override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested)
|
override val outerClassManager: FirOuterClassManager = FirOuterClassManager(session, context.outerLocalClassForNested)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildArrayOfCall
|
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
|
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<*>
|
||||||
|
}
|
||||||
|
|||||||
+1
-5
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransf
|
|||||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||||
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
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.CompositeTransformResult
|
||||||
import org.jetbrains.kotlin.fir.visitors.compose
|
import org.jetbrains.kotlin.fir.visitors.compose
|
||||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||||
@@ -191,10 +190,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran
|
|||||||
} else {
|
} else {
|
||||||
ResolutionMode.ContextIndependent
|
ResolutionMode.ContextIndependent
|
||||||
}
|
}
|
||||||
var result = transformer.transformExpression(jump, mode).single
|
val result = transformer.transformExpression(jump, mode).single
|
||||||
if (result is FirReturnExpression) {
|
|
||||||
result = result.transformResult(integerLiteralTypeApproximator, expectedTypeRef!!.coneTypeSafe())
|
|
||||||
}
|
|
||||||
dataFlowAnalyzer.exitJump(jump)
|
dataFlowAnalyzer.exitJump(jump)
|
||||||
return result.compose()
|
return result.compose()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -138,7 +138,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
withLocalScopeCleanup {
|
withLocalScopeCleanup {
|
||||||
addLocalScope(context.getPrimaryConstructorParametersScope())
|
addLocalScope(context.getPrimaryConstructorParametersScope())
|
||||||
property.transformChildrenWithoutAccessors(returnTypeRef)
|
property.transformChildrenWithoutAccessors(returnTypeRef)
|
||||||
property.transformInitializer(integerLiteralTypeApproximator, property.returnTypeRef.coneTypeSafe())
|
|
||||||
}
|
}
|
||||||
if (property.initializer != null) {
|
if (property.initializer != null) {
|
||||||
storeVariableReturnType(property)
|
storeVariableReturnType(property)
|
||||||
@@ -253,7 +252,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
(delegateProvider as? FirFunctionCall)?.let { dataFlowAnalyzer.dropSubgraphFromCall(it) }
|
(delegateProvider as? FirFunctionCall)?.let { dataFlowAnalyzer.dropSubgraphFromCall(it) }
|
||||||
return wrappedDelegateExpression.expression
|
return wrappedDelegateExpression.expression
|
||||||
.transformSingle(transformer, ResolutionMode.ContextDependent)
|
.transformSingle(transformer, ResolutionMode.ContextDependent)
|
||||||
.transform(integerLiteralTypeApproximator, null)
|
.approximateIfIsIntegerConst()
|
||||||
|
.compose()
|
||||||
} finally {
|
} finally {
|
||||||
dataFlowAnalyzer.exitDelegateExpression()
|
dataFlowAnalyzer.exitDelegateExpression()
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
.transformDelegate(transformer, resolutionMode)
|
.transformDelegate(transformer, resolutionMode)
|
||||||
.transformTypeParameters(transformer, resolutionMode)
|
.transformTypeParameters(transformer, resolutionMode)
|
||||||
.transformOtherChildren(transformer, resolutionMode)
|
.transformOtherChildren(transformer, resolutionMode)
|
||||||
.transformInitializer(integerLiteralTypeApproximator, null)
|
|
||||||
if (variable.initializer != null) {
|
if (variable.initializer != null) {
|
||||||
storeVariableReturnType(variable)
|
storeVariableReturnType(variable)
|
||||||
}
|
}
|
||||||
@@ -650,12 +649,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataFlowAnalyzer.enterValueParameter(valueParameter)
|
dataFlowAnalyzer.enterValueParameter(valueParameter)
|
||||||
val transformedValueParameter =
|
|
||||||
valueParameter.transformInitializer(integerLiteralTypeApproximator, valueParameter.returnTypeRef.coneType)
|
|
||||||
|
|
||||||
val result = transformDeclarationContent(
|
val result = transformDeclarationContent(
|
||||||
transformedValueParameter,
|
valueParameter,
|
||||||
withExpectedType(transformedValueParameter.returnTypeRef)
|
withExpectedType(valueParameter.returnTypeRef)
|
||||||
).single as FirValueParameter
|
).single as FirValueParameter
|
||||||
|
|
||||||
dataFlowAnalyzer.exitValueParameter(result)?.let { graph ->
|
dataFlowAnalyzer.exitValueParameter(result)?.let { graph ->
|
||||||
@@ -752,8 +748,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
|||||||
ConeSubstitutor.Empty,
|
ConeSubstitutor.Empty,
|
||||||
components.returnTypeCalculator,
|
components.returnTypeCalculator,
|
||||||
inferenceComponents.approximator,
|
inferenceComponents.approximator,
|
||||||
integerOperatorsTypeUpdater,
|
|
||||||
integerLiteralTypeApproximator
|
|
||||||
)
|
)
|
||||||
lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.toExpectedType())
|
lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.toExpectedType())
|
||||||
val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda)
|
val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda)
|
||||||
|
|||||||
+3
-14
@@ -309,14 +309,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
transformer.onBeforeStatementResolution(block.statements[index])
|
transformer.onBeforeStatementResolution(block.statements[index])
|
||||||
TransformData.Data(value)
|
TransformData.Data(value)
|
||||||
}
|
}
|
||||||
if (data == ResolutionMode.ContextIndependent) {
|
|
||||||
block.transformStatements(integerLiteralTypeApproximator, null)
|
|
||||||
} else {
|
|
||||||
block.transformAllStatementsExceptLast(
|
|
||||||
integerLiteralTypeApproximator,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
block.transformOtherChildren(transformer, data)
|
block.transformOtherChildren(transformer, data)
|
||||||
block.writeResultType(session)
|
block.writeResultType(session)
|
||||||
|
|
||||||
@@ -336,8 +328,8 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
return (comparisonExpression.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirComparisonExpression).also {
|
return (comparisonExpression.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirComparisonExpression).also {
|
||||||
it.resultType = comparisonExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
|
it.resultType = comparisonExpression.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type)
|
||||||
}.transformSingle(integerLiteralTypeApproximator, null)
|
dataFlowAnalyzer.exitComparisonExpressionCall(it)
|
||||||
.also(dataFlowAnalyzer::exitComparisonExpressionCall).compose()
|
}.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformAssignmentOperatorStatement(
|
override fun transformAssignmentOperatorStatement(
|
||||||
@@ -429,7 +421,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
): CompositeTransformResult<FirStatement> {
|
): CompositeTransformResult<FirStatement> {
|
||||||
val result = (equalityOperatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirEqualityOperatorCall)
|
val result = (equalityOperatorCall.transformChildren(transformer, ResolutionMode.ContextIndependent) as FirEqualityOperatorCall)
|
||||||
.also { it.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) }
|
.also { it.resultType = equalityOperatorCall.typeRef.resolvedTypeFromPrototype(builtinTypes.booleanType.type) }
|
||||||
.transformSingle(integerLiteralTypeApproximator, null)
|
|
||||||
dataFlowAnalyzer.exitEqualityOperatorCall(result)
|
dataFlowAnalyzer.exitEqualityOperatorCall(result)
|
||||||
return result.compose()
|
return result.compose()
|
||||||
}
|
}
|
||||||
@@ -481,7 +472,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
val resolved = components.typeResolverTransformer.withAllowedBareTypes {
|
val resolved = components.typeResolverTransformer.withAllowedBareTypes {
|
||||||
typeOperatorCall.transformConversionTypeRef(transformer, ResolutionMode.ContextIndependent)
|
typeOperatorCall.transformConversionTypeRef(transformer, ResolutionMode.ContextIndependent)
|
||||||
}.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
|
}.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
|
||||||
resolved.argumentList.transformArguments(integerLiteralTypeApproximator, null)
|
|
||||||
|
|
||||||
val conversionTypeRef = resolved.conversionTypeRef.withTypeArgumentsForBareType(resolved.argument)
|
val conversionTypeRef = resolved.conversionTypeRef.withTypeArgumentsForBareType(resolved.argument)
|
||||||
resolved.transformChildren(object : FirDefaultTransformer<Nothing?>() {
|
resolved.transformChildren(object : FirDefaultTransformer<Nothing?>() {
|
||||||
@@ -520,7 +510,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
else -> error("Unknown type operator: ${resolved.operation}")
|
else -> error("Unknown type operator: ${resolved.operation}")
|
||||||
}
|
}
|
||||||
dataFlowAnalyzer.exitTypeOperatorCall(resolved)
|
dataFlowAnalyzer.exitTypeOperatorCall(resolved)
|
||||||
return resolved.transform(integerLiteralTypeApproximator, null)
|
return resolved.compose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformCheckNotNullCall(
|
override fun transformCheckNotNullCall(
|
||||||
@@ -587,7 +577,6 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
|||||||
val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType).result // TODO: check
|
val completeAssignment = callCompleter.completeCall(resolvedAssignment, noExpectedType).result // TODO: check
|
||||||
val expectedType = components.typeFromCallee(completeAssignment)
|
val expectedType = components.typeFromCallee(completeAssignment)
|
||||||
completeAssignment.transformRValue(transformer, withExpectedType(expectedType))
|
completeAssignment.transformRValue(transformer, withExpectedType(expectedType))
|
||||||
.transformRValue(integerLiteralTypeApproximator, expectedType.coneTypeSafe())
|
|
||||||
} else {
|
} else {
|
||||||
// This can happen in erroneous code only
|
// This can happen in erroneous code only
|
||||||
resolvedAssignment
|
resolvedAssignment
|
||||||
|
|||||||
-192
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user