| Index: sdk/lib/_internal/lib/js_array.dart
|
| diff --git a/sdk/lib/_internal/lib/js_array.dart b/sdk/lib/_internal/lib/js_array.dart
|
| index 32c0c8cbc67f760fda7f80c2aa8d5b2fb28ffea0..bc6ae8391c253c62acf43734d85914a6408e7ea1 100644
|
| --- a/sdk/lib/_internal/lib/js_array.dart
|
| +++ b/sdk/lib/_internal/lib/js_array.dart
|
| @@ -14,6 +14,66 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
|
|
| const JSArray();
|
|
|
| + /**
|
| + * Returns a fresh JavaScript Array, marked as fixed-length.
|
| + *
|
| + * [length] must be a non-negative integer.
|
| + */
|
| + factory JSArray.fixed(int length) {
|
| + // Explicit type test is necessary to guard against JavaScript conversions
|
| + // in unchecked mode.
|
| + if ((length is !int) || (length < 0)) {
|
| + throw new ArgumentError("Length must be a non-negative integer: $length");
|
| + }
|
| + return new JSArray<E>.markFixed(JS('', 'new Array(#)', length));
|
| + }
|
| +
|
| + /**
|
| + * Returns a fresh growable JavaScript Array of zero length length.
|
| + */
|
| + factory JSArray.emptyGrowable() => new JSArray<E>.markGrowable(JS('', '[]'));
|
| +
|
| + /**
|
| + * Returns a fresh growable JavaScript Array with initial length.
|
| + *
|
| + * [validatedLength] must be a non-negative integer.
|
| + */
|
| + factory JSArray.growable(int length) {
|
| + // Explicit type test is necessary to guard against JavaScript conversions
|
| + // in unchecked mode.
|
| + if ((length is !int) || (length < 0)) {
|
| + throw new ArgumentError("Length must be a non-negative integer: $length");
|
| + }
|
| + return new JSArray<E>.markGrowable(JS('', 'new Array(#)', length));
|
| + }
|
| +
|
| + /**
|
| + * Constructor for adding type parameters to an existing JavaScript Array.
|
| + * The compiler specially recognizes this constructor.
|
| + *
|
| + * var a = new JSArray<int>.typed(JS('JSExtendableArray', '[]'));
|
| + * a is List<int> --> true
|
| + * a is List<String> --> false
|
| + *
|
| + * Usually either the [JSArray.markFixed] or [JSArray.markGrowable]
|
| + * constructors is used instead.
|
| + *
|
| + * The input must be a JavaScript Array. The JS form is just a re-assertion
|
| + * to help type analysis when the input type is sloppy.
|
| + */
|
| + factory JSArray.typed(allocation) => JS('JSArray', '#', allocation);
|
| +
|
| + factory JSArray.markFixed(allocation) =>
|
| + JS('JSFixedArray', '#', markFixedList(new JSArray<E>.typed(allocation)));
|
| +
|
| + factory JSArray.markGrowable(allocation) =>
|
| + JS('JSExtendableArray', '#', new JSArray<E>.typed(allocation));
|
| +
|
| + static List markFixedList(List list) {
|
| + JS('void', r'#.fixed$length = #', list, true);
|
| + return JS('JSFixedArray', '#', list);
|
| + }
|
| +
|
| checkMutable(reason) {
|
| if (this is !JSMutableArray) {
|
| throw new UnsupportedError(reason);
|
| @@ -174,9 +234,9 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
| throw new RangeError.range(end, start, length);
|
| }
|
| }
|
| - // TODO(ngeoffray): Parameterize the return value.
|
| - if (start == end) return [];
|
| - return JS('JSExtendableArray', r'#.slice(#, #)', this, start, end);
|
| + if (start == end) return <E>[];
|
| + return new JSArray<E>.markGrowable(
|
| + JS('', r'#.slice(#, #)', this, start, end));
|
| }
|
|
|
|
|
| @@ -268,8 +328,13 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
|
|
| String toString() => IterableMixinWorkaround.toStringIterable(this, '[', ']');
|
|
|
| - List<E> toList({ bool growable: true }) =>
|
| - new List<E>.from(this, growable: growable);
|
| + List<E> toList({ bool growable: true }) {
|
| + if (growable) {
|
| + return new JSArray<E>.markGrowable(JS('', '#.slice()', this));
|
| + } else {
|
| + return new JSArray<E>.markFixed(JS('', '#.slice()', this));
|
| + }
|
| + }
|
|
|
| Set<E> toSet() => new Set<E>.from(this);
|
|
|
| @@ -309,6 +374,6 @@ class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
|
| * information about arrays through their type. The CPA type inference
|
| * relies on the fact that these classes do not override [] nor []=.
|
| */
|
| -class JSMutableArray extends JSArray implements JSMutableIndexable {}
|
| -class JSFixedArray extends JSMutableArray {}
|
| -class JSExtendableArray extends JSMutableArray {}
|
| +class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {}
|
| +class JSFixedArray<E> extends JSMutableArray<E> {}
|
| +class JSExtendableArray<E> extends JSMutableArray<E> {}
|
|
|