Provide intrinsic generators for in/!in expression
TODO some tests should fail because range of comparables (e.g., '"Alpha" .. "Omega"') is currently not implemented
This commit is contained in:
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenForLambda;
|
|||||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor;
|
import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor;
|
||||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
|
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.forLoop.ForLoopGenerator;
|
||||||
import org.jetbrains.kotlin.codegen.inline.*;
|
import org.jetbrains.kotlin.codegen.inline.*;
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.*;
|
import org.jetbrains.kotlin.codegen.intrinsics.*;
|
||||||
@@ -2871,25 +2870,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
private StackValue generateIn(StackValue leftValue, KtExpression rangeExpression, KtSimpleNameExpression operationReference) {
|
private StackValue generateIn(StackValue leftValue, KtExpression rangeExpression, KtSimpleNameExpression operationReference) {
|
||||||
KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression);
|
KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression);
|
||||||
|
|
||||||
assert deparenthesized != null : "For with empty range expression";
|
assert deparenthesized != null : "For with empty range expression";
|
||||||
boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN;
|
RangeValue rangeValue = RangeValuesKt.createRangeValueForExpression(this, deparenthesized);
|
||||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
return rangeValue.createInExpressionGenerator(this, operationReference).generate(leftValue);
|
||||||
if (RangeCodegenUtilKt.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) ||
|
|
||||||
RangeCodegenUtilKt.isPrimitiveRangeToExtension(operationReference, bindingContext)) {
|
//boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN;
|
||||||
generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted);
|
//return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||||
}
|
// if (RangeCodegenUtilKt.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) ||
|
||||||
else {
|
// RangeCodegenUtilKt.isPrimitiveRangeToExtension(operationReference, bindingContext)) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
|
// generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted);
|
||||||
.getResolvedCallWithAssert(operationReference, bindingContext);
|
// }
|
||||||
StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none());
|
// else {
|
||||||
result.put(result.type, v);
|
// ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
|
||||||
if (isInverted) {
|
// .getResolvedCallWithAssert(operationReference, bindingContext);
|
||||||
genInvertBoolean(v);
|
// StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none());
|
||||||
}
|
// result.put(result.type, v);
|
||||||
}
|
// if (isInverted) {
|
||||||
return null;
|
// genInvertBoolean(v);
|
||||||
});
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
//});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ fun isRange(rangeType: KotlinType) =
|
|||||||
fun isProgression(rangeType: KotlinType) =
|
fun isProgression(rangeType: KotlinType) =
|
||||||
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
|
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
|
||||||
|
|
||||||
private fun getPrimitiveRangeElementType(rangeType: KotlinType) =
|
fun getPrimitiveRangeElementType(rangeType: KotlinType) =
|
||||||
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
|
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
|
||||||
|
|
||||||
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
|
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
|
||||||
|
|||||||
+175
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
+42
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
+37
@@ -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)
|
||||||
|
}
|
||||||
+38
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
+37
@@ -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)
|
||||||
|
}
|
||||||
@@ -20,66 +20,102 @@ import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
|||||||
import org.jetbrains.kotlin.codegen.forLoop.*
|
import org.jetbrains.kotlin.codegen.forLoop.*
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
|
||||||
interface RangeValue {
|
interface RangeValue {
|
||||||
fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator
|
fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator
|
||||||
|
|
||||||
|
fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
class ArrayRangeValue : RangeValue {
|
class ArrayRangeValue : RangeValue {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInArrayLoopGenerator(codegen, forExpression)
|
ForInArrayLoopGenerator(codegen, forExpression)
|
||||||
|
|
||||||
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||||
|
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimitiveRangeRangeValue : RangeValue {
|
class PrimitiveRangeRangeValue : RangeValue {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInRangeInstanceLoopGenerator(codegen, forExpression)
|
ForInRangeInstanceLoopGenerator(codegen, forExpression)
|
||||||
|
|
||||||
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||||
|
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimitiveProgressionRangeValue : RangeValue {
|
class PrimitiveProgressionRangeValue : RangeValue {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInProgressionExpressionLoopGenerator(codegen, forExpression)
|
ForInProgressionExpressionLoopGenerator(codegen, forExpression)
|
||||||
|
|
||||||
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||||
|
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
class CharSequenceRangeValue : RangeValue {
|
class CharSequenceRangeValue : RangeValue {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInCharSequenceLoopGenerator(codegen, forExpression)
|
ForInCharSequenceLoopGenerator(codegen, forExpression)
|
||||||
|
|
||||||
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||||
|
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
class IterableRangeValue : RangeValue {
|
class IterableRangeValue : RangeValue {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
IteratorForLoopGenerator(codegen, forExpression)
|
IteratorForLoopGenerator(codegen, forExpression)
|
||||||
|
|
||||||
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
|
||||||
|
CallBasedInExpressionGenerator(codegen, operatorReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CallIntrinsicRangeValue(protected val loopRangeCall: ResolvedCall<out CallableDescriptor>): RangeValue
|
abstract class CallIntrinsicRangeValue(protected val rangeCall: ResolvedCall<out CallableDescriptor>): RangeValue
|
||||||
|
|
||||||
class PrimitiveNumberRangeToRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class PrimitiveNumberRangeLiteralRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class DownToProgressionRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class PrimitiveNumberUntilRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class ArrayIndicesRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class CollectionIndicesRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
class CharSequenceIndicesRangeValue(loopRangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(loopRangeCall) {
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ private fun createIntrinsifiedRangeValueOrNull(rangeCall: ResolvedCall<out Calla
|
|||||||
|
|
||||||
return when {
|
return when {
|
||||||
isPrimitiveNumberRangeTo(rangeCallee) ->
|
isPrimitiveNumberRangeTo(rangeCallee) ->
|
||||||
PrimitiveNumberRangeToRangeValue(rangeCall)
|
PrimitiveNumberRangeLiteralRangeValue(rangeCall)
|
||||||
isPrimitiveNumberDownTo(rangeCallee) ->
|
isPrimitiveNumberDownTo(rangeCallee) ->
|
||||||
DownToProgressionRangeValue(rangeCall)
|
DownToProgressionRangeValue(rangeCall)
|
||||||
isPrimitiveNumberUntil(rangeCallee) ->
|
isPrimitiveNumberUntil(rangeCallee) ->
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
val iterable: Iterable<Int> = listOf(1, 2, 3)
|
||||||
|
|
||||||
|
fun box(): String = when {
|
||||||
|
0 in iterable -> "fail 1"
|
||||||
|
1 !in iterable -> "fail 2"
|
||||||
|
else -> "OK"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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
|
||||||
+30
@@ -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);
|
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")
|
@TestMetadata("inComparableRange.kt")
|
||||||
public void testInComparableRange() throws Exception {
|
public void testInComparableRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
||||||
@@ -13195,6 +13207,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inOptimizableDoubleRange.kt")
|
||||||
public void testInOptimizableDoubleRange() throws Exception {
|
public void testInOptimizableDoubleRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
||||||
@@ -13219,6 +13237,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inRangeWithCustomContains.kt")
|
||||||
public void testInRangeWithCustomContains() throws Exception {
|
public void testInRangeWithCustomContains() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("inComparableRange.kt")
|
||||||
public void testInComparableRange() throws Exception {
|
public void testInComparableRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
||||||
@@ -13195,6 +13207,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inOptimizableDoubleRange.kt")
|
||||||
public void testInOptimizableDoubleRange() throws Exception {
|
public void testInOptimizableDoubleRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
||||||
@@ -13219,6 +13237,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inRangeWithCustomContains.kt")
|
||||||
public void testInRangeWithCustomContains() throws Exception {
|
public void testInRangeWithCustomContains() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("inNonMatchingRange.kt")
|
||||||
public void testInNonMatchingRange() throws Exception {
|
public void testInNonMatchingRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ranges/inNonMatchingRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/ranges/inNonMatchingRange.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("inComparableRange.kt")
|
||||||
public void testInComparableRange() throws Exception {
|
public void testInComparableRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
||||||
@@ -13195,6 +13207,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inOptimizableDoubleRange.kt")
|
||||||
public void testInOptimizableDoubleRange() throws Exception {
|
public void testInOptimizableDoubleRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
||||||
@@ -13219,6 +13237,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("inRangeWithCustomContains.kt")
|
||||||
public void testInRangeWithCustomContains() throws Exception {
|
public void testInRangeWithCustomContains() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
||||||
|
|||||||
+30
@@ -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);
|
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")
|
@TestMetadata("inComparableRange.kt")
|
||||||
public void testInComparableRange() throws Exception {
|
public void testInComparableRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inComparableRange.kt");
|
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.");
|
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")
|
@TestMetadata("inOptimizableDoubleRange.kt")
|
||||||
public void testInOptimizableDoubleRange() throws Exception {
|
public void testInOptimizableDoubleRange() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inOptimizableDoubleRange.kt");
|
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.");
|
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")
|
@TestMetadata("inRangeWithCustomContains.kt")
|
||||||
public void testInRangeWithCustomContains() throws Exception {
|
public void testInRangeWithCustomContains() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user