Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: tool/input_sdk_patch/js_array.dart

Issue 955513008: cleans up sdk patching so we no longer have unresolved names (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tool/input_sdk_patch/isolate_serialization.dart ('k') | tool/input_sdk_patch/js_helper.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of _interceptors;
6
7 /**
8 * The interceptor class for [List]. The compiler recognizes this
9 * class as an interceptor, and changes references to [:this:] to
10 * actually use the receiver of the method, which is generated as an extra
11 * argument added to each member.
12 */
13 class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
14
15 const JSArray();
16
17 /**
18 * Returns a fresh JavaScript Array, marked as fixed-length.
19 *
20 * [length] must be a non-negative integer.
21 */
22 factory JSArray.fixed(int length) {
23 // Explicit type test is necessary to guard against JavaScript conversions
24 // in unchecked mode.
25 if ((length is !int) || (length < 0)) {
26 throw new ArgumentError("Length must be a non-negative integer: $length");
27 }
28 return new JSArray<E>.markFixed(JS('', 'new Array(#)', length));
29 }
30
31 /**
32 * Returns a fresh growable JavaScript Array of zero length length.
33 */
34 factory JSArray.emptyGrowable() => new JSArray<E>.markGrowable(JS('', '[]'));
35
36 /**
37 * Returns a fresh growable JavaScript Array with initial length.
38 *
39 * [validatedLength] must be a non-negative integer.
40 */
41 factory JSArray.growable(int length) {
42 // Explicit type test is necessary to guard against JavaScript conversions
43 // in unchecked mode.
44 if ((length is !int) || (length < 0)) {
45 throw new ArgumentError("Length must be a non-negative integer: $length");
46 }
47 return new JSArray<E>.markGrowable(JS('', 'new Array(#)', length));
48 }
49
50 /**
51 * Constructor for adding type parameters to an existing JavaScript Array.
52 * The compiler specially recognizes this constructor.
53 *
54 * var a = new JSArray<int>.typed(JS('JSExtendableArray', '[]'));
55 * a is List<int> --> true
56 * a is List<String> --> false
57 *
58 * Usually either the [JSArray.markFixed] or [JSArray.markGrowable]
59 * constructors is used instead.
60 *
61 * The input must be a JavaScript Array. The JS form is just a re-assertion
62 * to help type analysis when the input type is sloppy.
63 */
64 factory JSArray.typed(allocation) => JS('JSArray', '#', allocation);
65
66 factory JSArray.markFixed(allocation) =>
67 JS('JSFixedArray', '#', markFixedList(new JSArray<E>.typed(allocation)));
68
69 factory JSArray.markGrowable(allocation) =>
70 JS('JSExtendableArray', '#', new JSArray<E>.typed(allocation));
71
72 static List markFixedList(List list) {
73 // Functions are stored in the hidden class and not as properties in
74 // the object. We never actually look at the value, but only want
75 // to know if the property exists.
76 JS('void', r'#.fixed$length = Array', list);
77 return JS('JSFixedArray', '#', list);
78 }
79
80 checkMutable(reason) {
81 if (this is !JSMutableArray) {
82 throw new UnsupportedError(reason);
83 }
84 }
85
86 checkGrowable(reason) {
87 if (this is !JSExtendableArray) {
88 throw new UnsupportedError(reason);
89 }
90 }
91
92 void add(E value) {
93 checkGrowable('add');
94 JS('void', r'#.push(#)', this, value);
95 }
96
97 E removeAt(int index) {
98 if (index is !int) throw new ArgumentError(index);
99 if (index < 0 || index >= length) {
100 throw new RangeError.value(index);
101 }
102 checkGrowable('removeAt');
103 return JS('var', r'#.splice(#, 1)[0]', this, index);
104 }
105
106 void insert(int index, E value) {
107 if (index is !int) throw new ArgumentError(index);
108 if (index < 0 || index > length) {
109 throw new RangeError.value(index);
110 }
111 checkGrowable('insert');
112 JS('void', r'#.splice(#, 0, #)', this, index, value);
113 }
114
115 void insertAll(int index, Iterable<E> iterable) {
116 checkGrowable('insertAll');
117 IterableMixinWorkaround.insertAllList(this, index, iterable);
118 }
119
120 void setAll(int index, Iterable<E> iterable) {
121 checkMutable('setAll');
122 IterableMixinWorkaround.setAllList(this, index, iterable);
123 }
124
125 E removeLast() {
126 checkGrowable('removeLast');
127 if (length == 0) throw new RangeError.value(-1);
128 return JS('var', r'#.pop()', this);
129 }
130
131 bool remove(Object element) {
132 checkGrowable('remove');
133 for (int i = 0; i < this.length; i++) {
134 if (this[i] == element) {
135 JS('var', r'#.splice(#, 1)', this, i);
136 return true;
137 }
138 }
139 return false;
140 }
141
142 void removeWhere(bool test(E element)) {
143 // This could, and should, be optimized.
144 IterableMixinWorkaround.removeWhereList(this, test);
145 }
146
147 void retainWhere(bool test(E element)) {
148 IterableMixinWorkaround.removeWhereList(this,
149 (E element) => !test(element));
150 }
151
152 Iterable<E> where(bool f(E element)) {
153 return new IterableMixinWorkaround<E>().where(this, f);
154 }
155
156 Iterable expand(Iterable f(E element)) {
157 return IterableMixinWorkaround.expand(this, f);
158 }
159
160 void addAll(Iterable<E> collection) {
161 for (E e in collection) {
162 this.add(e);
163 }
164 }
165
166 void clear() {
167 length = 0;
168 }
169
170 void forEach(void f(E element)) {
171 int length = this.length;
172 for (int i = 0; i < length; i++) {
173 f(JS('', '#[#]', this, i));
174 if (length != this.length) {
175 throw new ConcurrentModificationError(this);
176 }
177 }
178 }
179
180 Iterable map(f(E element)) {
181 return IterableMixinWorkaround.mapList(this, f);
182 }
183
184 String join([String separator = ""]) {
185 var list = new List(this.length);
186 for (int i = 0; i < this.length; i++) {
187 list[i] = "${this[i]}";
188 }
189 return JS('String', "#.join(#)", list, separator);
190 }
191
192 Iterable<E> take(int n) {
193 return new IterableMixinWorkaround<E>().takeList(this, n);
194 }
195
196 Iterable<E> takeWhile(bool test(E value)) {
197 return new IterableMixinWorkaround<E>().takeWhile(this, test);
198 }
199
200 Iterable<E> skip(int n) {
201 return new IterableMixinWorkaround<E>().skipList(this, n);
202 }
203
204 Iterable<E> skipWhile(bool test(E value)) {
205 return new IterableMixinWorkaround<E>().skipWhile(this, test);
206 }
207
208 E reduce(E combine(E value, E element)) {
209 return IterableMixinWorkaround.reduce(this, combine);
210 }
211
212 fold(initialValue, combine(previousValue, E element)) {
213 return IterableMixinWorkaround.fold(this, initialValue, combine);
214 }
215
216 E firstWhere(bool test(E value), {E orElse()}) {
217 return IterableMixinWorkaround.firstWhere(this, test, orElse);
218 }
219
220 E lastWhere(bool test(E value), {E orElse()}) {
221 return IterableMixinWorkaround.lastWhereList(this, test, orElse);
222 }
223
224 E singleWhere(bool test(E value)) {
225 return IterableMixinWorkaround.singleWhere(this, test);
226 }
227
228 E elementAt(int index) {
229 return this[index];
230 }
231
232 List<E> sublist(int start, [int end]) {
233 checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
234 if (start is !int) throw new ArgumentError(start);
235 if (start < 0 || start > length) {
236 throw new RangeError.range(start, 0, length);
237 }
238 if (end == null) {
239 end = length;
240 } else {
241 if (end is !int) throw new ArgumentError(end);
242 if (end < start || end > length) {
243 throw new RangeError.range(end, start, length);
244 }
245 }
246 if (start == end) return <E>[];
247 return new JSArray<E>.markGrowable(
248 JS('', r'#.slice(#, #)', this, start, end));
249 }
250
251
252 Iterable<E> getRange(int start, int end) {
253 return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
254 }
255
256 E get first {
257 if (length > 0) return this[0];
258 throw new StateError("No elements");
259 }
260
261 E get last {
262 if (length > 0) return this[length - 1];
263 throw new StateError("No elements");
264 }
265
266 E get single {
267 if (length == 1) return this[0];
268 if (length == 0) throw new StateError("No elements");
269 throw new StateError("More than one element");
270 }
271
272 void removeRange(int start, int end) {
273 checkGrowable('removeRange');
274 int receiverLength = this.length;
275 if (start < 0 || start > receiverLength) {
276 throw new RangeError.range(start, 0, receiverLength);
277 }
278 if (end < start || end > receiverLength) {
279 throw new RangeError.range(end, start, receiverLength);
280 }
281 Lists.copy(this,
282 end,
283 this,
284 start,
285 receiverLength - end);
286 this.length = receiverLength - (end - start);
287 }
288
289 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
290 checkMutable('set range');
291 IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
292 }
293
294 void fillRange(int start, int end, [E fillValue]) {
295 checkMutable('fill range');
296 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
297 }
298
299 void replaceRange(int start, int end, Iterable<E> iterable) {
300 checkGrowable('removeRange');
301 IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
302 }
303
304 bool any(bool f(E element)) => IterableMixinWorkaround.any(this, f);
305
306 bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
307
308 Iterable<E> get reversed =>
309 new IterableMixinWorkaround<E>().reversedList(this);
310
311 void sort([int compare(E a, E b)]) {
312 checkMutable('sort');
313 IterableMixinWorkaround.sortList(this, compare);
314 }
315
316 void shuffle([Random random]) {
317 IterableMixinWorkaround.shuffleList(this, random);
318 }
319
320 int indexOf(Object element, [int start = 0]) {
321 return IterableMixinWorkaround.indexOfList(this, element, start);
322 }
323
324 int lastIndexOf(Object element, [int start]) {
325 return IterableMixinWorkaround.lastIndexOfList(this, element, start);
326 }
327
328 bool contains(Object other) {
329 for (int i = 0; i < length; i++) {
330 if (this[i] == other) return true;
331 }
332 return false;
333 }
334
335 bool get isEmpty => length == 0;
336
337 bool get isNotEmpty => !isEmpty;
338
339 String toString() => ListBase.listToString(this);
340
341 List<E> toList({ bool growable: true }) {
342 if (growable) {
343 return new JSArray<E>.markGrowable(JS('', '#.slice()', this));
344 } else {
345 return new JSArray<E>.markFixed(JS('', '#.slice()', this));
346 }
347 }
348
349 Set<E> toSet() => new Set<E>.from(this);
350
351 Iterator<E> get iterator => new ListIterator<E>(this);
352
353 int get hashCode => Primitives.objectHashCode(this);
354
355 int get length => JS('JSUInt32', r'#.length', this);
356
357 void set length(int newLength) {
358 if (newLength is !int) throw new ArgumentError(newLength);
359 if (newLength < 0) throw new RangeError.value(newLength);
360 checkGrowable('set length');
361 JS('void', r'#.length = #', this, newLength);
362 }
363
364 E operator [](int index) {
365 if (index is !int) throw new ArgumentError(index);
366 if (index >= length || index < 0) throw new RangeError.value(index);
367 return JS('var', '#[#]', this, index);
368 }
369
370 void operator []=(int index, E value) {
371 checkMutable('indexed set');
372 if (index is !int) throw new ArgumentError(index);
373 if (index >= length || index < 0) throw new RangeError.value(index);
374 JS('void', r'#[#] = #', this, index, value);
375 }
376
377 Map<int, E> asMap() {
378 return new IterableMixinWorkaround<E>().asMapList(this);
379 }
380 }
381
382 /**
383 * Dummy subclasses that allow the backend to track more precise
384 * information about arrays through their type. The CPA type inference
385 * relies on the fact that these classes do not override [] nor []=.
386 */
387 class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {}
388 class JSFixedArray<E> extends JSMutableArray<E> {}
389 class JSExtendableArray<E> extends JSMutableArray<E> {}
OLDNEW
« no previous file with comments | « tool/input_sdk_patch/isolate_serialization.dart ('k') | tool/input_sdk_patch/js_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698