Provide intrinsic for in/in! expression with range of Comparable

This commit is contained in:
Dmitry Petrov
2017-06-30 15:10:57 +03:00
parent bd2021411c
commit fd402cb76c
11 changed files with 315 additions and 155 deletions
@@ -20,8 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -128,6 +127,27 @@ fun isCharSequenceIndices(descriptor: CallableDescriptor): Boolean {
return KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)
}
fun isComparableRangeTo(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.original.extensionReceiverParameter ?: return false
val extensionReceiverTypeDescriptor = extensionReceiver.type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
val upperBoundType = extensionReceiverTypeDescriptor.upperBounds.singleOrNull() ?: return false
val upperBoundClassDescriptor = upperBoundType.constructor.declarationDescriptor as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(upperBoundClassDescriptor, "Comparable", "kotlin")) return false
return true
}
fun isClosedRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(containingClassDescriptor, "ClosedRange", "kotlin.ranges")) return false
return true
}
fun isPrimitiveRangeToExtension(operationReference: KtSimpleNameExpression, bindingContext: BindingContext): Boolean {
val resolvedCall = operationReference.getResolvedCallWithAssert(bindingContext)
val receiver = resolvedCall.dispatchReceiver as? ExpressionReceiver ?: return false
@@ -164,7 +184,7 @@ fun isPrimitiveRangeSpecializationOfType(
return false
}
private fun isTopLevelInPackage(descriptor: CallableDescriptor, name: String, packageName: String): Boolean {
private fun isTopLevelInPackage(descriptor: DeclarationDescriptor, name: String, packageName: String): Boolean {
if (name != descriptor.name.asString()) return false
val containingDeclaration = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
@@ -16,160 +16,79 @@
package org.jetbrains.kotlin.codegen.range
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.getPrimitiveRangeElementType
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,
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)
}
}
isInclusiveHighBound: Boolean
) : AbstractInRangeWithKnownBoundsExpressionGenerator(
codegen, operatorReference, isInclusiveHighBound, AsmTypes.valueTypeForPrimitive(getPrimitiveRangeElementType(rangeCall.resultingDescriptor.returnType!!))
) {
override val comparisonGenerator: ComparisonGenerator =
when (asmElementType) {
Type.INT_TYPE, Type.SHORT_TYPE, Type.BYTE_TYPE, Type.CHAR_TYPE -> PrimitiveIntegerComparisonGenerator
Type.LONG_TYPE -> PrimitiveLongComparisonGenerator
Type.FLOAT_TYPE, Type.DOUBLE_TYPE -> PrimitiveFloatComparisonGenerator(asmElementType)
else -> throw UnsupportedOperationException("Unexpected type: " + asmElementType)
}
private object PrimitiveIntegerComparisonGenerator : ComparisonGenerator {
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) = v.ificmpge(label)
override fun jumpIfLessOrEqual(v: InstructionAdapter, label: Label) = v.ificmple(label)
override fun jumpIfGreater(v: InstructionAdapter, label: Label) = v.ificmpgt(label)
override fun jumpIfLess(v: InstructionAdapter, label: Label) = v.ificmplt(label)
}
private object PrimitiveLongComparisonGenerator : ComparisonGenerator {
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
v.lcmp()
v.ifge(label)
}
override fun jumpIfLessOrEqual(v: InstructionAdapter, label: Label) {
v.lcmp()
v.ifle(label)
}
override fun jumpIfGreater(v: InstructionAdapter, label: Label) {
v.lcmp()
v.ifgt(label)
}
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
v.lcmp()
v.iflt(label)
}
}
private class PrimitiveFloatComparisonGenerator(val floatType: Type) : ComparisonGenerator {
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
v.cmpg(floatType)
v.ifge(label)
}
override fun jumpIfLessOrEqual(v: InstructionAdapter, label: Label) {
v.cmpg(floatType)
v.ifle(label)
}
override fun jumpIfGreater(v: InstructionAdapter, label: Label) {
v.cmpg(floatType)
v.ifgt(label)
}
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
v.cmpg(floatType)
v.iflt(label)
}
}
}
@@ -0,0 +1,104 @@
/*
* 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.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 AbstractInRangeWithKnownBoundsExpressionGenerator(
val codegen: ExpressionCodegen,
operatorReference: KtSimpleNameExpression,
protected val isInclusiveHighBound: Boolean,
protected val asmElementType: Type
) : InExpressionGenerator {
private val isNotIn = operatorReference.getReferencedNameElementType() == KtTokens.NOT_IN
protected abstract fun genLowBound(): StackValue
protected abstract fun genHighBound(): StackValue
protected interface ComparisonGenerator {
fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label)
fun jumpIfLessOrEqual(v: InstructionAdapter, label: Label)
fun jumpIfGreater(v: InstructionAdapter, label: Label)
fun jumpIfLess(v: InstructionAdapter, label: Label)
}
protected abstract val comparisonGenerator: ComparisonGenerator
override fun generate(argument: StackValue): BranchedValue =
gen(argument).let { if (isNotIn) 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)
comparisonGenerator.jumpIfGreaterOrEqual(v, cmpHighLabel)
AsmUtil.pop(v, operandType)
v.goTo(jumpLabel)
v.mark(cmpHighLabel)
genHighBound().put(operandType, v)
if (isInclusiveHighBound) {
comparisonGenerator.jumpIfGreater(v, jumpLabel)
}
else {
comparisonGenerator.jumpIfGreaterOrEqual(v, 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)
comparisonGenerator.jumpIfLess(v, trueLabel1)
genHighBound().put(operandType, v)
if (isInclusiveHighBound) {
comparisonGenerator.jumpIfLessOrEqual(v, jumpLabel)
}
else {
comparisonGenerator.jumpIfLess(v, jumpLabel)
}
v.goTo(trueLabel2)
v.mark(trueLabel1)
AsmUtil.pop(v, operandType)
v.mark(trueLabel2)
}
}
}
}
@@ -0,0 +1,72 @@
/*
* 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.descriptors.CallableDescriptor
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
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class InComparableRangeLiteralGenerator(
codegen: ExpressionCodegen,
operatorReference: KtSimpleNameExpression,
rangeCall: ResolvedCall<out CallableDescriptor>
) : AbstractInRangeWithKnownBoundsExpressionGenerator(
codegen, operatorReference, true,
Type.getType("Ljava/lang/Comparable;")
) {
private val from: ReceiverValue = rangeCall.extensionReceiver!!
private val to: KtExpression = ExpressionCodegen.getSingleArgumentExpression(rangeCall)!!
override fun genLowBound(): StackValue = codegen.generateReceiverValue(from, false)
override fun genHighBound(): StackValue = codegen.gen(to)
override val comparisonGenerator: ComparisonGenerator = ComparableComparisonGenerator
private object ComparableComparisonGenerator : ComparisonGenerator {
override fun jumpIfGreaterOrEqual(v: InstructionAdapter, label: Label) {
invokeCompare(v)
v.ifge(label)
}
override fun jumpIfLessOrEqual(v: InstructionAdapter, label: Label) {
invokeCompare(v)
v.ifle(label)
}
override fun jumpIfGreater(v: InstructionAdapter, label: Label) {
invokeCompare(v)
v.ifgt(label)
}
override fun jumpIfLess(v: InstructionAdapter, label: Label) {
invokeCompare(v)
v.iflt(label)
}
private fun invokeCompare(v: InstructionAdapter) {
v.invokeinterface("java/lang/Comparable", "compareTo", "(Ljava/lang/Object;)I")
}
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.range
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.forLoop.*
import org.jetbrains.kotlin.codegen.isClosedRangeContains
import org.jetbrains.kotlin.codegen.isPrimitiveRange
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.psi.KtForExpression
@@ -86,7 +87,7 @@ abstract class CallIntrinsicRangeValue(protected val rangeCall: ResolvedCall<out
}
abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(rangeCall) {
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>): Boolean =
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
resolvedCallForIn.resultingDescriptor.dispatchReceiverParameter?.let {
isPrimitiveRange(it.type)
} ?: false
@@ -96,7 +97,7 @@ class PrimitiveNumberRangeLiteralRangeValue(rangeCall: ResolvedCall<out Callable
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InPrimitiveNumberRangeLiteralGenerator(codegen, operatorReference, rangeCall)
}
@@ -104,7 +105,7 @@ class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInDownToProgressionLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InPrimitiveNumberDownToGenerator(codegen, operatorReference, rangeCall)
}
@@ -112,7 +113,7 @@ class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescrip
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInUntilRangeLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InPrimitiveNumberUntilGenerator(codegen, operatorReference, rangeCall)
}
@@ -120,7 +121,7 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): P
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InArrayIndicesGenerator(codegen, operatorReference, rangeCall)
}
@@ -128,7 +129,7 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InCollectionIndicesGenerator(codegen, operatorReference, rangeCall)
}
@@ -136,6 +137,17 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) =
InCharSequenceIndicesGenerator(codegen, operatorReference, rangeCall)
}
class ComparableRangeLiteralRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(rangeCall) {
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
IteratorForLoopGenerator(codegen, forExpression)
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
isClosedRangeContains(resolvedCallForIn.resultingDescriptor)
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression)=
InComparableRangeLiteralGenerator(codegen, operatorReference, rangeCall)
}
@@ -95,6 +95,8 @@ private fun createIntrinsifiedRangeValueOrNull(rangeCall: ResolvedCall<out Calla
CollectionIndicesRangeValue(rangeCall)
isCharSequenceIndices(rangeCallee) ->
CharSequenceIndicesRangeValue(rangeCall)
isComparableRangeTo(rangeCallee) ->
ComparableRangeLiteralRangeValue(rangeCall)
else ->
null
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
fun box(): String {
if ("z" in "Alpha" .. "Omega") return "Fail 1"
if ("Gamma" !in "Alpha" .. "Omega") return "Fail 2"
return "OK"
}
@@ -13249,6 +13249,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
doTest(fileName);
}
@TestMetadata("inRangeOfComparable.kt")
public void testInRangeOfComparable() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeOfComparable.kt");
doTest(fileName);
}
@TestMetadata("inRangeWithCustomContains.kt")
public void testInRangeWithCustomContains() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
@@ -13249,6 +13249,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("inRangeOfComparable.kt")
public void testInRangeOfComparable() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeOfComparable.kt");
doTest(fileName);
}
@TestMetadata("inRangeWithCustomContains.kt")
public void testInRangeWithCustomContains() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
@@ -13249,6 +13249,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
doTest(fileName);
}
@TestMetadata("inRangeOfComparable.kt")
public void testInRangeOfComparable() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeOfComparable.kt");
doTest(fileName);
}
@TestMetadata("inRangeWithCustomContains.kt")
public void testInRangeWithCustomContains() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");
@@ -14899,6 +14899,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
doTest(fileName);
}
@TestMetadata("inRangeOfComparable.kt")
public void testInRangeOfComparable() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeOfComparable.kt");
doTest(fileName);
}
@TestMetadata("inRangeWithCustomContains.kt")
public void testInRangeWithCustomContains() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/ranges/contains/inRangeWithCustomContains.kt");