| Index: pkg/dev_compiler/tool/input_sdk/private/js_array.dart
|
| diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
|
| index 2a3cfe7ee29c999f38bbc7e81d7c56a3c7ce9d13..44b6271471c15b0ddd33591c0be69cd0dfd45f84 100644
|
| --- a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
|
| +++ b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
|
| @@ -64,30 +64,29 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| JS('void', r'#.push(#)', this, value);
|
| }
|
|
|
| - E removeAt(int index) {
|
| + E removeAt(@nullCheck int index) {
|
| checkGrowable('removeAt');
|
| - if (index is! int) throw argumentErrorValue(index);
|
| if (index < 0 || index >= length) {
|
| throw new RangeError.value(index);
|
| }
|
| return JS('-dynamic', r'#.splice(#, 1)[0]', this, index);
|
| }
|
|
|
| - void insert(int index, E value) {
|
| + void insert(@nullCheck int index, E value) {
|
| checkGrowable('insert');
|
| - if (index is! int) throw argumentErrorValue(index);
|
| if (index < 0 || index > length) {
|
| throw new RangeError.value(index);
|
| }
|
| JS('void', r'#.splice(#, 0, #)', this, index, value);
|
| }
|
|
|
| - void insertAll(int index, Iterable<E> iterable) {
|
| + void insertAll(@nullCheck int index, Iterable<E> iterable) {
|
| checkGrowable('insertAll');
|
| RangeError.checkValueInInterval(index, 0, this.length, "index");
|
| if (iterable is! EfficientLengthIterable) {
|
| iterable = iterable.toList();
|
| }
|
| + @nullCheck
|
| int insertionLength = iterable.length;
|
| this.length += insertionLength;
|
| int end = index + insertionLength;
|
| @@ -95,7 +94,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| this.setRange(index, end, iterable);
|
| }
|
|
|
| - void setAll(int index, Iterable<E> iterable) {
|
| + void setAll(@nullCheck int index, Iterable<E> iterable) {
|
| checkMutable('setAll');
|
| RangeError.checkValueInInterval(index, 0, this.length, "index");
|
| for (var element in iterable) {
|
| @@ -111,7 +110,8 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
|
|
| bool remove(Object element) {
|
| checkGrowable('remove');
|
| - for (int i = 0; i < this.length; i++) {
|
| + var length = this.length;
|
| + for (int i = 0; i < length; i++) {
|
| if (this[i] == element) {
|
| JS('var', r'#.splice(#, 1)', this, i);
|
| return true;
|
| @@ -146,7 +146,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| for (int i = 0; i < end; i++) {
|
| // TODO(22407): Improve bounds check elimination to allow this JS code to
|
| // be replaced by indexing.
|
| - var element = JS('', '#[#]', this, i);
|
| + E element = JS('-dynamic', '#[#]', this, i);
|
| // !test() ensures bool conversion in checked mode.
|
| if (!test(element) == removeMatching) {
|
| retained.add(element);
|
| @@ -155,8 +155,10 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
| if (retained.length == end) return;
|
| this.length = retained.length;
|
| - for (int i = 0; i < retained.length; i++) {
|
| - this[i] = retained[i];
|
| + @nullCheck
|
| + var length = retained.length;
|
| + for (int i = 0; i < length; i++) {
|
| + JS('', '#[#] = #[#]', this, i, retained, i);
|
| }
|
| }
|
|
|
| @@ -198,8 +200,9 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
|
|
| String join([String separator = ""]) {
|
| - var list = new List(this.length);
|
| - for (int i = 0; i < this.length; i++) {
|
| + var length = this.length;
|
| + var list = new List(length);
|
| + for (int i = 0; i < length; i++) {
|
| list[i] = "${this[i]}";
|
| }
|
| return JS('String', "#.join(#)", list, separator);
|
| @@ -285,7 +288,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| for (int i = 0; i < length; i++) {
|
| // TODO(22407): Improve bounds check elimination to allow this JS code to
|
| // be replaced by indexing.
|
| - var element = JS('', '#[#]', this, i);
|
| + E element = JS('-dynamic', '#[#]', this, i);
|
| if (test(element)) {
|
| if (matchFound) {
|
| throw IterableElementError.tooMany();
|
| @@ -305,17 +308,16 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| return this[index];
|
| }
|
|
|
| - List<E> sublist(int start, [int end]) {
|
| - checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
|
| - if (start is! int) throw argumentErrorValue(start);
|
| + List<E> sublist(@nullCheck int start, [int end]) {
|
| if (start < 0 || start > length) {
|
| throw new RangeError.range(start, 0, length, "start");
|
| }
|
| if (end == null) {
|
| end = length;
|
| } else {
|
| - if (end is! int) throw argumentErrorValue(end);
|
| - if (end < start || end > length) {
|
| + @notNull
|
| + var _end = end;
|
| + if (_end < start || _end > length) {
|
| throw new RangeError.range(end, start, length, "end");
|
| }
|
| }
|
| @@ -344,14 +346,15 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| throw IterableElementError.tooMany();
|
| }
|
|
|
| - void removeRange(int start, int end) {
|
| + void removeRange(@nullCheck int start, @nullCheck int end) {
|
| checkGrowable('removeRange');
|
| RangeError.checkValidRange(start, end, this.length);
|
| int deleteCount = end - start;
|
| JS('', '#.splice(#, #)', this, start, deleteCount);
|
| }
|
|
|
| - void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
|
| + void setRange(@nullCheck int start, @nullCheck int end, Iterable<E> iterable,
|
| + [@nullCheck int skipCount = 0]) {
|
| checkMutable('set range');
|
|
|
| RangeError.checkValidRange(start, end, this.length);
|
| @@ -359,10 +362,10 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| if (length == 0) return;
|
| RangeError.checkNotNegative(skipCount, "skipCount");
|
|
|
| - List/*<E>*/ otherList;
|
| - int otherStart;
|
| + List<E> otherList;
|
| + int otherStart = 0;
|
| // TODO(floitsch): Make this accept more.
|
| - if (iterable is List) {
|
| + if (iterable is List<E>) {
|
| otherList = iterable;
|
| otherStart = skipCount;
|
| } else {
|
| @@ -391,7 +394,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
| }
|
|
|
| - void fillRange(int start, int end, [E fillValue]) {
|
| + void fillRange(@nullCheck int start, @nullCheck int end, [E fillValue]) {
|
| checkMutable('fill range');
|
| RangeError.checkValidRange(start, end, this.length);
|
| for (int i = start; i < end; i++) {
|
| @@ -400,13 +403,15 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
| }
|
|
|
| - void replaceRange(int start, int end, Iterable<E> replacement) {
|
| + void replaceRange(
|
| + @nullCheck int start, @nullCheck int end, Iterable<E> replacement) {
|
| checkGrowable('replace range');
|
| RangeError.checkValidRange(start, end, this.length);
|
| if (replacement is! EfficientLengthIterable) {
|
| replacement = replacement.toList();
|
| }
|
| int removeLength = end - start;
|
| + @nullCheck
|
| int insertLength = replacement.length;
|
| if (removeLength >= insertLength) {
|
| int delta = removeLength - insertLength;
|
| @@ -444,7 +449,7 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| for (int i = 0; i < end; i++) {
|
| // TODO(22407): Improve bounds check elimination to allow this JS code to
|
| // be replaced by indexing.
|
| - var/*=E*/ element = JS('', '#[#]', this, i);
|
| + E element = JS('-dynamic', '#[#]', this, i);
|
| if (!test(element)) return false;
|
| if (this.length != end) throw new ConcurrentModificationError(this);
|
| }
|
| @@ -475,14 +480,15 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
| }
|
|
|
| - int indexOf(Object element, [int start = 0]) {
|
| - if (start >= this.length) {
|
| + int indexOf(Object element, [@nullCheck int start = 0]) {
|
| + int length = this.length;
|
| + if (start >= length) {
|
| return -1;
|
| }
|
| if (start < 0) {
|
| start = 0;
|
| }
|
| - for (int i = start; i < this.length; i++) {
|
| + for (int i = start; i < length; i++) {
|
| if (this[i] == element) {
|
| return i;
|
| }
|
| @@ -490,16 +496,13 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| return -1;
|
| }
|
|
|
| - int lastIndexOf(Object element, [int startIndex]) {
|
| - if (startIndex == null) {
|
| + int lastIndexOf(Object element, [int _startIndex]) {
|
| + @notNull
|
| + int startIndex = _startIndex ?? this.length - 1;
|
| + if (startIndex >= this.length) {
|
| startIndex = this.length - 1;
|
| - } else {
|
| - if (startIndex < 0) {
|
| - return -1;
|
| - }
|
| - if (startIndex >= this.length) {
|
| - startIndex = this.length - 1;
|
| - }
|
| + } else if (startIndex < 0) {
|
| + return -1;
|
| }
|
| for (int i = startIndex; i >= 0; i--) {
|
| if (this[i] == element) {
|
| @@ -510,19 +513,23 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
| }
|
|
|
| bool contains(Object other) {
|
| + var length = this.length;
|
| for (int i = 0; i < length; i++) {
|
| - if (this[i] == other) return true;
|
| + E element = JS('-dynamic | Null', '#[#]', this, i);
|
| + if (element == other) return true;
|
| }
|
| return false;
|
| }
|
|
|
| + @notNull
|
| bool get isEmpty => length == 0;
|
|
|
| + @notNull
|
| bool get isNotEmpty => !isEmpty;
|
|
|
| String toString() => ListBase.listToString(this);
|
|
|
| - List<E> toList({bool growable: true}) {
|
| + List<E> toList({@nullCheck bool growable: true}) {
|
| var list = JS('', '#.slice()', this);
|
| if (!growable) markFixedList(list);
|
| return new JSArray<E>.of(list);
|
| @@ -534,15 +541,14 @@ class JSArray<E> implements List<E>, JSIndexable<E> {
|
|
|
| int get hashCode => Primitives.objectHashCode(this);
|
|
|
| + @notNull
|
| bool operator ==(other) => identical(this, other);
|
|
|
| + @notNull
|
| int get length => JS('int', r'#.length', this);
|
|
|
| - void set length(int newLength) {
|
| + void set length(@nullCheck int newLength) {
|
| checkGrowable('set length');
|
| - if (newLength is! int) {
|
| - throw new ArgumentError.value(newLength, 'newLength');
|
| - }
|
| // TODO(sra): Remove this test and let JavaScript throw an error.
|
| if (newLength < 0) {
|
| throw new RangeError.range(newLength, 0, null, 'newLength');
|
| @@ -603,7 +609,9 @@ class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.
|
| ///
|
| class ArrayIterator<E> implements Iterator<E> {
|
| final JSArray<E> _iterable;
|
| + @notNull
|
| final int _length;
|
| + @notNull
|
| int _index;
|
| E _current;
|
|
|
| @@ -615,6 +623,7 @@ class ArrayIterator<E> implements Iterator<E> {
|
| E get current => _current;
|
|
|
| bool moveNext() {
|
| + @notNull
|
| int length = _iterable.length;
|
|
|
| // We have to do the length check even on fixed length Arrays. If we can
|
|
|