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

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

Issue 258503008: Support Dart debugger API directly (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: PTAL Created 6 years, 7 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
« tools/dom/idl/dart/dart.idl ('K') | « tools/dom/idl/dart/dart.idl ('k') | no next file » | 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) 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, invoc ation.namedArguments);
23 } 49 }
24 } 50 }
25 51
26 void clear() => _data.clear(); 52 void clear() => _data.clear();
27 53
28 /** 54 /**
29 * List all variables currently defined. 55 * List all variables currently defined.
30 */ 56 */
31 List variables() => _data.keys.toList(growable: false); 57 List variables() => _data.keys.toList();
58 }
59
60 /**
61 * Base class for invocation trampolines used to closurize methods, getters
62 * and setters.
63 */
64 abstract class _Trampoline implements Function {
65 final ObjectMirror _receiver;
66 final MethodMirror _methodMirror;
67 final Symbol _selector;
68
69 _Trampoline(this._receiver, this._methodMirror, this._selector);
70 }
71
72 class _MethodTrampoline extends _Trampoline {
73 _MethodTrampoline(ObjectMirror receiver, MethodMirror methodMirror, Symbol sel ector) :
74 super(receiver, methodMirror, selector);
75
76 noSuchMethod(Invocation msg) {
77 if (msg.memberName != #call) return super.noSuchMethod(msg);
78 return _receiver.invoke(_selector,
79 msg.positionalArguments,
80 msg.namedArguments).reflectee;
81 }
82 }
83
84 /**
85 * Invocation trampoline class used to closurize getters.
86 */
87 class _GetterTrampoline extends _Trampoline {
88 _GetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror, Symbol sel ector) :
89 super(receiver, methodMirror, selector);
90
91 call() => _receiver.getField(_selector).reflectee;
92 }
93
94 /**
95 * Invocation trampoline class used to closurize setters.
96 */
97 class _SetterTrampoline extends _Trampoline {
98 _SetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror, Symbol sel ector) :
99 super(receiver, methodMirror, selector);
100
101 call(value) {
102 _receiver.setField(_selector, value);
103 }
32 } 104 }
33 105
34 class _Utils { 106 class _Utils {
35 static double dateTimeToDouble(DateTime dateTime) => 107 static double dateTimeToDouble(DateTime dateTime) =>
36 dateTime.millisecondsSinceEpoch.toDouble(); 108 dateTime.millisecondsSinceEpoch.toDouble();
37 static DateTime doubleToDateTime(double dateTime) { 109 static DateTime doubleToDateTime(double dateTime) {
38 try { 110 try {
39 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt()); 111 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
40 } catch(_) { 112 } catch(_) {
41 // TODO(antonnm): treat exceptions properly in bindings and 113 // TODO(antonnm): treat exceptions properly in bindings and
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 var map = {}; 209 var map = {};
138 for (int i = 0; i < localVariables.length; i+=2) { 210 for (int i = 0; i < localVariables.length; i+=2) {
139 map[stripMemberName(localVariables[i])] = localVariables[i+1]; 211 map[stripMemberName(localVariables[i])] = localVariables[i+1];
140 } 212 }
141 return map; 213 return map;
142 } 214 }
143 215
144 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables(); 216 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();
145 217
146 /** 218 /**
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 219 * Takes an [expression] and a list of [local] variable and returns an
159 * expression for a closure with a body matching the original expression 220 * expression for a closure with a body matching the original expression
160 * where locals are passed in as arguments. Returns a list containing the 221 * 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 222 * String expression for the closure and the list of arguments that should
162 * be passed to it. The expression should then be evaluated using 223 * be passed to it. The expression should then be evaluated using
163 * Dart_EvaluateExpr which will generate a closure that should be invoked 224 * Dart_EvaluateExpr which will generate a closure that should be invoked
164 * with the list of arguments passed to this method. 225 * with the list of arguments passed to this method.
165 * 226 *
166 * For example: 227 * For example:
167 * <code> 228 * <code>
168 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue} 229 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
169 * wrapExpressionAsClosure("${_CONSOLE_API_SUPPORT_HEADER}foo + bar + a", 230 * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true)
170 * ["bar", 40, "foo", 2])
171 * </code> 231 * </code>
172 * will return: 232 * will return:
173 * <code> 233 * <code>
174 * ["""(final $consoleVariables, final bar, final foo, final a, final b) => 234 * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
175 * (foo + bar + a 235 * (foo + bar + a
176 * )""", 236 * )""",
177 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]] 237 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
178 * </code> 238 * </code>
179 */ 239 */
180 static List wrapExpressionAsClosure(String expression, List locals) { 240 static List wrapExpressionAsClosure(String expression, List locals,
181 // FIXME: dartbug.com/10434 find a less fragile way to determine whether 241 bool includeCommandLineAPI) {
182 // we need to strip off console API support added by InjectedScript.
183 var args = {}; 242 var args = {};
184 var sb = new StringBuffer("("); 243 var sb = new StringBuffer("(");
185 addArg(arg, value) { 244 addArg(arg, value) {
186 arg = stripMemberName(arg); 245 arg = stripMemberName(arg);
187 if (args.containsKey(arg)) return; 246 if (args.containsKey(arg)) return;
188 // We ignore arguments with the name 'this' rather than throwing an 247 // We ignore arguments with the name 'this' rather than throwing an
189 // exception because Dart_GetLocalVariables includes 'this' and it 248 // exception because Dart_GetLocalVariables includes 'this' and it
190 // is more convenient to filter it out here than from C++ code. 249 // is more convenient to filter it out here than from C++ code.
191 // 'this' needs to be handled by calling Dart_EvaluateExpr with 250 // 'this' needs to be handled by calling Dart_EvaluateExpr with
192 // 'this' as the target rather than by passing it as an argument. 251 // 'this' as the target rather than by passing it as an argument.
193 if (arg == 'this') return; 252 if (arg == 'this') return;
194 if (args.isNotEmpty) { 253 if (args.isNotEmpty) {
195 sb.write(", "); 254 sb.write(", ");
196 } 255 }
197 sb.write("final $arg"); 256 sb.write("final $arg");
198 args[arg] = value; 257 args[arg] = value;
199 } 258 }
200 259
201 if (expectsConsoleApi(expression)) { 260 if (includeCommandLineAPI) {
202 expression = expression.substring(expression.indexOf('\n') + 1);
203 expression = expression.substring(0, expression.lastIndexOf('\n'));
204
205 addArg("\$consoleVariables", _consoleTempVariables); 261 addArg("\$consoleVariables", _consoleTempVariables);
206 262
207 // FIXME: use a real Dart tokenizer. The following regular expressions 263 // FIXME: use a real Dart tokenizer. The following regular expressions
208 // only allow setting variables at the immediate start of the expression 264 // only allow setting variables at the immediate start of the expression
209 // to limit the number of edge cases we have to handle. 265 // to limit the number of edge cases we have to handle.
210 266
211 // Match expressions that start with "var x" 267 // Match expressions that start with "var x"
212 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)"); 268 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
213 // Match expressions that start with "someExistingConsoleVar =" 269 // Match expressions that start with "someExistingConsoleVar ="
214 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)"); 270 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 307
252 // TODO(jacobr): remove the parentheses around the expresson once 308 // TODO(jacobr): remove the parentheses around the expresson once
253 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses 309 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
254 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM 310 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
255 // quietly ignores trailing Dart statements resulting in user confusion 311 // quietly ignores trailing Dart statements resulting in user confusion
256 // when part of an invalid expression they entered is ignored. 312 // when part of an invalid expression they entered is ignored.
257 sb..write(') => (\n$expression\n)'); 313 sb..write(') => (\n$expression\n)');
258 return [sb.toString(), args.values.toList(growable: false)]; 314 return [sb.toString(), args.values.toList(growable: false)];
259 } 315 }
260 316
261 /** 317 static String _getShortSymbolName(Symbol symbol,
262 * TODO(jacobr): this is a big hack to get around the fact that we are still 318 DeclarationMirror declaration) {
263 * passing some JS expression to the evaluate method even when in a Dart 319 var name = MirrorSystem.getName(symbol);
264 * context. 320 if (declaration is MethodMirror) {
265 */ 321 if (declaration.isSetter && name[name.length-1] == "=") {
266 static bool isJsExpression(String expression) => 322 return name.substring(0, name.length-1);
267 expression.startsWith("(function getCompletions"); 323 }
268 324 if (declaration.isConstructor) {
269 /** 325 return name.substring(name.indexOf('.') + 1);
270 * Returns a list of completions to use if the receiver is o. 326 }
271 */ 327 }
272 static List<String> getCompletions(o) { 328 return name;
273 MirrorSystem system = currentMirrorSystem(); 329 }
274 var completions = new Set<String>(); 330
275 addAll(Map<Symbol, dynamic> map, bool isStatic) { 331 /**
276 map.forEach((symbol, mirror) { 332 * Adds all candidate String completitions from [declarations] to [output]
277 if (mirror.isStatic == isStatic && !mirror.isPrivate) { 333 * filtering based on [staticContext] and [includePrivate].
334 */
335 static void _getCompletionsHelper(ClassMirror classMirror,
336 bool staticContext, LibraryMirror libraryMirror, Set<String> output) {
337 bool includePrivate = libraryMirror == classMirror.owner;
338 classMirror.declarations.forEach((symbol, declaration) {
339 if (!includePrivate && declaration.isPrivate) return;
340 if (declaration is VariableMirror) {
341 if (staticContext != declaration.isStatic) return;
342 } else if (declaration is MethodMirror) {
343 if (declaration.isOperator) return;
344 if (declaration.isConstructor) {
345 if (!staticContext) return;
346 var name = MirrorSystem.getName(declaration.constructorName);
347 if (name.isNotEmpty) output.add(name);
348 return;
349 }
350 if (staticContext != declaration.isStatic) return;
351 } else if (declaration is TypeMirror) {
352 return;
353 }
354 output.add(_getShortSymbolName(symbol, declaration));
355 });
356
357 if (!staticContext) {
358 for (var interface in classMirror.superinterfaces) {
359 _getCompletionsHelper(interface, staticContext,
360 libraryMirror, output);
361 }
362 if (classMirror.superclass != null) {
363 _getCompletionsHelper(classMirror.superclass, staticContext,
364 libraryMirror, output);
365 }
366 }
367 }
368
369 static void _getLibraryCompletionsHelper(
370 LibraryMirror library, bool includePrivate, Set<String> output) {
371 library.declarations.forEach((symbol, declaration) {
372 if (!includePrivate && declaration.isPrivate) return;
373 output.add(_getShortSymbolName(symbol, declaration));
374 });
375 }
376
377 static LibraryMirror getLibraryMirror(String url) =>
378 currentMirrorSystem().libraries[Uri.parse(url)];
379
380 /**
381 * Get code completions for [o] only showing privates from [libraryUrl].
382 */
383 static List<String> getObjectCompletions(o, String libraryUrl) {
384 var classMirror;
385 bool staticContext;
386 if (o is Type) {
387 classMirror = reflectClass(o);
388 staticContext = true;
389 } else {
390 classMirror = reflect(o).type;
391 staticContext = false;
392 }
393 var names = new Set<String>();
394 getClassCompletions(classMirror, names, staticContext, libraryUrl);
395 return names.toList()..sort();
396 }
397
398 static void getClassCompletions(ClassMirror classMirror, Set<String> names,
399 bool staticContext, String libraryUrl) {
400 LibraryMirror libraryMirror = getLibraryMirror(libraryUrl);
401 _getCompletionsHelper(classMirror, staticContext, libraryMirror, names);
402 }
403
404 static List<String> getLibraryCompletions(String url) {
405 var names = new Set<String>();
406 _getLibraryCompletionsHelper(getLibraryMirror(url), true, names);
407 return names.toList();
408 }
409
410 /**
411 * Get valid code completitions from within a library and all libraries
412 * imported by that library.
413 */
414 static List<String> getLibraryCompletionsIncludingImports(String url) {
415 var names = new Set<String>();
416 var libraryMirror = getLibraryMirror(url);
417 _getLibraryCompletionsHelper(libraryMirror, true, names);
418 for (var dependency in libraryMirror.libraryDependencies) {
419 if (dependency.isImport) {
420 if (dependency.prefix == null) {
421 _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
422 } else {
423 names.add(MirrorSystem.getName(dependency.prefix));
424 }
425 }
426 }
427 return names.toList();
428 }
429
430 static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
431 ..add('dart:html')
432 ..add('dart:indexed_db')
433 ..add('dart:svg')
434 ..add('dart:typed_data')
435 ..add('dart:web_audio')
436 ..add('dart:web_gl')
437 ..add('dart:web_sql');
438 /**
439 * For parity with the JavaScript debugger, we treat some getters as if
440 * they are fields so that users can see their values immediately.
441 * This matches JavaScript's behavior for getters on DOM objects.
442 * In the future we should consider adding an annotation to tag getters
443 * in user libraries as side effect free.
444 */
445 static bool _isSideEffectFreeGetter(MethodMirror methodMirror) {
446 var owner = methodMirror.owner;
447 var libraryMirror;
448 if (owner is ClassMirror) {
449 libraryMirror = owner.owner;
450 } else if (owner is LibraryMirror) {
451 libraryMirror = owner;
452 }
453 if (libraryMirror != null) {
454 // This matches JavaScript behavior. We should consider displaying
455 // getters for all dart platform libraries rather than just the DOM
456 // libraries.
457 if (libraryMirror.uri.scheme == 'dart' &&
458 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString())) {
459 return true;
460 }
461 }
462 return false;
463 }
464
465 /**
466 * Whether we should treat a property as a field for the purposes of the
467 * debugger.
468 */
469 static bool treatPropertyAsField(MethodMirror methodMirror) =>
470 (methodMirror.isGetter || methodMirror.isSetter) &&
471 (methodMirror.isSynthetic || _isSideEffectFreeGetter(methodMirror));
472
473 // TODO(jacobr): generate more concise function descriptions instead of
474 // dumping the entire function source.
475 static String describeFunction(function) {
476 if (function is _Trampoline) return function._methodMirror.source;
477 try {
478 return reflect(function).function.source;
479 } catch (e) {
480 return function.toString();
481 }
482 }
483
484 static List getInvocationTrampolineDetails(_Trampoline method) {
485 var loc = method._methodMirror.location;
486 return [loc.line, loc.column, loc.sourceUri.toString(),
487 MirrorSystem.getName(method._selector)];
488 }
489
490 static List getLibraryProperties(String libraryUrl, bool ownProperties,
491 bool accessorPropertiesOnly) {
492 var properties = new Map<String, _Property>();
493 var libraryMirror = getLibraryMirror(libraryUrl);
494 _addInstanceMirrors(libraryMirror, libraryMirror,
495 libraryMirror.declarations,
496 ownProperties, accessorPropertiesOnly, false, false,
497 properties);
498 if (!accessorPropertiesOnly) {
499 // We need to add class properties for all classes in the library.
500 libraryMirror.declarations.forEach((symbol, declarationMirror) {
501 if (declarationMirror is ClassMirror) {
278 var name = MirrorSystem.getName(symbol); 502 var name = MirrorSystem.getName(symbol);
279 if (mirror is MethodMirror && mirror.isSetter) 503 if (declarationMirror.hasReflectedType
280 name = name.substring(0, name.length - 1); 504 && !properties.containsKey(name)) {
281 completions.add(name); 505 properties[name] = new _Property(name)
506 ..value = declarationMirror.reflectedType;
507 }
282 } 508 }
283 }); 509 });
284 } 510 }
285 511 return packageProperties(properties);
286 addForClass(ClassMirror mirror, bool isStatic) { 512 }
287 if (mirror == null) 513
514 static List getObjectProperties(o, bool ownProperties,
515 bool accessorPropertiesOnly) {
516 var properties = new Map<String, _Property>();
517 var names = new Set<String>();
518 var objectMirror = reflect(o);
519 var classMirror = objectMirror.type;
520 _addInstanceMirrors(objectMirror, classMirror.owner,
521 classMirror.instanceMembers,
522 ownProperties, accessorPropertiesOnly, false, true,
523 properties);
524 return packageProperties(properties);
525 }
526
527 static List getObjectClassProperties(o, bool ownProperties,
528 bool accessorPropertiesOnly) {
529 var properties = new Map<String, _Property>();
530 var objectMirror = reflect(o);
531 var classMirror = objectMirror.type;
532 _addInstanceMirrors(objectMirror, classMirror.owner,
533 classMirror.instanceMembers,
534 ownProperties, accessorPropertiesOnly, true, false,
535 properties);
536 _addStatics(classMirror, properties, accessorPropertiesOnly);
537 return packageProperties(properties);
538 }
539
540 static List getClassProperties(Type t, bool ownProperties,
541 bool accessorPropertiesOnly) {
542 var properties = new Map<String, _Property>();
543 var classMirror = reflectClass(t);
544 _addStatics(classMirror, properties, accessorPropertiesOnly);
545 return packageProperties(properties);
546 }
547
548 static void _addStatics(ClassMirror classMirror,
549 Map<String, _Property> properties,
550 bool accessorPropertiesOnly) {
551 classMirror.declarations.forEach((symbol, declaration) {
552 var name = _getShortSymbolName(symbol, declaration);
553 if (declaration is VariableMirror) {
554 if (accessorPropertiesOnly) return;
555 if (!declaration.isStatic) return;
556 properties.putIfAbsent(name, () => new _Property(name))
557 ..value = classMirror.getField(symbol).reflectee
558 ..writable = declaration.isFinal && !declaration.isConst;
559 } else if (declaration is MethodMirror) {
560 MethodMirror methodMirror = declaration;
561 // FIXMEDART: should we display constructors?
562 if (methodMirror.isConstructor) return;
563 if (!methodMirror.isStatic) return;
564 if (accessorPropertiesOnly) {
565 if (methodMirror.isRegularMethod ||
566 treatPropertyAsField(methodMirror)) {
567 return;
568 }
569 } else if (!methodMirror.isRegularMethod &&
570 !treatPropertyAsField(methodMirror)) {
571 return;
572 }
573 var property = properties.putIfAbsent(name, () => new _Property(name));
574 if (methodMirror.isRegularMethod) {
575 property
576 ..value = new _MethodTrampoline(classMirror, methodMirror, symbol)
577 ..isMethod = true;
578 } else if (methodMirror.isGetter) {
579 if (treatPropertyAsField(methodMirror)) {
580 try {
581 property.value = classMirror.getField(symbol).reflectee;
582 } catch (e) {
583 property
584 ..wasThrown = true
585 ..value = e;
586 }
587 } else if (accessorPropertiesOnly) {
588 property.getter = new _GetterTrampoline(classMirror,
589 methodMirror, symbol);
590 }
591 } else if (methodMirror.isSetter) {
592 if (accessorPropertiesOnly && !treatPropertyAsField(methodMirror)) {
593 property.setter = new _SetterTrampoline(classMirror,
594 methodMirror, classMirror.owner);
595 }
596 property.writable = true;
597 }
598 }
599 });
600 }
601
602 /**
603 * Helper method that handles collecting up properties from classes
604 * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
605 * [hideFields], and [hideMethods] to determine which properties are
606 * collected. [accessorPropertiesOnly] specifies whether all properties
607 * should be returned or just accessors. [hideFields] specifies whether
608 * fields should be hidden. hideMethods specifies whether methods should be
609 * shown or hidden. [ownProperties] is not currently used but is part of the
610 * Blink devtools API for enumerating properties.
611 */
612 static void _addInstanceMirrors(
613 ObjectMirror objectMirror,
614 LibraryMirror libraryMirror,
615 Map<Symbol, Mirror> declarations,
616 bool ownProperties, bool accessorPropertiesOnly,
617 bool hideFields, bool hideMethods,
618 Map<String, _Property> properties) {
619 declarations.forEach((Symbol symbol, Mirror declaration) {
620 if (declaration is TypedefMirror || declaration is ClassMirror) return;
621 var name = _getShortSymbolName(symbol, declaration);
622 bool isField = declaration is VariableMirror ||
623 (declaration is MethodMirror && treatPropertyAsField(declaration));
624 if ((isField && hideFields) || (hideMethods && !isField)) return;
625 if (accessorPropertiesOnly) {
626 if (declaration is ClassMirror || declaration is VariableMirror ||
627 declaration.isRegularMethod || isField) {
628 return;
629 }
630 } else if (declaration is MethodMirror &&
631 (declaration.isGetter || declaration.isSetter) &&
632 !treatPropertyAsField(declaration)) {
288 return; 633 return;
289 addAll(mirror.declarations, isStatic); 634 }
290 if (mirror.superclass != null) 635 var property = properties.putIfAbsent(name, () => new _Property(name));
291 addForClass(mirror.superclass, isStatic); 636 if (declaration is VariableMirror) {
292 for (var interface in mirror.superinterfaces) { 637 property.value = objectMirror.getField(symbol).reflectee;
293 addForClass(interface, isStatic); 638 property.writable = !declaration.isFinal && !declaration.isConst;
294 } 639 } else if (declaration is ClassMirror) {
295 } 640 property.value = declaration.runtimeType;
296 641 } else if (declaration.isRegularMethod) {
297 if (o is Type) { 642 property.value = new _MethodTrampoline(objectMirror,
298 addForClass(reflectClass(o), true); 643 declaration, symbol);
299 } else { 644 property.isMethod = true;
300 addForClass(reflect(o).type, false); 645 } else if (declaration.isGetter) {
301 } 646 if (treatPropertyAsField(declaration)) {
302 return completions.toList(growable: false); 647 try {
303 } 648 property.value = objectMirror.getField(symbol).reflectee;
304 649 } catch (e) {
305 /** 650 property
306 * Convenience helper to get the keys of a [Map] as a [List]. 651 ..wasThrown = true
307 */ 652 ..value = e;
653 }
654 } else if (accessorPropertiesOnly) {
655 property.getter = new _GetterTrampoline(objectMirror,
656 declaration, symbol);
657 }
658 } else if (declaration.isSetter) {
659 property.writable = true;
660 if (accessorPropertiesOnly && !treatPropertyAsField(declaration)) {
661 property.setter = new _SetterTrampoline(objectMirror,
662 declaration, MirrorSystem.getSymbol(name, libraryMirror));
663 }
664 }
665 });
666 }
667
668 /**
669 * Flatten down the properties data structure into a List that is easy to
670 * access from native code.
671 */
672 static List packageProperties(Map<String, _Property> properties) {
673 var ret = [];
674 for (var property in properties.values) {
675 ret.addAll([property.name,
676 property.setter,
677 property.getter,
678 property.value,
679 property.hasValue,
680 property.writable,
681 property.isMethod,
682 property.isOwn,
683 property.wasThrown]);
684 }
685 return ret;
686 }
687
688 /**
689 * Get a property, returning null if the property does not exist.
690 * For private property names, we attempt to resolve the property in the
691 * context of each library that the property name could be associated with.
692 */
693 static getObjectPropertySafe(o, String propertyName) {
694 var objectMirror = reflect(o);
695 var classMirror = objectMirror.type;
696 if (propertyName.startsWith("_")) {
697 var attemptedLibraries = new Set<LibraryMirror>();
698 while (classMirror != null) {
699 LibraryMirror library = classMirror.owner;
700 if (!attemptedLibraries.contains(library)) {
701 try {
702 return objectMirror.getField(
703 MirrorSystem.getSymbol(propertyName, library)).reflectee;
704 } catch (e) { }
705 attemptedLibraries.add(library);
706 }
707 classMirror = classMirror.superclass;
708 }
709 return null;
710 }
711 try {
712 return objectMirror.getField(
713 MirrorSystem.getSymbol(propertyName)).reflectee;
714 } catch (e) {
715 return null;
716 }
717 }
718
719 /**
720 * Helper to wrap the inspect method on InjectedScriptHost to provide the
721 * inspect method required for the
722 */
723 static List consoleApi(host) {
724 return [
725 "inspect",
726 (o) {
727 host.inspect(o, null);
728 return o;
729 },
730 "dir",
731 window().console.dir,
732 "dirxml",
733 window().console.dirxml
734 // FIXME: add copy method.
735 ];
736 }
737
308 static List getMapKeyList(Map map) => map.keys.toList(); 738 static List getMapKeyList(Map map) => map.keys.toList();
309 739
310 /** 740 /**
311 * Returns the keys of an arbitrary Dart Map encoded as unique Strings. 741 * 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 742 * Keys that are strings are left unchanged except that the prefix ":" is
313 * added to disambiguate keys from other Dart members. 743 * 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 744 * 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 745 * 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 746 * decode. The use case for this method is displaying all map keys in a human
317 * readable way in debugging tools. 747 * readable way in debugging tools.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 _scheduleImmediateHelper._schedule(callback); 1026 _scheduleImmediateHelper._schedule(callback);
597 }; 1027 };
598 1028
599 get _pureIsolateScheduleImmediateClosure => ((void callback()) => 1029 get _pureIsolateScheduleImmediateClosure => ((void callback()) =>
600 throw new UnimplementedError("scheduleMicrotask in background isolates " 1030 throw new UnimplementedError("scheduleMicrotask in background isolates "
601 "are not supported in the browser")); 1031 "are not supported in the browser"));
602 1032
603 void _initializeCustomElement(Element e) { 1033 void _initializeCustomElement(Element e) {
604 _Utils.initializeCustomElement(e); 1034 _Utils.initializeCustomElement(e);
605 } 1035 }
OLDNEW
« tools/dom/idl/dart/dart.idl ('K') | « tools/dom/idl/dart/dart.idl ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698