diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt index 5c325f9a319..f2459f1d64c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt @@ -24,30 +24,30 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type +val supportedRangeTypes = listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG) + private val RANGE_TO_ELEMENT_TYPE: Map = - supportedRangeTypes().associateBy { + supportedRangeTypes.associateBy { RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range")) } private val PROGRESSION_TO_ELEMENT_TYPE: Map = - supportedRangeTypes().associateBy { + supportedRangeTypes.associateBy { RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression")) } -fun supportedRangeTypes() = - listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG) - fun isPrimitiveRange(rangeType: KotlinType) = !rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null fun isPrimitiveProgression(rangeType: KotlinType) = !rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null -fun getPrimitiveRangeElementType(rangeType: KotlinType) = +fun getPrimitiveRangeElementType(rangeType: KotlinType): PrimitiveType? = getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE) private fun getPrimitiveProgressionElementType(rangeType: KotlinType) = @@ -62,6 +62,32 @@ private fun getPrimitiveRangeOrProgressionElementType( return map[fqName.toSafe()] } +fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? { + val rangeTypeDescriptor = rangeType.constructor.declarationDescriptor ?: return null + val builtIns = rangeTypeDescriptor.builtIns + + return when { + isTopLevelInPackage(rangeTypeDescriptor, "CharRange", "kotlin.ranges") -> builtIns.charType + isTopLevelInPackage(rangeTypeDescriptor, "IntRange", "kotlin.ranges") -> builtIns.intType + isTopLevelInPackage(rangeTypeDescriptor, "LongRange", "kotlin.ranges") -> builtIns.longType + + isTopLevelInPackage(rangeTypeDescriptor, "CharProgression", "kotlin.ranges") -> builtIns.charType + isTopLevelInPackage(rangeTypeDescriptor, "IntProgression", "kotlin.ranges") -> builtIns.intType + isTopLevelInPackage(rangeTypeDescriptor, "LongProgression", "kotlin.ranges") -> builtIns.longType + + isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatRange", "kotlin.ranges") -> builtIns.floatType + isTopLevelInPackage(rangeTypeDescriptor, "ClosedDoubleRange", "kotlin.ranges") -> builtIns.doubleType + + isTopLevelInPackage(rangeTypeDescriptor, "ClosedRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type + + isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatingPointRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type + + isTopLevelInPackage(rangeTypeDescriptor, "ComparableRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type + + else -> null + } +} + fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? = RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?: PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName] diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/ProgressionIteratorBasicValue.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/ProgressionIteratorBasicValue.java index 00c629c27c0..77b8f2ef866 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/ProgressionIteratorBasicValue.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/ProgressionIteratorBasicValue.java @@ -32,7 +32,7 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue { private final static ImmutableMap VALUES_TYPENAME_TO_TYPE; static { ImmutableMap.Builder builder = ImmutableMap.builder(); - for (PrimitiveType primitiveType : RangeCodegenUtilKt.supportedRangeTypes()) { + for (PrimitiveType primitiveType : RangeCodegenUtilKt.getSupportedRangeTypes()) { builder.put(primitiveType.getTypeName().asString(), Type.getType(JvmPrimitiveType.get(primitiveType).getDesc())); } VALUES_TYPENAME_TO_TYPE = builder.build(); @@ -41,7 +41,7 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue { private static final ImmutableMap ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE; static { ImmutableMap.Builder builder = ImmutableMap.builder(); - for (PrimitiveType elementType : RangeCodegenUtilKt.supportedRangeTypes()) { + for (PrimitiveType elementType : RangeCodegenUtilKt.getSupportedRangeTypes()) { builder.put(elementType, new ProgressionIteratorBasicValue(elementType.getTypeName().asString())); } ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE = builder.build(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayIndicesRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayIndicesRangeValue.kt index a63fbb56db5..e75dece7c10 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayIndicesRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayIndicesRangeValue.kt @@ -19,24 +19,17 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.generateCallReceiver -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInArrayIndicesRangeLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type -class ArrayIndicesRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) +class ArrayIndicesRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) - private val boundedValue = + override fun getBoundedValue(codegen: ExpressionCodegen) = SimpleBoundedValue( codegen, rangeCall, lowBound = StackValue.constant(0, asmElementType), @@ -49,6 +42,4 @@ class ArrayIndicesRangeValue( override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallIntrinsicRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallIntrinsicRangeValue.kt index f96cb6ea75f..379bee5789d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallIntrinsicRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CallIntrinsicRangeValue.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator import org.jetbrains.kotlin.descriptors.CallableDescriptor @@ -27,12 +28,12 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall abstract class CallIntrinsicRangeValue(protected val rangeCall: ResolvedCall): RangeValue { protected abstract fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall): Boolean - protected abstract fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator + protected abstract fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression, resolvedCall: ResolvedCall): InExpressionGenerator override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator { val resolvedCall = operatorReference.getResolvedCallWithAssert(codegen.bindingContext) return if (isIntrinsicInCall(resolvedCall)) - createIntrinsicInExpressionGenerator(codegen, operatorReference) + createIntrinsicInExpressionGenerator(codegen, operatorReference, resolvedCall) else CallBasedInExpressionGenerator(codegen, operatorReference) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceIndicesRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceIndicesRangeValue.kt index 23520c86b4f..2968b0500c9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceIndicesRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceIndicesRangeValue.kt @@ -19,24 +19,17 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.generateCallReceiver -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInCharSequenceIndicesRangeLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type -class CharSequenceIndicesRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) +class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) - private val boundedValue = + override fun getBoundedValue(codegen: ExpressionCodegen) = SimpleBoundedValue( codegen, rangeCall, lowBound = StackValue.constant(0, asmElementType), @@ -48,7 +41,4 @@ class CharSequenceIndicesRangeValue( override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) - - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CollectionIndicesRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CollectionIndicesRangeValue.kt index 6b37bfcb499..70cd5c4a9f9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CollectionIndicesRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CollectionIndicesRangeValue.kt @@ -19,24 +19,17 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.generateCallReceiver -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInCollectionIndicesRangeLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Type -class CollectionIndicesRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) +class CollectionIndicesRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall) - private val boundedValue = + override fun getBoundedValue(codegen: ExpressionCodegen) = SimpleBoundedValue( codegen, rangeCall, lowBound = StackValue.constant(0, asmElementType), @@ -48,7 +41,4 @@ class CollectionIndicesRangeValue( override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, rangeCall) - - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt index 579fbaa689f..a68a3aa61cd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ComparableRangeLiteralRangeValue.kt @@ -17,19 +17,14 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen -import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.isClosedRangeContains import org.jetbrains.kotlin.codegen.range.comparison.ObjectComparisonGenerator import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.psi.KtExpression 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.scopes.receivers.ReceiverValue -import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter class ComparableRangeLiteralRangeValue( codegen: ExpressionCodegen, @@ -43,6 +38,6 @@ class ComparableRangeLiteralRangeValue( override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall) = isClosedRangeContains(resolvedCallForIn.resultingDescriptor) - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression)= + override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression, resolvedCall: ResolvedCall)= InContinuousRangeExpressionGenerator(operatorReference, boundedValue, ObjectComparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/DownToProgressionRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/DownToProgressionRangeValue.kt index d159f2b0574..08d92dc89bd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/DownToProgressionRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/DownToProgressionRangeValue.kt @@ -19,21 +19,13 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.generateCallReceiver import org.jetbrains.kotlin.codegen.generateCallSingleArgument -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInDownToProgressionLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 -class DownToProgressionRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) - - private val boundedValue = +class DownToProgressionRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { + override fun getBoundedValue(codegen: ExpressionCodegen) = SimpleBoundedValue( codegen, rangeCall, lowBound = codegen.generateCallSingleArgument(rangeCall), @@ -42,7 +34,4 @@ class DownToProgressionRangeValue( override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInDownToProgressionLoopGenerator(codegen, forExpression, rangeCall) - - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt index 55049555bea..f632bff7566 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeIntrinsicRangeValue.kt @@ -16,11 +16,14 @@ package org.jetbrains.kotlin.codegen.range -import org.jetbrains.kotlin.codegen.getAsmRangeElementTypeForPrimitiveRangeOrProgression -import org.jetbrains.kotlin.codegen.isClosedFloatingPointRangeContains -import org.jetbrains.kotlin.codegen.isIntPrimitiveRangeExtensionForInt -import org.jetbrains.kotlin.codegen.isPrimitiveRangeContains +import org.jetbrains.kotlin.codegen.* +import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator +import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall +import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall): CallIntrinsicRangeValue(rangeCall) { @@ -32,4 +35,18 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall + ): InExpressionGenerator { + val comparisonGenerator = getComparisonGeneratorForRangeContainsCall(codegen, resolvedCall) + return if (comparisonGenerator != null) + InContinuousRangeExpressionGenerator(operatorReference, getBoundedValue(codegen), comparisonGenerator) + else + CallBasedInExpressionGenerator(codegen, operatorReference) + } + + protected abstract fun getBoundedValue(codegen: ExpressionCodegen): BoundedValue } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeLiteralRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeLiteralRangeValue.kt index d1a307755f7..141b8fc74dd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeLiteralRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberRangeLiteralRangeValue.kt @@ -17,24 +17,15 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInRangeLiteralLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 -class PrimitiveNumberRangeLiteralRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) - private val boundedValue = SimpleBoundedValue(codegen, rangeCall) +class PrimitiveNumberRangeLiteralRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { + override fun getBoundedValue(codegen: ExpressionCodegen) = + SimpleBoundedValue(codegen, rangeCall) override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall) - - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberUntilRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberUntilRangeValue.kt index 08bac0b6684..ef44ba1f0e9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberUntilRangeValue.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/PrimitiveNumberUntilRangeValue.kt @@ -17,24 +17,15 @@ package org.jetbrains.kotlin.codegen.range import org.jetbrains.kotlin.codegen.ExpressionCodegen -import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForPrimitiveType import org.jetbrains.kotlin.codegen.range.forLoop.ForInUntilRangeLoopGenerator -import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator 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 -class PrimitiveNumberUntilRangeValue( - codegen: ExpressionCodegen, - rangeCall: ResolvedCall -): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { - private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType) - private val boundedValue = SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false) +class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) { + override fun getBoundedValue(codegen: ExpressionCodegen) = + SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false) override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) = ForInUntilRangeLoopGenerator(codegen, forExpression, rangeCall) - - override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression) = - InContinuousRangeExpressionGenerator(operatorReference, boundedValue, comparisonGenerator) } \ No newline at end of file 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 9123d48799b..7a72585169e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt @@ -84,17 +84,17 @@ private fun ExpressionCodegen.createIntrinsifiedRangeValueOrNull(rangeCall: Reso return when { isPrimitiveNumberRangeTo(rangeCallee) -> - PrimitiveNumberRangeLiteralRangeValue(this, rangeCall) + PrimitiveNumberRangeLiteralRangeValue(rangeCall) isPrimitiveNumberDownTo(rangeCallee) -> - DownToProgressionRangeValue(this, rangeCall) + DownToProgressionRangeValue(rangeCall) isPrimitiveNumberUntil(rangeCallee) -> - PrimitiveNumberUntilRangeValue(this, rangeCall) + PrimitiveNumberUntilRangeValue(rangeCall) isArrayOrPrimitiveArrayIndices(rangeCallee) -> - ArrayIndicesRangeValue(this, rangeCall) + ArrayIndicesRangeValue(rangeCall) isCollectionIndices(rangeCallee) -> - CollectionIndicesRangeValue(this, rangeCall) + CollectionIndicesRangeValue(rangeCall) isCharSequenceIndices(rangeCallee) -> - CharSequenceIndicesRangeValue(this, rangeCall) + CharSequenceIndicesRangeValue(rangeCall) isComparableRangeTo(rangeCallee) -> ComparableRangeLiteralRangeValue(this, rangeCall) else -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/comparison/ComparisonGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/comparison/ComparisonGenerator.kt index 79f878efcfd..2cde2f11032 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/comparison/ComparisonGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/comparison/ComparisonGenerator.kt @@ -16,6 +16,10 @@ package org.jetbrains.kotlin.codegen.range.comparison +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.getRangeOrProgressionElementType +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter @@ -30,10 +34,44 @@ interface ComparisonGenerator { } fun getComparisonGeneratorForPrimitiveType(type: Type): ComparisonGenerator = - when (type) { - Type.INT_TYPE, Type.SHORT_TYPE, Type.BYTE_TYPE, Type.CHAR_TYPE -> IntComparisonGenerator - Type.LONG_TYPE -> LongComparisonGenerator - Type.FLOAT_TYPE -> FloatComparisonGenerator - Type.DOUBLE_TYPE -> DoubleComparisonGenerator + when { + type.isRepresentedAsPrimitiveInt() -> IntComparisonGenerator + type == Type.LONG_TYPE -> LongComparisonGenerator + type == Type.FLOAT_TYPE -> FloatComparisonGenerator + type == Type.DOUBLE_TYPE -> DoubleComparisonGenerator else -> throw UnsupportedOperationException("Unexpected primitive type: " + type) - } \ No newline at end of file + } + +fun getComparisonGeneratorForRangeContainsCall(codegen: ExpressionCodegen, call: ResolvedCall): ComparisonGenerator? { + val descriptor = call.resultingDescriptor + + val receiverType = descriptor.extensionReceiverParameter?.type ?: descriptor.dispatchReceiverParameter?.type ?: return null + + val elementType = getRangeOrProgressionElementType(receiverType) ?: return null + + val valueParameterType = descriptor.valueParameters.singleOrNull()?.type ?: return null + + val asmElementType = codegen.asmType(elementType) + val asmValueParameterType = codegen.asmType(valueParameterType) + + return when { + asmElementType == asmValueParameterType -> + getComparisonGeneratorForPrimitiveType(asmElementType) + + asmElementType.isRepresentedAsPrimitiveInt() && asmValueParameterType.isRepresentedAsPrimitiveInt() -> + IntComparisonGenerator + + asmElementType.isRepresentedAsPrimitiveInt() && asmValueParameterType == Type.LONG_TYPE || + asmValueParameterType.isRepresentedAsPrimitiveInt() && asmElementType == Type.LONG_TYPE -> + LongComparisonGenerator + + asmElementType == Type.FLOAT_TYPE && asmValueParameterType == Type.DOUBLE_TYPE || + asmElementType == Type.DOUBLE_TYPE && asmValueParameterType == Type.FLOAT_TYPE -> + DoubleComparisonGenerator + + else -> null + } +} + +private fun Type.isRepresentedAsPrimitiveInt() = + this == Type.INT_TYPE || this == Type.SHORT_TYPE || this == Type.BYTE_TYPE || this == Type.CHAR_TYPE \ No newline at end of file