From 0d94c3aeb44162bb5cd7cd672b1c4a58927d7dbc Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 17 Aug 2016 17:21:33 +0300 Subject: [PATCH] 'in' and '!in' operators. --- .../generators/IrOperatorConventions.kt | 76 +++++++++++++++++++ .../IrOperatorExpressionGenerator.kt | 61 ++++----------- compiler/testData/ir/irText/in.kt | 4 + compiler/testData/ir/irText/in.txt | 31 ++++++++ .../kotlin/ir/IrTextTestCaseGenerated.java | 6 ++ 5 files changed, 131 insertions(+), 47 deletions(-) create mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorConventions.kt create mode 100644 compiler/testData/ir/irText/in.kt create mode 100644 compiler/testData/ir/irText/in.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorConventions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorConventions.kt new file mode 100644 index 00000000000..5a7e095543b --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorConventions.kt @@ -0,0 +1,76 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.psi2ir.generators + +import com.intellij.psi.tree.IElementType +import org.jetbrains.kotlin.ir.expressions.IrOperator +import org.jetbrains.kotlin.lexer.KtTokens + + + +internal fun getIrOperator(ktOperator: IElementType): IrOperator? = + KT_TOKEN_TO_IR_OPERATOR[ktOperator] + +internal val KT_TOKEN_TO_IR_OPERATOR = + mapOf( + KtTokens.EQ to IrOperator.EQ, + + KtTokens.PLUSEQ to IrOperator.PLUSEQ, + KtTokens.MINUSEQ to IrOperator.MINUSEQ, + KtTokens.MULTEQ to IrOperator.MULTEQ, + KtTokens.DIVEQ to IrOperator.DIVEQ, + KtTokens.PERCEQ to IrOperator.PERCEQ, + + KtTokens.PLUS to IrOperator.PLUS, + KtTokens.MINUS to IrOperator.MINUS, + KtTokens.MUL to IrOperator.MUL, + KtTokens.DIV to IrOperator.DIV, + KtTokens.PERC to IrOperator.PERC, + KtTokens.RANGE to IrOperator.RANGE, + + KtTokens.LT to IrOperator.LT, + KtTokens.LTEQ to IrOperator.LTEQ, + KtTokens.GT to IrOperator.GT, + KtTokens.GTEQ to IrOperator.GTEQ, + + KtTokens.EQEQ to IrOperator.EQEQ, + KtTokens.EXCLEQ to IrOperator.EXCLEQ, + + KtTokens.EQEQEQ to IrOperator.EQEQEQ, + KtTokens.EXCLEQEQEQ to IrOperator.EXCLEQEQ, + + KtTokens.IN_KEYWORD to IrOperator.IN, + KtTokens.NOT_IN to IrOperator.NOT_IN + ) + +internal val AUGMENTED_ASSIGNMENTS = + setOf(IrOperator.PLUSEQ, IrOperator.MINUSEQ, IrOperator.MULTEQ, IrOperator.DIVEQ, IrOperator.PERCEQ) + +internal val BINARY_OPERATORS_DESUGARED_TO_CALLS = + setOf(IrOperator.PLUS, IrOperator.MINUS, IrOperator.MUL, IrOperator.DIV, IrOperator.PERC, IrOperator.RANGE) + +internal val COMPARISON_OPERATORS = + setOf(IrOperator.LT, IrOperator.LTEQ, IrOperator.GT, IrOperator.GTEQ) + +internal val EQUALITY_OPERATORS = + setOf(IrOperator.EQEQ, IrOperator.EXCLEQ) + +internal val IDENTITY_OPERATORS = + setOf(IrOperator.EQEQEQ, IrOperator.EXCLEQEQ) + +internal val IN_OPERATORS = + setOf(IrOperator.IN, IrOperator.NOT_IN) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorExpressionGenerator.kt index 902a4e45bf6..38b69a6632a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/IrOperatorExpressionGenerator.kt @@ -16,13 +16,12 @@ package org.jetbrains.kotlin.psi2ir.generators -import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.ir.expressions.IrBinaryOperatorExpressionImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrOperator -import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.ir.expressions.IrUnaryOperatorExpressionImpl import org.jetbrains.kotlin.psi.KtArrayAccessExpression import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtExpression @@ -34,48 +33,6 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall import org.jetbrains.kotlin.types.typeUtil.makeNullable -internal val KT_TOKEN_TO_IR_OPERATOR = - mapOf( - KtTokens.EQ to IrOperator.EQ, - - KtTokens.PLUSEQ to IrOperator.PLUSEQ, - KtTokens.MINUSEQ to IrOperator.MINUSEQ, - KtTokens.MULTEQ to IrOperator.MULTEQ, - KtTokens.DIVEQ to IrOperator.DIVEQ, - KtTokens.PERCEQ to IrOperator.PERCEQ, - - KtTokens.PLUS to IrOperator.PLUS, - KtTokens.MINUS to IrOperator.MINUS, - KtTokens.MUL to IrOperator.MUL, - KtTokens.DIV to IrOperator.DIV, - KtTokens.PERC to IrOperator.PERC, - KtTokens.RANGE to IrOperator.RANGE, - - KtTokens.LT to IrOperator.LT, - KtTokens.LTEQ to IrOperator.LTEQ, - KtTokens.GT to IrOperator.GT, - KtTokens.GTEQ to IrOperator.GTEQ, - - KtTokens.EQEQ to IrOperator.EQEQ, - KtTokens.EXCLEQ to IrOperator.EXCLEQ, - KtTokens.EQEQEQ to IrOperator.EQEQEQ, - KtTokens.EXCLEQEQEQ to IrOperator.EXCLEQEQ - ) - -internal val AUGMENTED_ASSIGNMENTS = - setOf(IrOperator.PLUSEQ, IrOperator.MINUSEQ, IrOperator.MULTEQ, IrOperator.DIVEQ, IrOperator.PERCEQ) - -internal val BINARY_OPERATORS_DESUGARED_TO_CALLS = - setOf(IrOperator.PLUS, IrOperator.MINUS, IrOperator.MUL, IrOperator.DIV, IrOperator.PERC, IrOperator.RANGE) - -internal val COMPARISON_OPERATORS = - setOf(IrOperator.LT, IrOperator.LTEQ, IrOperator.GT, IrOperator.GTEQ) - -internal val EQUALITY_OPERATORS = - setOf(IrOperator.EQEQ, IrOperator.EXCLEQ) - -internal val IDENTITY_OPERATORS = - setOf(IrOperator.EQEQEQ, IrOperator.EXCLEQEQ) class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerator): IrGenerator { override val context: IrGeneratorContext get() = irStatementGenerator.context @@ -92,10 +49,23 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat in COMPARISON_OPERATORS -> generateComparisonOperator(expression, irOperator) in EQUALITY_OPERATORS -> generateEqualityOperator(expression, irOperator) in IDENTITY_OPERATORS -> generateIdentityOperator(expression, irOperator) + in IN_OPERATORS -> generateInOperator(expression, irOperator) else -> createDummyExpression(expression, ktOperator.toString()) } } + private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression { + val operatorCall = getResolvedCall(expression)!! + + val irOperatorCall = IrCallGenerator(irStatementGenerator).generateCall(expression, operatorCall, irOperator) + + return if (irOperator == IrOperator.IN) + irOperatorCall + else + IrUnaryOperatorExpressionImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, + IrOperator.EXCL, null, irOperatorCall) + } + private fun generateIdentityOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression { val irArgument0 = irStatementGenerator.generateExpression(expression.left!!) val irArgument1 = irStatementGenerator.generateExpression(expression.right!!) @@ -175,9 +145,6 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat } } - private fun getIrOperator(ktOperator: IElementType): IrOperator? = - KT_TOKEN_TO_IR_OPERATOR[ktOperator] - private fun generateAssignment(expression: KtBinaryExpression): IrExpression { val ktLeft = expression.left!! val ktRight = expression.right!! diff --git a/compiler/testData/ir/irText/in.kt b/compiler/testData/ir/irText/in.kt new file mode 100644 index 00000000000..94af6759b0f --- /dev/null +++ b/compiler/testData/ir/irText/in.kt @@ -0,0 +1,4 @@ +fun test1(a: Any, x: Collection) = a in x +fun test2(a: Any, x: Collection) = a !in x +fun test3(a: T, x: Collection) = a in x +fun test4(a: T, x: Collection) = a !in x \ No newline at end of file diff --git a/compiler/testData/ir/irText/in.txt b/compiler/testData/ir/irText/in.txt new file mode 100644 index 00000000000..bc20c3dffa9 --- /dev/null +++ b/compiler/testData/ir/irText/in.txt @@ -0,0 +1,31 @@ +IrFile /in.kt + IrFunction public fun test1(/*0*/ a: kotlin.Any, /*1*/ x: kotlin.collections.Collection): kotlin.Boolean + IrExpressionBody + BLOCK type= hasResult=false isDesugared=true + RETURN type= + CALL .contains type=kotlin.Boolean operator=IN + $this: GET_VAR x type=kotlin.collections.Collection + element: GET_VAR a type=kotlin.Any + IrFunction public fun test2(/*0*/ a: kotlin.Any, /*1*/ x: kotlin.collections.Collection): kotlin.Boolean + IrExpressionBody + BLOCK type= hasResult=false isDesugared=true + RETURN type= + UNARY_OP operator=EXCL type=kotlin.Boolean related=null + CALL .contains type=kotlin.Boolean operator=NOT_IN + $this: GET_VAR x type=kotlin.collections.Collection + element: GET_VAR a type=kotlin.Any + IrFunction public fun test3(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection): kotlin.Boolean + IrExpressionBody + BLOCK type= hasResult=false isDesugared=true + RETURN type= + CALL .contains type=kotlin.Boolean operator=IN + $this: GET_VAR x type=kotlin.collections.Collection + element: GET_VAR a type=T + IrFunction public fun test4(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection): kotlin.Boolean + IrExpressionBody + BLOCK type= hasResult=false isDesugared=true + RETURN type= + UNARY_OP operator=EXCL type=kotlin.Boolean related=null + CALL .contains type=kotlin.Boolean operator=NOT_IN + $this: GET_VAR x type=kotlin.collections.Collection + element: GET_VAR a type=T diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 67f879ddf68..287abdc7422 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -125,6 +125,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("in.kt") + public void testIn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/in.kt"); + doTest(fileName); + } + @TestMetadata("primitiveComparisons.kt") public void testPrimitiveComparisons() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/primitiveComparisons.kt");