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

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

Issue 23291005: add JsArray and JsObject.asJsMap() Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix dart2js and add automatic convertion of Iterables and Maps Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « pkg/browser/lib/interop.js ('k') | sdk/lib/js/dartium/js_dartium.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:collection' show ListMixin, Maps;
7 import 'dart:_foreign_helper' show JS; 8 import 'dart:_foreign_helper' show JS;
8 import 'dart:_js_helper' show convertDartClosureToJS; 9 import 'dart:_js_helper' show convertDartClosureToJS;
9 10
10 JsObject get context { 11 JsObject get context {
11 return new JsObject._fromJs(JS('=Object', 'window')); 12 return new JsObject._fromJs(JS('=Object', 'window'));
12 } 13 }
13 14
14 JsObject jsify(dynamic data) => data == null ? null : new JsObject._json(data); 15 JsObject jsify(dynamic data) => data == null ? null : new JsObject._json(data);
15 16
16 class Callback implements Serializable<JsFunction> { 17 class Callback implements Serializable<JsFunction> {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 return new JsObject._fromJs(JS('=Object', r'''(function(){ 95 return new JsObject._fromJs(JS('=Object', r'''(function(){
95 var Type = function(){}; 96 var Type = function(){};
96 Type.prototype = #.prototype; 97 Type.prototype = #.prototype;
97 var instance = new Type(); 98 var instance = new Type();
98 ret = #.apply(instance, #); 99 ret = #.apply(instance, #);
99 ret = Object(ret) === ret ? ret : instance; 100 ret = Object(ret) === ret ? ret : instance;
100 return ret; 101 return ret;
101 })()''', constr, constr, args)); 102 })()''', constr, constr, args));
102 } 103 }
103 104
104 factory JsObject._json(data) => new JsObject._fromJs(_convertDataTree(data)); 105 factory JsObject._json(data) => _convertToDart(_convertDataTree(data));
105 106
106 static _convertDataTree(data) { 107 static _convertDataTree(data) {
107 if (data is Map) { 108 if (data is Map) {
108 final convertedData = JS('=Object', '{}'); 109 final convertedData = JS('=Object', '{}');
109 for (var key in data.keys) { 110 for (var key in data.keys) {
110 JS('=Object', '#[#]=#', convertedData, key, 111 JS('=Object', '#[#]=#', convertedData, key,
111 _convertDataTree(data[key])); 112 _convertDataTree(data[key]));
112 } 113 }
113 return convertedData; 114 return convertedData;
114 } else if (data is Iterable) { 115 } else if (data is Iterable) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 return JS('String', '#.toString()', _convertToJS(this)); 148 return JS('String', '#.toString()', _convertToJS(this));
148 } catch(e) { 149 } catch(e) {
149 return super.toString(); 150 return super.toString();
150 } 151 }
151 } 152 }
152 153
153 callMethod(String name, [List args]) => 154 callMethod(String name, [List args]) =>
154 _convertToDart(JS('=Object', '#[#].apply(#, #)', _convertToJS(this), name, 155 _convertToDart(JS('=Object', '#[#].apply(#, #)', _convertToJS(this), name,
155 _convertToJS(this), 156 _convertToJS(this),
156 args == null ? null : args.map(_convertToJS).toList())); 157 args == null ? null : args.map(_convertToJS).toList()));
158
159 Map<String, dynamic> asJsMap() => new _JsObjectAsMap(this);
157 } 160 }
158 161
159 class JsFunction extends JsObject implements Serializable<JsFunction> { 162 class JsFunction extends JsObject implements Serializable<JsFunction> {
160 JsFunction._fromJs(jsObject) : super._fromJs(jsObject); 163 JsFunction._fromJs(jsObject) : super._fromJs(jsObject);
161 apply(thisArg, [List args]) => 164 apply(thisArg, [List args]) =>
162 _convertToDart(JS('=Object', '#.apply(#, #)', _convertToJS(this), 165 _convertToDart(JS('=Object', '#.apply(#, #)', _convertToJS(this),
163 _convertToJS(thisArg), 166 _convertToJS(thisArg),
164 args == null ? null : args.map(_convertToJS).toList())); 167 args == null ? null : args.map(_convertToJS).toList()));
165 } 168 }
166 169
170 /// A [JsObject] subtype for JavaScript arrays.
171 class JsArray extends JsObject with ListMixin {
172 JsArray._fromJs(jsObject) : super._fromJs(jsObject);
173
174 // Iterable
175 /*@override*/ int get length => super['length'];
176
177 // Collection
178 /*@override*/ void add(value) { callMethod('push', [value]); }
179
180 // List
181 /*@override*/ operator [](index) {
182 if (index is int && (index < 0 || index >= this.length)) {
vsm 2013/08/20 15:44:13 Should JsArray throw on non-int indices?
alexandre.ardhuin 2013/08/20 20:58:55 In Js an array is an object. So it's possible to s
183 throw new RangeError.value(index);
184 }
185 return super[index];
186 }
187 /*@override*/ void operator []=(index, value) {
188 if (index is int && (index < 0 || index >= this.length)) {
189 throw new RangeError.value(index);
190 }
191 super[index] = value;
192 }
193 /*@override*/ void set length(int length) { super['length'] = length; }
194 /*@override*/ void sort([int compare(a, b)]) {
195 final sortedList = toList()..sort(compare);
196 setRange(0, sortedList.length, sortedList);
197 }
198 /*@override*/ void insert(int index, element) {
199 callMethod('splice', [index, 0, element]);
200 }
201 /*@override*/ removeAt(int index) {
202 if (index < 0 || index >= this.length) throw new RangeError.value(index);
203 return callMethod('splice', [index, 1])[0];
204 }
205 /*@override*/ removeLast() => callMethod('pop');
206 /*@override*/ void setRange(int start, int length, List from,
207 [int startFrom = 0]) {
208 final args = [start, length];
209 for(int i = startFrom; i < startFrom + length; i++) {
210 args.add(from[i]);
211 }
212 callMethod('splice', args);
213 }
214 /*@override*/ void removeRange(int start, int end) {
215 callMethod('splice', [start, end - start]);
216 }
217 }
218
219 class _JsObjectAsMap implements Map<String, dynamic> {
220 JsObject _jsObject;
vsm 2013/08/20 15:44:13 It seems odd that Array extends JsObject while Map
alexandre.ardhuin 2013/08/20 20:58:55 Ideally I would have made JsObject implementing Ma
221
222 _JsObjectAsMap(this._jsObject);
223
224 /*@override*/ operator [](String key) => _jsObject[key];
225 /*@override*/ void operator []=(String key, value) {
226 _jsObject[key] = value;
227 }
228 /*@override*/ remove(String key) {
229 final value = this[key];
230 _jsObject.deleteProperty(key);
231 return value;
232 }
233 /*@override*/ Iterable<String> get keys =>
234 context['Object'].callMethod('keys', [_jsObject]);
235
236 // use Maps to implement functions
237 /*@override*/ bool containsValue(value) => Maps.containsValue(this, value);
238 /*@override*/ bool containsKey(String key) => Maps.containsKey(this, key);
239 /*@override*/ putIfAbsent(String key, ifAbsent()) =>
240 Maps.putIfAbsent(this, key, ifAbsent);
241 /*@override*/ void addAll(Map<String, dynamic> other) {
242 if (other != null) {
243 other.forEach((k,v) => this[k] = v);
244 }
245 }
246 /*@override*/ void clear() => Maps.clear(this);
247 /*@override*/ void forEach(void f(String key, value)) => Maps.forEach(this, f) ;
248 /*@override*/ Iterable get values => Maps.getValues(this);
249 /*@override*/ int get length => Maps.length(this);
250 /*@override*/ bool get isEmpty => Maps.isEmpty(this);
251 /*@override*/ bool get isNotEmpty => Maps.isNotEmpty(this);
252 }
253
167 abstract class Serializable<T> { 254 abstract class Serializable<T> {
168 T toJs(); 255 T toJs();
169 } 256 }
170 257
171 dynamic _convertToJS(dynamic o) { 258 dynamic _convertToJS(dynamic o) {
172 if (o == null) { 259 if (o == null) {
173 return null; 260 return null;
174 } else if (o is String || o is num || o is bool) { 261 } else if (o is String || o is num || o is bool) {
175 return o; 262 return o;
176 } else if (o is JsObject) { 263 } else if (o is JsObject) {
177 return o._jsObject; 264 return o._jsObject;
178 } else if (o is Serializable) { 265 } else if (o is Serializable) {
179 return _convertToJS(o.toJs()); 266 return _convertToJS(o.toJs());
180 } else if (o is Function) { 267 } else if (o is Function) {
181 return _convertToJS(new Callback(o)); 268 return _convertToJS(new Callback(o));
269 } else if (o is Map) {
270 return _convertToJS(jsify(o));
271 } else if (o is Iterable) {
272 return _convertToJS(jsify(o));
182 } else { 273 } else {
183 return JS('=Object', 'new DartProxy(#)', o); 274 return JS('=Object', 'new DartProxy(#)', o);
184 } 275 }
185 } 276 }
186 277
187 dynamic _convertToDart(dynamic o) { 278 dynamic _convertToDart(dynamic o) {
188 if (JS('bool', '# == null', o)) { 279 if (JS('bool', '# == null', o)) {
189 return null; 280 return null;
190 } else if (JS('bool', 'typeof # == "string" || # instanceof String', o, o) || 281 } else if (JS('bool', 'typeof # == "string" || # instanceof String', o, o) ||
191 JS('bool', 'typeof # == "number" || # instanceof Number', o, o) || 282 JS('bool', 'typeof # == "number" || # instanceof Number', o, o) ||
192 JS('bool', 'typeof # == "boolean" || # instanceof Boolean', o, o)) { 283 JS('bool', 'typeof # == "boolean" || # instanceof Boolean', o, o)) {
193 return o; 284 return o;
194 } else if (JS('bool', '# instanceof Function', o)) { 285 } else if (JS('bool', '# instanceof Function', o)) {
195 return new JsFunction._fromJs(JS('=Object', '#', o)); 286 return new JsFunction._fromJs(JS('=Object', '#', o));
287 } else if (JS('bool', '# instanceof Array', o)) {
288 return new JsArray._fromJs(JS('=Object', '#', o));
vsm 2013/08/20 15:44:13 After talking to sra, I think the right to put her
alexandre.ardhuin 2013/08/20 20:58:55 Done
196 } else if (JS('bool', '# instanceof DartProxy', o)) { 289 } else if (JS('bool', '# instanceof DartProxy', o)) {
197 return JS('var', '#.o', o); 290 return JS('var', '#.o', o);
198 } else { 291 } else {
199 return new JsObject._fromJs(JS('=Object', '#', o)); 292 return new JsObject._fromJs(JS('=Object', '#', o));
200 } 293 }
201 } 294 }
OLDNEW
« no previous file with comments | « pkg/browser/lib/interop.js ('k') | sdk/lib/js/dartium/js_dartium.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698