KT-12985 Do not create range instances for 'for' loop in CharSequence.indices

This commit is contained in:
Dmitry Petrov
2016-07-05 16:06:18 +03:00
parent 3dc23a0e02
commit 3445fe0d30
6 changed files with 71 additions and 1 deletions
@@ -656,6 +656,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assert extensionReceiver != null : "Extension receiver should be non-null for optimizable 'Collection.indices' call";
return new ForInCollectionIndicesRangeLoopGenerator(forExpression, extensionReceiver);
}
else if (RangeCodegenUtil.isCharSequenceIndices(loopRangeCallee)) {
ReceiverValue extensionReceiver = loopRangeCall.getExtensionReceiver();
assert extensionReceiver != null : "Extension receiver should be non-null for optimizable 'CharSequence.indices' call";
return new ForInCharSequenceIndicesRangeLoopGenerator(forExpression, extensionReceiver);
}
return null;
}
@@ -1198,7 +1203,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
StackValue receiver = generateReceiverValue(receiverValue, false);
Type receiverType = asmType(receiverValue.getType());
receiver.put(receiverType, v); // NB receiverType is a collection or an array
receiver.put(receiverType, v);
getReceiverSizeAsInt();
v.iconst(1);
v.sub(Type.INT_TYPE);
@@ -1233,6 +1238,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
private class ForInCharSequenceIndicesRangeLoopGenerator extends ForInOptimizedIndicesLoopGenerator {
private ForInCharSequenceIndicesRangeLoopGenerator(@NotNull KtForExpression forExpression, @NotNull ReceiverValue receiverValue) {
super(forExpression, receiverValue);
}
@Override
protected void getReceiverSizeAsInt() {
v.invokeinterface("java/lang/CharSequence", "length", "()I");
}
}
private class ForInProgressionExpressionLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator {
private int incrementVar;
private Type incrementType;
@@ -165,6 +165,17 @@ public class RangeCodegenUtil {
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;
}
private static boolean isTopLevelInPackage(@NotNull CallableDescriptor descriptor, @NotNull String name, @NotNull String packageName) {
if (!name.equals(descriptor.getName().asString())) return false;