Raw FIR: convert in to contains and !in to contains.not
This commit is contained in:
@@ -160,8 +160,6 @@ internal fun IElementType.toFirOperation(): FirOperation =
|
||||
KtTokens.EXCLEQ -> FirOperation.NOT_EQ
|
||||
KtTokens.EQEQEQ -> FirOperation.IDENTITY
|
||||
KtTokens.EXCLEQEQEQ -> FirOperation.NOT_IDENTITY
|
||||
KtTokens.IN_KEYWORD -> FirOperation.IN
|
||||
KtTokens.NOT_IN -> FirOperation.NOT_IN
|
||||
|
||||
KtTokens.EQ -> FirOperation.ASSIGN
|
||||
KtTokens.PLUSEQ -> FirOperation.PLUS_ASSIGN
|
||||
@@ -237,14 +235,8 @@ internal fun KtWhenCondition.toFirWhenCondition(
|
||||
}
|
||||
}
|
||||
is KtWhenConditionInRange -> {
|
||||
FirOperatorCallImpl(
|
||||
session,
|
||||
rangeExpression,
|
||||
if (isNegated) FirOperation.NOT_IN else FirOperation.IN
|
||||
).apply {
|
||||
arguments += firSubjectExpression
|
||||
arguments += rangeExpression.convert("No range in condition with range")
|
||||
}
|
||||
val firRange = rangeExpression.convert("No range in condition with range")
|
||||
firRange.generateContainsOperation(session, firSubjectExpression, isNegated, rangeExpression, operationReference)
|
||||
}
|
||||
is KtWhenConditionIsPattern -> {
|
||||
FirTypeOperatorCallImpl(
|
||||
@@ -321,6 +313,25 @@ internal fun Array<KtStringTemplateEntry>.toInterpolatingCall(
|
||||
return if (hasExpressions) result!! else FirConstExpressionImpl(session, base, IrConstKind.String, sb.toString())
|
||||
}
|
||||
|
||||
internal fun FirExpression.generateContainsOperation(
|
||||
session: FirSession,
|
||||
argument: FirExpression,
|
||||
inverted: Boolean,
|
||||
base: KtExpression?,
|
||||
operationReference: KtOperationReferenceExpression
|
||||
): FirFunctionCall {
|
||||
val containsCall = FirFunctionCallImpl(session, base).apply {
|
||||
calleeReference = FirSimpleNamedReference(session, operationReference, OperatorNameConventions.CONTAINS)
|
||||
explicitReceiver = this@generateContainsOperation
|
||||
arguments += argument
|
||||
}
|
||||
if (!inverted) return containsCall
|
||||
return FirFunctionCallImpl(session, base).apply {
|
||||
calleeReference = FirSimpleNamedReference(session, operationReference, OperatorNameConventions.NOT)
|
||||
explicitReceiver = containsCall
|
||||
}
|
||||
}
|
||||
|
||||
internal fun generateIncrementOrDecrementBlock(
|
||||
session: FirSession,
|
||||
baseExpression: KtUnaryExpression,
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -1137,6 +1136,10 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
|
||||
return leftArgument.generateNotNullOrOther(session, rightArgument, "elvis", expression)
|
||||
ANDAND, OROR ->
|
||||
return leftArgument.generateLazyLogicalOperation(session, rightArgument, operationToken == ANDAND, expression)
|
||||
in OperatorConventions.IN_OPERATIONS ->
|
||||
return rightArgument.generateContainsOperation(
|
||||
session, leftArgument, operationToken == NOT_IN, expression, expression.operationReference
|
||||
)
|
||||
}
|
||||
val conventionCallName = operationToken.toBinaryName()
|
||||
return if (conventionCallName != null || operationToken == IDENTIFIER) {
|
||||
|
||||
@@ -57,7 +57,7 @@ FILE: branches.kt
|
||||
==($subj$, Int(3)) -> {
|
||||
String(Mediocre)
|
||||
}
|
||||
in($subj$, Int(1).rangeTo#(Int(2))) -> {
|
||||
Int(1).rangeTo#(Int(2)).contains#($subj$) -> {
|
||||
String(Fail)
|
||||
}
|
||||
($subj$ is Number) -> {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fun foo(x: Int, y: Int, c: Collection<Int>) =
|
||||
x in c && y !in c
|
||||
@@ -0,0 +1,12 @@
|
||||
FILE: in.kt
|
||||
public? final? fun foo(x: Int, y: Int, c: Collection<Int>): <implicit> {
|
||||
^foo when () {
|
||||
c#.contains#(x#) -> {
|
||||
c#.contains#(y#).not#()
|
||||
}
|
||||
else -> {
|
||||
Boolean(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Generated
+5
@@ -204,6 +204,11 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/genericCalls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("in.kt")
|
||||
public void testIn() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/in.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("init.kt")
|
||||
public void testInit() throws Exception {
|
||||
runTest("compiler/fir/psi2fir/testData/rawBuilder/expressions/init.kt");
|
||||
|
||||
@@ -17,8 +17,6 @@ enum class FirOperation(val operator: String = "???") {
|
||||
GT(">"),
|
||||
LT_EQ("<="),
|
||||
GT_EQ(">="),
|
||||
IN("in"),
|
||||
NOT_IN("!in"),
|
||||
|
||||
ASSIGN("="),
|
||||
PLUS_ASSIGN("+="),
|
||||
@@ -41,7 +39,7 @@ enum class FirOperation(val operator: String = "???") {
|
||||
val ASSIGNMENTS: Set<FirOperation> = EnumSet.of(ASSIGN, PLUS_ASSIGN, MINUS_ASSIGN, TIMES_ASSIGN, DIV_ASSIGN, REM_ASSIGN)
|
||||
|
||||
val BOOLEANS: Set<FirOperation> = EnumSet.of(
|
||||
EQ, NOT_EQ, IDENTITY, NOT_IDENTITY, LT, GT, LT_EQ, GT_EQ, IN, NOT_IN, IS, NOT_IS
|
||||
EQ, NOT_EQ, IDENTITY, NOT_IDENTITY, LT, GT, LT_EQ, GT_EQ, IS, NOT_IS
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user