Use elementKotlinType in primitive number range intrinsics
This commit is contained in:
@@ -38,7 +38,7 @@ class ArrayIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor>) :
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, elementType),
|
||||
StackValue.constant(0, codegen.asmType(elementKotlinType), elementKotlinType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class CharSequenceIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescript
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, elementType),
|
||||
StackValue.constant(0, codegen.asmType(elementKotlinType), elementKotlinType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class CollectionIndicesRangeValue(rangeCall: ResolvedCall<out CallableDescriptor
|
||||
override fun getBoundedValue(codegen: ExpressionCodegen) =
|
||||
SimpleBoundedValue(
|
||||
codegen.asmType(rangeCall.resultingDescriptor.returnType!!),
|
||||
StackValue.constant(0, elementType),
|
||||
StackValue.constant(0, codegen.asmType(elementKotlinType), elementKotlinType),
|
||||
true,
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateCallReceiver(rangeCall).put(codegen.asmType(expectedReceiverType), expectedReceiverType, v)
|
||||
|
||||
+2
-4
@@ -43,8 +43,6 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
rangeCall.resultingDescriptor.returnType?.let { getRangeOrProgressionElementType(it) }
|
||||
?: throw AssertionError("Unexpected range ")
|
||||
|
||||
protected val elementType = getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCall.resultingDescriptor)
|
||||
|
||||
override fun isIntrinsicInCall(resolvedCallForIn: ResolvedCall<out CallableDescriptor>) =
|
||||
resolvedCallForIn.resultingDescriptor.let {
|
||||
isPrimitiveRangeContains(it) ||
|
||||
@@ -145,7 +143,7 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
codegen, forExpression,
|
||||
startValue = startValue,
|
||||
isStartInclusive = isStartInclusive,
|
||||
endValue = StackValue.integerConstant(endIntValue, elementType),
|
||||
endValue = StackValue.integerConstant(endIntValue, codegen.asmType(elementKotlinType)),
|
||||
isEndInclusive = true,
|
||||
comparisonGenerator = getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
step = step
|
||||
@@ -163,7 +161,7 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||
codegen, forExpression,
|
||||
startValue = startValue,
|
||||
isStartInclusive = isStartInclusive,
|
||||
endValue = StackValue.constant(endLongValue, elementType),
|
||||
endValue = StackValue.constant(endLongValue, codegen.asmType(elementKotlinType), elementKotlinType),
|
||||
isEndInclusive = true,
|
||||
comparisonGenerator = getComparisonGeneratorForKotlinType(elementKotlinType),
|
||||
step = step
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtForExpression
|
||||
@@ -18,9 +19,8 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
val supportedRangeTypes = listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG)
|
||||
|
||||
@@ -61,32 +61,52 @@ private fun getPrimitiveRangeOrProgressionElementType(
|
||||
return map[fqName.toSafe()]
|
||||
}
|
||||
|
||||
private const val CHAR_RANGE_FQN = "kotlin.ranges.CharRange"
|
||||
private const val INT_RANGE_FQN = "kotlin.ranges.IntRange"
|
||||
private const val LONG_RANGE_FQN = "kotlin.ranges.LongRange"
|
||||
private const val CHAR_PROGRESSION_FQN = "kotlin.ranges.CharProgression"
|
||||
private const val INT_PROGRESSION_FQN = "kotlin.ranges.IntProgression"
|
||||
private const val LONG_PROGRESSION_FQN = "kotlin.ranges.LongProgression"
|
||||
private const val CLOSED_FLOAT_RANGE_FQN = "kotlin.ranges.ClosedFloatRange"
|
||||
private const val CLOSED_DOUBLE_RANGE_FQN = "kotlin.ranges.ClosedDoubleRange"
|
||||
private const val CLOSED_RANGE_FQN = "kotlin.ranges.ClosedRange"
|
||||
private const val CLOSED_FLOATING_POINT_RANGE_FQN = "kotlin.ranges.ClosedFloatingPointRange"
|
||||
private const val COMPARABLE_RANGE_FQN = "kotlin.ranges.ComparableRange"
|
||||
private const val UINT_RANGE_FQN = "kotlin.ranges.UIntRange"
|
||||
private const val ULONG_RANGE_FQN = "kotlin.ranges.ULongRange"
|
||||
|
||||
fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
|
||||
val rangeClassDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
val builtIns = rangeClassDescriptor.builtIns
|
||||
|
||||
return when (rangeClassDescriptor.fqNameSafe.asString()) {
|
||||
"kotlin.ranges.CharRange" -> builtIns.charType
|
||||
"kotlin.ranges.IntRange" -> builtIns.intType
|
||||
"kotlin.ranges.LongRange" -> builtIns.longType
|
||||
CHAR_RANGE_FQN -> builtIns.charType
|
||||
INT_RANGE_FQN -> builtIns.intType
|
||||
LONG_RANGE_FQN -> builtIns.longType
|
||||
|
||||
"kotlin.ranges.CharProgression" -> builtIns.charType
|
||||
"kotlin.ranges.IntProgression" -> builtIns.intType
|
||||
"kotlin.ranges.LongProgression" -> builtIns.longType
|
||||
CHAR_PROGRESSION_FQN -> builtIns.charType
|
||||
INT_PROGRESSION_FQN -> builtIns.intType
|
||||
LONG_PROGRESSION_FQN -> builtIns.longType
|
||||
|
||||
"kotlin.ranges.ClosedFloatRange" -> builtIns.floatType
|
||||
"kotlin.ranges.ClosedDoubleRange" -> builtIns.doubleType
|
||||
CLOSED_FLOAT_RANGE_FQN -> builtIns.floatType
|
||||
CLOSED_DOUBLE_RANGE_FQN -> builtIns.doubleType
|
||||
|
||||
"kotlin.ranges.ClosedRange" -> rangeType.arguments.singleOrNull()?.type
|
||||
CLOSED_RANGE_FQN -> rangeType.arguments.singleOrNull()?.type
|
||||
|
||||
"kotlin.ranges.ClosedFloatingPointRange" -> rangeType.arguments.singleOrNull()?.type
|
||||
CLOSED_FLOATING_POINT_RANGE_FQN -> rangeType.arguments.singleOrNull()?.type
|
||||
|
||||
"kotlin.ranges.ComparableRange" -> rangeType.arguments.singleOrNull()?.type
|
||||
COMPARABLE_RANGE_FQN -> rangeType.arguments.singleOrNull()?.type
|
||||
|
||||
UINT_RANGE_FQN -> rangeClassDescriptor.findTypeInModuleByTopLevelClassFqName(KotlinBuiltIns.FQ_NAMES.uIntFqName)
|
||||
ULONG_RANGE_FQN -> rangeClassDescriptor.findTypeInModuleByTopLevelClassFqName(KotlinBuiltIns.FQ_NAMES.uLongFqName)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor.findTypeInModuleByTopLevelClassFqName(fqName: FqName) =
|
||||
module.findClassAcrossModuleDependencies(ClassId.topLevel(fqName))?.defaultType
|
||||
|
||||
fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType {
|
||||
val loopRange = forExpression.loopRange!!
|
||||
val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange)
|
||||
@@ -104,6 +124,14 @@ fun isPrimitiveNumberRangeTo(rangeTo: CallableDescriptor) =
|
||||
"rangeTo" == rangeTo.name.asString() && isPrimitiveNumberClassDescriptor(rangeTo.containingDeclaration) ||
|
||||
isPrimitiveRangeToExtension(rangeTo)
|
||||
|
||||
fun isUnsignedIntegerRangeTo(rangeTo: CallableDescriptor) =
|
||||
"rangeTo" == rangeTo.name.asString() && isUnsignedIntegerClass(rangeTo.containingDeclaration)
|
||||
|
||||
fun isUnsignedIntegerClass(descriptor: DeclarationDescriptor) =
|
||||
descriptor is ClassDescriptor && descriptor.defaultType.let { type ->
|
||||
KotlinBuiltIns.isUByte(type) || KotlinBuiltIns.isUShort(type) || KotlinBuiltIns.isUInt(type) || KotlinBuiltIns.isULong(type)
|
||||
}
|
||||
|
||||
private inline fun CallableDescriptor.isTopLevelExtensionOnType(
|
||||
name: String,
|
||||
packageFQN: String,
|
||||
@@ -225,35 +253,6 @@ fun isClosedFloatingPointRangeContains(descriptor: CallableDescriptor): Boolean
|
||||
return true
|
||||
}
|
||||
|
||||
fun getClosedFloatingPointRangeElementType(rangeType: KotlinType): KotlinType? {
|
||||
val classDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
|
||||
if (!classDescriptor.isTopLevelInPackage("ClosedFloatingPointRange", "kotlin.ranges")) return null
|
||||
return rangeType.arguments.singleOrNull()?.type
|
||||
}
|
||||
|
||||
fun getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCallee: CallableDescriptor): Type {
|
||||
val rangeType = rangeCallee.returnType!!
|
||||
|
||||
getPrimitiveRangeElementType(rangeType)?.let {
|
||||
return AsmTypes.valueTypeForPrimitive(it)
|
||||
}
|
||||
|
||||
getPrimitiveProgressionElementType(rangeType)?.let {
|
||||
return AsmTypes.valueTypeForPrimitive(it)
|
||||
}
|
||||
|
||||
getClosedFloatingPointRangeElementType(rangeType)?.let {
|
||||
when {
|
||||
KotlinBuiltIns.isDouble(it) -> return Type.DOUBLE_TYPE
|
||||
KotlinBuiltIns.isFloat(it) -> return Type.FLOAT_TYPE
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw AssertionError("Unexpected range type: $rangeType")
|
||||
}
|
||||
|
||||
fun isCharSequenceIterator(descriptor: CallableDescriptor) =
|
||||
descriptor.isTopLevelExtensionOnType("iterator", "kotlin.text") {
|
||||
it.constructor.declarationDescriptor?.isTopLevelInPackage("CharSequence", "kotlin")
|
||||
|
||||
Reference in New Issue
Block a user