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.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
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> =
|
private val RANGE_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
|
||||||
supportedRangeTypes().associateBy {
|
supportedRangeTypes.associateBy {
|
||||||
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
|
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
|
private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
|
||||||
supportedRangeTypes().associateBy {
|
supportedRangeTypes.associateBy {
|
||||||
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
|
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun supportedRangeTypes() =
|
|
||||||
listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG)
|
|
||||||
|
|
||||||
fun isPrimitiveRange(rangeType: KotlinType) =
|
fun isPrimitiveRange(rangeType: KotlinType) =
|
||||||
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
|
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
|
||||||
|
|
||||||
fun isPrimitiveProgression(rangeType: KotlinType) =
|
fun isPrimitiveProgression(rangeType: KotlinType) =
|
||||||
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
|
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
|
||||||
|
|
||||||
fun getPrimitiveRangeElementType(rangeType: KotlinType) =
|
fun getPrimitiveRangeElementType(rangeType: KotlinType): PrimitiveType? =
|
||||||
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
|
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
|
||||||
|
|
||||||
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
|
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
|
||||||
@@ -62,6 +62,32 @@ private fun getPrimitiveRangeOrProgressionElementType(
|
|||||||
return map[fqName.toSafe()]
|
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? =
|
fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? =
|
||||||
RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?:
|
RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?:
|
||||||
PROGRESSION_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;
|
private final static ImmutableMap<String, Type> VALUES_TYPENAME_TO_TYPE;
|
||||||
static {
|
static {
|
||||||
ImmutableMap.Builder<String, Type> builder = ImmutableMap.builder();
|
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()));
|
builder.put(primitiveType.getTypeName().asString(), Type.getType(JvmPrimitiveType.get(primitiveType).getDesc()));
|
||||||
}
|
}
|
||||||
VALUES_TYPENAME_TO_TYPE = builder.build();
|
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;
|
private static final ImmutableMap<PrimitiveType, ProgressionIteratorBasicValue> ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE;
|
||||||
static {
|
static {
|
||||||
ImmutableMap.Builder<PrimitiveType, ProgressionIteratorBasicValue> builder = ImmutableMap.builder();
|
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()));
|
builder.put(elementType, new ProgressionIteratorBasicValue(elementType.getTypeName().asString()));
|
||||||
}
|
}
|
||||||
ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE = builder.build();
|
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.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
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.forLoop.ForInArrayIndicesRangeLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class ArrayIndicesRangeValue(
|
class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
||||||
|
|
||||||
private val boundedValue =
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
SimpleBoundedValue(
|
SimpleBoundedValue(
|
||||||
codegen, rangeCall,
|
codegen, rangeCall,
|
||||||
lowBound = StackValue.constant(0, asmElementType),
|
lowBound = StackValue.constant(0, asmElementType),
|
||||||
@@ -49,6 +42,4 @@ class ArrayIndicesRangeValue(
|
|||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInArrayIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
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
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
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.CallBasedInExpressionGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
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 {
|
abstract class CallIntrinsicRangeValue(protected val rangeCall: ResolvedCall<out CallableDescriptor>): RangeValue {
|
||||||
protected abstract fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>): Boolean
|
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 {
|
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator {
|
||||||
val resolvedCall = operatorReference.getResolvedCallWithAssert(codegen.bindingContext)
|
val resolvedCall = operatorReference.getResolvedCallWithAssert(codegen.bindingContext)
|
||||||
return if (isIntrinsicInCall(resolvedCall))
|
return if (isIntrinsicInCall(resolvedCall))
|
||||||
createIntrinsicInExpressionGenerator(codegen, operatorReference)
|
createIntrinsicInExpressionGenerator(codegen, operatorReference, resolvedCall)
|
||||||
else
|
else
|
||||||
CallBasedInExpressionGenerator(codegen, operatorReference)
|
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.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
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.forLoop.ForInCharSequenceIndicesRangeLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class CharSequenceIndicesRangeValue(
|
class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
||||||
|
|
||||||
private val boundedValue =
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
SimpleBoundedValue(
|
SimpleBoundedValue(
|
||||||
codegen, rangeCall,
|
codegen, rangeCall,
|
||||||
lowBound = StackValue.constant(0, asmElementType),
|
lowBound = StackValue.constant(0, asmElementType),
|
||||||
@@ -48,7 +41,4 @@ class CharSequenceIndicesRangeValue(
|
|||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInCharSequenceIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
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.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
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.forLoop.ForInCollectionIndicesRangeLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class CollectionIndicesRangeValue(
|
class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
private val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(rangeCall)
|
||||||
|
|
||||||
private val boundedValue =
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
SimpleBoundedValue(
|
SimpleBoundedValue(
|
||||||
codegen, rangeCall,
|
codegen, rangeCall,
|
||||||
lowBound = StackValue.constant(0, asmElementType),
|
lowBound = StackValue.constant(0, asmElementType),
|
||||||
@@ -48,7 +41,4 @@ class CollectionIndicesRangeValue(
|
|||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInCollectionIndicesRangeLoopGenerator(codegen, forExpression, rangeCall)
|
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
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.codegen.isClosedRangeContains
|
import org.jetbrains.kotlin.codegen.isClosedRangeContains
|
||||||
import org.jetbrains.kotlin.codegen.range.comparison.ObjectComparisonGenerator
|
import org.jetbrains.kotlin.codegen.range.comparison.ObjectComparisonGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
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(
|
class ComparableRangeLiteralRangeValue(
|
||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
@@ -43,6 +38,6 @@ class ComparableRangeLiteralRangeValue(
|
|||||||
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
|
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
|
||||||
isClosedRangeContains(resolvedCallForIn.resultingDescriptor)
|
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)
|
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.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
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.forLoop.ForInDownToProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
|
|
||||||
class DownToProgressionRangeValue(
|
class DownToProgressionRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
|
|
||||||
private val boundedValue =
|
|
||||||
SimpleBoundedValue(
|
SimpleBoundedValue(
|
||||||
codegen, rangeCall,
|
codegen, rangeCall,
|
||||||
lowBound = codegen.generateCallSingleArgument(rangeCall),
|
lowBound = codegen.generateCallSingleArgument(rangeCall),
|
||||||
@@ -42,7 +34,4 @@ class DownToProgressionRangeValue(
|
|||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInDownToProgressionLoopGenerator(codegen, forExpression, rangeCall)
|
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
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.getAsmRangeElementTypeForPrimitiveRangeOrProgression
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.isClosedFloatingPointRangeContains
|
import org.jetbrains.kotlin.codegen.range.comparison.ComparisonGenerator
|
||||||
import org.jetbrains.kotlin.codegen.isIntPrimitiveRangeExtensionForInt
|
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall
|
||||||
import org.jetbrains.kotlin.codegen.isPrimitiveRangeContains
|
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.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
|
||||||
abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(rangeCall) {
|
abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): CallIntrinsicRangeValue(rangeCall) {
|
||||||
@@ -32,4 +35,18 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(rangeCall: ResolvedCall<o
|
|||||||
isClosedFloatingPointRangeContains(it) ||
|
isClosedFloatingPointRangeContains(it) ||
|
||||||
isIntPrimitiveRangeExtensionForInt(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
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
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.forLoop.ForInRangeLiteralLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
|
|
||||||
class PrimitiveNumberRangeLiteralRangeValue(
|
class PrimitiveNumberRangeLiteralRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
SimpleBoundedValue(codegen, rangeCall)
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
private val boundedValue = SimpleBoundedValue(codegen, rangeCall)
|
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInRangeLiteralLoopGenerator(codegen, forExpression, rangeCall)
|
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
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
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.forLoop.ForInUntilRangeLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InContinuousRangeExpressionGenerator
|
|
||||||
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
|
||||||
|
|
||||||
class PrimitiveNumberUntilRangeValue(
|
class PrimitiveNumberUntilRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
||||||
codegen: ExpressionCodegen,
|
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||||
rangeCall: ResolvedCall<out CallableDescriptor>
|
SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false)
|
||||||
): PrimitiveNumberRangeIntrinsicRangeValue(rangeCall) {
|
|
||||||
private val comparisonGenerator = getComparisonGeneratorForPrimitiveType(asmElementType)
|
|
||||||
private val boundedValue = SimpleBoundedValue(codegen, rangeCall, isLowInclusive = true, isHighInclusive = false)
|
|
||||||
|
|
||||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression) =
|
||||||
ForInUntilRangeLoopGenerator(codegen, forExpression, rangeCall)
|
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 {
|
return when {
|
||||||
isPrimitiveNumberRangeTo(rangeCallee) ->
|
isPrimitiveNumberRangeTo(rangeCallee) ->
|
||||||
PrimitiveNumberRangeLiteralRangeValue(this, rangeCall)
|
PrimitiveNumberRangeLiteralRangeValue(rangeCall)
|
||||||
isPrimitiveNumberDownTo(rangeCallee) ->
|
isPrimitiveNumberDownTo(rangeCallee) ->
|
||||||
DownToProgressionRangeValue(this, rangeCall)
|
DownToProgressionRangeValue(rangeCall)
|
||||||
isPrimitiveNumberUntil(rangeCallee) ->
|
isPrimitiveNumberUntil(rangeCallee) ->
|
||||||
PrimitiveNumberUntilRangeValue(this, rangeCall)
|
PrimitiveNumberUntilRangeValue(rangeCall)
|
||||||
isArrayOrPrimitiveArrayIndices(rangeCallee) ->
|
isArrayOrPrimitiveArrayIndices(rangeCallee) ->
|
||||||
ArrayIndicesRangeValue(this, rangeCall)
|
ArrayIndicesRangeValue(rangeCall)
|
||||||
isCollectionIndices(rangeCallee) ->
|
isCollectionIndices(rangeCallee) ->
|
||||||
CollectionIndicesRangeValue(this, rangeCall)
|
CollectionIndicesRangeValue(rangeCall)
|
||||||
isCharSequenceIndices(rangeCallee) ->
|
isCharSequenceIndices(rangeCallee) ->
|
||||||
CharSequenceIndicesRangeValue(this, rangeCall)
|
CharSequenceIndicesRangeValue(rangeCall)
|
||||||
isComparableRangeTo(rangeCallee) ->
|
isComparableRangeTo(rangeCallee) ->
|
||||||
ComparableRangeLiteralRangeValue(this, rangeCall)
|
ComparableRangeLiteralRangeValue(this, rangeCall)
|
||||||
else ->
|
else ->
|
||||||
|
|||||||
+43
-5
@@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.range.comparison
|
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.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
@@ -30,10 +34,44 @@ interface ComparisonGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getComparisonGeneratorForPrimitiveType(type: Type): ComparisonGenerator =
|
fun getComparisonGeneratorForPrimitiveType(type: Type): ComparisonGenerator =
|
||||||
when (type) {
|
when {
|
||||||
Type.INT_TYPE, Type.SHORT_TYPE, Type.BYTE_TYPE, Type.CHAR_TYPE -> IntComparisonGenerator
|
type.isRepresentedAsPrimitiveInt() -> IntComparisonGenerator
|
||||||
Type.LONG_TYPE -> LongComparisonGenerator
|
type == Type.LONG_TYPE -> LongComparisonGenerator
|
||||||
Type.FLOAT_TYPE -> FloatComparisonGenerator
|
type == Type.FLOAT_TYPE -> FloatComparisonGenerator
|
||||||
Type.DOUBLE_TYPE -> DoubleComparisonGenerator
|
type == Type.DOUBLE_TYPE -> DoubleComparisonGenerator
|
||||||
else -> throw UnsupportedOperationException("Unexpected primitive type: " + type)
|
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