Pull up logic for ComparisonGenerator selection
This commit is contained in:
@@ -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<FqName, PrimitiveType> =
|
||||
supportedRangeTypes().associateBy {
|
||||
supportedRangeTypes.associateBy {
|
||||
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
|
||||
}
|
||||
|
||||
private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
|
||||
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]
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue {
|
||||
private final static ImmutableMap<String, Type> VALUES_TYPENAME_TO_TYPE;
|
||||
static {
|
||||
ImmutableMap.Builder<String, Type> 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<PrimitiveType, ProgressionIteratorBasicValue> ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE;
|
||||
static {
|
||||
ImmutableMap.Builder<PrimitiveType, ProgressionIteratorBasicValue> 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();
|
||||
|
||||
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
@@ -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<out CallableDescriptor>): RangeValue {
|
||||
protected abstract fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>): Boolean
|
||||
|
||||
protected abstract fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator
|
||||
protected abstract fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression, resolvedCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
|
||||
+2
-12
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
+2
-12
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
+1
-6
@@ -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<out CallableDescriptor>) =
|
||||
isClosedRangeContains(resolvedCallForIn.resultingDescriptor)
|
||||
|
||||
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression)=
|
||||
override fun createIntrinsicInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression, resolvedCall: ResolvedCall<out CallableDescriptor>)=
|
||||
InContinuousRangeExpressionGenerator(operatorReference, boundedValue, ObjectComparisonGenerator)
|
||||
}
|
||||
+2
-13
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
|
||||
private val boundedValue =
|
||||
class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
+21
-4
@@ -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<out CallableDescriptor>): CallIntrinsicRangeValue(rangeCall) {
|
||||
@@ -32,4 +35,18 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall<o
|
||||
isClosedFloatingPointRangeContains(it) ||
|
||||
isIntPrimitiveRangeExtensionForInt(it)
|
||||
}
|
||||
|
||||
override fun createIntrinsicInExpressionGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
operatorReference: KtSimpleNameExpression,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>
|
||||
): 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
|
||||
}
|
||||
+3
-12
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
private val boundedValue = SimpleBoundedValue(codegen, rangeCall)
|
||||
class PrimitiveNumberRangeLiteralRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
+3
-12
@@ -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<out CallableDescriptor>
|
||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
||||
private val boundedValue = SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false)
|
||||
class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): 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)
|
||||
}
|
||||
@@ -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 ->
|
||||
|
||||
+44
-6
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
fun getComparisonGeneratorForRangeContainsCall(codegen: ExpressionCodegen, call: ResolvedCall<out CallableDescriptor>): 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
|
||||
Reference in New Issue
Block a user