'in' and '!in' operators.
This commit is contained in:
committed by
Dmitry Petrov
parent
96e3c52878
commit
0d94c3aeb4
+76
@@ -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)
|
||||
+14
-47
@@ -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!!
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
fun test1(a: Any, x: Collection<Any>) = a in x
|
||||
fun test2(a: Any, x: Collection<Any>) = a !in x
|
||||
fun <T> test3(a: T, x: Collection<T>) = a in x
|
||||
fun <T> test4(a: T, x: Collection<T>) = a !in x
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
IrFile /in.kt
|
||||
IrFunction public fun test1(/*0*/ a: kotlin.Any, /*1*/ x: kotlin.collections.Collection<kotlin.Any>): kotlin.Boolean
|
||||
IrExpressionBody
|
||||
BLOCK type=<no-type> hasResult=false isDesugared=true
|
||||
RETURN type=<no-type>
|
||||
CALL .contains type=kotlin.Boolean operator=IN
|
||||
$this: GET_VAR x type=kotlin.collections.Collection<kotlin.Any>
|
||||
element: GET_VAR a type=kotlin.Any
|
||||
IrFunction public fun test2(/*0*/ a: kotlin.Any, /*1*/ x: kotlin.collections.Collection<kotlin.Any>): kotlin.Boolean
|
||||
IrExpressionBody
|
||||
BLOCK type=<no-type> hasResult=false isDesugared=true
|
||||
RETURN type=<no-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<kotlin.Any>
|
||||
element: GET_VAR a type=kotlin.Any
|
||||
IrFunction public fun </*0*/ T> test3(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection<T>): kotlin.Boolean
|
||||
IrExpressionBody
|
||||
BLOCK type=<no-type> hasResult=false isDesugared=true
|
||||
RETURN type=<no-type>
|
||||
CALL .contains type=kotlin.Boolean operator=IN
|
||||
$this: GET_VAR x type=kotlin.collections.Collection<T>
|
||||
element: GET_VAR a type=T
|
||||
IrFunction public fun </*0*/ T> test4(/*0*/ a: T, /*1*/ x: kotlin.collections.Collection<T>): kotlin.Boolean
|
||||
IrExpressionBody
|
||||
BLOCK type=<no-type> hasResult=false isDesugared=true
|
||||
RETURN type=<no-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<T>
|
||||
element: GET_VAR a type=T
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user