array.indices
This commit is contained in:
@@ -58,6 +58,7 @@ public class JetTypeMapper {
|
||||
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
|
||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
||||
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
||||
|
||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||
this.standardLibrary = standardLibrary;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayIndices implements IntrinsicMethod {
|
||||
@Override
|
||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
v.arraylength();
|
||||
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
|
||||
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,8 @@ public class IntrinsicMethods {
|
||||
private static final IntrinsicMethod DEC = new Increment(-1);
|
||||
|
||||
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
|
||||
public static final ArraySize ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
||||
|
||||
private final Project myProject;
|
||||
private final JetStandardLibrary myStdLib;
|
||||
@@ -89,15 +90,29 @@ public class IntrinsicMethods {
|
||||
declareIntrinsicProperty("CharArray", "size", ARRAY_SIZE);
|
||||
declareIntrinsicProperty("BooleanArray", "size", ARRAY_SIZE);
|
||||
|
||||
declareOverload(myStdLib.getArray().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getByteArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getShortArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getIntArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getLongArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getFloatArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getDoubleArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getCharArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareOverload(myStdLib.getBooleanArrayClass().getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("ByteArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("ShortArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("IntArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("LongArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("FloatArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("DoubleArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("CharArray", "indices", ARRAY_INDICES);
|
||||
declareIntrinsicProperty("BooleanArray", "indices", ARRAY_INDICES);
|
||||
|
||||
declareIterator(myStdLib.getArray());
|
||||
declareIterator(myStdLib.getByteArrayClass());
|
||||
declareIterator(myStdLib.getShortArrayClass());
|
||||
declareIterator(myStdLib.getIntArrayClass());
|
||||
declareIterator(myStdLib.getLongArrayClass());
|
||||
declareIterator(myStdLib.getFloatArrayClass());
|
||||
declareIterator(myStdLib.getDoubleArrayClass());
|
||||
declareIterator(myStdLib.getCharArrayClass());
|
||||
declareIterator(myStdLib.getBooleanArrayClass());
|
||||
}
|
||||
|
||||
private void declareIterator(ClassDescriptor classDescriptor) {
|
||||
declareOverload(classDescriptor.getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
|
||||
}
|
||||
|
||||
private void declareIntrinsicStringMethods() {
|
||||
|
||||
@@ -54,6 +54,8 @@ class Array<T>(val size : Int, init : fun(Int) : T = null ) {
|
||||
fun set(index : Int, value : T) : Unit
|
||||
|
||||
fun iterator() : Iterator<T>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class ByteArray(val size : Int) {
|
||||
@@ -61,6 +63,8 @@ class ByteArray(val size : Int) {
|
||||
fun set(index : Int, value : Byte) : Unit
|
||||
|
||||
fun iterator() : Iterator<Byte>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class ShortArray(val size : Int) {
|
||||
@@ -68,6 +72,8 @@ class ShortArray(val size : Int) {
|
||||
fun set(index : Int, value : Short) : Unit
|
||||
|
||||
fun iterator() : Iterator<Short>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class IntArray(val size : Int) {
|
||||
@@ -75,6 +81,8 @@ class IntArray(val size : Int) {
|
||||
fun set(index : Int, value : Int) : Unit
|
||||
|
||||
fun iterator() : Iterator<Int>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class LongArray(val size : Int) {
|
||||
@@ -82,6 +90,8 @@ class LongArray(val size : Int) {
|
||||
fun set(index : Int, value : Long) : Unit
|
||||
|
||||
fun iterator() : Iterator<Long>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class FloatArray(val size : Int) {
|
||||
@@ -89,6 +99,8 @@ class FloatArray(val size : Int) {
|
||||
fun set(index : Int, value : Float) : Unit
|
||||
|
||||
fun iterator() : Iterator<Float>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class DoubleArray(val size : Int) {
|
||||
@@ -96,6 +108,8 @@ class DoubleArray(val size : Int) {
|
||||
fun set(index : Int, value : Double) : Unit
|
||||
|
||||
fun iterator() : Iterator<Double>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class CharArray(val size : Int) {
|
||||
@@ -103,6 +117,8 @@ class CharArray(val size : Int) {
|
||||
fun set(index : Int, value : Char) : Unit
|
||||
|
||||
fun iterator() : Iterator<Char>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
class BooleanArray(val size : Int) {
|
||||
@@ -110,6 +126,8 @@ class BooleanArray(val size : Int) {
|
||||
fun set(index : Int, value : Boolean) : Unit
|
||||
|
||||
fun iterator() : Iterator<Boolean>
|
||||
|
||||
val indices : IntRange
|
||||
}
|
||||
|
||||
trait Comparable<in T> {
|
||||
@@ -152,8 +170,16 @@ trait Range<in T : Comparable<T>> {
|
||||
fun contains(item : T) : Boolean
|
||||
}
|
||||
|
||||
class IntRange<T : Comparable<T>>(val start : Int, val end : Int) : Range<T>, Iterable<T> {
|
||||
class IntRange(val start : Int, val excludedEnd : Int) : Range<Int>, Iterable<Int> {
|
||||
fun iterator () : Iterator<Int>
|
||||
|
||||
fun contains (elem: Int) : Boolean
|
||||
}
|
||||
|
||||
class LongRange(val start : Long, val end : Long) : Range<Long>, Iterable<Long> {
|
||||
fun iterator () : Iterator<Long>
|
||||
|
||||
fun contains (elem: Long) : Boolean
|
||||
}
|
||||
|
||||
abstract class Number : Hashable {
|
||||
@@ -349,11 +375,11 @@ class Long : Number, Comparable<Long> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Double>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Long>
|
||||
fun rangeTo(other : Short) : IntRange<Long>
|
||||
fun rangeTo(other : Byte) : IntRange<Long>
|
||||
fun rangeTo(other : Char) : IntRange<Long>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : LongRange
|
||||
fun rangeTo(other : Short) : LongRange
|
||||
fun rangeTo(other : Byte) : LongRange
|
||||
fun rangeTo(other : Char) : LongRange
|
||||
|
||||
fun inc() : Long
|
||||
fun dec() : Long
|
||||
@@ -420,11 +446,11 @@ class Int : Number, Comparable<Int> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Double>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Int>
|
||||
fun rangeTo(other : Byte) : IntRange<Int>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Int
|
||||
fun dec() : Int
|
||||
@@ -491,11 +517,11 @@ class Char : Number, Comparable<Char> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Byte>
|
||||
fun rangeTo(other : Char) : IntRange<Char>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Char
|
||||
fun dec() : Char
|
||||
@@ -554,11 +580,11 @@ class Short : Number, Comparable<Short> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Short>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Short
|
||||
fun dec() : Short
|
||||
@@ -617,11 +643,11 @@ class Byte : Number, Comparable<Byte> {
|
||||
|
||||
fun rangeTo(other : Double) : Range<Double>
|
||||
fun rangeTo(other : Float) : Range<Float>
|
||||
fun rangeTo(other : Long) : IntRange<Long>
|
||||
fun rangeTo(other : Int) : IntRange<Int>
|
||||
fun rangeTo(other : Short) : IntRange<Short>
|
||||
fun rangeTo(other : Byte) : IntRange<Byte>
|
||||
fun rangeTo(other : Char) : IntRange<Int>
|
||||
fun rangeTo(other : Long) : LongRange
|
||||
fun rangeTo(other : Int) : IntRange
|
||||
fun rangeTo(other : Short) : IntRange
|
||||
fun rangeTo(other : Byte) : IntRange
|
||||
fun rangeTo(other : Char) : IntRange
|
||||
|
||||
fun inc() : Byte
|
||||
fun dec() : Byte
|
||||
|
||||
@@ -86,4 +86,18 @@ public class ArrayGenTest extends CodegenTestCase {
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testArrayIndices () throws Exception {
|
||||
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
|
||||
public void testCharIndices () throws Exception {
|
||||
loadText("fun box() { val x = CharArray(5).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
foo.invoke(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,8 +433,8 @@ public class NamespaceGenTest extends CodegenTestCase {
|
||||
final Method main = generateFunction();
|
||||
IntRange result = (IntRange) main.invoke(null);
|
||||
assertTrue(result.contains(1));
|
||||
assertTrue(result.contains(10));
|
||||
assertFalse(result.contains(11));
|
||||
assertTrue(result.contains(9));
|
||||
assertFalse(result.contains(10));
|
||||
}
|
||||
|
||||
public void testSubstituteJavaMethodTypeParameters() throws Exception {
|
||||
|
||||
@@ -1,28 +1,75 @@
|
||||
package jet;
|
||||
|
||||
public class IntRange implements Range<Integer> {
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObject {
|
||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
||||
|
||||
private final int startValue;
|
||||
private final int endValue;
|
||||
private final int excludedEndValue;
|
||||
|
||||
public IntRange(int startValue, int endValue) {
|
||||
this.startValue = startValue;
|
||||
this.endValue = endValue;
|
||||
this.excludedEndValue = endValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Integer item) {
|
||||
if (item == null) return false;
|
||||
if (startValue <= endValue) {
|
||||
return item >= startValue && item <= endValue;
|
||||
if (startValue < excludedEndValue) {
|
||||
return item >= startValue && item < excludedEndValue;
|
||||
}
|
||||
return item <= startValue && item >= endValue;
|
||||
return item <= startValue && item > excludedEndValue;
|
||||
}
|
||||
|
||||
public int getStartValue() {
|
||||
public int getStart() {
|
||||
return startValue;
|
||||
}
|
||||
|
||||
public int getEndValue() {
|
||||
return endValue;
|
||||
public int getEnd() {
|
||||
return excludedEndValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return new MyIterator(startValue, excludedEndValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public static IntRange count(int length) {
|
||||
return new IntRange(0, length);
|
||||
}
|
||||
|
||||
private static class MyIterator implements Iterator<Integer> {
|
||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
||||
private final int lastValue;
|
||||
|
||||
private int cur;
|
||||
private boolean reversed;
|
||||
|
||||
public MyIterator(int startValue, int endValue) {
|
||||
reversed = endValue <= startValue;
|
||||
this.lastValue = reversed ? startValue : endValue-1;
|
||||
cur = reversed ? endValue-1 : startValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return reversed ? cur >= lastValue : cur <= lastValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
return reversed ? cur-- : cur++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package jet;
|
||||
|
||||
import jet.typeinfo.TypeInfo;
|
||||
|
||||
public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
|
||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
|
||||
|
||||
private final long startValue;
|
||||
private final long excludedEndValue;
|
||||
|
||||
public LongRange(long startValue, long endValue) {
|
||||
this.startValue = startValue;
|
||||
this.excludedEndValue = endValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Long item) {
|
||||
if (item == null) return false;
|
||||
if (startValue < excludedEndValue) {
|
||||
return item >= startValue && item < excludedEndValue;
|
||||
}
|
||||
return item <= startValue && item > excludedEndValue;
|
||||
}
|
||||
|
||||
public long getStart() {
|
||||
return startValue;
|
||||
}
|
||||
|
||||
public long getEnd() {
|
||||
return excludedEndValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Long> iterator() {
|
||||
return new MyIterator(startValue, excludedEndValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
public static IntRange count(int length) {
|
||||
return new IntRange(0, length);
|
||||
}
|
||||
|
||||
private static class MyIterator implements Iterator<Long> {
|
||||
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
|
||||
private final long lastValue;
|
||||
|
||||
private long cur;
|
||||
private boolean reversed;
|
||||
|
||||
public MyIterator(long startValue, long endValue) {
|
||||
reversed = endValue <= startValue;
|
||||
this.lastValue = reversed ? startValue : endValue-1;
|
||||
cur = reversed ? endValue-1 : startValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return reversed ? cur >= lastValue : cur <= lastValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long next() {
|
||||
return reversed ? cur-- : cur++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeInfo<?> getTypeInfo() {
|
||||
return typeInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user