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

Side by Side Diff: tools/dom/src/native_DOMImplementation.dart

Issue 680913006: Stop generating dart:blink from dart scripts (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add dartium generated dart:blink to sdk Created 6 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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 part of html; 5 part of html;
6 6
7 class _Property {
8 _Property(this.name) :
9 _hasValue = false,
10 writable = false,
11 isMethod = false,
12 isOwn = true,
13 wasThrown = false;
14
15 bool get hasValue => _hasValue;
16 get value => _value;
17 set value(v) {
18 _value = v;
19 _hasValue = true;
20 }
21
22 final String name;
23 Function setter;
24 Function getter;
25 var _value;
26 bool _hasValue;
27 bool writable;
28 bool isMethod;
29 bool isOwn;
30 bool wasThrown;
31 }
32
7 class _ConsoleVariables { 33 class _ConsoleVariables {
8 Map<String, Object> _data = new Map<String, Object>(); 34 Map<String, Object> _data = new Map<String, Object>();
9 35
10 /** 36 /**
11 * Forward member accesses to the backing JavaScript object. 37 * Forward member accesses to the backing JavaScript object.
12 */ 38 */
13 noSuchMethod(Invocation invocation) { 39 noSuchMethod(Invocation invocation) {
14 String member = MirrorSystem.getName(invocation.memberName); 40 String member = MirrorSystem.getName(invocation.memberName);
15 if (invocation.isGetter) { 41 if (invocation.isGetter) {
16 return _data[member]; 42 return _data[member];
17 } else if (invocation.isSetter) { 43 } else if (invocation.isSetter) {
18 assert(member.endsWith('=')); 44 assert(member.endsWith('='));
19 member = member.substring(0, member.length - 1); 45 member = member.substring(0, member.length - 1);
20 _data[member] = invocation.positionalArguments[0]; 46 _data[member] = invocation.positionalArguments[0];
21 } else { 47 } else {
22 return Function.apply(_data[member], invocation.positionalArguments, invoc ation.namedArguments); 48 return Function.apply(_data[member], invocation.positionalArguments,
49 invocation.namedArguments);
23 } 50 }
24 } 51 }
25 52
26 void clear() => _data.clear(); 53 void clear() => _data.clear();
27 54
28 /** 55 /**
29 * List all variables currently defined. 56 * List all variables currently defined.
30 */ 57 */
31 List variables() => _data.keys.toList(growable: false); 58 List variables() => _data.keys.toList();
59
60 void setVariable(String name, value) {
61 _data[name] = value;
62 }
63 }
64
65 /**
66 * Base class for invocation trampolines used to closurize methods, getters
67 * and setters.
68 */
69 abstract class _Trampoline implements Function {
70 final ObjectMirror _receiver;
71 final MethodMirror _methodMirror;
72 final Symbol _selector;
73
74 _Trampoline(this._receiver, this._methodMirror, this._selector);
75 }
76
77 class _MethodTrampoline extends _Trampoline {
78 _MethodTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
79 Symbol selector) :
80 super(receiver, methodMirror, selector);
81
82 noSuchMethod(Invocation msg) {
83 if (msg.memberName != #call) return super.noSuchMethod(msg);
84 return _receiver.invoke(_selector,
85 msg.positionalArguments,
86 msg.namedArguments).reflectee;
87 }
88 }
89
90 /**
91 * Invocation trampoline class used to closurize getters.
92 */
93 class _GetterTrampoline extends _Trampoline {
94 _GetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
95 Symbol selector) :
96 super(receiver, methodMirror, selector);
97
98 call() => _receiver.getField(_selector).reflectee;
99 }
100
101 /**
102 * Invocation trampoline class used to closurize setters.
103 */
104 class _SetterTrampoline extends _Trampoline {
105 _SetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror,
106 Symbol selector) :
107 super(receiver, methodMirror, selector);
108
109 call(value) {
110 _receiver.setField(_selector, value);
111 }
32 } 112 }
33 113
34 class _Utils { 114 class _Utils {
35 static double dateTimeToDouble(DateTime dateTime) => 115 static double dateTimeToDouble(DateTime dateTime) =>
36 dateTime.millisecondsSinceEpoch.toDouble(); 116 dateTime.millisecondsSinceEpoch.toDouble();
37 static DateTime doubleToDateTime(double dateTime) { 117 static DateTime doubleToDateTime(double dateTime) {
38 try { 118 try {
39 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt()); 119 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
40 } catch(_) { 120 } catch(_) {
41 // TODO(antonnm): treat exceptions properly in bindings and 121 // TODO(antonnm): treat exceptions properly in bindings and
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 result[list[i]] = list[i + 1]; 155 result[list[i]] = list[i + 1];
76 } 156 }
77 } 157 }
78 158
79 static bool isMap(obj) => obj is Map; 159 static bool isMap(obj) => obj is Map;
80 160
81 static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null; 161 static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null;
82 162
83 static Map createMap() => {}; 163 static Map createMap() => {};
84 164
165 static parseJson(String jsonSource) => const JsonDecoder().convert(jsonSource) ;
166
85 static makeUnimplementedError(String fileName, int lineNo) { 167 static makeUnimplementedError(String fileName, int lineNo) {
86 return new UnsupportedError('[info: $fileName:$lineNo]'); 168 return new UnsupportedError('[info: $fileName:$lineNo]');
87 } 169 }
88 170
89 static bool isTypeSubclassOf(Type type, Type other) { 171 static bool isTypeSubclassOf(Type type, Type other) {
90 if (type == other) { 172 if (type == other) {
91 return true; 173 return true;
92 } 174 }
93 var superclass = reflectClass(type).superclass; 175 var superclass = reflectClass(type).superclass;
94 if (superclass != null) { 176 if (superclass != null) {
95 return isTypeSubclassOf(superclass.reflectedType, other); 177 return isTypeSubclassOf(superclass.reflectedType, other);
96 } 178 }
97 return false; 179 return false;
98 } 180 }
99 181
100 static Element getAndValidateNativeType(Type type, String tagName) { 182 static Element getAndValidateNativeType(Type type, String tagName) {
101 var element = new Element.tag(tagName); 183 var element = new Element.tag(tagName);
102 if (!isTypeSubclassOf(type, element.runtimeType)) { 184 if (!isTypeSubclassOf(type, element.runtimeType)) {
103 return null; 185 return null;
104 } 186 }
105 return element; 187 return element;
106 } 188 }
107 189
108 static window() native "Utils_window"; 190 static window() => _blink.Blink_Utils.window();
109 static forwardingPrint(String message) native "Utils_forwardingPrint"; 191 static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(m essage);
110 // TODO(vsm): Make this API compatible with spawnUri. It should also 192 // TODO(vsm): Make this API compatible with spawnUri. It should also
111 // return a Future<Isolate>. 193 // return a Future<Isolate>.
112 static spawnDomUri(String uri) native "Utils_spawnDomUri"; 194 static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri);
113 195
114 // The following methods were added for debugger integration to make working 196 // The following methods were added for debugger integration to make working
115 // with the Dart C mirrors API simpler. 197 // with the Dart C mirrors API simpler.
116 // TODO(jacobr): consider moving them to a separate library. 198 // TODO(jacobr): consider moving them to a separate library.
117 // If Dart supported dynamic code injection, we would only inject this code 199 // If Dart supported dynamic code injection, we would only inject this code
118 // when the debugger is invoked. 200 // when the debugger is invoked.
119 201
120 /** 202 /**
121 * Strips the private secret prefix from member names of the form 203 * Strips the private secret prefix from member names of the form
122 * someName@hash. 204 * someName@hash.
(...skipping 14 matching lines...) Expand all
137 var map = {}; 219 var map = {};
138 for (int i = 0; i < localVariables.length; i+=2) { 220 for (int i = 0; i < localVariables.length; i+=2) {
139 map[stripMemberName(localVariables[i])] = localVariables[i+1]; 221 map[stripMemberName(localVariables[i])] = localVariables[i+1];
140 } 222 }
141 return map; 223 return map;
142 } 224 }
143 225
144 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables(); 226 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();
145 227
146 /** 228 /**
147 * Header passed in from the Dartium Developer Tools when an expression is
148 * evaluated in the console as opposed to the watch window or another context
149 * that does not expect REPL support.
150 */
151 static const _CONSOLE_API_SUPPORT_HEADER =
152 'with ((console && console._commandLineAPI) || { __proto__: null }) {\n';
153 static bool expectsConsoleApi(String expression) {
154 return expression.indexOf(_CONSOLE_API_SUPPORT_HEADER) == 0;;
155 }
156
157 /**
158 * Takes an [expression] and a list of [local] variable and returns an 229 * Takes an [expression] and a list of [local] variable and returns an
159 * expression for a closure with a body matching the original expression 230 * expression for a closure with a body matching the original expression
160 * where locals are passed in as arguments. Returns a list containing the 231 * where locals are passed in as arguments. Returns a list containing the
161 * String expression for the closure and the list of arguments that should 232 * String expression for the closure and the list of arguments that should
162 * be passed to it. The expression should then be evaluated using 233 * be passed to it. The expression should then be evaluated using
163 * Dart_EvaluateExpr which will generate a closure that should be invoked 234 * Dart_EvaluateExpr which will generate a closure that should be invoked
164 * with the list of arguments passed to this method. 235 * with the list of arguments passed to this method.
165 * 236 *
166 * For example: 237 * For example:
167 * <code> 238 * <code>
168 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue} 239 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
169 * wrapExpressionAsClosure("${_CONSOLE_API_SUPPORT_HEADER}foo + bar + a", 240 * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true)
170 * ["bar", 40, "foo", 2])
171 * </code> 241 * </code>
172 * will return: 242 * will return:
173 * <code> 243 * <code>
174 * ["""(final $consoleVariables, final bar, final foo, final a, final b) => 244 * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
175 * (foo + bar + a 245 * (foo + bar + a
176 * )""", 246 * )""",
177 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]] 247 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
178 * </code> 248 * </code>
179 */ 249 */
180 static List wrapExpressionAsClosure(String expression, List locals) { 250 static List wrapExpressionAsClosure(String expression, List locals,
181 // FIXME: dartbug.com/10434 find a less fragile way to determine whether 251 bool includeCommandLineAPI) {
182 // we need to strip off console API support added by InjectedScript.
183 var args = {}; 252 var args = {};
184 var sb = new StringBuffer("("); 253 var sb = new StringBuffer("(");
185 addArg(arg, value) { 254 addArg(arg, value) {
186 arg = stripMemberName(arg); 255 arg = stripMemberName(arg);
187 if (args.containsKey(arg)) return; 256 if (args.containsKey(arg)) return;
188 // We ignore arguments with the name 'this' rather than throwing an 257 // We ignore arguments with the name 'this' rather than throwing an
189 // exception because Dart_GetLocalVariables includes 'this' and it 258 // exception because Dart_GetLocalVariables includes 'this' and it
190 // is more convenient to filter it out here than from C++ code. 259 // is more convenient to filter it out here than from C++ code.
191 // 'this' needs to be handled by calling Dart_EvaluateExpr with 260 // 'this' needs to be handled by calling Dart_EvaluateExpr with
192 // 'this' as the target rather than by passing it as an argument. 261 // 'this' as the target rather than by passing it as an argument.
193 if (arg == 'this') return; 262 if (arg == 'this') return;
194 if (args.isNotEmpty) { 263 if (args.isNotEmpty) {
195 sb.write(", "); 264 sb.write(", ");
196 } 265 }
197 sb.write("final $arg"); 266 sb.write("final $arg");
198 args[arg] = value; 267 args[arg] = value;
199 } 268 }
200 269
201 if (expectsConsoleApi(expression)) { 270 if (includeCommandLineAPI) {
202 expression = expression.substring(expression.indexOf('\n') + 1);
203 expression = expression.substring(0, expression.lastIndexOf('\n'));
204
205 addArg("\$consoleVariables", _consoleTempVariables); 271 addArg("\$consoleVariables", _consoleTempVariables);
206 272
207 // FIXME: use a real Dart tokenizer. The following regular expressions 273 // FIXME: use a real Dart tokenizer. The following regular expressions
208 // only allow setting variables at the immediate start of the expression 274 // only allow setting variables at the immediate start of the expression
209 // to limit the number of edge cases we have to handle. 275 // to limit the number of edge cases we have to handle.
210 276
211 // Match expressions that start with "var x" 277 // Match expressions that start with "var x"
212 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)"); 278 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
213 // Match expressions that start with "someExistingConsoleVar =" 279 // Match expressions that start with "someExistingConsoleVar ="
214 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)"); 280 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 317
252 // TODO(jacobr): remove the parentheses around the expresson once 318 // TODO(jacobr): remove the parentheses around the expresson once
253 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses 319 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
254 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM 320 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
255 // quietly ignores trailing Dart statements resulting in user confusion 321 // quietly ignores trailing Dart statements resulting in user confusion
256 // when part of an invalid expression they entered is ignored. 322 // when part of an invalid expression they entered is ignored.
257 sb..write(') => (\n$expression\n)'); 323 sb..write(') => (\n$expression\n)');
258 return [sb.toString(), args.values.toList(growable: false)]; 324 return [sb.toString(), args.values.toList(growable: false)];
259 } 325 }
260 326
261 /** 327 static String _getShortSymbolName(Symbol symbol,
262 * TODO(jacobr): this is a big hack to get around the fact that we are still 328 DeclarationMirror declaration) {
263 * passing some JS expression to the evaluate method even when in a Dart 329 var name = MirrorSystem.getName(symbol);
264 * context. 330 if (declaration is MethodMirror) {
265 */ 331 if (declaration.isSetter && name[name.length-1] == "=") {
266 static bool isJsExpression(String expression) => 332 return name.substring(0, name.length-1);
267 expression.startsWith("(function getCompletions"); 333 }
334 if (declaration.isConstructor) {
335 return name.substring(name.indexOf('.') + 1);
336 }
337 }
338 return name;
339 }
268 340
269 /** 341 /**
270 * Returns a list of completions to use if the receiver is o. 342 * Returns a list of completions to use if the receiver is o.
271 */ 343 */
272 static List<String> getCompletions(o) { 344 static List<String> getCompletions(o) {
273 MirrorSystem system = currentMirrorSystem(); 345 MirrorSystem system = currentMirrorSystem();
274 var completions = new Set<String>(); 346 var completions = new Set<String>();
275 addAll(Map<Symbol, dynamic> map, bool isStatic) { 347 addAll(Map<Symbol, dynamic> map, bool isStatic) {
276 map.forEach((symbol, mirror) { 348 map.forEach((symbol, mirror) {
277 if (mirror.isStatic == isStatic && !mirror.isPrivate) { 349 if (mirror.isStatic == isStatic && !mirror.isPrivate) {
(...skipping 18 matching lines...) Expand all
296 368
297 if (o is Type) { 369 if (o is Type) {
298 addForClass(reflectClass(o), true); 370 addForClass(reflectClass(o), true);
299 } else { 371 } else {
300 addForClass(reflect(o).type, false); 372 addForClass(reflect(o).type, false);
301 } 373 }
302 return completions.toList(growable: false); 374 return completions.toList(growable: false);
303 } 375 }
304 376
305 /** 377 /**
306 * Convenience helper to get the keys of a [Map] as a [List]. 378 * Adds all candidate String completitions from [declarations] to [output]
307 */ 379 * filtering based on [staticContext] and [includePrivate].
380 */
381 static void _getCompletionsHelper(ClassMirror classMirror,
382 bool staticContext, LibraryMirror libraryMirror, Set<String> output) {
383 bool includePrivate = libraryMirror == classMirror.owner;
384 classMirror.declarations.forEach((symbol, declaration) {
385 if (!includePrivate && declaration.isPrivate) return;
386 if (declaration is VariableMirror) {
387 if (staticContext != declaration.isStatic) return;
388 } else if (declaration is MethodMirror) {
389 if (declaration.isOperator) return;
390 if (declaration.isConstructor) {
391 if (!staticContext) return;
392 var name = MirrorSystem.getName(declaration.constructorName);
393 if (name.isNotEmpty) output.add(name);
394 return;
395 }
396 if (staticContext != declaration.isStatic) return;
397 } else if (declaration is TypeMirror) {
398 return;
399 }
400 output.add(_getShortSymbolName(symbol, declaration));
401 });
402
403 if (!staticContext) {
404 for (var interface in classMirror.superinterfaces) {
405 _getCompletionsHelper(interface, staticContext,
406 libraryMirror, output);
407 }
408 if (classMirror.superclass != null) {
409 _getCompletionsHelper(classMirror.superclass, staticContext,
410 libraryMirror, output);
411 }
412 }
413 }
414
415 static void _getLibraryCompletionsHelper(
416 LibraryMirror library, bool includePrivate, Set<String> output) {
417 library.declarations.forEach((symbol, declaration) {
418 if (!includePrivate && declaration.isPrivate) return;
419 output.add(_getShortSymbolName(symbol, declaration));
420 });
421 }
422
423 static LibraryMirror getLibraryMirror(String url) =>
424 currentMirrorSystem().libraries[Uri.parse(url)];
425
426 /**
427 * Get code completions for [o] only showing privates from [libraryUrl].
428 */
429 static List<String> getObjectCompletions(o, String libraryUrl) {
430 var classMirror;
431 bool staticContext;
432 if (o is Type) {
433 classMirror = reflectClass(o);
434 staticContext = true;
435 } else {
436 classMirror = reflect(o).type;
437 staticContext = false;
438 }
439 var names = new Set<String>();
440 getClassCompletions(classMirror, names, staticContext, libraryUrl);
441 return names.toList()..sort();
442 }
443
444 static void getClassCompletions(ClassMirror classMirror, Set<String> names,
445 bool staticContext, String libraryUrl) {
446 LibraryMirror libraryMirror = getLibraryMirror(libraryUrl);
447 _getCompletionsHelper(classMirror, staticContext, libraryMirror, names);
448 }
449
450 static List<String> getLibraryCompletions(String url) {
451 var names = new Set<String>();
452 _getLibraryCompletionsHelper(getLibraryMirror(url), true, names);
453 return names.toList();
454 }
455
456 /**
457 * Get valid code completitions from within a library and all libraries
458 * imported by that library.
459 */
460 static List<String> getLibraryCompletionsIncludingImports(String url) {
461 var names = new Set<String>();
462 var libraryMirror = getLibraryMirror(url);
463 _getLibraryCompletionsHelper(libraryMirror, true, names);
464 for (var dependency in libraryMirror.libraryDependencies) {
465 if (dependency.isImport) {
466 if (dependency.prefix == null) {
467 _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
468 } else {
469 names.add(MirrorSystem.getName(dependency.prefix));
470 }
471 }
472 }
473 return names.toList();
474 }
475
476 static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
477 ..add('dart:html')
478 ..add('dart:indexed_db')
479 ..add('dart:svg')
480 ..add('dart:typed_data')
481 ..add('dart:web_audio')
482 ..add('dart:web_gl')
483 ..add('dart:web_sql');
484
485 static LibraryMirror _getLibrary(MethodMirror methodMirror) {
486 var owner = methodMirror.owner;
487 if (owner is ClassMirror) {
488 return owner;
489 } else if (owner is LibraryMirror) {
490 return owner;
491 }
492 return null;
493 }
494
495 /**
496 * For parity with the JavaScript debugger, we treat some getters as if
497 * they are fields so that users can see their values immediately.
498 * This matches JavaScript's behavior for getters on DOM objects.
499 * In the future we should consider adding an annotation to tag getters
500 * in user libraries as side effect free.
501 */
502 static bool _isSideEffectFreeGetter(MethodMirror methodMirror,
503 LibraryMirror libraryMirror) {
504 // This matches JavaScript behavior. We should consider displaying
505 // getters for all dart platform libraries rather than just the DOM
506 // libraries.
507 return libraryMirror.uri.scheme == 'dart' &&
508 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
509 }
510
511 /**
512 * Whether we should treat a property as a field for the purposes of the
513 * debugger.
514 */
515 static bool treatPropertyAsField(MethodMirror methodMirror,
516 LibraryMirror libraryMirror) {
517 return (methodMirror.isGetter || methodMirror.isSetter) &&
518 (methodMirror.isSynthetic ||
519 _isSideEffectFreeGetter(methodMirror,libraryMirror));
520 }
521
522 // TODO(jacobr): generate more concise function descriptions instead of
523 // dumping the entire function source.
524 static String describeFunction(function) {
525 if (function is _Trampoline) return function._methodMirror.source;
526 try {
527 var mirror = reflect(function);
528 return mirror.function.source;
529 } catch (e) {
530 return function.toString();
531 }
532 }
533
534 static List getInvocationTrampolineDetails(_Trampoline method) {
535 var loc = method._methodMirror.location;
536 return [loc.line, loc.column, loc.sourceUri.toString(),
537 MirrorSystem.getName(method._selector)];
538 }
539
540 static List getLibraryProperties(String libraryUrl, bool ownProperties,
541 bool accessorPropertiesOnly) {
542 var properties = new Map<String, _Property>();
543 var libraryMirror = getLibraryMirror(libraryUrl);
544 _addInstanceMirrors(libraryMirror, libraryMirror,
545 libraryMirror.declarations,
546 ownProperties, accessorPropertiesOnly, false, false,
547 properties);
548 if (!accessorPropertiesOnly) {
549 // We need to add class properties for all classes in the library.
550 libraryMirror.declarations.forEach((symbol, declarationMirror) {
551 if (declarationMirror is ClassMirror) {
552 var name = MirrorSystem.getName(symbol);
553 if (declarationMirror.hasReflectedType
554 && !properties.containsKey(name)) {
555 properties[name] = new _Property(name)
556 ..value = declarationMirror.reflectedType;
557 }
558 }
559 });
560 }
561 return packageProperties(properties);
562 }
563
564 static List getObjectProperties(o, bool ownProperties,
565 bool accessorPropertiesOnly) {
566 var properties = new Map<String, _Property>();
567 var names = new Set<String>();
568 var objectMirror = reflect(o);
569 var classMirror = objectMirror.type;
570 _addInstanceMirrors(objectMirror, classMirror.owner,
571 classMirror.instanceMembers,
572 ownProperties, accessorPropertiesOnly, false, true,
573 properties);
574 return packageProperties(properties);
575 }
576
577 static List getObjectClassProperties(o, bool ownProperties,
578 bool accessorPropertiesOnly) {
579 var properties = new Map<String, _Property>();
580 var objectMirror = reflect(o);
581 var classMirror = objectMirror.type;
582 _addInstanceMirrors(objectMirror, classMirror.owner,
583 classMirror.instanceMembers,
584 ownProperties, accessorPropertiesOnly, true, false,
585 properties);
586 _addStatics(classMirror, properties, accessorPropertiesOnly);
587 return packageProperties(properties);
588 }
589
590 static List getClassProperties(Type t, bool ownProperties,
591 bool accessorPropertiesOnly) {
592 var properties = new Map<String, _Property>();
593 var classMirror = reflectClass(t);
594 _addStatics(classMirror, properties, accessorPropertiesOnly);
595 return packageProperties(properties);
596 }
597
598 static void _addStatics(ClassMirror classMirror,
599 Map<String, _Property> properties,
600 bool accessorPropertiesOnly) {
601 var libraryMirror = classMirror.owner;
602 classMirror.declarations.forEach((symbol, declaration) {
603 var name = _getShortSymbolName(symbol, declaration);
604 if (name.isEmpty) return;
605 if (declaration is VariableMirror) {
606 if (accessorPropertiesOnly) return;
607 if (!declaration.isStatic) return;
608 properties.putIfAbsent(name, () => new _Property(name))
609 ..value = classMirror.getField(symbol).reflectee
610 ..writable = !declaration.isFinal && !declaration.isConst;
611 } else if (declaration is MethodMirror) {
612 MethodMirror methodMirror = declaration;
613 // FIXMEDART: should we display constructors?
614 if (methodMirror.isConstructor) return;
615 if (!methodMirror.isStatic) return;
616 if (accessorPropertiesOnly) {
617 if (methodMirror.isRegularMethod ||
618 treatPropertyAsField(methodMirror, libraryMirror)) {
619 return;
620 }
621 } else if (!methodMirror.isRegularMethod &&
622 !treatPropertyAsField(methodMirror, libraryMirror)) {
623 return;
624 }
625 var property = properties.putIfAbsent(name, () => new _Property(name));
626 _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror,
627 symbol, accessorPropertiesOnly, property);
628 }
629 });
630 }
631
632 static void _fillMethodMirrorProperty(LibraryMirror libraryMirror,
633 methodOwner, MethodMirror methodMirror, Symbol symbol,
634 bool accessorPropertiesOnly, _Property property) {
635 if (methodMirror.isRegularMethod) {
636 property
637 ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol)
638 ..isMethod = true;
639 } else if (methodMirror.isGetter) {
640 if (treatPropertyAsField(methodMirror, libraryMirror)) {
641 try {
642 property.value = methodOwner.getField(symbol).reflectee;
643 } catch (e) {
644 property
645 ..wasThrown = true
646 ..value = e;
647 }
648 } else if (accessorPropertiesOnly) {
649 property.getter = new _GetterTrampoline(methodOwner,
650 methodMirror, symbol);
651 }
652 } else if (methodMirror.isSetter) {
653 if (accessorPropertiesOnly &&
654 !treatPropertyAsField(methodMirror, libraryMirror)) {
655 property.setter = new _SetterTrampoline(methodOwner,
656 methodMirror, MirrorSystem.getSymbol(property.name, libraryMirror));
657 }
658 property.writable = true;
659 }
660 }
661
662 /**
663 * Helper method that handles collecting up properties from classes
664 * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
665 * [hideFields], and [hideMethods] to determine which properties are
666 * collected. [accessorPropertiesOnly] specifies whether all properties
667 * should be returned or just accessors. [hideFields] specifies whether
668 * fields should be hidden. hideMethods specifies whether methods should be
669 * shown or hidden. [ownProperties] is not currently used but is part of the
670 * Blink devtools API for enumerating properties.
671 */
672 static void _addInstanceMirrors(
673 ObjectMirror objectMirror,
674 LibraryMirror libraryMirror,
675 Map<Symbol, Mirror> declarations,
676 bool ownProperties, bool accessorPropertiesOnly,
677 bool hideFields, bool hideMethods,
678 Map<String, _Property> properties) {
679 declarations.forEach((symbol, declaration) {
680 if (declaration is TypedefMirror || declaration is ClassMirror) return;
681 var name = _getShortSymbolName(symbol, declaration);
682 if (name.isEmpty) return;
683 bool isField = declaration is VariableMirror ||
684 (declaration is MethodMirror &&
685 treatPropertyAsField(declaration, libraryMirror));
686 if ((isField && hideFields) || (hideMethods && !isField)) return;
687 if (accessorPropertiesOnly) {
688 if (declaration is VariableMirror || declaration.isRegularMethod ||
689 isField) {
690 return;
691 }
692 } else if (declaration is MethodMirror &&
693 (declaration.isGetter || declaration.isSetter) &&
694 !treatPropertyAsField(declaration, libraryMirror)) {
695 return;
696 }
697 var property = properties.putIfAbsent(name, () => new _Property(name));
698 if (declaration is VariableMirror) {
699 property
700 ..value = objectMirror.getField(symbol).reflectee
701 ..writable = !declaration.isFinal && !declaration.isConst;
702 return;
703 }
704 _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration,
705 symbol, accessorPropertiesOnly, property);
706 });
707 }
708
709 /**
710 * Flatten down the properties data structure into a List that is easy to
711 * access from native code.
712 */
713 static List packageProperties(Map<String, _Property> properties) {
714 var ret = [];
715 for (var property in properties.values) {
716 ret.addAll([property.name,
717 property.setter,
718 property.getter,
719 property.value,
720 property.hasValue,
721 property.writable,
722 property.isMethod,
723 property.isOwn,
724 property.wasThrown]);
725 }
726 return ret;
727 }
728
729 /**
730 * Get a property, returning null if the property does not exist.
731 * For private property names, we attempt to resolve the property in the
732 * context of each library that the property name could be associated with.
733 */
734 static getObjectPropertySafe(o, String propertyName) {
735 var objectMirror = reflect(o);
736 var classMirror = objectMirror.type;
737 if (propertyName.startsWith("_")) {
738 var attemptedLibraries = new Set<LibraryMirror>();
739 while (classMirror != null) {
740 LibraryMirror library = classMirror.owner;
741 if (!attemptedLibraries.contains(library)) {
742 try {
743 return objectMirror.getField(
744 MirrorSystem.getSymbol(propertyName, library)).reflectee;
745 } catch (e) { }
746 attemptedLibraries.add(library);
747 }
748 classMirror = classMirror.superclass;
749 }
750 return null;
751 }
752 try {
753 return objectMirror.getField(
754 MirrorSystem.getSymbol(propertyName)).reflectee;
755 } catch (e) {
756 return null;
757 }
758 }
759
760 /**
761 * Helper to wrap the inspect method on InjectedScriptHost to provide the
762 * inspect method required for the
763 */
764 static List consoleApi(host) {
765 return [
766 "inspect",
767 (o) {
768 host.inspect(o, null);
769 return o;
770 },
771 "dir",
772 window().console.dir,
773 "dirxml",
774 window().console.dirxml
775 // FIXME: add copy method.
776 ];
777 }
778
308 static List getMapKeyList(Map map) => map.keys.toList(); 779 static List getMapKeyList(Map map) => map.keys.toList();
309 780
310 /**
311 * Returns the keys of an arbitrary Dart Map encoded as unique Strings.
312 * Keys that are strings are left unchanged except that the prefix ":" is
313 * added to disambiguate keys from other Dart members.
314 * Keys that are not strings have # followed by the index of the key in the ma p
315 * prepended to disambuguate. This scheme is simplistic but easy to encode and
316 * decode. The use case for this method is displaying all map keys in a human
317 * readable way in debugging tools.
318 */
319 static List<String> getEncodedMapKeyList(dynamic obj) {
320 if (obj is! Map) return null;
321
322 var ret = new List<String>();
323 int i = 0;
324 return obj.keys.map((key) {
325 var encodedKey;
326 if (key is String) {
327 encodedKey = ':$key';
328 } else {
329 // If the key isn't a string, return a guaranteed unique for this map
330 // string representation of the key that is still somewhat human
331 // readable.
332 encodedKey = '#${i}:$key';
333 }
334 i++;
335 return encodedKey;
336 }).toList(growable: false);
337 }
338
339 static final RegExp _NON_STRING_KEY_REGEXP = new RegExp("^#(\\d+):(.+)\$");
340
341 static _decodeKey(Map map, String key) {
342 // The key is a regular old String.
343 if (key.startsWith(':')) return key.substring(1);
344
345 var match = _NON_STRING_KEY_REGEXP.firstMatch(key);
346 if (match != null) {
347 int index = int.parse(match.group(1));
348 var iter = map.keys.skip(index);
349 if (iter.isNotEmpty) {
350 var ret = iter.first;
351 // Validate that the toString representation of the key matches what we
352 // expect. FIXME: throw an error if it does not.
353 assert(match.group(2) == '$ret');
354 return ret;
355 }
356 }
357 return null;
358 }
359
360 /**
361 * Converts keys encoded with [getEncodedMapKeyList] to their actual keys.
362 */
363 static lookupValueForEncodedMapKey(Map obj, String key) => obj[_decodeKey(obj, key)];
364
365 /**
366 * Builds a constructor name with the form expected by the C Dart mirrors API.
367 */
368 static String buildConstructorName(String className, String constructorName) = > '$className.$constructorName';
369
370 /**
371 * Strips the class name from an expression of the form "className.someName".
372 */
373 static String stripClassName(String str, String className) {
374 if (str.length > className.length + 1 &&
375 str.startsWith(className) && str[className.length] == '.') {
376 return str.substring(className.length + 1);
377 } else {
378 return str;
379 }
380 }
381
382 /**
383 * Removes the trailing dot from an expression ending in a dot.
384 * This method is used as Library prefixes include a trailing dot when using
385 * the C Dart debugger API.
386 */
387 static String stripTrailingDot(String str) =>
388 (str != null && str[str.length - 1] == '.') ? str.substring(0, str.length - 1) : str;
389
390 static String addTrailingDot(String str) => '${str}.';
391
392 static String demangle(String str) {
393 var atPos = str.indexOf('@');
394 return atPos == -1 ? str : str.substring(0, atPos);
395 }
396
397 static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError; 781 static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
398 782
399 static void register(Document document, String tag, Type type, 783 static void register(Document document, String tag, Type type,
400 String extendsTagName) { 784 String extendsTagName) {
401 var nativeClass = _validateCustomType(type); 785 var nativeClass = _validateCustomType(type);
402 786
403 if (extendsTagName == null) { 787 if (extendsTagName == null) {
404 if (nativeClass.reflectedType != HtmlElement) { 788 if (nativeClass.reflectedType != HtmlElement) {
405 throw new UnsupportedError('Class must provide extendsTag if base ' 789 throw new UnsupportedError('Class must provide extendsTag if base '
406 'native class is not HTMLElement'); 790 'native class is not HTMLElement');
407 } 791 }
408 } 792 }
409 793
410 _register(document, tag, type, extendsTagName); 794 _register(document, tag, type, extendsTagName);
411 } 795 }
412 796
413 static void _register(Document document, String tag, Type customType, 797 static void _register(Document document, String tag, Type customType,
414 String extendsTagName) native "Utils_register"; 798 String extendsTagName) => _blink.Blink_Utils.register(document, tag, customT ype, extendsTagName);
415 799
416 static Element createElement(Document document, String tagName) native "Utils_ createElement"; 800 static Element createElement(Document document, String tagName) =>
801 _blink.Blink_Utils.createElement(document, tagName);
417 802
418 static void initializeCustomElement(HtmlElement element) native "Utils_initial izeCustomElement"; 803 static void initializeCustomElement(HtmlElement element) =>
804 _blink.Blink_Utils.initializeCustomElement(element);
419 805
420 static Element changeElementWrapper(HtmlElement element, Type type) native "Ut ils_changeElementWrapper"; 806 static Element changeElementWrapper(HtmlElement element, Type type) =>
807 _blink.Blink_Utils.changeElementWrapper(element, type);
421 } 808 }
422 809
423 class _DOMWindowCrossFrame extends NativeFieldWrapperClass2 implements 810 class _DOMWindowCrossFrame extends NativeFieldWrapperClass2 implements
424 WindowBase { 811 WindowBase {
425 _DOMWindowCrossFrame.internal(); 812 _DOMWindowCrossFrame.internal();
426 813
427 // Fields. 814 // Fields.
428 HistoryBase get history native "Window_history_cross_frame_Getter"; 815 HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this);
429 LocationBase get location native "Window_location_cross_frame_Getter"; 816 LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(thi s);
430 bool get closed native "Window_closed_Getter"; 817 bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
431 int get length native "Window_length_Getter"; 818 WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
432 WindowBase get opener native "Window_opener_Getter"; 819 WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
433 WindowBase get parent native "Window_parent_Getter"; 820 WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);
434 WindowBase get top native "Window_top_Getter";
435 821
436 // Methods. 822 // Methods.
437 void close() native "Window_close_Callback"; 823 void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
438 void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) native "Window_postMessage_Callback"; 824 void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
825 _blink.Blink_DOMWindowCrossFrame.postMessage(this, message, targetOrigin, me ssagePorts);
439 826
440 // Implementation support. 827 // Implementation support.
441 String get typeName => "Window"; 828 String get typeName => "Window";
442 829
443 // TODO(efortuna): Remove this method. dartbug.com/16814 830 // TODO(efortuna): Remove this method. dartbug.com/16814
444 Events get on => throw new UnsupportedError( 831 Events get on => throw new UnsupportedError(
445 'You can only attach EventListeners to your own window.'); 832 'You can only attach EventListeners to your own window.');
446 // TODO(efortuna): Remove this method. dartbug.com/16814 833 // TODO(efortuna): Remove this method. dartbug.com/16814
834 void _addEventListener([String type, EventListener listener, bool useCapture])
835 => throw new UnsupportedError(
836 'You can only attach EventListeners to your own window.');
837 // TODO(efortuna): Remove this method. dartbug.com/16814
447 void addEventListener(String type, EventListener listener, [bool useCapture]) 838 void addEventListener(String type, EventListener listener, [bool useCapture])
448 => throw new UnsupportedError( 839 => throw new UnsupportedError(
449 'You can only attach EventListeners to your own window.'); 840 'You can only attach EventListeners to your own window.');
450 // TODO(efortuna): Remove this method. dartbug.com/16814 841 // TODO(efortuna): Remove this method. dartbug.com/16814
451 bool dispatchEvent(Event event) => throw new UnsupportedError( 842 bool dispatchEvent(Event event) => throw new UnsupportedError(
452 'You can only attach EventListeners to your own window.'); 843 'You can only attach EventListeners to your own window.');
453 // TODO(efortuna): Remove this method. dartbug.com/16814 844 // TODO(efortuna): Remove this method. dartbug.com/16814
845 void _removeEventListener([String type, EventListener listener,
846 bool useCapture]) => throw new UnsupportedError(
847 'You can only attach EventListeners to your own window.');
848 // TODO(efortuna): Remove this method. dartbug.com/16814
454 void removeEventListener(String type, EventListener listener, 849 void removeEventListener(String type, EventListener listener,
455 [bool useCapture]) => throw new UnsupportedError( 850 [bool useCapture]) => throw new UnsupportedError(
456 'You can only attach EventListeners to your own window.'); 851 'You can only attach EventListeners to your own window.');
457 } 852 }
458 853
459 class _HistoryCrossFrame extends NativeFieldWrapperClass2 implements HistoryBase { 854 class _HistoryCrossFrame extends NativeFieldWrapperClass2 implements HistoryBase {
460 _HistoryCrossFrame.internal(); 855 _HistoryCrossFrame.internal();
461 856
462 // Methods. 857 // Methods.
463 void back() native "History_back_Callback"; 858 void back() => _blink.Blink_HistoryCrossFrame.back(this);
464 void forward() native "History_forward_Callback"; 859 void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
465 void go(int distance) native "History_go_Callback"; 860 void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);
466 861
467 // Implementation support. 862 // Implementation support.
468 String get typeName => "History"; 863 String get typeName => "History";
469 } 864 }
470 865
471 class _LocationCrossFrame extends NativeFieldWrapperClass2 implements LocationBa se { 866 class _LocationCrossFrame extends NativeFieldWrapperClass2 implements LocationBa se {
472 _LocationCrossFrame.internal(); 867 _LocationCrossFrame.internal();
473 868
474 // Fields. 869 // Fields.
475 void set href(String) native "Location_href_Setter"; 870 void set href(String h) => _blink.Blink_LocationCrossFrame.set_href(this, h);
476 871
477 // Implementation support. 872 // Implementation support.
478 String get typeName => "Location"; 873 String get typeName => "Location";
479 } 874 }
480 875
481 class _DOMStringMap extends NativeFieldWrapperClass2 implements Map<String, Stri ng> { 876 class _DOMStringMap extends NativeFieldWrapperClass2 implements Map<String, Stri ng> {
482 _DOMStringMap.internal(); 877 _DOMStringMap.internal();
483 878
484 bool containsValue(String value) => Maps.containsValue(this, value); 879 bool containsValue(String value) => Maps.containsValue(this, value);
485 bool containsKey(String key) native "DOMStringMap_containsKey_Callback"; 880 bool containsKey(String key) => _blink.Blink_DOMStringMap.containsKey(this, ke y);
486 String operator [](String key) native "DOMStringMap_item_Callback"; 881 String operator [](String key) => _blink.Blink_DOMStringMap.item(this, key);
487 void operator []=(String key, String value) native "DOMStringMap_setItem_Callb ack"; 882 void operator []=(String key, String value) => _blink.Blink_DOMStringMap.setIt em(this, key, value);
488 String putIfAbsent(String key, String ifAbsent()) => Maps.putIfAbsent(this, ke y, ifAbsent); 883 String putIfAbsent(String key, String ifAbsent()) => Maps.putIfAbsent(this, ke y, ifAbsent);
489 String remove(String key) native "DOMStringMap_remove_Callback"; 884 String remove(String key) => _blink.Blink_DOMStringMap.remove(this, key);
490 void clear() => Maps.clear(this); 885 void clear() => Maps.clear(this);
491 void forEach(void f(String key, String value)) => Maps.forEach(this, f); 886 void forEach(void f(String key, String value)) => Maps.forEach(this, f);
492 Iterable<String> get keys native "DOMStringMap_getKeys_Callback"; 887 Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this);
493 Iterable<String> get values => Maps.getValues(this); 888 Iterable<String> get values => Maps.getValues(this);
494 int get length => Maps.length(this); 889 int get length => Maps.length(this);
495 bool get isEmpty => Maps.isEmpty(this); 890 bool get isEmpty => Maps.isEmpty(this);
496 bool get isNotEmpty => Maps.isNotEmpty(this); 891 bool get isNotEmpty => Maps.isNotEmpty(this);
497 void addAll(Map<String, String> other) { 892 void addAll(Map<String, String> other) {
498 other.forEach((key, value) => this[key] = value); 893 other.forEach((key, value) => this[key] = value);
499 } 894 }
500 } 895 }
501 896
502 final _printClosure = (s) => window.console.log(s); 897 final _printClosure = (s) => window.console.log(s);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 _scheduleImmediateHelper._schedule(callback); 991 _scheduleImmediateHelper._schedule(callback);
597 }; 992 };
598 993
599 get _pureIsolateScheduleImmediateClosure => ((void callback()) => 994 get _pureIsolateScheduleImmediateClosure => ((void callback()) =>
600 throw new UnimplementedError("scheduleMicrotask in background isolates " 995 throw new UnimplementedError("scheduleMicrotask in background isolates "
601 "are not supported in the browser")); 996 "are not supported in the browser"));
602 997
603 void _initializeCustomElement(Element e) { 998 void _initializeCustomElement(Element e) {
604 _Utils.initializeCustomElement(e); 999 _Utils.initializeCustomElement(e);
605 } 1000 }
1001
1002 // Class for unsupported native browser 'DOM' objects.
1003 class _UnsupportedBrowserObject extends NativeFieldWrapperClass2 {
1004 }
OLDNEW
« no previous file with comments | « tools/dom/src/html_native_DOMImplementation.dart ('k') | tools/dom/templates/html/dartium/_blink_dartium.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698