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

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

Issue 1865803004: Add support for switching library from the chrome devtools console. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ptal Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sdk/lib/html/dartium/html_dartium.dart ('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 { 7 class _Property {
8 _Property(this.name) : 8 _Property(this.name)
9 _hasValue = false, 9 : _hasValue = false,
10 writable = false, 10 writable = false,
11 isMethod = false, 11 isMethod = false,
12 isOwn = true, 12 isOwn = true,
13 wasThrown = false; 13 wasThrown = false;
14 14
15 bool get hasValue => _hasValue; 15 bool get hasValue => _hasValue;
16 get value => _value; 16 get value => _value;
17 set value(v) { 17 set value(v) {
18 _value = v; 18 _value = v;
19 _hasValue = true; 19 _hasValue = true;
20 } 20 }
21 21
22 final String name; 22 final String name;
23 Function setter; 23 Function setter;
24 Function getter; 24 Function getter;
25 var _value; 25 var _value;
26 bool _hasValue; 26 bool _hasValue;
27 bool writable; 27 bool writable;
28 bool isMethod; 28 bool isMethod;
29 bool isOwn; 29 bool isOwn;
30 bool wasThrown; 30 bool wasThrown;
31 } 31 }
32 32
33 /**
34 * Manager for navigating between libraries from the devtools console.
35 */
36 class _LibraryManager {
37 /**
38 * Current active library
39 */
40 static var _currentLibrary;
41 static var _validCache = false;
42
43 static List<Uri> _libraryUris;
44
45 // List of all maps to check to determine if there is an exact match.
46 static Map<String, List<Uri>> _fastPaths;
47
48 static void _addFastPath(String key, Uri uri) {
49 _fastPaths.putIfAbsent(key, () => <Uri>[]).add(uri);
50 }
51
52 static cache() {
53 if (_validCache) return;
54 _validCache = true;
55 _libraryUris = <Uri>[];
56 _fastPaths = new Map<String, List<Uri>>();
57 var system = currentMirrorSystem();
58 system.libraries.forEach((uri, library) {
59 _libraryUris.add(uri);
60 _addFastPath(uri.toString(), uri);
61 _addFastPath(MirrorSystem.getName(library.simpleName), uri);
62 });
63 }
64
65 static String get currentLibrary {
66 if (_currentLibrary == null) {
67 _currentLibrary =
68 currentMirrorSystem().isolate.rootLibrary.uri.toString();
69 }
70 return _currentLibrary;
71 }
72
73 /**
74 * Find libraries matching a given name.
75 *
76 * Uses heuristics to only return a single match when the user intent is
77 * generally unambiguous.
78 */
79 static List<Uri> findMatches(String name) {
80 cache();
81 var nameAsFile = name.endsWith('.dart') ? name : '${name}.dart';
82 // Perfect match first.
83 var fastPatchMatches = _fastPaths[name];
84 if (fastPatchMatches != null) {
85 return fastPatchMatches.toList();
86 }
87
88 // Exact match for file path.
89 var matches = new LinkedHashSet<Uri>();
90 for (var uri in _libraryUris) {
91 if (uri.path == name || uri.path == nameAsFile) matches.add(uri);
92 }
93 if (matches.isNotEmpty) return matches.toList();
94
95 // Exact match for file name.
96 if (name != nameAsFile) {
97 for (var uri in _libraryUris) {
98 if (uri.pathSegments.isNotEmpty &&
99 (uri.pathSegments.last == nameAsFile)) {
100 matches.add(uri);
101 }
102 }
103 if (matches.isNotEmpty) return matches.toList();
104 }
105
106 for (var uri in _libraryUris) {
107 if (uri.pathSegments.isNotEmpty && (uri.pathSegments.last == name)) {
108 matches.add(uri);
109 }
110 }
111 if (matches.isNotEmpty) return matches.toList();
112
113 // Partial match on path.
114 for (var uri in _libraryUris) {
115 if (uri.path.contains(name)) {
116 matches.add(uri);
117 }
118 }
119 if (matches.isNotEmpty) return matches.toList();
120
121 // Partial match on entire uri.
122 for (var uri in _libraryUris) {
123 if (uri.toString().contains(name)) {
124 matches.add(uri);
125 }
126 }
127
128 if (matches.isNotEmpty) return matches.toList();
129
130 // Partial match on entire uri ignoring case.
131 name = name.toLowerCase();
132 for (var uri in _libraryUris) {
133 if (uri.toString().toLowerCase().contains(name)) {
134 matches.add(uri);
135 }
136 }
137 return matches.toList();
138 }
139
140 static setLibrary([String name]) {
141 // Bust cache in case library list has changed. Ideally we would listen for
142 // when libraries are loaded and invalidate based on that.
143 _validCache = false;
144 cache();
145 if (name == null) {
146 window.console
147 ..group("Current library: $_currentLibrary")
148 ..groupCollapsed("All libraries:");
149 _listLibraries();
150 window.console..groupEnd()..groupEnd();
151 return;
152 }
153 var matches = findMatches(name);
154 if (matches.length != 1) {
155 if (matches.length > 1) {
156 window.console.warn("Ambiguous library name: $name");
157 }
158 showMatches(name, matches);
159 return;
160 }
161 _currentLibrary = matches.first.toString();
162 window.console.log("Set library to $_currentLibrary");
163 }
164
165 static getLibrary() {
166 return currentLibrary;
167 }
168
169 static List<Uri> _sortUris(Iterable<Uri> uris) {
170 return (uris.toList())
171 ..sort((Uri a, Uri b) {
172 if (a.scheme != b.scheme) {
173 if (a.scheme == 'dart') return -1;
174 if (b.scheme == 'dart') return 1;
175 return a.scheme.compareTo(b.scheme);
176 }
177 return a.toString().compareTo(b.toString());
178 });
179 }
180
181 static void listLibraries() {
182 _validCache = false;
183 cache();
184 _listLibraries();
185 }
186
187 static void _listLibraries() {
188 window.console.log(_sortUris(_libraryUris).join("\n"));
189 }
190
191 // Workaround to allow calling console.log with an arbitrary number of
192 // arguments.
193 static void _log(List<String> args) {
194 js.JsNative.callMethod(window.console, 'log', args);
195 }
196
197 static showMatches(String key, Iterable<Uri> uris) {
198 var boldPairs = [];
199 var sb = new StringBuffer();
200 if (uris.isEmpty) {
201 window.console.group("All libraries:");
202 _listLibraries();
203 window.console
204 ..groupEnd()
205 ..error("No library names or URIs match '$key'");
206 return;
207 }
208 sb.write("${uris.length} matches\n");
209 var lowerCaseKey = key.toLowerCase();
210 for (var uri in uris) {
211 var txt = uri.toString();
212 int index = txt.toLowerCase().indexOf(lowerCaseKey);
213 if (index != -1) {
214 // %c enables styling console log messages with css
215 // specified at the end of the console.
216 sb..write(txt.substring(0, index))..write('%c');
217 var matchEnd = index + key.length;
218 sb
219 ..write(txt.substring(index, matchEnd))
220 ..write('%c')
221 ..write(txt.substring(matchEnd))
222 ..write('\n');
223 boldPairs..add('font-weight: bold')..add('font-weight: normal');
224 }
225 }
226 _log([sb.toString()]..addAll(boldPairs));
227 }
228 }
229
33 class _ConsoleVariables { 230 class _ConsoleVariables {
34 Map<String, Object> _data = new Map<String, Object>(); 231 Map<String, Object> _data = new Map<String, Object>();
35 232
36 /** 233 /**
37 * Forward member accesses to the backing JavaScript object. 234 * Forward member accesses to the backing JavaScript object.
38 */ 235 */
39 noSuchMethod(Invocation invocation) { 236 noSuchMethod(Invocation invocation) {
40 String member = MirrorSystem.getName(invocation.memberName); 237 String member = MirrorSystem.getName(invocation.memberName);
41 if (invocation.isGetter) { 238 if (invocation.isGetter) {
42 return _data[member]; 239 return _data[member];
(...skipping 25 matching lines...) Expand all
68 */ 265 */
69 abstract class _Trampoline implements Function { 266 abstract class _Trampoline implements Function {
70 final ObjectMirror _receiver; 267 final ObjectMirror _receiver;
71 final MethodMirror _methodMirror; 268 final MethodMirror _methodMirror;
72 final Symbol _selector; 269 final Symbol _selector;
73 270
74 _Trampoline(this._receiver, this._methodMirror, this._selector); 271 _Trampoline(this._receiver, this._methodMirror, this._selector);
75 } 272 }
76 273
77 class _MethodTrampoline extends _Trampoline { 274 class _MethodTrampoline extends _Trampoline {
78 _MethodTrampoline(ObjectMirror receiver, MethodMirror methodMirror, 275 _MethodTrampoline(
79 Symbol selector) : 276 ObjectMirror receiver, MethodMirror methodMirror, Symbol selector)
80 super(receiver, methodMirror, selector); 277 : super(receiver, methodMirror, selector);
81 278
82 noSuchMethod(Invocation msg) { 279 noSuchMethod(Invocation msg) {
83 if (msg.memberName != #call) return super.noSuchMethod(msg); 280 if (msg.memberName != #call) return super.noSuchMethod(msg);
84 return _receiver.invoke(_selector, 281 return _receiver
85 msg.positionalArguments, 282 .invoke(_selector, msg.positionalArguments, msg.namedArguments)
86 msg.namedArguments).reflectee; 283 .reflectee;
87 } 284 }
88 } 285 }
89 286
90 /** 287 /**
91 * Invocation trampoline class used to closurize getters. 288 * Invocation trampoline class used to closurize getters.
92 */ 289 */
93 class _GetterTrampoline extends _Trampoline { 290 class _GetterTrampoline extends _Trampoline {
94 _GetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror, 291 _GetterTrampoline(
95 Symbol selector) : 292 ObjectMirror receiver, MethodMirror methodMirror, Symbol selector)
96 super(receiver, methodMirror, selector); 293 : super(receiver, methodMirror, selector);
97 294
98 call() => _receiver.getField(_selector).reflectee; 295 call() => _receiver.getField(_selector).reflectee;
99 } 296 }
100 297
101 /** 298 /**
102 * Invocation trampoline class used to closurize setters. 299 * Invocation trampoline class used to closurize setters.
103 */ 300 */
104 class _SetterTrampoline extends _Trampoline { 301 class _SetterTrampoline extends _Trampoline {
105 _SetterTrampoline(ObjectMirror receiver, MethodMirror methodMirror, 302 _SetterTrampoline(
106 Symbol selector) : 303 ObjectMirror receiver, MethodMirror methodMirror, Symbol selector)
107 super(receiver, methodMirror, selector); 304 : super(receiver, methodMirror, selector);
108 305
109 call(value) { 306 call(value) {
110 _receiver.setField(_selector, value); 307 _receiver.setField(_selector, value);
111 } 308 }
112 } 309 }
113 310
114 class _Utils { 311 class _Utils {
115 static double dateTimeToDouble(DateTime dateTime) => 312 static double dateTimeToDouble(DateTime dateTime) =>
116 dateTime.millisecondsSinceEpoch.toDouble(); 313 dateTime.millisecondsSinceEpoch.toDouble();
117 static DateTime doubleToDateTime(double dateTime) { 314 static DateTime doubleToDateTime(double dateTime) {
118 try { 315 try {
119 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt()); 316 return new DateTime.fromMillisecondsSinceEpoch(dateTime.toInt());
120 } catch(_) { 317 } catch (_) {
121 // TODO(antonnm): treat exceptions properly in bindings and 318 // TODO(antonnm): treat exceptions properly in bindings and
122 // find out how to treat NaNs. 319 // find out how to treat NaNs.
123 return null; 320 return null;
124 } 321 }
125 } 322 }
126 323
127 static List convertToList(List list) { 324 static List convertToList(List list) {
128 // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it. 325 // FIXME: [possible optimization]: do not copy the array if Dart_IsArray is fine w/ it.
129 final length = list.length; 326 final length = list.length;
130 List result = new List(length); 327 List result = new List(length);
(...skipping 24 matching lines...) Expand all
155 result[list[i]] = list[i + 1]; 352 result[list[i]] = list[i + 1];
156 } 353 }
157 } 354 }
158 355
159 static bool isMap(obj) => obj is Map; 356 static bool isMap(obj) => obj is Map;
160 357
161 static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null; 358 static List toListIfIterable(obj) => obj is Iterable ? obj.toList() : null;
162 359
163 static Map createMap() => {}; 360 static Map createMap() => {};
164 361
165 static parseJson(String jsonSource) => const JsonDecoder().convert(jsonSource) ; 362 static parseJson(String jsonSource) =>
363 const JsonDecoder().convert(jsonSource);
364
365 static String getLibraryUrl() => _LibraryManager.currentLibrary;
166 366
167 static makeUnimplementedError(String fileName, int lineNo) { 367 static makeUnimplementedError(String fileName, int lineNo) {
168 return new UnsupportedError('[info: $fileName:$lineNo]'); 368 return new UnsupportedError('[info: $fileName:$lineNo]');
169 } 369 }
170 370
171 static bool isTypeSubclassOf(Type type, Type other) { 371 static bool isTypeSubclassOf(Type type, Type other) {
172 if (type == other) { 372 if (type == other) {
173 return true; 373 return true;
174 } 374 }
175 var superclass = reflectClass(type).superclass; 375 var superclass = reflectClass(type).superclass;
176 if (superclass != null) { 376 if (superclass != null) {
177 return isTypeSubclassOf(superclass.reflectedType, other); 377 return isTypeSubclassOf(superclass.reflectedType, other);
178 } 378 }
179 return false; 379 return false;
180 } 380 }
181 381
182 static Element getAndValidateNativeType(Type type, String tagName) { 382 static Element getAndValidateNativeType(Type type, String tagName) {
183 var element = new Element.tag(tagName); 383 var element = new Element.tag(tagName);
184 if (!isTypeSubclassOf(type, element.runtimeType)) { 384 if (!isTypeSubclassOf(type, element.runtimeType)) {
185 return null; 385 return null;
186 } 386 }
187 return element; 387 return element;
188 } 388 }
189 389
190 static forwardingPrint(String message) => _blink.Blink_Utils.forwardingPrint(m essage); 390 static forwardingPrint(String message) =>
391 _blink.Blink_Utils.forwardingPrint(message);
191 static void spawnDomHelper(Function f, int replyTo) => 392 static void spawnDomHelper(Function f, int replyTo) =>
192 _blink.Blink_Utils.spawnDomHelper(f, replyTo); 393 _blink.Blink_Utils.spawnDomHelper(f, replyTo);
193 394
194 // TODO(vsm): Make this API compatible with spawnUri. It should also 395 // TODO(vsm): Make this API compatible with spawnUri. It should also
195 // return a Future<Isolate>. 396 // return a Future<Isolate>.
196 // TODO(jacobr): IS THIS RIGHT? I worry we have broken conversion from Promise to Future. 397 // TODO(jacobr): IS THIS RIGHT? I worry we have broken conversion from Promise to Future.
197 static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri); 398 static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri);
198 399
199 // The following methods were added for debugger integration to make working 400 // The following methods were added for debugger integration to make working
200 // with the Dart C mirrors API simpler. 401 // with the Dart C mirrors API simpler.
(...skipping 12 matching lines...) Expand all
213 414
214 /** 415 /**
215 * Takes a list containing variable names and corresponding values and 416 * Takes a list containing variable names and corresponding values and
216 * returns a map from normalized names to values. Variable names are assumed 417 * returns a map from normalized names to values. Variable names are assumed
217 * to have list offsets 2*n values at offset 2*n+1. This method is required 418 * to have list offsets 2*n values at offset 2*n+1. This method is required
218 * because Dart_GetLocalVariables returns a list instead of an object that 419 * because Dart_GetLocalVariables returns a list instead of an object that
219 * can be queried to lookup names and values. 420 * can be queried to lookup names and values.
220 */ 421 */
221 static Map<String, dynamic> createLocalVariablesMap(List localVariables) { 422 static Map<String, dynamic> createLocalVariablesMap(List localVariables) {
222 var map = {}; 423 var map = {};
223 for (int i = 0; i < localVariables.length; i+=2) { 424 for (int i = 0; i < localVariables.length; i += 2) {
224 map[stripMemberName(localVariables[i])] = localVariables[i+1]; 425 map[stripMemberName(localVariables[i])] = localVariables[i + 1];
225 } 426 }
226 return map; 427 return map;
227 } 428 }
228 429
229 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables(); 430 static _ConsoleVariables _consoleTempVariables = new _ConsoleVariables();
230 431
231 /** 432 /**
232 * Takes an [expression] and a list of [local] variable and returns an 433 * Takes an [expression] and a list of [local] variable and returns an
233 * expression for a closure with a body matching the original expression 434 * expression for a closure with a body matching the original expression
234 * where locals are passed in as arguments. Returns a list containing the 435 * where locals are passed in as arguments. Returns a list containing the
235 * String expression for the closure and the list of arguments that should 436 * String expression for the closure and the list of arguments that should
236 * be passed to it. The expression should then be evaluated using 437 * be passed to it. The expression should then be evaluated using
237 * Dart_EvaluateExpr which will generate a closure that should be invoked 438 * Dart_EvaluateExpr which will generate a closure that should be invoked
238 * with the list of arguments passed to this method. 439 * with the list of arguments passed to this method.
239 * 440 *
240 * For example: 441 * For example:
241 * <code> 442 * <code>
242 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue} 443 * _consoleTempVariables = {'a' : someValue, 'b': someOtherValue}
243 * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true) 444 * wrapExpressionAsClosure("foo + bar + a", ["bar", 40, "foo", 2], true)
244 * </code> 445 * </code>
245 * will return: 446 * will return:
246 * <code> 447 * <code>
247 * ["""(final $consoleVariables, final bar, final foo, final a, final b) => 448 * ["""(final $consoleVariables, final bar, final foo, final a, final b) =>
248 * (foo + bar + a 449 * (foo + bar + a
249 * )""", 450 * )""",
250 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]] 451 * [_consoleTempVariables, 40, 2, someValue, someOtherValue]]
251 * </code> 452 * </code>
252 */ 453 */
253 static List wrapExpressionAsClosure(String expression, List locals, 454 static List wrapExpressionAsClosure(
254 bool includeCommandLineAPI) { 455 String expression, List locals, bool includeCommandLineAPI) {
255 var args = {}; 456 var args = {};
256 var sb = new StringBuffer("("); 457 var sb = new StringBuffer("(");
257 addArg(arg, value) { 458 addArg(arg, value) {
258 arg = stripMemberName(arg); 459 arg = stripMemberName(arg);
259 if (args.containsKey(arg)) return; 460 if (args.containsKey(arg)) return;
260 // We ignore arguments with the name 'this' rather than throwing an 461 // We ignore arguments with the name 'this' rather than throwing an
261 // exception because Dart_GetLocalVariables includes 'this' and it 462 // exception because Dart_GetLocalVariables includes 'this' and it
262 // is more convenient to filter it out here than from C++ code. 463 // is more convenient to filter it out here than from C++ code.
263 // 'this' needs to be handled by calling Dart_EvaluateExpr with 464 // 'this' needs to be handled by calling Dart_EvaluateExpr with
264 // 'this' as the target rather than by passing it as an argument. 465 // 'this' as the target rather than by passing it as an argument.
(...skipping 14 matching lines...) Expand all
279 // FIXME: use a real Dart tokenizer. The following regular expressions 480 // FIXME: use a real Dart tokenizer. The following regular expressions
280 // only allow setting variables at the immediate start of the expression 481 // only allow setting variables at the immediate start of the expression
281 // to limit the number of edge cases we have to handle. 482 // to limit the number of edge cases we have to handle.
282 483
283 // Match expressions that start with "var x" 484 // Match expressions that start with "var x"
284 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)"); 485 final _VARIABLE_DECLARATION = new RegExp("^(\\s*)var\\s+(\\w+)");
285 // Match expressions that start with "someExistingConsoleVar =" 486 // Match expressions that start with "someExistingConsoleVar ="
286 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)"); 487 final _SET_VARIABLE = new RegExp("^(\\s*)(\\w+)(\\s*=)");
287 // Match trailing semicolons. 488 // Match trailing semicolons.
288 final _ENDING_SEMICOLONS = new RegExp("(;\\s*)*\$"); 489 final _ENDING_SEMICOLONS = new RegExp("(;\\s*)*\$");
289 expression = expression.replaceAllMapped(_VARIABLE_DECLARATION, 490 expression = expression.replaceAllMapped(_VARIABLE_DECLARATION, (match) {
290 (match) { 491 var variableName = match[2];
291 var variableName = match[2]; 492 // Set the console variable if it isn't already set.
292 // Set the console variable if it isn't already set. 493 if (!_consoleTempVariables._data.containsKey(variableName)) {
293 if (!_consoleTempVariables._data.containsKey(variableName)) { 494 _consoleTempVariables._data[variableName] = null;
294 _consoleTempVariables._data[variableName] = null; 495 }
295 } 496 return "${match[1]}\$consoleVariables.${variableName}";
296 return "${match[1]}\$consoleVariables.${variableName}"; 497 });
297 });
298 498
299 expression = expression.replaceAllMapped(_SET_VARIABLE, 499 expression = expression.replaceAllMapped(_SET_VARIABLE, (match) {
300 (match) { 500 var variableName = match[2];
301 var variableName = match[2]; 501 // Only rewrite if the name matches an existing console variable.
302 // Only rewrite if the name matches an existing console variable. 502 if (_consoleTempVariables._data.containsKey(variableName)) {
303 if (_consoleTempVariables._data.containsKey(variableName)) { 503 return "${match[1]}\$consoleVariables.${variableName}${match[3]}";
304 return "${match[1]}\$consoleVariables.${variableName}${match[3]}"; 504 } else {
305 } else { 505 return match[0];
306 return match[0]; 506 }
307 } 507 });
308 });
309 508
310 // We only allow dart expressions not Dart statements. Silently remove 509 // We only allow dart expressions not Dart statements. Silently remove
311 // trailing semicolons the user might have added by accident to reduce the 510 // trailing semicolons the user might have added by accident to reduce the
312 // number of spurious compile errors. 511 // number of spurious compile errors.
313 expression = expression.replaceFirst(_ENDING_SEMICOLONS, ""); 512 expression = expression.replaceFirst(_ENDING_SEMICOLONS, "");
314 } 513 }
315 514
316 if (locals != null) { 515 if (locals != null) {
317 for (int i = 0; i < locals.length; i+= 2) { 516 for (int i = 0; i < locals.length; i += 2) {
318 addArg(locals[i], locals[i+1]); 517 addArg(locals[i], locals[i + 1]);
319 } 518 }
320 } 519 }
321 // Inject all the already defined console variables. 520 // Inject all the already defined console variables.
322 _consoleTempVariables._data.forEach(addArg); 521 _consoleTempVariables._data.forEach(addArg);
323 522
324 // TODO(jacobr): remove the parentheses around the expresson once 523 // TODO(jacobr): remove the parentheses around the expresson once
325 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses 524 // dartbug.com/13723 is fixed. Currently we wrap expression in parentheses
326 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM 525 // to ensure only valid Dart expressions are allowed. Otherwise the DartVM
327 // quietly ignores trailing Dart statements resulting in user confusion 526 // quietly ignores trailing Dart statements resulting in user confusion
328 // when part of an invalid expression they entered is ignored. 527 // when part of an invalid expression they entered is ignored.
329 sb..write(') => (\n$expression\n)'); 528 sb..write(') => (\n$expression\n)');
330 return [sb.toString(), args.values.toList(growable: false)]; 529 return [sb.toString(), args.values.toList(growable: false)];
331 } 530 }
332 531
333 static String _getShortSymbolName(Symbol symbol, 532 static String _getShortSymbolName(
334 DeclarationMirror declaration) { 533 Symbol symbol, DeclarationMirror declaration) {
335 var name = MirrorSystem.getName(symbol); 534 var name = MirrorSystem.getName(symbol);
336 if (declaration is MethodMirror) { 535 if (declaration is MethodMirror) {
337 if (declaration.isSetter && name[name.length-1] == "=") { 536 if (declaration.isSetter && name[name.length - 1] == "=") {
338 return name.substring(0, name.length-1); 537 return name.substring(0, name.length - 1);
339 } 538 }
340 if (declaration.isConstructor) { 539 if (declaration.isConstructor) {
341 return name.substring(name.indexOf('.') + 1); 540 return name.substring(name.indexOf('.') + 1);
342 } 541 }
343 } 542 }
344 return name; 543 return name;
345 } 544 }
346 545
347 /** 546 /**
547 * Handle special console commands such as $lib and $libs that should not be
548 * evaluated as Dart expressions and instead should be interpreted directly.
549 * Commands supported:
550 * library <-- shows the current library and lists all libraries.
551 * library "library_uri" <-- select a specific library
552 * library "library_uri_fragment"
553 */
554 static bool maybeHandleSpecialConsoleCommand(String expression) {
555 expression = expression.trim();
556 var setLibraryCommand = r'library ';
557 if (expression == r'library') {
558 _LibraryManager.setLibrary();
559 return true;
560 }
561 if (expression.startsWith(setLibraryCommand)) {
562 expression = expression.substring(setLibraryCommand.length);
563 if (expression.length >= 2) {
564 String start = expression[0];
565 String end = expression[expression.length - 1];
566 // TODO(jacobr): maybe we should require quotes.
567 if ((start == "'" && end == "'") || (start == '"' && end == '"')) {
568 expression = expression.substring(1, expression.length - 1);
569 }
570 }
571
572 _LibraryManager.setLibrary(expression);
573 return true;
574 }
575 return false;
576 }
577
578 /**
348 * Returns a list of completions to use if the receiver is o. 579 * Returns a list of completions to use if the receiver is o.
349 */ 580 */
350 static List<String> getCompletions(o) { 581 static List<String> getCompletions(o) {
351 MirrorSystem system = currentMirrorSystem(); 582 MirrorSystem system = currentMirrorSystem();
352 var completions = new Set<String>(); 583 var completions = new Set<String>();
353 addAll(Map<Symbol, dynamic> map, bool isStatic) { 584 addAll(Map<Symbol, dynamic> map, bool isStatic) {
354 map.forEach((symbol, mirror) { 585 map.forEach((symbol, mirror) {
355 if (mirror.isStatic == isStatic && !mirror.isPrivate) { 586 if (mirror.isStatic == isStatic && !mirror.isPrivate) {
356 var name = MirrorSystem.getName(symbol); 587 var name = MirrorSystem.getName(symbol);
357 if (mirror is MethodMirror && mirror.isSetter) 588 if (mirror is MethodMirror && mirror.isSetter) name =
358 name = name.substring(0, name.length - 1); 589 name.substring(0, name.length - 1);
359 completions.add(name); 590 completions.add(name);
360 } 591 }
361 }); 592 });
362 } 593 }
363 594
364 addForClass(ClassMirror mirror, bool isStatic) { 595 addForClass(ClassMirror mirror, bool isStatic) {
365 if (mirror == null) 596 if (mirror == null) return;
366 return;
367 addAll(mirror.declarations, isStatic); 597 addAll(mirror.declarations, isStatic);
368 if (mirror.superclass != null) 598 if (mirror.superclass != null) addForClass(mirror.superclass, isStatic);
369 addForClass(mirror.superclass, isStatic);
370 for (var interface in mirror.superinterfaces) { 599 for (var interface in mirror.superinterfaces) {
371 addForClass(interface, isStatic); 600 addForClass(interface, isStatic);
372 } 601 }
373 } 602 }
374 603
375 if (o is Type) { 604 if (o is Type) {
376 addForClass(reflectClass(o), true); 605 addForClass(reflectClass(o), true);
377 } else { 606 } else {
378 addForClass(reflect(o).type, false); 607 addForClass(reflect(o).type, false);
379 } 608 }
380 return completions.toList(growable: false); 609 return completions.toList(growable: false);
381 } 610 }
382 611
383 /** 612 /**
384 * Adds all candidate String completitions from [declarations] to [output] 613 * Adds all candidate String completitions from [declarations] to [output]
385 * filtering based on [staticContext] and [includePrivate]. 614 * filtering based on [staticContext] and [includePrivate].
386 */ 615 */
387 static void _getCompletionsHelper(ClassMirror classMirror, 616 static void _getCompletionsHelper(ClassMirror classMirror, bool staticContext,
388 bool staticContext, LibraryMirror libraryMirror, Set<String> output) { 617 LibraryMirror libraryMirror, Set<String> output) {
389 bool includePrivate = libraryMirror == classMirror.owner; 618 bool includePrivate = libraryMirror == classMirror.owner;
390 classMirror.declarations.forEach((symbol, declaration) { 619 classMirror.declarations.forEach((symbol, declaration) {
391 if (!includePrivate && declaration.isPrivate) return; 620 if (!includePrivate && declaration.isPrivate) return;
392 if (declaration is VariableMirror) { 621 if (declaration is VariableMirror) {
393 if (staticContext != declaration.isStatic) return; 622 if (staticContext != declaration.isStatic) return;
394 } else if (declaration is MethodMirror) { 623 } else if (declaration is MethodMirror) {
395 if (declaration.isOperator) return; 624 if (declaration.isOperator) return;
396 if (declaration.isConstructor) { 625 if (declaration.isConstructor) {
397 if (!staticContext) return; 626 if (!staticContext) return;
398 var name = MirrorSystem.getName(declaration.constructorName); 627 var name = MirrorSystem.getName(declaration.constructorName);
399 if (name.isNotEmpty) output.add(name); 628 if (name.isNotEmpty) output.add(name);
400 return; 629 return;
401 } 630 }
402 if (staticContext != declaration.isStatic) return; 631 if (staticContext != declaration.isStatic) return;
403 } else if (declaration is TypeMirror) { 632 } else if (declaration is TypeMirror) {
404 return; 633 return;
405 } 634 }
406 output.add(_getShortSymbolName(symbol, declaration)); 635 output.add(_getShortSymbolName(symbol, declaration));
407 }); 636 });
408 637
409 if (!staticContext) { 638 if (!staticContext) {
410 for (var interface in classMirror.superinterfaces) { 639 for (var interface in classMirror.superinterfaces) {
411 _getCompletionsHelper(interface, staticContext, 640 _getCompletionsHelper(interface, staticContext, libraryMirror, output);
412 libraryMirror, output);
413 } 641 }
414 if (classMirror.superclass != null) { 642 if (classMirror.superclass != null) {
415 _getCompletionsHelper(classMirror.superclass, staticContext, 643 _getCompletionsHelper(
416 libraryMirror, output); 644 classMirror.superclass, staticContext, libraryMirror, output);
417 } 645 }
418 } 646 }
419 } 647 }
420 648
421 static void _getLibraryCompletionsHelper( 649 static void _getLibraryCompletionsHelper(
422 LibraryMirror library, bool includePrivate, Set<String> output) { 650 LibraryMirror library, bool includePrivate, Set<String> output) {
423 library.declarations.forEach((symbol, declaration) { 651 library.declarations.forEach((symbol, declaration) {
424 if (!includePrivate && declaration.isPrivate) return; 652 if (!includePrivate && declaration.isPrivate) return;
425 output.add(_getShortSymbolName(symbol, declaration)); 653 output.add(_getShortSymbolName(symbol, declaration));
426 }); 654 });
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 _getLibraryCompletionsHelper(dependency.targetLibrary, false, names); 701 _getLibraryCompletionsHelper(dependency.targetLibrary, false, names);
474 } else { 702 } else {
475 names.add(MirrorSystem.getName(dependency.prefix)); 703 names.add(MirrorSystem.getName(dependency.prefix));
476 } 704 }
477 } 705 }
478 } 706 }
479 return names.toList(); 707 return names.toList();
480 } 708 }
481 709
482 static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>() 710 static final SIDE_EFFECT_FREE_LIBRARIES = new Set<String>()
483 ..add('dart:html') 711 ..add('dart:html')
484 ..add('dart:indexed_db') 712 ..add('dart:indexed_db')
485 ..add('dart:svg') 713 ..add('dart:svg')
486 ..add('dart:typed_data') 714 ..add('dart:typed_data')
487 ..add('dart:web_audio') 715 ..add('dart:web_audio')
488 ..add('dart:web_gl') 716 ..add('dart:web_gl')
489 ..add('dart:web_sql'); 717 ..add('dart:web_sql');
490 718
491 static LibraryMirror _getLibrary(MethodMirror methodMirror) { 719 static LibraryMirror _getLibrary(MethodMirror methodMirror) {
492 var owner = methodMirror.owner; 720 var owner = methodMirror.owner;
493 if (owner is ClassMirror) { 721 if (owner is ClassMirror) {
494 return owner; 722 return owner;
495 } else if (owner is LibraryMirror) { 723 } else if (owner is LibraryMirror) {
496 return owner; 724 return owner;
497 } 725 }
498 return null; 726 return null;
499 } 727 }
500 728
501 /** 729 /**
502 * For parity with the JavaScript debugger, we treat some getters as if 730 * For parity with the JavaScript debugger, we treat some getters as if
503 * they are fields so that users can see their values immediately. 731 * they are fields so that users can see their values immediately.
504 * This matches JavaScript's behavior for getters on DOM objects. 732 * This matches JavaScript's behavior for getters on DOM objects.
505 * In the future we should consider adding an annotation to tag getters 733 * In the future we should consider adding an annotation to tag getters
506 * in user libraries as side effect free. 734 * in user libraries as side effect free.
507 */ 735 */
508 static bool _isSideEffectFreeGetter(MethodMirror methodMirror, 736 static bool _isSideEffectFreeGetter(
509 LibraryMirror libraryMirror) { 737 MethodMirror methodMirror, LibraryMirror libraryMirror) {
510 // This matches JavaScript behavior. We should consider displaying 738 // This matches JavaScript behavior. We should consider displaying
511 // getters for all dart platform libraries rather than just the DOM 739 // getters for all dart platform libraries rather than just the DOM
512 // libraries. 740 // libraries.
513 return libraryMirror.uri.scheme == 'dart' && 741 return libraryMirror.uri.scheme == 'dart' &&
514 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString()); 742 SIDE_EFFECT_FREE_LIBRARIES.contains(libraryMirror.uri.toString());
515 } 743 }
516 744
517 /** 745 /**
518 * Whether we should treat a property as a field for the purposes of the 746 * Whether we should treat a property as a field for the purposes of the
519 * debugger. 747 * debugger.
520 */ 748 */
521 static bool treatPropertyAsField(MethodMirror methodMirror, 749 static bool treatPropertyAsField(
522 LibraryMirror libraryMirror) { 750 MethodMirror methodMirror, LibraryMirror libraryMirror) {
523 return (methodMirror.isGetter || methodMirror.isSetter) && 751 return (methodMirror.isGetter || methodMirror.isSetter) &&
524 (methodMirror.isSynthetic || 752 (methodMirror.isSynthetic ||
525 _isSideEffectFreeGetter(methodMirror,libraryMirror)); 753 _isSideEffectFreeGetter(methodMirror, libraryMirror));
526 } 754 }
527 755
528 // TODO(jacobr): generate more concise function descriptions instead of 756 // TODO(jacobr): generate more concise function descriptions instead of
529 // dumping the entire function source. 757 // dumping the entire function source.
530 static String describeFunction(function) { 758 static String describeFunction(function) {
531 if (function is _Trampoline) return function._methodMirror.source; 759 if (function is _Trampoline) return function._methodMirror.source;
532 try { 760 try {
533 var mirror = reflect(function); 761 var mirror = reflect(function);
534 return mirror.function.source; 762 return mirror.function.source;
535 } catch (e) { 763 } catch (e) {
536 return function.toString(); 764 return function.toString();
537 } 765 }
538 } 766 }
539 767
540 static List getInvocationTrampolineDetails(_Trampoline method) { 768 static List getInvocationTrampolineDetails(_Trampoline method) {
541 var loc = method._methodMirror.location; 769 var loc = method._methodMirror.location;
542 return [loc.line, loc.column, loc.sourceUri.toString(), 770 return [
543 MirrorSystem.getName(method._selector)]; 771 loc.line,
772 loc.column,
773 loc.sourceUri.toString(),
774 MirrorSystem.getName(method._selector)
775 ];
544 } 776 }
545 777
546 static List getLibraryProperties(String libraryUrl, bool ownProperties, 778 static List getLibraryProperties(
547 bool accessorPropertiesOnly) { 779 String libraryUrl, bool ownProperties, bool accessorPropertiesOnly) {
548 var properties = new Map<String, _Property>(); 780 var properties = new Map<String, _Property>();
549 var libraryMirror = getLibraryMirror(libraryUrl); 781 var libraryMirror = getLibraryMirror(libraryUrl);
550 _addInstanceMirrors(libraryMirror, libraryMirror, 782 _addInstanceMirrors(
783 libraryMirror,
784 libraryMirror,
551 libraryMirror.declarations, 785 libraryMirror.declarations,
552 ownProperties, accessorPropertiesOnly, false, false, 786 ownProperties,
787 accessorPropertiesOnly,
788 false,
789 false,
553 properties); 790 properties);
554 if (!accessorPropertiesOnly) { 791 if (!accessorPropertiesOnly) {
555 // We need to add class properties for all classes in the library. 792 // We need to add class properties for all classes in the library.
556 libraryMirror.declarations.forEach((symbol, declarationMirror) { 793 libraryMirror.declarations.forEach((symbol, declarationMirror) {
557 if (declarationMirror is ClassMirror) { 794 if (declarationMirror is ClassMirror) {
558 var name = MirrorSystem.getName(symbol); 795 var name = MirrorSystem.getName(symbol);
559 if (declarationMirror.hasReflectedType 796 if (declarationMirror.hasReflectedType &&
560 && !properties.containsKey(name)) { 797 !properties.containsKey(name)) {
561 properties[name] = new _Property(name) 798 properties[name] = new _Property(name)
562 ..value = declarationMirror.reflectedType; 799 ..value = declarationMirror.reflectedType;
563 } 800 }
564 } 801 }
565 }); 802 });
566 } 803 }
567 return packageProperties(properties); 804 return packageProperties(properties);
568 } 805 }
569 806
570 static List getObjectProperties(o, bool ownProperties, 807 static List getObjectProperties(
571 bool accessorPropertiesOnly) { 808 o, bool ownProperties, bool accessorPropertiesOnly) {
572 var properties = new Map<String, _Property>(); 809 var properties = new Map<String, _Property>();
573 var names = new Set<String>(); 810 var names = new Set<String>();
574 var objectMirror = reflect(o); 811 var objectMirror = reflect(o);
575 var classMirror = objectMirror.type; 812 var classMirror = objectMirror.type;
576 _addInstanceMirrors(objectMirror, classMirror.owner, 813 _addInstanceMirrors(
814 objectMirror,
815 classMirror.owner,
577 classMirror.instanceMembers, 816 classMirror.instanceMembers,
578 ownProperties, accessorPropertiesOnly, false, true, 817 ownProperties,
818 accessorPropertiesOnly,
819 false,
820 true,
579 properties); 821 properties);
580 return packageProperties(properties); 822 return packageProperties(properties);
581 } 823 }
582 824
583 static List getObjectClassProperties(o, bool ownProperties, 825 static List getObjectClassProperties(
584 bool accessorPropertiesOnly) { 826 o, bool ownProperties, bool accessorPropertiesOnly) {
585 var properties = new Map<String, _Property>(); 827 var properties = new Map<String, _Property>();
586 var objectMirror = reflect(o); 828 var objectMirror = reflect(o);
587 var classMirror = objectMirror.type; 829 var classMirror = objectMirror.type;
588 _addInstanceMirrors(objectMirror, classMirror.owner, 830 _addInstanceMirrors(
831 objectMirror,
832 classMirror.owner,
589 classMirror.instanceMembers, 833 classMirror.instanceMembers,
590 ownProperties, accessorPropertiesOnly, true, false, 834 ownProperties,
835 accessorPropertiesOnly,
836 true,
837 false,
591 properties); 838 properties);
592 _addStatics(classMirror, properties, accessorPropertiesOnly); 839 _addStatics(classMirror, properties, accessorPropertiesOnly);
593 return packageProperties(properties); 840 return packageProperties(properties);
594 } 841 }
595 842
596 static List getClassProperties(Type t, bool ownProperties, 843 static List getClassProperties(
597 bool accessorPropertiesOnly) { 844 Type t, bool ownProperties, bool accessorPropertiesOnly) {
598 var properties = new Map<String, _Property>(); 845 var properties = new Map<String, _Property>();
599 var classMirror = reflectClass(t); 846 var classMirror = reflectClass(t);
600 _addStatics(classMirror, properties, accessorPropertiesOnly); 847 _addStatics(classMirror, properties, accessorPropertiesOnly);
601 return packageProperties(properties); 848 return packageProperties(properties);
602 } 849 }
603 850
604 static void _addStatics(ClassMirror classMirror, 851 static void _addStatics(ClassMirror classMirror,
605 Map<String, _Property> properties, 852 Map<String, _Property> properties, bool accessorPropertiesOnly) {
606 bool accessorPropertiesOnly) {
607 var libraryMirror = classMirror.owner; 853 var libraryMirror = classMirror.owner;
608 classMirror.declarations.forEach((symbol, declaration) { 854 classMirror.declarations.forEach((symbol, declaration) {
609 var name = _getShortSymbolName(symbol, declaration); 855 var name = _getShortSymbolName(symbol, declaration);
610 if (name.isEmpty) return; 856 if (name.isEmpty) return;
611 if (declaration is VariableMirror) { 857 if (declaration is VariableMirror) {
612 if (accessorPropertiesOnly) return; 858 if (accessorPropertiesOnly) return;
613 if (!declaration.isStatic) return; 859 if (!declaration.isStatic) return;
614 properties.putIfAbsent(name, () => new _Property(name)) 860 properties.putIfAbsent(name, () => new _Property(name))
615 ..value = classMirror.getField(symbol).reflectee 861 ..value = classMirror.getField(symbol).reflectee
616 ..writable = !declaration.isFinal && !declaration.isConst; 862 ..writable = !declaration.isFinal && !declaration.isConst;
617 } else if (declaration is MethodMirror) { 863 } else if (declaration is MethodMirror) {
618 MethodMirror methodMirror = declaration; 864 MethodMirror methodMirror = declaration;
619 // FIXMEDART: should we display constructors? 865 // FIXMEDART: should we display constructors?
620 if (methodMirror.isConstructor) return; 866 if (methodMirror.isConstructor) return;
621 if (!methodMirror.isStatic) return; 867 if (!methodMirror.isStatic) return;
622 if (accessorPropertiesOnly) { 868 if (accessorPropertiesOnly) {
623 if (methodMirror.isRegularMethod || 869 if (methodMirror.isRegularMethod ||
624 treatPropertyAsField(methodMirror, libraryMirror)) { 870 treatPropertyAsField(methodMirror, libraryMirror)) {
625 return; 871 return;
626 } 872 }
627 } else if (!methodMirror.isRegularMethod && 873 } else if (!methodMirror.isRegularMethod &&
628 !treatPropertyAsField(methodMirror, libraryMirror)) { 874 !treatPropertyAsField(methodMirror, libraryMirror)) {
629 return; 875 return;
630 } 876 }
631 var property = properties.putIfAbsent(name, () => new _Property(name)); 877 var property = properties.putIfAbsent(name, () => new _Property(name));
632 _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror, 878 _fillMethodMirrorProperty(libraryMirror, classMirror, methodMirror,
633 symbol, accessorPropertiesOnly, property); 879 symbol, accessorPropertiesOnly, property);
634 } 880 }
635 }); 881 });
636 } 882 }
637 883
638 static void _fillMethodMirrorProperty(LibraryMirror libraryMirror, 884 static void _fillMethodMirrorProperty(
639 methodOwner, MethodMirror methodMirror, Symbol symbol, 885 LibraryMirror libraryMirror,
640 bool accessorPropertiesOnly, _Property property) { 886 methodOwner,
887 MethodMirror methodMirror,
888 Symbol symbol,
889 bool accessorPropertiesOnly,
890 _Property property) {
641 if (methodMirror.isRegularMethod) { 891 if (methodMirror.isRegularMethod) {
642 property 892 property
643 ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol) 893 ..value = new _MethodTrampoline(methodOwner, methodMirror, symbol)
644 ..isMethod = true; 894 ..isMethod = true;
645 } else if (methodMirror.isGetter) { 895 } else if (methodMirror.isGetter) {
646 if (treatPropertyAsField(methodMirror, libraryMirror)) { 896 if (treatPropertyAsField(methodMirror, libraryMirror)) {
647 try { 897 try {
648 property.value = methodOwner.getField(symbol).reflectee; 898 property.value = methodOwner.getField(symbol).reflectee;
649 } catch (e) { 899 } catch (e) {
650 property 900 property
651 ..wasThrown = true 901 ..wasThrown = true
652 ..value = e; 902 ..value = e;
653 } 903 }
654 } else if (accessorPropertiesOnly) { 904 } else if (accessorPropertiesOnly) {
655 property.getter = new _GetterTrampoline(methodOwner, 905 property.getter =
656 methodMirror, symbol); 906 new _GetterTrampoline(methodOwner, methodMirror, symbol);
657 } 907 }
658 } else if (methodMirror.isSetter) { 908 } else if (methodMirror.isSetter) {
659 if (accessorPropertiesOnly && 909 if (accessorPropertiesOnly &&
660 !treatPropertyAsField(methodMirror, libraryMirror)) { 910 !treatPropertyAsField(methodMirror, libraryMirror)) {
661 property.setter = new _SetterTrampoline(methodOwner, 911 property.setter = new _SetterTrampoline(methodOwner, methodMirror,
662 methodMirror, MirrorSystem.getSymbol(property.name, libraryMirror)); 912 MirrorSystem.getSymbol(property.name, libraryMirror));
663 } 913 }
664 property.writable = true; 914 property.writable = true;
665 } 915 }
666 } 916 }
667 917
668 /** 918 /**
669 * Helper method that handles collecting up properties from classes 919 * Helper method that handles collecting up properties from classes
670 * or libraries using the filters [ownProperties], [accessorPropertiesOnly], 920 * or libraries using the filters [ownProperties], [accessorPropertiesOnly],
671 * [hideFields], and [hideMethods] to determine which properties are 921 * [hideFields], and [hideMethods] to determine which properties are
672 * collected. [accessorPropertiesOnly] specifies whether all properties 922 * collected. [accessorPropertiesOnly] specifies whether all properties
673 * should be returned or just accessors. [hideFields] specifies whether 923 * should be returned or just accessors. [hideFields] specifies whether
674 * fields should be hidden. hideMethods specifies whether methods should be 924 * fields should be hidden. hideMethods specifies whether methods should be
675 * shown or hidden. [ownProperties] is not currently used but is part of the 925 * shown or hidden. [ownProperties] is not currently used but is part of the
676 * Blink devtools API for enumerating properties. 926 * Blink devtools API for enumerating properties.
677 */ 927 */
678 static void _addInstanceMirrors( 928 static void _addInstanceMirrors(
679 ObjectMirror objectMirror, 929 ObjectMirror objectMirror,
680 LibraryMirror libraryMirror, 930 LibraryMirror libraryMirror,
681 Map<Symbol, Mirror> declarations, 931 Map<Symbol, Mirror> declarations,
682 bool ownProperties, bool accessorPropertiesOnly, 932 bool ownProperties,
683 bool hideFields, bool hideMethods, 933 bool accessorPropertiesOnly,
934 bool hideFields,
935 bool hideMethods,
684 Map<String, _Property> properties) { 936 Map<String, _Property> properties) {
685 declarations.forEach((symbol, declaration) { 937 declarations.forEach((symbol, declaration) {
686 if (declaration is TypedefMirror || declaration is ClassMirror) return; 938 if (declaration is TypedefMirror || declaration is ClassMirror) return;
687 var name = _getShortSymbolName(symbol, declaration); 939 var name = _getShortSymbolName(symbol, declaration);
688 if (name.isEmpty) return; 940 if (name.isEmpty) return;
689 bool isField = declaration is VariableMirror || 941 bool isField = declaration is VariableMirror ||
690 (declaration is MethodMirror && 942 (declaration is MethodMirror &&
691 treatPropertyAsField(declaration, libraryMirror)); 943 treatPropertyAsField(declaration, libraryMirror));
692 if ((isField && hideFields) || (hideMethods && !isField)) return; 944 if ((isField && hideFields) || (hideMethods && !isField)) return;
693 if (accessorPropertiesOnly) { 945 if (accessorPropertiesOnly) {
694 if (declaration is VariableMirror || declaration.isRegularMethod || 946 if (declaration is VariableMirror ||
947 declaration.isRegularMethod ||
695 isField) { 948 isField) {
696 return; 949 return;
697 } 950 }
698 } else if (declaration is MethodMirror && 951 } else if (declaration is MethodMirror &&
699 (declaration.isGetter || declaration.isSetter) && 952 (declaration.isGetter || declaration.isSetter) &&
700 !treatPropertyAsField(declaration, libraryMirror)) { 953 !treatPropertyAsField(declaration, libraryMirror)) {
701 return; 954 return;
702 } 955 }
703 var property = properties.putIfAbsent(name, () => new _Property(name)); 956 var property = properties.putIfAbsent(name, () => new _Property(name));
704 if (declaration is VariableMirror) { 957 if (declaration is VariableMirror) {
705 property 958 property
706 ..value = objectMirror.getField(symbol).reflectee 959 ..value = objectMirror.getField(symbol).reflectee
707 ..writable = !declaration.isFinal && !declaration.isConst; 960 ..writable = !declaration.isFinal && !declaration.isConst;
708 return; 961 return;
709 } 962 }
710 _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration, 963 _fillMethodMirrorProperty(libraryMirror, objectMirror, declaration,
711 symbol, accessorPropertiesOnly, property); 964 symbol, accessorPropertiesOnly, property);
712 }); 965 });
713 } 966 }
714 967
715 /** 968 /**
716 * Flatten down the properties data structure into a List that is easy to 969 * Flatten down the properties data structure into a List that is easy to
717 * access from native code. 970 * access from native code.
718 */ 971 */
719 static List packageProperties(Map<String, _Property> properties) { 972 static List packageProperties(Map<String, _Property> properties) {
720 var ret = []; 973 var ret = [];
721 for (var property in properties.values) { 974 for (var property in properties.values) {
722 ret.addAll([property.name, 975 ret.addAll([
723 property.setter, 976 property.name,
724 property.getter, 977 property.setter,
725 property.value, 978 property.getter,
726 property.hasValue, 979 property.value,
727 property.writable, 980 property.hasValue,
728 property.isMethod, 981 property.writable,
729 property.isOwn, 982 property.isMethod,
730 property.wasThrown]); 983 property.isOwn,
984 property.wasThrown
985 ]);
731 } 986 }
732 return ret; 987 return ret;
733 } 988 }
734 989
735 /** 990 /**
736 * Get a property, returning null if the property does not exist. 991 * Get a property, returning null if the property does not exist.
737 * For private property names, we attempt to resolve the property in the 992 * For private property names, we attempt to resolve the property in the
738 * context of each library that the property name could be associated with. 993 * context of each library that the property name could be associated with.
739 */ 994 */
740 static getObjectPropertySafe(o, String propertyName) { 995 static getObjectPropertySafe(o, String propertyName) {
741 var objectMirror = reflect(o); 996 var objectMirror = reflect(o);
742 var classMirror = objectMirror.type; 997 var classMirror = objectMirror.type;
743 if (propertyName.startsWith("_")) { 998 if (propertyName.startsWith("_")) {
744 var attemptedLibraries = new Set<LibraryMirror>(); 999 var attemptedLibraries = new Set<LibraryMirror>();
745 while (classMirror != null) { 1000 while (classMirror != null) {
746 LibraryMirror library = classMirror.owner; 1001 LibraryMirror library = classMirror.owner;
747 if (!attemptedLibraries.contains(library)) { 1002 if (!attemptedLibraries.contains(library)) {
748 try { 1003 try {
749 return objectMirror.getField( 1004 return objectMirror
750 MirrorSystem.getSymbol(propertyName, library)).reflectee; 1005 .getField(MirrorSystem.getSymbol(propertyName, library))
751 } catch (e) { } 1006 .reflectee;
1007 } catch (e) {}
752 attemptedLibraries.add(library); 1008 attemptedLibraries.add(library);
753 } 1009 }
754 classMirror = classMirror.superclass; 1010 classMirror = classMirror.superclass;
755 } 1011 }
756 return null; 1012 return null;
757 } 1013 }
758 try { 1014 try {
759 return objectMirror.getField( 1015 return objectMirror
760 MirrorSystem.getSymbol(propertyName)).reflectee; 1016 .getField(MirrorSystem.getSymbol(propertyName))
1017 .reflectee;
761 } catch (e) { 1018 } catch (e) {
762 return null; 1019 return null;
763 } 1020 }
764 } 1021 }
765 1022
766 /** 1023 /**
767 * Helper to wrap the inspect method on InjectedScriptHost to provide the 1024 * Helper to wrap the inspect method on InjectedScriptHost to provide the
768 * inspect method required for the 1025 * inspect method required for the
769 */ 1026 */
770 static List consoleApi(host) { 1027 static List consoleApi(host) {
771 return [ 1028 return [
772 "inspect", 1029 "inspect",
773 (o) { 1030 (o) {
774 js.JsNative.callMethod(host, "_inspect", [o]); 1031 js.JsNative.callMethod(host, "_inspect", [o]);
775 return o; 1032 return o;
776 }, 1033 },
777 "dir", 1034 "dir",
778 window.console.dir, 1035 window.console.dir,
779 "dirxml", 1036 "dirxml",
780 window.console.dirxml 1037 window.console.dirxml
781 // FIXME: add copy method. 1038 // FIXME: add copy method.
782 ]; 1039 ];
783 } 1040 }
784 1041
785 static List getMapKeyList(Map map) => map.keys.toList(); 1042 static List getMapKeyList(Map map) => map.keys.toList();
786 1043
787 static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError; 1044 static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
788 1045
789 static void register(Document document, String tag, Type type, 1046 static void register(
790 String extendsTagName) { 1047 Document document, String tag, Type type, String extendsTagName) {
791 var nativeClass = _validateCustomType(type); 1048 var nativeClass = _validateCustomType(type);
792 1049
793 if (extendsTagName == null) { 1050 if (extendsTagName == null) {
794 if (nativeClass.reflectedType != HtmlElement) { 1051 if (nativeClass.reflectedType != HtmlElement) {
795 throw new UnsupportedError('Class must provide extendsTag if base ' 1052 throw new UnsupportedError('Class must provide extendsTag if base '
796 'native class is not HTMLElement'); 1053 'native class is not HTMLElement');
797 } 1054 }
798 } 1055 }
799 1056
800 _register(document, tag, type, extendsTagName); 1057 _register(document, tag, type, extendsTagName);
801 } 1058 }
802 1059
803 static void _register(Document document, String tag, Type customType, 1060 static void _register(Document document, String tag, Type customType,
804 String extendsTagName) => _blink.Blink_Utils.register(document, tag, customT ype, extendsTagName); 1061 String extendsTagName) =>
1062 _blink.Blink_Utils.register(document, tag, customType, extendsTagName);
805 1063
806 static Element createElement(Document document, String tagName) => 1064 static Element createElement(Document document, String tagName) =>
807 _blink.Blink_Utils.createElement(document, tagName); 1065 _blink.Blink_Utils.createElement(document, tagName);
808 } 1066 }
809 1067
810 // TODO(jacobr): this seems busted. I believe we are actually 1068 // TODO(jacobr): this seems busted. I believe we are actually
811 // giving users real windows for opener, parent, top, etc. 1069 // giving users real windows for opener, parent, top, etc.
812 // Or worse, we are probaly returning a raw JSObject. 1070 // Or worse, we are probaly returning a raw JSObject.
813 class _DOMWindowCrossFrame extends DartHtmlDomObject implements 1071 class _DOMWindowCrossFrame extends DartHtmlDomObject implements WindowBase {
814 WindowBase { 1072 _DOMWindowCrossFrame.internal();
815 1073
816 _DOMWindowCrossFrame.internal(); 1074 static _createSafe(win) =>
817 1075 _blink.Blink_Utils.setInstanceInterceptor(win, _DOMWindowCrossFrame);
818 static _createSafe(win) => _blink.Blink_Utils.setInstanceInterceptor(win, _DOM WindowCrossFrame);
819 1076
820 // Fields. 1077 // Fields.
821 HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this); 1078 HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this);
822 LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(thi s); 1079 LocationBase get location =>
1080 _blink.Blink_DOMWindowCrossFrame.get_location(this);
823 bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this); 1081 bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
824 WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this); 1082 WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
825 WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this); 1083 WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
826 WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this); 1084 WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);
827 1085
828 // Methods. 1086 // Methods.
829 void close() => _blink.Blink_DOMWindowCrossFrame.close(this); 1087 void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
830 void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) => 1088 void postMessage(/*SerializedScriptValue*/ message, String targetOrigin,
831 _blink.Blink_DOMWindowCrossFrame.postMessage(this, 1089 [List messagePorts]) =>
832 convertDartToNative_SerializedScriptValue(message), targetOrigin, messa gePorts); 1090 _blink.Blink_DOMWindowCrossFrame.postMessage(
1091 this,
1092 convertDartToNative_SerializedScriptValue(message),
1093 targetOrigin,
1094 messagePorts);
833 1095
834 // Implementation support. 1096 // Implementation support.
835 String get typeName => "Window"; 1097 String get typeName => "Window";
836 1098
837 // TODO(efortuna): Remove this method. dartbug.com/16814 1099 // TODO(efortuna): Remove this method. dartbug.com/16814
838 Events get on => throw new UnsupportedError( 1100 Events get on => throw new UnsupportedError(
839 'You can only attach EventListeners to your own window.'); 1101 'You can only attach EventListeners to your own window.');
840 // TODO(efortuna): Remove this method. dartbug.com/16814 1102 // TODO(efortuna): Remove this method. dartbug.com/16814
841 void _addEventListener([String type, EventListener listener, bool useCapture]) 1103 void _addEventListener(
842 => throw new UnsupportedError( 1104 [String type, EventListener listener, bool useCapture]) =>
843 'You can only attach EventListeners to your own window.'); 1105 throw new UnsupportedError(
1106 'You can only attach EventListeners to your own window.');
844 // TODO(efortuna): Remove this method. dartbug.com/16814 1107 // TODO(efortuna): Remove this method. dartbug.com/16814
845 void addEventListener(String type, EventListener listener, [bool useCapture]) 1108 void addEventListener(String type, EventListener listener,
846 => throw new UnsupportedError( 1109 [bool useCapture]) =>
847 'You can only attach EventListeners to your own window.'); 1110 throw new UnsupportedError(
1111 'You can only attach EventListeners to your own window.');
848 // TODO(efortuna): Remove this method. dartbug.com/16814 1112 // TODO(efortuna): Remove this method. dartbug.com/16814
849 bool dispatchEvent(Event event) => throw new UnsupportedError( 1113 bool dispatchEvent(Event event) => throw new UnsupportedError(
850 'You can only attach EventListeners to your own window.'); 1114 'You can only attach EventListeners to your own window.');
851 // TODO(efortuna): Remove this method. dartbug.com/16814 1115 // TODO(efortuna): Remove this method. dartbug.com/16814
852 void _removeEventListener([String type, EventListener listener, 1116 void _removeEventListener(
853 bool useCapture]) => throw new UnsupportedError( 1117 [String type, EventListener listener, bool useCapture]) =>
854 'You can only attach EventListeners to your own window.'); 1118 throw new UnsupportedError(
1119 'You can only attach EventListeners to your own window.');
855 // TODO(efortuna): Remove this method. dartbug.com/16814 1120 // TODO(efortuna): Remove this method. dartbug.com/16814
856 void removeEventListener(String type, EventListener listener, 1121 void removeEventListener(String type, EventListener listener,
857 [bool useCapture]) => throw new UnsupportedError( 1122 [bool useCapture]) =>
858 'You can only attach EventListeners to your own window.'); 1123 throw new UnsupportedError(
1124 'You can only attach EventListeners to your own window.');
859 } 1125 }
860 1126
861 class _HistoryCrossFrame extends DartHtmlDomObject implements HistoryBase { 1127 class _HistoryCrossFrame extends DartHtmlDomObject implements HistoryBase {
862 _HistoryCrossFrame.internal(); 1128 _HistoryCrossFrame.internal();
863 1129
864 // Methods. 1130 // Methods.
865 void back() => _blink.Blink_HistoryCrossFrame.back(this); 1131 void back() => _blink.Blink_HistoryCrossFrame.back(this);
866 void forward() => _blink.Blink_HistoryCrossFrame.forward(this); 1132 void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
867 void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance); 1133 void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);
868 1134
(...skipping 21 matching lines...) Expand all
890 final port = new ReceivePort(); 1156 final port = new ReceivePort();
891 port.listen((result) { 1157 port.listen((result) {
892 completer.complete(result); 1158 completer.complete(result);
893 port.close(); 1159 port.close();
894 }); 1160 });
895 // TODO: SendPort.hashCode is ugly way to access port id. 1161 // TODO: SendPort.hashCode is ugly way to access port id.
896 spawnRequest(port.sendPort.hashCode); 1162 spawnRequest(port.sendPort.hashCode);
897 return completer.future; 1163 return completer.future;
898 } 1164 }
899 1165
900 Future<SendPort> _spawnDomHelper(Function f) => 1166 Future<SendPort> _spawnDomHelper(Function f) => _makeSendPortFuture((portId) {
901 _makeSendPortFuture((portId) { _Utils.spawnDomHelper(f, portId); }); 1167 _Utils.spawnDomHelper(f, portId);
1168 });
902 1169
903 final Future<SendPort> __HELPER_ISOLATE_PORT = 1170 final Future<SendPort> __HELPER_ISOLATE_PORT =
904 _spawnDomHelper(_helperIsolateMain); 1171 _spawnDomHelper(_helperIsolateMain);
905 1172
906 // Tricky part. 1173 // Tricky part.
907 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then 1174 // Once __HELPER_ISOLATE_PORT gets resolved, it will still delay in .then
908 // and to delay Timer.run is used. However, Timer.run will try to register 1175 // and to delay Timer.run is used. However, Timer.run will try to register
909 // another Timer and here we got stuck: event cannot be posted as then 1176 // another Timer and here we got stuck: event cannot be posted as then
910 // callback is not executed because it's delayed with timer. 1177 // callback is not executed because it's delayed with timer.
911 // Therefore once future is resolved, it's unsafe to call .then on it 1178 // Therefore once future is resolved, it's unsafe to call .then on it
(...skipping 21 matching lines...) Expand all
933 _helperIsolateMain(originalSendPort) { 1200 _helperIsolateMain(originalSendPort) {
934 var port = new ReceivePort(); 1201 var port = new ReceivePort();
935 originalSendPort.send(port.sendPort); 1202 originalSendPort.send(port.sendPort);
936 port.listen((args) { 1203 port.listen((args) {
937 var msg = args.first; 1204 var msg = args.first;
938 var replyTo = args.last; 1205 var replyTo = args.last;
939 final cmd = msg[0]; 1206 final cmd = msg[0];
940 if (cmd == _NEW_TIMER) { 1207 if (cmd == _NEW_TIMER) {
941 final duration = new Duration(milliseconds: msg[1]); 1208 final duration = new Duration(milliseconds: msg[1]);
942 bool periodic = msg[2]; 1209 bool periodic = msg[2];
943 ping() { replyTo.send(_TIMER_PING); }; 1210 ping() {
944 _TIMER_REGISTRY[replyTo] = periodic ? 1211 replyTo.send(_TIMER_PING);
945 new Timer.periodic(duration, (_) { ping(); }) : 1212 }
946 new Timer(duration, ping); 1213 ;
1214 _TIMER_REGISTRY[replyTo] = periodic
1215 ? new Timer.periodic(duration, (_) {
1216 ping();
1217 })
1218 : new Timer(duration, ping);
947 } else if (cmd == _CANCEL_TIMER) { 1219 } else if (cmd == _CANCEL_TIMER) {
948 _TIMER_REGISTRY.remove(replyTo).cancel(); 1220 _TIMER_REGISTRY.remove(replyTo).cancel();
949 } else if (cmd == _PRINT) { 1221 } else if (cmd == _PRINT) {
950 final message = msg[1]; 1222 final message = msg[1];
951 // TODO(antonm): we need somehow identify those isolates. 1223 // TODO(antonm): we need somehow identify those isolates.
952 print('[From isolate] $message'); 1224 print('[From isolate] $message');
953 } 1225 }
954 }); 1226 });
955 } 1227 }
956 1228
957 final _printClosure = (s) => window.console.log(s); 1229 final _printClosure = (s) => window.console.log(s);
958 final _pureIsolatePrintClosure = (s) { 1230 final _pureIsolatePrintClosure = (s) {
959 _sendToHelperIsolate([_PRINT, s], null); 1231 _sendToHelperIsolate([_PRINT, s], null);
960 }; 1232 };
961 1233
962 final _forwardingPrintClosure = _Utils.forwardingPrint; 1234 final _forwardingPrintClosure = _Utils.forwardingPrint;
963 1235
964 final _uriBaseClosure = () => Uri.parse(window.location.href); 1236 final _uriBaseClosure = () => Uri.parse(window.location.href);
965 1237
966 final _pureIsolateUriBaseClosure = () { 1238 final _pureIsolateUriBaseClosure = () {
967 throw new UnimplementedError("Uri.base on a background isolate " 1239 throw new UnimplementedError("Uri.base on a background isolate "
968 "is not supported in the browser"); 1240 "is not supported in the browser");
969 }; 1241 };
970 1242
971 class _Timer implements Timer { 1243 class _Timer implements Timer {
972 static const int _STATE_TIMEOUT = 0; 1244 static const int _STATE_TIMEOUT = 0;
973 static const int _STATE_INTERVAL = 1; 1245 static const int _STATE_INTERVAL = 1;
974 int _state; 1246 int _state;
975 1247
976 _Timer(int milliSeconds, void callback(Timer timer), bool repeating) { 1248 _Timer(int milliSeconds, void callback(Timer timer), bool repeating) {
977 if (repeating) { 1249 if (repeating) {
978 _state = (window._setInterval(() { 1250 _state = (window._setInterval(() {
979 callback(this); 1251 callback(this);
980 }, milliSeconds) << 1) | _STATE_INTERVAL; 1252 }, milliSeconds) <<
1253 1) |
1254 _STATE_INTERVAL;
981 } else { 1255 } else {
982 _state = (window._setTimeout(() { 1256 _state = (window._setTimeout(() {
983 _state = null; 1257 _state = null;
984 callback(this); 1258 callback(this);
985 }, milliSeconds) << 1) | _STATE_TIMEOUT; 1259 }, milliSeconds) <<
1260 1) |
1261 _STATE_TIMEOUT;
986 } 1262 }
987 } 1263 }
988 1264
989 void cancel() { 1265 void cancel() {
990 if (_state == null) return; 1266 if (_state == null) return;
991 int id = _state >> 1; 1267 int id = _state >> 1;
992 if ((_state & 1) == _STATE_TIMEOUT) { 1268 if ((_state & 1) == _STATE_TIMEOUT) {
993 window._clearTimeout(id); 1269 window._clearTimeout(id);
994 } else { 1270 } else {
995 window._clearInterval(id); 1271 window._clearInterval(id);
996 } 1272 }
997 _state = null; 1273 _state = null;
998 } 1274 }
999 1275
1000 bool get isActive => _state != null; 1276 bool get isActive => _state != null;
1001 } 1277 }
1002 1278
1003 get _timerFactoryClosure => 1279 get _timerFactoryClosure =>
1004 (int milliSeconds, void callback(Timer timer), bool repeating) { 1280 (int milliSeconds, void callback(Timer timer), bool repeating) {
1005 return new _Timer(milliSeconds, callback, repeating); 1281 return new _Timer(milliSeconds, callback, repeating);
1006 }; 1282 };
1007 1283
1008 class _PureIsolateTimer implements Timer { 1284 class _PureIsolateTimer implements Timer {
1009 bool _isActive = true; 1285 bool _isActive = true;
1010 final ReceivePort _port = new ReceivePort(); 1286 final ReceivePort _port = new ReceivePort();
1011 SendPort _sendPort; // Effectively final. 1287 SendPort _sendPort; // Effectively final.
1012 1288
1013 // static SendPort _SEND_PORT; 1289 // static SendPort _SEND_PORT;
1014 1290
1015 _PureIsolateTimer(int milliSeconds, callback, repeating) { 1291 _PureIsolateTimer(int milliSeconds, callback, repeating) {
1016 _sendPort = _port.sendPort; 1292 _sendPort = _port.sendPort;
(...skipping 19 matching lines...) Expand all
1036 1312
1037 _send(msg) { 1313 _send(msg) {
1038 _sendToHelperIsolate(msg, _sendPort); 1314 _sendToHelperIsolate(msg, _sendPort);
1039 } 1315 }
1040 1316
1041 bool get isActive => _isActive; 1317 bool get isActive => _isActive;
1042 } 1318 }
1043 1319
1044 get _pureIsolateTimerFactoryClosure => 1320 get _pureIsolateTimerFactoryClosure =>
1045 ((int milliSeconds, void callback(Timer time), bool repeating) => 1321 ((int milliSeconds, void callback(Timer time), bool repeating) =>
1046 new _PureIsolateTimer(milliSeconds, callback, repeating)); 1322 new _PureIsolateTimer(milliSeconds, callback, repeating));
1047 1323
1048 class _ScheduleImmediateHelper { 1324 class _ScheduleImmediateHelper {
1049 MutationObserver _observer; 1325 MutationObserver _observer;
1050 final DivElement _div = new DivElement(); 1326 final DivElement _div = new DivElement();
1051 Function _callback; 1327 Function _callback;
1052 1328
1053 _ScheduleImmediateHelper() { 1329 _ScheduleImmediateHelper() {
1054 // Run in the root-zone as the DOM callback would otherwise execute in the 1330 // Run in the root-zone as the DOM callback would otherwise execute in the
1055 // current zone. 1331 // current zone.
1056 Zone.ROOT.run(() { 1332 Zone.ROOT.run(() {
(...skipping 18 matching lines...) Expand all
1075 var tmp = _callback; 1351 var tmp = _callback;
1076 _callback = null; 1352 _callback = null;
1077 tmp(); 1353 tmp();
1078 } 1354 }
1079 } 1355 }
1080 1356
1081 final _ScheduleImmediateHelper _scheduleImmediateHelper = 1357 final _ScheduleImmediateHelper _scheduleImmediateHelper =
1082 new _ScheduleImmediateHelper(); 1358 new _ScheduleImmediateHelper();
1083 1359
1084 get _scheduleImmediateClosure => (void callback()) { 1360 get _scheduleImmediateClosure => (void callback()) {
1085 _scheduleImmediateHelper._schedule(callback); 1361 _scheduleImmediateHelper._schedule(callback);
1086 }; 1362 };
1087 1363
1088 get _pureIsolateScheduleImmediateClosure => ((void callback()) => 1364 get _pureIsolateScheduleImmediateClosure => ((void callback()) =>
1089 throw new UnimplementedError("scheduleMicrotask in background isolates " 1365 throw new UnimplementedError("scheduleMicrotask in background isolates "
1090 "are not supported in the browser")); 1366 "are not supported in the browser"));
1091 1367
1092 // Class for unsupported native browser 'DOM' objects. 1368 // Class for unsupported native browser 'DOM' objects.
1093 class _UnsupportedBrowserObject extends DartHtmlDomObject { 1369 class _UnsupportedBrowserObject extends DartHtmlDomObject {}
1094 }
OLDNEW
« no previous file with comments | « sdk/lib/html/dartium/html_dartium.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698