diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 73e6f058f3d..5f9080ce526 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenForLambda; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; -import org.jetbrains.kotlin.codegen.forLoop.AbstractForLoopGenerator; import org.jetbrains.kotlin.codegen.forLoop.ForLoopGenerator; import org.jetbrains.kotlin.codegen.inline.*; import org.jetbrains.kotlin.codegen.intrinsics.*; @@ -2871,25 +2870,27 @@ public class ExpressionCodegen extends KtVisitor impleme private StackValue generateIn(StackValue leftValue, KtExpression rangeExpression, KtSimpleNameExpression operationReference) { KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression); - assert deparenthesized != null : "For with empty range expression"; - boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN; - return StackValue.operation(Type.BOOLEAN_TYPE, v -> { - if (RangeCodegenUtilKt.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) || - RangeCodegenUtilKt.isPrimitiveRangeToExtension(operationReference, bindingContext)) { - generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted); - } - else { - ResolvedCall resolvedCall = CallUtilKt - .getResolvedCallWithAssert(operationReference, bindingContext); - StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none()); - result.put(result.type, v); - if (isInverted) { - genInvertBoolean(v); - } - } - return null; - }); + RangeValue rangeValue = RangeValuesKt.createRangeValueForExpression(this, deparenthesized); + return rangeValue.createInExpressionGenerator(this, operationReference).generate(leftValue); + + //boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN; + //return StackValue.operation(Type.BOOLEAN_TYPE, v -> { + // if (RangeCodegenUtilKt.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) || + // RangeCodegenUtilKt.isPrimitiveRangeToExtension(operationReference, bindingContext)) { + // generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted); + // } + // else { + // ResolvedCall resolvedCall = CallUtilKt + // .getResolvedCallWithAssert(operationReference, bindingContext); + // StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none()); + // result.put(result.type, v); + // if (isInverted) { + // genInvertBoolean(v); + // } + // } + // return null; + //}); } /* diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt index 1f16a9aa232..50be6a87f39 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt @@ -55,7 +55,7 @@ fun isRange(rangeType: KotlinType) = fun isProgression(rangeType: KotlinType) = !rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null -private fun getPrimitiveRangeElementType(rangeType: KotlinType) = +fun getPrimitiveRangeElementType(rangeType: KotlinType) = getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE) private fun getPrimitiveProgressionElementType(rangeType: KotlinType) = diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractInPrimitiveNumberRangeExpressionGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractInPrimitiveNumberRangeExpressionGenerator.kt new file mode 100644 index 00000000000..774e5a29447 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractInPrimitiveNumberRangeExpressionGenerator.kt @@ -0,0 +1,175 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter + +abstract class AbstractInPrimitiveNumberRangeExpressionGenerator( + val codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*>, + private val isInclusiveHighBound: Boolean +) : InExpressionGenerator { + protected val asmElementType = + AsmTypes.valueTypeForPrimitive( + getPrimitiveRangeElementType(rangeCall.resultingDescriptor.returnType!!) + ) + + private val isInverted = + operatorReference.getReferencedNameElementType() == KtTokens.NOT_IN + + protected abstract fun genLowBound(): StackValue + protected abstract fun genHighBound(): StackValue + + override fun generate(argument: StackValue): BranchedValue = + gen(argument).let { if (isInverted) Invert(it) else it } + + private fun gen(argument: StackValue): BranchedValue = + object : BranchedValue(argument, null, asmElementType, Opcodes.IFEQ) { + override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { + if (jumpIfFalse) { + // arg1 in low .. high + // arg1 >= low && arg1 <[=] high + val cmpHighLabel = Label() + + arg1.put(operandType, v) + AsmUtil.dup(v, operandType) + + genLowBound().put(operandType, v) + v.jumpIfGe(cmpHighLabel) + + AsmUtil.pop(v, operandType) + v.goTo(jumpLabel) + + v.mark(cmpHighLabel) + genHighBound().put(operandType, v) + if (isInclusiveHighBound) { + v.jumpIfGt(jumpLabel) + } + else { + v.jumpIfGe(jumpLabel) + } + } + else { + // arg1 !in low .. high + // arg1 < low || arg1 >[=] high + val trueLabel1 = Label() + val trueLabel2 = Label() + + arg1.put(operandType, v) + AsmUtil.dup(v, operandType) + + genLowBound().put(operandType, v) + v.jumpIfLt(trueLabel1) + + genLowBound().put(operandType, v) + if (isInclusiveHighBound) { + v.jumpIfLe(jumpLabel) + } + else { + v.jumpIfLt(jumpLabel) + } + v.goTo(trueLabel2) + + v.mark(trueLabel1) + AsmUtil.pop(v, operandType) + + v.mark(trueLabel2) + } + } + + private fun InstructionAdapter.jumpIfGe(label: Label) { + when { + AsmUtil.isIntPrimitive(operandType) -> ificmpge(label) + + operandType === Type.LONG_TYPE -> { + lcmp() + ifge(label) + } + + operandType === Type.FLOAT_TYPE || operandType === Type.DOUBLE_TYPE -> { + cmpg(operandType) + ifge(label) + } + + else -> throw UnsupportedOperationException("Unexpected type: " + operandType) + } + } + + private fun InstructionAdapter.jumpIfLe(label: Label) { + when { + AsmUtil.isIntPrimitive(operandType) -> ificmple(label) + + operandType === Type.LONG_TYPE -> { + lcmp() + ifle(label) + } + + operandType === Type.FLOAT_TYPE || operandType === Type.DOUBLE_TYPE -> { + cmpg(operandType) + ifle(label) + } + + else -> throw UnsupportedOperationException("Unexpected type: " + operandType) + } + } + + private fun InstructionAdapter.jumpIfGt(label: Label) { + when { + AsmUtil.isIntPrimitive(operandType) -> ificmpgt(label) + + operandType === Type.LONG_TYPE -> { + lcmp() + ifgt(label) + } + + operandType === Type.FLOAT_TYPE || operandType === Type.DOUBLE_TYPE -> { + cmpg(operandType) + ifgt(label) + } + + else -> throw UnsupportedOperationException("Unexpected type: " + operandType) + } + } + + private fun InstructionAdapter.jumpIfLt(label: Label) { + when { + AsmUtil.isIntPrimitive(operandType) -> ificmplt(label) + + operandType === Type.LONG_TYPE -> { + lcmp() + iflt(label) + } + + operandType === Type.FLOAT_TYPE || operandType === Type.DOUBLE_TYPE -> { + cmpg(operandType) + iflt(label) + } + + else -> throw UnsupportedOperationException("Unexpected type: " + operandType) + } + } + } +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallBasedInExpressionGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallBasedInExpressionGenerator.kt new file mode 100644 index 00000000000..76f44d8fcdc --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallBasedInExpressionGenerator.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter + +class CallBasedInExpressionGenerator( + val codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression +) : InExpressionGenerator { + private val resolvedCall = operatorReference.getResolvedCallWithAssert(codegen.bindingContext) + private val isInverted = operatorReference.getReferencedNameElementType() == KtTokens.NOT_IN + + override fun generate(argument: StackValue): BranchedValue = + gen(argument).let { if (isInverted) Invert(it) else it } + + private fun gen(argument: StackValue): BranchedValue = + object : BranchedValue(argument, null, argument.type, Opcodes.IFEQ) { + override fun putSelector(type: Type, v: InstructionAdapter) { + invokeFunction(v) + } + + override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { + invokeFunction(v) + v.visitJumpInsn(if (jumpIfFalse) Opcodes.IFEQ else Opcodes.IFNE, jumpLabel) + } + + private fun invokeFunction(v: InstructionAdapter) { + val result = codegen.invokeFunction(resolvedCall.call, resolvedCall, none()) + result.put(result.type, v) + } + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InArrayIndicesGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InArrayIndicesGenerator.kt new file mode 100644 index 00000000000..e893512ce88 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InArrayIndicesGenerator.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.org.objectweb.asm.Type + +class InArrayIndicesGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = false) { + private val receiverValue: ReceiverValue = rangeCall.extensionReceiver!! + private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) + + override fun genLowBound(): StackValue = StackValue.constant(0, asmElementType) + + override fun genHighBound(): StackValue = + StackValue.operation(Type.INT_TYPE) { v -> + codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v) + v.arraylength() + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCharSequenceIndicesGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCharSequenceIndicesGenerator.kt new file mode 100644 index 00000000000..ffc34baee28 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCharSequenceIndicesGenerator.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.org.objectweb.asm.Type + +class InCharSequenceIndicesGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = false) { + private val receiverValue: ReceiverValue = rangeCall.extensionReceiver!! + private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) + + override fun genLowBound(): StackValue = StackValue.constant(0, asmElementType) + + override fun genHighBound(): StackValue = + StackValue.operation(Type.INT_TYPE) { v -> + codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v) + v.invokeinterface("java/lang/CharSequence", "length", "()I") + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCollectionIndicesGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCollectionIndicesGenerator.kt new file mode 100644 index 00000000000..0dd8d9234df --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InCollectionIndicesGenerator.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.org.objectweb.asm.Type + +class InCollectionIndicesGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = false) { + private val receiverValue: ReceiverValue = rangeCall.extensionReceiver!! + private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) + + override fun genLowBound(): StackValue = StackValue.constant(0, asmElementType) + + override fun genHighBound(): StackValue = + StackValue.operation(Type.INT_TYPE) { v -> + codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v) + v.invokeinterface("java/util/Collection", "size", "()I") + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InExpressionGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InExpressionGenerator.kt new file mode 100644 index 00000000000..75a2509add7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InExpressionGenerator.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.BranchedValue +import org.jetbrains.kotlin.codegen.StackValue + +interface InExpressionGenerator { + fun generate(argument: StackValue): BranchedValue +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberDownToGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberDownToGenerator.kt new file mode 100644 index 00000000000..e2b018a32a7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberDownToGenerator.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue + +class InPrimitiveNumberDownToGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = true) { + private val from: ReceiverValue = rangeCall.dispatchReceiver!! + private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(rangeCall)!! + + override fun genLowBound(): StackValue = codegen.gen(to) + + override fun genHighBound(): StackValue = codegen.generateReceiverValue(from, false) +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberRangeLiteralGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberRangeLiteralGenerator.kt new file mode 100644 index 00000000000..b8f3eb8cf0f --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberRangeLiteralGenerator.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue + +class InPrimitiveNumberRangeLiteralGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = true) { + private val from: ReceiverValue = rangeCall.dispatchReceiver!! + private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(rangeCall)!! + + override fun genLowBound(): StackValue = codegen.generateReceiverValue(from, false) + + override fun genHighBound(): StackValue = codegen.gen(to) +} + diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberUntilGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberUntilGenerator.kt new file mode 100644 index 00000000000..c64993983e4 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/InPrimitiveNumberUntilGenerator.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2017 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.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue + +class InPrimitiveNumberUntilGenerator( + codegen: ExpressionCodegen, + operatorReference: KtSimpleNameExpression, + rangeCall: ResolvedCall<*> +) : AbstractInPrimitiveNumberRangeExpressionGenerator(codegen, operatorReference, rangeCall, isInclusiveHighBound = false) { + private val from: ReceiverValue = rangeCall.dispatchReceiver!! + private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(rangeCall)!! + + override fun genLowBound(): StackValue = codegen.generateReceiverValue(from, false) + + override fun genHighBound(): StackValue = codegen.gen(to) +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValue.kt index 3d71c7b6acf..3b81d96f115 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValue.kt @@ -20,66 +20,102 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.forLoop.* import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall interface RangeValue { fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator + + fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator } class ArrayRangeValue : RangeValue { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInArrayLoopGenerator(codegen, forExpression) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) } class PrimitiveRangeRangeValue : RangeValue { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInRangeInstanceLoopGenerator(codegen, forExpression) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) } class PrimitiveProgressionRangeValue : RangeValue { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInProgressionExpressionLoopGenerator(codegen, forExpression) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) } class CharSequenceRangeValue : RangeValue { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInCharSequenceLoopGenerator(codegen, forExpression) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) } class IterableRangeValue : RangeValue { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = IteratorForLoopGenerator(codegen, forExpression) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) } -abstract class CallIntrinsicRangeValue(protected val loopRangeCall: ResolvedCall): RangeValue +abstract class CallIntrinsicRangeValue(protected val rangeCall: ResolvedCall): RangeValue -class PrimitiveNumberRangeToRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { +class PrimitiveNumberRangeLiteralRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInRangeLiteralLoopGenerator(codegen, forExpression, loopRangeCall) + ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InPrimitiveNumberRangeLiteralGenerator(codegen, operatorReference, rangeCall) } class DownToProgressionRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInDownToProgressionLoopGenerator(codegen, forExpression, loopRangeCall) + ForInDownToProgressionLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InPrimitiveNumberDownToGenerator(codegen, operatorReference, rangeCall) } class PrimitiveNumberUntilRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInUntilRangeLoopGenerator(codegen, forExpression, loopRangeCall) + ForInUntilRangeLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InPrimitiveNumberUntilGenerator(codegen, operatorReference, rangeCall) } class ArrayIndicesRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, loopRangeCall) + ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InArrayIndicesGenerator(codegen, operatorReference, rangeCall) } class CollectionIndicesRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, loopRangeCall) + ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InCollectionIndicesGenerator(codegen, operatorReference, rangeCall) } class CharSequenceIndicesRangeValue(loopRangeCall: ResolvedCall): CallIntrinsicRangeValue(loopRangeCall) { override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = - ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, loopRangeCall) + ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + InCharSequenceIndicesGenerator(codegen, operatorReference, rangeCall) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt index efa8493dbef..40620744c99 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt @@ -84,7 +84,7 @@ private fun createIntrinsifiedRangeValueOrNull(rangeCall: ResolvedCall - PrimitiveNumberRangeToRangeValue(rangeCall) + PrimitiveNumberRangeLiteralRangeValue(rangeCall) isPrimitiveNumberDownTo(rangeCallee) -> DownToProgressionRangeValue(rangeCall) isPrimitiveNumberUntil(rangeCallee) -> diff --git a/compiler/testData/codegen/box/ranges/contains/inArray.kt b/compiler/testData/codegen/box/ranges/contains/inArray.kt new file mode 100644 index 00000000000..496d9095a00 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inArray.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME + +fun box(): String = when { + 0 in intArrayOf(1, 2, 3) -> "fail 1" + 1 !in intArrayOf(1, 2, 3) -> "fail 2" + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/contains/inCharSequence.kt b/compiler/testData/codegen/box/ranges/contains/inCharSequence.kt new file mode 100644 index 00000000000..56b17a69f6f --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inCharSequence.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +val charSeq: String = "123" + +fun box(): String = when { + '0' in charSeq -> "fail 1" + '1' !in charSeq -> "fail 2" + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/contains/inIterable.kt b/compiler/testData/codegen/box/ranges/contains/inIterable.kt new file mode 100644 index 00000000000..8a418e12d1a --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inIterable.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +val iterable: Iterable = listOf(1, 2, 3) + +fun box(): String = when { + 0 in iterable -> "fail 1" + 1 !in iterable -> "fail 2" + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt b/compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt new file mode 100644 index 00000000000..96f588d5b97 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +val progression = 1 .. 3 step 2 + +fun box(): String = when { + 0 in progression -> "fail 1" + 1 !in progression -> "fail 2" + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt b/compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt new file mode 100644 index 00000000000..2113dca0c54 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME + +val range = 1 .. 3 + +fun box(): String = when { + 0 in range -> "fail 1" + 1 !in range -> "fail 2" + else -> "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/ranges/ifNotInCollection.kt b/compiler/testData/codegen/bytecodeText/ranges/ifNotInCollection.kt new file mode 100644 index 00000000000..3caf46830a9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/ranges/ifNotInCollection.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME + +// FILE: Ints.kt +val ints = listOf(1, 2, 3) + +// FILE: Test.kt +fun test1(i: Int) = + if (i in ints) "Yes" else "No" + +fun test2(i: Int) = + if (i !in ints) "Yes" else "No" + +// @TestKt.class: +// 0 ICONST_0 +// 0 ICONST_1 +// 0 IXOR diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 30f1c4eb4e2..65c0daff396 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13177,6 +13177,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inArray.kt") + public void testInArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt"); + doTest(fileName); + } + + @TestMetadata("inCharSequence.kt") + public void testInCharSequence() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inCharSequence.kt"); + doTest(fileName); + } + @TestMetadata("inComparableRange.kt") public void testInComparableRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt"); @@ -13195,6 +13207,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("inIterable.kt") + public void testInIterable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inIterable.kt"); + doTest(fileName); + } + @TestMetadata("inOptimizableDoubleRange.kt") public void testInOptimizableDoubleRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt"); @@ -13219,6 +13237,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("inPrimitiveProgression.kt") + public void testInPrimitiveProgression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt"); + doTest(fileName); + } + + @TestMetadata("inPrimitiveRange.kt") + public void testInPrimitiveRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt"); + doTest(fileName); + } + @TestMetadata("inRangeWithCustomContains.kt") public void testInRangeWithCustomContains() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 61690be8606..3865bbf5b81 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13177,6 +13177,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inArray.kt") + public void testInArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt"); + doTest(fileName); + } + + @TestMetadata("inCharSequence.kt") + public void testInCharSequence() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inCharSequence.kt"); + doTest(fileName); + } + @TestMetadata("inComparableRange.kt") public void testInComparableRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt"); @@ -13195,6 +13207,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("inIterable.kt") + public void testInIterable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inIterable.kt"); + doTest(fileName); + } + @TestMetadata("inOptimizableDoubleRange.kt") public void testInOptimizableDoubleRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt"); @@ -13219,6 +13237,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("inPrimitiveProgression.kt") + public void testInPrimitiveProgression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt"); + doTest(fileName); + } + + @TestMetadata("inPrimitiveRange.kt") + public void testInPrimitiveRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt"); + doTest(fileName); + } + @TestMetadata("inRangeWithCustomContains.kt") public void testInRangeWithCustomContains() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 973f232f3dd..8985f11ce22 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1853,6 +1853,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/ranges"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("ifNotInCollection.kt") + public void testIfNotInCollection() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ranges/ifNotInCollection.kt"); + doTest(fileName); + } + @TestMetadata("inNonMatchingRange.kt") public void testInNonMatchingRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ranges/inNonMatchingRange.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 36a274cf08d..caa01bbaeff 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13177,6 +13177,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inArray.kt") + public void testInArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt"); + doTest(fileName); + } + + @TestMetadata("inCharSequence.kt") + public void testInCharSequence() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inCharSequence.kt"); + doTest(fileName); + } + @TestMetadata("inComparableRange.kt") public void testInComparableRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt"); @@ -13195,6 +13207,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("inIterable.kt") + public void testInIterable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inIterable.kt"); + doTest(fileName); + } + @TestMetadata("inOptimizableDoubleRange.kt") public void testInOptimizableDoubleRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt"); @@ -13219,6 +13237,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("inPrimitiveProgression.kt") + public void testInPrimitiveProgression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt"); + doTest(fileName); + } + + @TestMetadata("inPrimitiveRange.kt") + public void testInPrimitiveRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt"); + doTest(fileName); + } + @TestMetadata("inRangeWithCustomContains.kt") public void testInRangeWithCustomContains() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index c743766c697..ad0feb12d2d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -14785,6 +14785,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/contains"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("inArray.kt") + public void testInArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inArray.kt"); + doTest(fileName); + } + + @TestMetadata("inCharSequence.kt") + public void testInCharSequence() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inCharSequence.kt"); + doTest(fileName); + } + @TestMetadata("inComparableRange.kt") public void testInComparableRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt"); @@ -14821,6 +14833,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("inIterable.kt") + public void testInIterable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inIterable.kt"); + doTest(fileName); + } + @TestMetadata("inOptimizableDoubleRange.kt") public void testInOptimizableDoubleRange() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt"); @@ -14869,6 +14887,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("inPrimitiveProgression.kt") + public void testInPrimitiveProgression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveProgression.kt"); + doTest(fileName); + } + + @TestMetadata("inPrimitiveRange.kt") + public void testInPrimitiveRange() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inPrimitiveRange.kt"); + doTest(fileName); + } + @TestMetadata("inRangeWithCustomContains.kt") public void testInRangeWithCustomContains() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");