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

Side by Side Diff: sdk/lib/js/dart2js/js_dart2js.dart

Issue 41163005: Add JsArray (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add JsArray Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/html/js_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart.js; 5 library dart.js;
6 6
7 import 'dart:html' show Blob, ImageData, Node; 7 import 'dart:html' show Blob, ImageData, Node;
8 import 'dart:collection' show HashMap; 8 import 'dart:collection' show HashMap, ListMixin;
9 import 'dart:indexed_db' show KeyRange; 9 import 'dart:indexed_db' show KeyRange;
10 import 'dart:typed_data' show TypedData; 10 import 'dart:typed_data' show TypedData;
11 11
12 import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS; 12 import 'dart:_foreign_helper' show JS, DART_CLOSURE_TO_JS;
13 import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject; 13 import 'dart:_interceptors' show JavaScriptObject, UnknownJavaScriptObject;
14 import 'dart:_js_helper' show Primitives, convertDartClosureToJS; 14 import 'dart:_js_helper' show Primitives, convertDartClosureToJS;
15 15
16 final JsObject context = new JsObject._fromJs(Primitives.computeGlobalThis()); 16 final JsObject context = new JsObject._fromJs(Primitives.computeGlobalThis());
17 17
18 _convertDartFunction(Function f, {bool captureThis: false}) { 18 _convertDartFunction(Function f, {bool captureThis: false}) {
19 return JS('', 19 return JS('',
20 'function(_call, f, captureThis) {' 20 'function(_call, f, captureThis) {'
21 'return function() {' 21 'return function() {'
22 'return _call(f, captureThis, this, ' 22 'return _call(f, captureThis, this, '
23 'Array.prototype.slice.apply(arguments));' 23 'Array.prototype.slice.apply(arguments));'
24 '}' 24 '}'
25 '}(#, #, #)', DART_CLOSURE_TO_JS(_callDartFunction), f, captureThis); 25 '}(#, #, #)', DART_CLOSURE_TO_JS(_callDartFunction), f, captureThis);
26 } 26 }
27 27
28 _callDartFunction(callback, bool captureThis, self, List arguments) { 28 _callDartFunction(callback, bool captureThis, self, List arguments) {
29 if (captureThis) { 29 if (captureThis) {
30 arguments = [self]..addAll(arguments); 30 arguments = [self]..addAll(arguments);
31 } 31 }
32 var dartArgs = arguments.map(_convertToDart).toList(); 32 var dartArgs = new List.from(arguments.map(_convertToDart));
33 return _convertToJS(Function.apply(callback, dartArgs)); 33 return _convertToJS(Function.apply(callback, dartArgs));
34 } 34 }
35 35
36 36
37 class JsObject { 37 class JsObject {
38 // The wrapped JS object. 38 // The wrapped JS object.
39 final dynamic _jsObject; 39 final dynamic _jsObject;
40 40
41 JsObject._fromJs(this._jsObject) { 41 JsObject._fromJs(this._jsObject) {
42 assert(_jsObject != null); 42 assert(_jsObject != null);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 return super.toString(); 180 return super.toString();
181 } 181 }
182 } 182 }
183 183
184 dynamic callMethod(name, [List args]) { 184 dynamic callMethod(name, [List args]) {
185 if (name is! String && name is! num) { 185 if (name is! String && name is! num) {
186 throw new ArgumentError("name is not a String or num"); 186 throw new ArgumentError("name is not a String or num");
187 } 187 }
188 return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, name, 188 return _convertToDart(JS('', '#[#].apply(#, #)', _jsObject, name,
189 _jsObject, 189 _jsObject,
190 args == null ? null : args.map(_convertToJS).toList())); 190 args == null ? null : new List.from(args.map(_convertToJS))));
191 } 191 }
192 } 192 }
193 193
194 class JsFunction extends JsObject { 194 class JsFunction extends JsObject {
195 195
196 /** 196 /**
197 * Returns a [JsFunction] that captures its 'this' binding and calls [f] 197 * Returns a [JsFunction] that captures its 'this' binding and calls [f]
198 * with the value of this passed as the first argument. 198 * with the value of this passed as the first argument.
199 */ 199 */
200 factory JsFunction.withThis(Function f) { 200 factory JsFunction.withThis(Function f) {
201 var jsFunc = _convertDartFunction(f, captureThis: true); 201 var jsFunc = _convertDartFunction(f, captureThis: true);
202 return new JsFunction._fromJs(jsFunc); 202 return new JsFunction._fromJs(jsFunc);
203 } 203 }
204 204
205 JsFunction._fromJs(jsObject) : super._fromJs(jsObject); 205 JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
206 206
207 dynamic apply(List args, { thisArg }) => 207 dynamic apply(List args, { thisArg }) =>
208 _convertToDart(JS('', '#.apply(#, #)', _jsObject, 208 _convertToDart(JS('', '#.apply(#, #)', _jsObject,
209 _convertToJS(thisArg), 209 _convertToJS(thisArg),
210 args == null ? null : args.map(_convertToJS).toList())); 210 args == null ? null : new List.from(args.map(_convertToJS))));
211 }
212
213 /**
214 * A [List] that is stored in a JavaScript array.
215 */
216 class JsArray<E> extends JsObject with ListMixin<E> {
217
218 JsArray() : super._fromJs([]);
219
220 JsArray.from(Iterable<E> other)
221 : super._fromJs([]..addAll(other.map(_convertToJS)));
222
223 JsArray._fromJs(jsObject) : super._fromJs(jsObject);
224
225 _checkIndex(int index, {bool insert: false}) {
Jacob 2013/10/24 21:02:09 why not have two check index methods? one for inse
justinfagnani 2013/10/26 03:26:52 Done.
226 int length = insert ? this.length + 1 : this.length;
227 if (index is int && (index < 0 || index >= length)) {
228 throw new RangeError.range(index, 0, length);
229 }
230 }
231
232 _checkRange(int start, int end) {
233 if (start < 0 || start > this.length) {
234 throw new RangeError.range(start, 0, this.length);
235 }
236 if (end < start || end > this.length) {
237 throw new RangeError.range(end, start, this.length);
238 }
239 }
240
241 // Methods required by ListMixin
242
243 E operator [](int index) {
244 _checkIndex(index);
245 return super[index];
246 }
247
248 void operator []=(int index, E value) {
249 _checkIndex(index);
250 super[index] = value;
251 }
252
253 int get length => super['length'];
254
255 void set length(int length) { super['length'] = length; }
256
257
258 // Methods overriden for better performance
259
260 void add(E value) {
261 callMethod('push', [value]);
262 }
263
264 void addAll(Iterable<E> iterable) {
265 var list = (JS('bool', '# instanceof Array', iterable))
266 ? iterable
267 : new List.from(iterable);
268 callMethod('push', list);
269 }
270
271 void insert(int index, E element) {
272 _checkIndex(index, insert:true);
273 callMethod('splice', [index, 0, element]);
274 }
275
276 E removeAt(int index) {
277 _checkIndex(index);
278 return callMethod('splice', [index, 1])[0];
279 }
280
281 E removeLast() {
282 if (length == 0) throw new RangeError(-1);
283 return callMethod('pop');
284 }
285
286 void removeRange(int start, int end) {
287 _checkRange(start, end);
288 callMethod('splice', [start, end - start]);
289 }
290
291 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
292 _checkRange(start, end);
293 int length = end - start;
294 if (length == 0) return;
295 if (skipCount < 0) throw new ArgumentError(skipCount);
296 var args = [start, length]..addAll(iterable.skip(skipCount).take(length));
297 callMethod('splice', args);
298 }
299
300 void sort([int compare(E a, E b)]) {
301 callMethod('sort', [compare]);
302 }
211 } 303 }
212 304
213 // property added to a Dart object referencing its JS-side DartObject proxy 305 // property added to a Dart object referencing its JS-side DartObject proxy
214 const _DART_OBJECT_PROPERTY_NAME = r'_$dart_dartObject'; 306 const _DART_OBJECT_PROPERTY_NAME = r'_$dart_dartObject';
215 const _DART_CLOSURE_PROPERTY_NAME = r'_$dart_dartClosure'; 307 const _DART_CLOSURE_PROPERTY_NAME = r'_$dart_dartClosure';
216 308
217 // property added to a JS object referencing its Dart-side JsObject proxy 309 // property added to a JS object referencing its Dart-side JsObject proxy
218 const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject'; 310 const _JS_OBJECT_PROPERTY_NAME = r'_$dart_jsObject';
219 const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction'; 311 const _JS_FUNCTION_PROPERTY_NAME = r'$dart_jsFunction';
220 312
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 return o; 366 return o;
275 } else if (o is Blob || o is KeyRange || o is ImageData || o is Node 367 } else if (o is Blob || o is KeyRange || o is ImageData || o is Node
276 || o is TypedData) { 368 || o is TypedData) {
277 return JS('Blob|KeyRange|ImageData|Node|TypedData', '#', o); 369 return JS('Blob|KeyRange|ImageData|Node|TypedData', '#', o);
278 } else if (JS('bool', '# instanceof Date', o)) { 370 } else if (JS('bool', '# instanceof Date', o)) {
279 var ms = JS('num', '#.getMilliseconds()', o); 371 var ms = JS('num', '#.getMilliseconds()', o);
280 return new DateTime.fromMillisecondsSinceEpoch(ms); 372 return new DateTime.fromMillisecondsSinceEpoch(ms);
281 } else if (JS('bool', 'typeof # == "function"', o)) { 373 } else if (JS('bool', 'typeof # == "function"', o)) {
282 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME, 374 return _getDartProxy(o, _DART_CLOSURE_PROPERTY_NAME,
283 (o) => new JsFunction._fromJs(o)); 375 (o) => new JsFunction._fromJs(o));
376 } else if (JS('bool', '# instanceof Array', o)) {
377 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
378 (o) => new JsArray._fromJs(o));
284 } else if (JS('bool', '#.constructor === DartObject', o)) { 379 } else if (JS('bool', '#.constructor === DartObject', o)) {
285 return JS('', '#.o', o); 380 return JS('', '#.o', o);
286 } else { 381 } else {
287 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME, 382 return _getDartProxy(o, _DART_OBJECT_PROPERTY_NAME,
288 (o) => new JsObject._fromJs(o)); 383 (o) => new JsObject._fromJs(o));
289 } 384 }
290 } 385 }
291 386
292 Object _getDartProxy(o, String propertyName, createProxy(o)) { 387 Object _getDartProxy(o, String propertyName, createProxy(o)) {
293 var dartProxy = JS('', '#[#]', o, propertyName); 388 var dartProxy = JS('', '#[#]', o, propertyName);
294 if (dartProxy == null) { 389 if (dartProxy == null) {
295 dartProxy = createProxy(o); 390 dartProxy = createProxy(o);
296 _defineProperty(o, propertyName, dartProxy); 391 _defineProperty(o, propertyName, dartProxy);
297 } 392 }
298 return dartProxy; 393 return dartProxy;
299 } 394 }
OLDNEW
« no previous file with comments | « no previous file | tests/html/js_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698