RangeCodegenUtil: convert to Kotlin + cleanup

This commit is contained in:
Dmitry Petrov
2017-06-28 15:46:14 +03:00
parent 304e4e8dce
commit c870eeac2e
5 changed files with 144 additions and 213 deletions
@@ -2874,8 +2874,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assert deparenthesized != null : "For with empty range expression"; assert deparenthesized != null : "For with empty range expression";
boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN; boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN;
return StackValue.operation(Type.BOOLEAN_TYPE, v -> { return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
if (RangeCodegenUtil.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) || if (RangeCodegenUtilKt.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) ||
RangeCodegenUtil.isPrimitiveRangeToExtension(operationReference, bindingContext)) { RangeCodegenUtilKt.isPrimitiveRangeToExtension(operationReference, bindingContext)) {
generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted); generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted);
} }
else { else {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2017 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -14,228 +14,160 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen
import com.google.common.collect.ImmutableMap; import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt; import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
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
import java.util.Arrays; private val RANGE_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
import java.util.List; supportedRangeTypes().associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor;
public class RangeCodegenUtil {
private static final ImmutableMap<FqName, PrimitiveType> RANGE_TO_ELEMENT_TYPE;
private static final ImmutableMap<FqName, PrimitiveType> PROGRESSION_TO_ELEMENT_TYPE;
@NotNull
public static List<PrimitiveType> supportedRangeTypes() {
return Arrays.asList(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG);
}
static {
ImmutableMap.Builder<FqName, PrimitiveType> rangeBuilder = ImmutableMap.builder();
ImmutableMap.Builder<FqName, PrimitiveType> progressionBuilder = ImmutableMap.builder();
for (PrimitiveType primitiveType : supportedRangeTypes()) {
FqName rangeClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
FqName progressionClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
rangeBuilder.put(rangeClassFqName, primitiveType);
progressionBuilder.put(progressionClassFqName, primitiveType);
} }
RANGE_TO_ELEMENT_TYPE = rangeBuilder.build();
PROGRESSION_TO_ELEMENT_TYPE = progressionBuilder.build();
}
private RangeCodegenUtil() {} private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
supportedRangeTypes().associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
}
public static boolean isRange(KotlinType rangeType) { fun supportedRangeTypes() =
return !rangeType.isMarkedNullable() && getPrimitiveRangeElementType(rangeType) != null; listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG)
}
public static boolean isProgression(KotlinType rangeType) { fun isRange(rangeType: KotlinType) =
return !rangeType.isMarkedNullable() && getPrimitiveProgressionElementType(rangeType) != null; !rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
}
@Nullable fun isProgression(rangeType: KotlinType) =
private static PrimitiveType getPrimitiveRangeElementType(KotlinType rangeType) { !rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
return getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE);
}
@Nullable private fun getPrimitiveRangeElementType(rangeType: KotlinType) =
private static PrimitiveType getPrimitiveProgressionElementType(KotlinType rangeType) { getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
return getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE);
}
@Nullable private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
private static PrimitiveType getPrimitiveRangeOrProgressionElementType( getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE)
@NotNull KotlinType rangeOrProgression,
@NotNull ImmutableMap<FqName, PrimitiveType> map
) {
ClassifierDescriptor declarationDescriptor = rangeOrProgression.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor == null) return null;
FqNameUnsafe fqName = DescriptorUtils.getFqName(declarationDescriptor);
if (!fqName.isSafe()) return null;
return map.get(fqName.toSafe());
}
@Nullable private fun getPrimitiveRangeOrProgressionElementType(
public static PrimitiveType getPrimitiveRangeOrProgressionElementType(@NotNull FqName rangeOrProgressionName) { rangeOrProgression: KotlinType,
PrimitiveType result = RANGE_TO_ELEMENT_TYPE.get(rangeOrProgressionName); map: Map<FqName, PrimitiveType>
return result != null ? result : PROGRESSION_TO_ELEMENT_TYPE.get(rangeOrProgressionName); ): PrimitiveType? {
} val declarationDescriptor = rangeOrProgression.constructor.declarationDescriptor ?: return null
val fqName = DescriptorUtils.getFqName(declarationDescriptor).takeIf { it.isSafe } ?: return null
return map[fqName.toSafe()]
}
public static boolean isRangeOrProgression(@NotNull FqName className) { fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? =
return getPrimitiveRangeOrProgressionElementType(className) != null; RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?:
} PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName]
public static boolean isPrimitiveNumberRangeTo(CallableDescriptor rangeTo) { fun isRangeOrProgression(className: FqName) =
if (!"rangeTo".equals(rangeTo.getName().asString())) return false; getPrimitiveRangeOrProgressionElementType(className) != null
if (!isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) return false; fun isPrimitiveNumberRangeTo(rangeTo: CallableDescriptor) =
"rangeTo" == rangeTo.name.asString() &&
isPrimitiveNumberClassDescriptor(rangeTo.containingDeclaration)
return true; private fun isPrimitiveRangeToExtension(descriptor: CallableDescriptor): Boolean {
} if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
private static boolean isPrimitiveRangeToExtension(@NotNull CallableDescriptor descriptor) { val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false; return KotlinBuiltIns.isPrimitiveType(extensionReceiver.type)
}
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter(); fun isPrimitiveNumberDownTo(descriptor: CallableDescriptor): Boolean {
if (extensionReceiver == null) return false; if (!isTopLevelInPackage(descriptor, "downTo", "kotlin.ranges")) return false
return KotlinBuiltIns.isPrimitiveType(extensionReceiver.getType()); val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
} val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
}
public static boolean isPrimitiveNumberDownTo(@NotNull CallableDescriptor descriptor) { fun isPrimitiveNumberUntil(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "downTo", "kotlin.ranges")) return false; if (!isTopLevelInPackage(descriptor, "until", "kotlin.ranges")) return false
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter(); val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
if (extensionReceiver == null) return false; val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
ClassifierDescriptor extensionReceiverClassifier = extensionReceiver.getType().getConstructor().getDeclarationDescriptor(); return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
if (!isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)) return false; }
return true; fun isArrayOrPrimitiveArrayIndices(descriptor: CallableDescriptor): Boolean {
} if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
public static boolean isPrimitiveNumberUntil(@NotNull CallableDescriptor descriptor) { val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
if (!isTopLevelInPackage(descriptor, "until", "kotlin.ranges")) return false; val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isArray(extensionReceiverType) || KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)
}
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter(); fun isCollectionIndices(descriptor: CallableDescriptor): Boolean {
if (extensionReceiver == null) return false; if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
ClassifierDescriptor extensionReceiverClassifier = extensionReceiver.getType().getConstructor().getDeclarationDescriptor();
if (!isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)) return false;
return true; val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
} val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)
}
public static boolean isArrayOrPrimitiveArrayIndices(@NotNull CallableDescriptor descriptor) { fun isCharSequenceIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false; if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text")) return false
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter(); val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
if (extensionReceiver == null) return false; val extensionReceiverType = extensionReceiver.type
KotlinType extensionReceiverType = extensionReceiver.getType(); return KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)
if (!KotlinBuiltIns.isArray(extensionReceiverType) && !KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)) return false; }
return true; fun isPrimitiveRangeToExtension(operationReference: KtSimpleNameExpression, bindingContext: BindingContext): Boolean {
} val resolvedCall = operationReference.getResolvedCallWithAssert(bindingContext)
val receiver = resolvedCall.dispatchReceiver as? ExpressionReceiver ?: return false
public static boolean isCollectionIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)) return false;
return true;
}
public static boolean isCharSequenceIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)) return false;
return true;
}
public static boolean isPrimitiveRangeToExtension(@NotNull KtSimpleNameExpression operationReference, @NotNull BindingContext bindingContext) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
.getResolvedCallWithAssert(operationReference, bindingContext);
ReceiverValue receiver = resolvedCall.getDispatchReceiver();
/*
* Range is optimizable if
* 'in' receiver is expression 'rangeTo' from stdlib package
* and its argument has same primitive type as generic range parameter.
* For non-matching primitive types (e.g. int in double range)
* dispatch receiver will be null, because extension method will be called.
*/
if (!(receiver instanceof ExpressionReceiver)) return false;
ExpressionReceiver e = (ExpressionReceiver) receiver;
ResolvedCall<? extends CallableDescriptor> resolvedReceiver =
CallUtilKt.getResolvedCall(e.getExpression(), bindingContext);
if (resolvedReceiver == null) return false;
return isPrimitiveRangeToExtension(resolvedReceiver.getResultingDescriptor());
}
/* /*
* Checks whether for expression 'x in a..b' a..b is primitive integral range * Range is optimizable if
* with same type as x. * receiver is a call for 'rangeTo' from stdlib package
* and its argument has same primitive type as generic range parameter.
* For non-matching primitive types (e.g. int in double range)
* dispatch receiver will be null, because extension method will be called.
*/ */
public static boolean isPrimitiveRangeSpecializationOfType(
@NotNull Type argumentType,
@NotNull KtExpression rangeExpression,
@NotNull BindingContext bindingContext
) {
if (rangeExpression instanceof KtBinaryExpression &&
((KtBinaryExpression) rangeExpression).getOperationReference().getReferencedNameElementType() == KtTokens.RANGE) {
KotlinType kotlinType = bindingContext.getType(rangeExpression);
assert kotlinType != null;
DeclarationDescriptor descriptor = kotlinType.getConstructor().getDeclarationDescriptor();
if (descriptor != null) {
FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor);
if (fqName.equals(KotlinBuiltIns.FQ_NAMES.longRange)) {
return argumentType == Type.LONG_TYPE;
}
if (fqName.equals(KotlinBuiltIns.FQ_NAMES.charRange) || fqName.equals(KotlinBuiltIns.FQ_NAMES.intRange)) {
return AsmUtil.isIntPrimitive(argumentType);
}
}
}
return false; val resolvedReceiver = receiver.expression.getResolvedCall(bindingContext) ?: return false
} return isPrimitiveRangeToExtension(resolvedReceiver.resultingDescriptor)
}
private static boolean isTopLevelInPackage(@NotNull CallableDescriptor descriptor, @NotNull String name, @NotNull String packageName) {
if (!name.equals(descriptor.getName().asString())) return false; /*
* Checks whether for expression 'x in a..b' a..b is primitive integral range
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); * with same type as x.
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) return false; */
String packageFqName = ((PackageFragmentDescriptor) containingDeclaration).getFqName().asString(); fun isPrimitiveRangeSpecializationOfType(
if (!packageName.equals(packageFqName)) return false; argumentType: Type,
rangeExpression: KtExpression,
return true; bindingContext: BindingContext
} ): Boolean {
if (rangeExpression is KtBinaryExpression && rangeExpression.operationReference.getReferencedNameElementType() === KtTokens.RANGE) {
val kotlinType = bindingContext.getType(rangeExpression)!!
val descriptor = kotlinType.constructor.declarationDescriptor ?: return false
val fqName = DescriptorUtils.getFqName(descriptor)
return (fqName == KotlinBuiltIns.FQ_NAMES.longRange && argumentType === Type.LONG_TYPE) ||
(fqName == KotlinBuiltIns.FQ_NAMES.charRange || fqName == KotlinBuiltIns.FQ_NAMES.intRange) && AsmUtil.isIntPrimitive(argumentType)
}
return false
}
private fun isTopLevelInPackage(descriptor: CallableDescriptor, name: String, packageName: String): Boolean {
if (name != descriptor.name.asString()) return false
val containingDeclaration = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
val packageFqName = containingDeclaration.fqName.asString()
return packageName == packageFqName
} }
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.RangeCodegenUtil
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.isRangeOrProgression
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -213,7 +213,7 @@ fun AbstractInsnNode.isIteratorMethodCallOfProgression(values: List<BasicValue>)
} }
fun isProgressionClass(type: Type) = fun isProgressionClass(type: Type) =
RangeCodegenUtil.isRangeOrProgression(buildFqNameByInternal(type.internalName)) isRangeOrProgression(buildFqNameByInternal(type.internalName))
fun AbstractInsnNode.isAreEqualIntrinsicForSameTypedBoxedValues(values: List<BasicValue>) = fun AbstractInsnNode.isAreEqualIntrinsicForSameTypedBoxedValues(values: List<BasicValue>) =
isAreEqualIntrinsic() && areSameTypedBoxedValues(values) isAreEqualIntrinsic() && areSameTypedBoxedValues(values)
@@ -20,7 +20,7 @@ import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.codegen.RangeCodegenUtil; import org.jetbrains.kotlin.codegen.RangeCodegenUtilKt;
import org.jetbrains.kotlin.codegen.intrinsics.IteratorNext; import org.jetbrains.kotlin.codegen.intrinsics.IteratorNext;
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue; import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
@@ -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 : RangeCodegenUtil.supportedRangeTypes()) { for (PrimitiveType primitiveType : RangeCodegenUtilKt.supportedRangeTypes()) {
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 : RangeCodegenUtil.supportedRangeTypes()) { for (PrimitiveType elementType : RangeCodegenUtilKt.supportedRangeTypes()) {
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();
@@ -67,7 +67,7 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue {
@Nullable @Nullable
public static ProgressionIteratorBasicValue byProgressionClassType(@NotNull Type progressionClassType) { public static ProgressionIteratorBasicValue byProgressionClassType(@NotNull Type progressionClassType) {
FqName classFqName = new FqName(progressionClassType.getClassName()); FqName classFqName = new FqName(progressionClassType.getClassName());
PrimitiveType elementType = RangeCodegenUtil.getPrimitiveRangeOrProgressionElementType(classFqName); PrimitiveType elementType = RangeCodegenUtilKt.getPrimitiveRangeOrProgressionElementType(classFqName);
return ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE.get(elementType); return ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE.get(elementType);
} }
@@ -17,8 +17,7 @@
package org.jetbrains.kotlin.codegen.range package org.jetbrains.kotlin.codegen.range
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.RangeCodegenUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -42,9 +41,9 @@ fun ExpressionCodegen.createRangeValueForExpression(rangeExpression: KtExpressio
return when { return when {
asmRangeType.sort == Type.ARRAY -> asmRangeType.sort == Type.ARRAY ->
ArrayRangeValue() ArrayRangeValue()
RangeCodegenUtil.isRange(rangeType) -> isRange(rangeType) ->
PrimitiveRangeRangeValue() PrimitiveRangeRangeValue()
RangeCodegenUtil.isProgression(rangeType) -> isProgression(rangeType) ->
PrimitiveProgressionRangeValue() PrimitiveProgressionRangeValue()
isSubtypeOfCharSequence(rangeType, state.module.builtIns) -> isSubtypeOfCharSequence(rangeType, state.module.builtIns) ->
CharSequenceRangeValue() CharSequenceRangeValue()
@@ -84,17 +83,17 @@ private fun createIntrinsifiedRangeValueOrNull(rangeCall: ResolvedCall<out Calla
val rangeCallee = rangeCall.resultingDescriptor val rangeCallee = rangeCall.resultingDescriptor
return when { return when {
RangeCodegenUtil.isPrimitiveNumberRangeTo(rangeCallee) -> isPrimitiveNumberRangeTo(rangeCallee) ->
PrimitiveNumberRangeToRangeValue(rangeCall) PrimitiveNumberRangeToRangeValue(rangeCall)
RangeCodegenUtil.isPrimitiveNumberDownTo(rangeCallee) -> isPrimitiveNumberDownTo(rangeCallee) ->
DownToProgressionRangeValue(rangeCall) DownToProgressionRangeValue(rangeCall)
RangeCodegenUtil.isPrimitiveNumberUntil(rangeCallee) -> isPrimitiveNumberUntil(rangeCallee) ->
PrimitiveNumberUntilRangeValue(rangeCall) PrimitiveNumberUntilRangeValue(rangeCall)
RangeCodegenUtil.isArrayOrPrimitiveArrayIndices(rangeCallee) -> isArrayOrPrimitiveArrayIndices(rangeCallee) ->
ArrayIndicesRangeValue(rangeCall) ArrayIndicesRangeValue(rangeCall)
RangeCodegenUtil.isCollectionIndices(rangeCallee) -> isCollectionIndices(rangeCallee) ->
CollectionIndicesRangeValue(rangeCall) CollectionIndicesRangeValue(rangeCall)
RangeCodegenUtil.isCharSequenceIndices(rangeCallee) -> isCharSequenceIndices(rangeCallee) ->
CharSequenceIndicesRangeValue(rangeCall) CharSequenceIndicesRangeValue(rangeCall)
else -> else ->
null null