Raw FIR: convert in to contains and !in to contains.not

This commit is contained in:
Mikhail Glukhikh
2019-04-05 12:17:11 +03:00
parent 4482a8f794
commit a0c4e2f05f
7 changed files with 46 additions and 15 deletions
@@ -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)
}
}
}
@@ -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
)
}
}