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

Side by Side Diff: dart/sdk/lib/_internal/lib/js_mirrors.dart

Issue 22831004: Collections returned by mirror API should be unmodifiable. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart._js_mirrors; 5 library dart._js_mirrors;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection' show UnmodifiableListView;
8 import 'dart:mirrors'; 9 import 'dart:mirrors';
9 10
10 import 'dart:_foreign_helper' show 11 import 'dart:_foreign_helper' show
11 JS, 12 JS,
12 JS_CURRENT_ISOLATE, 13 JS_CURRENT_ISOLATE,
13 JS_CURRENT_ISOLATE_CONTEXT, 14 JS_CURRENT_ISOLATE_CONTEXT,
14 JS_GET_NAME; 15 JS_GET_NAME;
15 import 'dart:_collection-dev' as _symbol_dev; 16 import 'dart:_collection-dev' as _symbol_dev;
16 import 'dart:_js_helper' show 17 import 'dart:_js_helper' show
17 BoundClosure, 18 BoundClosure,
(...skipping 15 matching lines...) Expand all
33 /// No-op method that is called to inform the compiler that metadata must be 34 /// No-op method that is called to inform the compiler that metadata must be
34 /// preserved at runtime. 35 /// preserved at runtime.
35 preserveMetadata() {} 36 preserveMetadata() {}
36 37
37 String getName(Symbol symbol) { 38 String getName(Symbol symbol) {
38 preserveNames(); 39 preserveNames();
39 return n(symbol); 40 return n(symbol);
40 } 41 }
41 42
42 class JsMirrorSystem implements MirrorSystem { 43 class JsMirrorSystem implements MirrorSystem {
44 UnmodifiableMapView<Uri, LibraryMirror> _cachedLibraries;
45
43 final IsolateMirror isolate = new JsIsolateMirror(); 46 final IsolateMirror isolate = new JsIsolateMirror();
44 47
45 TypeMirror get dynamicType => _dynamicType; 48 TypeMirror get dynamicType => _dynamicType;
46 TypeMirror get voidType => _voidType; 49 TypeMirror get voidType => _voidType;
47 50
48 final static TypeMirror _dynamicType = 51 final static TypeMirror _dynamicType =
49 new JsTypeMirror(const Symbol('dynamic')); 52 new JsTypeMirror(const Symbol('dynamic'));
50 final static TypeMirror _voidType = new JsTypeMirror(const Symbol('void')); 53 final static TypeMirror _voidType = new JsTypeMirror(const Symbol('void'));
51 54
52 static final Map<String, List<LibraryMirror>> librariesByName = 55 static final Map<String, List<LibraryMirror>> librariesByName =
53 computeLibrariesByName(); 56 computeLibrariesByName();
54 57
55 Map<Uri, LibraryMirror> get libraries { 58 Map<Uri, LibraryMirror> get libraries {
56 Map<Uri, LibraryMirror> result = new Map<Uri, LibraryMirror>(); 59 if (_cachedLibraries != null) return _cachedLibraries;
60 Map<Uri, LibraryMirror> result = new Map();
57 for (List<LibraryMirror> list in librariesByName.values) { 61 for (List<LibraryMirror> list in librariesByName.values) {
58 for (LibraryMirror library in list) { 62 for (LibraryMirror library in list) {
59 result[library.uri] = library; 63 result[library.uri] = library;
60 } 64 }
61 } 65 }
62 return result; 66 return _cachedLibraries =
67 new UnmodifiableMapView<Uri, LibraryMirror>(result);
63 } 68 }
64 69
65 Iterable<LibraryMirror> findLibrary(Symbol libraryName) { 70 Iterable<LibraryMirror> findLibrary(Symbol libraryName) {
66 return new List<LibraryMirror>.from(librariesByName[n(libraryName)]); 71 return new UnmodifiableListView<LibraryMirror>(
72 librariesByName[n(libraryName)]);
67 } 73 }
68 74
69 static Map<String, List<LibraryMirror>> computeLibrariesByName() { 75 static Map<String, List<LibraryMirror>> computeLibrariesByName() {
70 disableTreeShaking(); 76 disableTreeShaking();
71 var result = new Map<String, List<LibraryMirror>>(); 77 var result = new Map<String, List<LibraryMirror>>();
72 var jsLibraries = JS('JSExtendableArray|Null', 'init.libraries'); 78 var jsLibraries = JS('JSExtendableArray|Null', 'init.libraries');
73 if (jsLibraries == null) return result; 79 if (jsLibraries == null) return result;
74 for (List data in jsLibraries) { 80 for (List data in jsLibraries) {
75 String name = data[0]; 81 String name = data[0];
76 Uri uri = Uri.parse(data[1]); 82 Uri uri = Uri.parse(data[1]);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 class JsLibraryMirror extends JsDeclarationMirror with JsObjectMirror 187 class JsLibraryMirror extends JsDeclarationMirror with JsObjectMirror
182 implements LibraryMirror { 188 implements LibraryMirror {
183 final Uri uri; 189 final Uri uri;
184 final List<String> _classes; 190 final List<String> _classes;
185 final List<String> _functions; 191 final List<String> _functions;
186 final List _metadata; 192 final List _metadata;
187 final String _compactFieldSpecification; 193 final String _compactFieldSpecification;
188 final bool _isRoot; 194 final bool _isRoot;
189 List<JsMethodMirror> _cachedFunctionMirrors; 195 List<JsMethodMirror> _cachedFunctionMirrors;
190 List<JsVariableMirror> _cachedFields; 196 List<JsVariableMirror> _cachedFields;
197 UnmodifiableMapView<Symbol, ClassMirror> _cachedClasses;
198 UnmodifiableMapView<Symbol, MethodMirror> _cachedFunctions;
199 UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
200 UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
201 UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
202 UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
203 UnmodifiableListView<InstanceMirror> _cachedMetadata;
191 204
192 JsLibraryMirror(Symbol simpleName, 205 JsLibraryMirror(Symbol simpleName,
193 this.uri, 206 this.uri,
194 this._classes, 207 this._classes,
195 this._functions, 208 this._functions,
196 this._metadata, 209 this._metadata,
197 this._compactFieldSpecification, 210 this._compactFieldSpecification,
198 this._isRoot) 211 this._isRoot)
199 : super(simpleName); 212 : super(simpleName);
200 213
201 String get _prettyName => 'LibraryMirror'; 214 String get _prettyName => 'LibraryMirror';
202 215
203 Symbol get qualifiedName => simpleName; 216 Symbol get qualifiedName => simpleName;
204 217
205 List<JsMethodMirror> get _methods => _functionMirrors; 218 List<JsMethodMirror> get _methods => _functionMirrors;
206 219
207 Map<Symbol, ClassMirror> get classes { 220 Map<Symbol, ClassMirror> get classes {
208 var result = new Map<Symbol, ClassMirror>(); 221 if (_cachedClasses != null) return _cachedClasses;
222 var result = new Map();
209 for (String className in _classes) { 223 for (String className in _classes) {
210 JsClassMirror cls = reflectClassByMangledName(className); 224 JsClassMirror cls = reflectClassByMangledName(className);
211 result[cls.simpleName] = cls; 225 result[cls.simpleName] = cls;
212 cls._owner = this; 226 cls._owner = this;
213 } 227 }
214 return result; 228 return _cachedClasses =
229 new UnmodifiableMapView<Symbol, ClassMirror>(result);
215 } 230 }
216 231
217 InstanceMirror setField(Symbol fieldName, Object arg) { 232 InstanceMirror setField(Symbol fieldName, Object arg) {
218 String name = n(fieldName); 233 String name = n(fieldName);
219 if (name.endsWith('=')) throw new ArgumentError(''); 234 if (name.endsWith('=')) throw new ArgumentError('');
220 var mirror = functions[s('$name=')]; 235 var mirror = functions[s('$name=')];
221 if (mirror == null) mirror = variables[fieldName]; 236 if (mirror == null) mirror = variables[fieldName];
222 if (mirror == null) { 237 if (mirror == null) {
223 // TODO(ahe): What receiver to use? 238 // TODO(ahe): What receiver to use?
224 throw new NoSuchMethodError(this, '${n(fieldName)}=', [arg], null); 239 throw new NoSuchMethodError(this, '${n(fieldName)}=', [arg], null);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 mirror._owner = this; 301 mirror._owner = this;
287 } 302 }
288 return _cachedFunctionMirrors = result; 303 return _cachedFunctionMirrors = result;
289 } 304 }
290 305
291 List<VariableMirror> get _fields { 306 List<VariableMirror> get _fields {
292 if (_cachedFields != null) return _cachedFields; 307 if (_cachedFields != null) return _cachedFields;
293 var result = <VariableMirror>[]; 308 var result = <VariableMirror>[];
294 parseCompactFieldSpecification( 309 parseCompactFieldSpecification(
295 this, _compactFieldSpecification, true, result); 310 this, _compactFieldSpecification, true, result);
296 _cachedFields = result; 311 return _cachedFields = result;
297 return _cachedFields;
298 } 312 }
299 313
300 Map<Symbol, MethodMirror> get functions { 314 Map<Symbol, MethodMirror> get functions {
301 var result = new Map<Symbol, MethodMirror>(); 315 if (_cachedFunctions != null) return _cachedFunctions;
316 var result = new Map();
302 for (JsMethodMirror mirror in _functionMirrors) { 317 for (JsMethodMirror mirror in _functionMirrors) {
303 if (!mirror.isConstructor) result[mirror.simpleName] = mirror; 318 if (!mirror.isConstructor) result[mirror.simpleName] = mirror;
304 } 319 }
305 return result; 320 return _cachedFunctions =
321 new UnmodifiableMapView<Symbol, MethodMirror>(result);
306 } 322 }
307 323
308 Map<Symbol, MethodMirror> get getters { 324 Map<Symbol, MethodMirror> get getters {
309 var result = new Map<Symbol, MethodMirror>(); 325 if (_cachedGetters != null) return _cachedGetters;
326 var result = new Map();
310 // TODO(ahe): Implement this. 327 // TODO(ahe): Implement this.
311 return result; 328 return _cachedGetters =
329 new UnmodifiableMapView<Symbol, MethodMirror>(result);
312 } 330 }
313 331
314 Map<Symbol, MethodMirror> get setters { 332 Map<Symbol, MethodMirror> get setters {
315 var result = new Map<Symbol, MethodMirror>(); 333 if (_cachedSetters != null) return _cachedSetters;
334 var result = new Map();
316 // TODO(ahe): Implement this. 335 // TODO(ahe): Implement this.
317 return result; 336 return _cachedSetters =
337 new UnmodifiableMapView<Symbol, MethodMirror>(result);
318 } 338 }
319 339
320 Map<Symbol, VariableMirror> get variables { 340 Map<Symbol, VariableMirror> get variables {
321 var result = new Map<Symbol, VariableMirror>(); 341 if (_cachedVariables != null) return _cachedVariables;
342 var result = new Map();
322 for (JsVariableMirror mirror in _fields) { 343 for (JsVariableMirror mirror in _fields) {
323 result[mirror.simpleName] = mirror; 344 result[mirror.simpleName] = mirror;
324 } 345 }
325 return result; 346 return _cachedVariables =
347 new UnmodifiableMapView<Symbol, VariableMirror>(result);
326 } 348 }
327 349
328 Map<Symbol, Mirror> get members { 350 Map<Symbol, Mirror> get members {
329 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(classes); 351 if (_cachedMembers != null) return _cachedMembers;
352 Map<Symbol, Mirror> result = new Map.from(classes);
330 addToResult(Symbol key, Mirror value) { 353 addToResult(Symbol key, Mirror value) {
331 result[key] = value; 354 result[key] = value;
332 } 355 }
333 functions.forEach(addToResult); 356 functions.forEach(addToResult);
334 getters.forEach(addToResult); 357 getters.forEach(addToResult);
335 setters.forEach(addToResult); 358 setters.forEach(addToResult);
336 variables.forEach(addToResult); 359 variables.forEach(addToResult);
337 return result; 360 return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
338 } 361 }
339 362
340 List<InstanceMirror> get metadata { 363 List<InstanceMirror> get metadata {
364 if (_cachedMetadata != null) return _cachedMetadata;
341 preserveMetadata(); 365 preserveMetadata();
342 return _metadata.map(reflect).toList(); 366 return _cachedMetadata =
367 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
343 } 368 }
344 369
345 // TODO(ahe): Test this getter. 370 // TODO(ahe): Test this getter.
346 DeclarationMirror get owner => null; 371 DeclarationMirror get owner => null;
347 } 372 }
348 373
349 String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); 374 String n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
350 375
351 Symbol s(String name) { 376 Symbol s(String name) {
352 if (name == null) return null; 377 if (name == null) return null;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 class JsClassMirror extends JsTypeMirror with JsObjectMirror 529 class JsClassMirror extends JsTypeMirror with JsObjectMirror
505 implements ClassMirror { 530 implements ClassMirror {
506 final String _mangledName; 531 final String _mangledName;
507 final _jsConstructorOrInterceptor; 532 final _jsConstructorOrInterceptor;
508 final String _fieldsDescriptor; 533 final String _fieldsDescriptor;
509 final List _fieldsMetadata; 534 final List _fieldsMetadata;
510 List _metadata; 535 List _metadata;
511 JsClassMirror _superclass; 536 JsClassMirror _superclass;
512 List<JsMethodMirror> _cachedMethods; 537 List<JsMethodMirror> _cachedMethods;
513 List<JsVariableMirror> _cachedFields; 538 List<JsVariableMirror> _cachedFields;
539 UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors;
540 UnmodifiableMapView<Symbol, MethodMirror> _cachedMethodsMap;
541 UnmodifiableMapView<Symbol, MethodMirror> _cachedGetters;
542 UnmodifiableMapView<Symbol, MethodMirror> _cachedSetters;
543 UnmodifiableMapView<Symbol, VariableMirror> _cachedVariables;
544 UnmodifiableMapView<Symbol, Mirror> _cachedMembers;
545 UnmodifiableListView<InstanceMirror> _cachedMetadata;
514 546
515 // Set as side-effect of accessing JsLibraryMirror.classes. 547 // Set as side-effect of accessing JsLibraryMirror.classes.
516 JsLibraryMirror _owner; 548 JsLibraryMirror _owner;
517 549
518 JsClassMirror(Symbol simpleName, 550 JsClassMirror(Symbol simpleName,
519 this._mangledName, 551 this._mangledName,
520 this._jsConstructorOrInterceptor, 552 this._jsConstructorOrInterceptor,
521 this._fieldsDescriptor, 553 this._fieldsDescriptor,
522 this._fieldsMetadata) 554 this._fieldsMetadata)
523 : super(simpleName); 555 : super(simpleName);
524 556
525 String get _prettyName => 'ClassMirror'; 557 String get _prettyName => 'ClassMirror';
526 558
527 get _jsConstructor { 559 get _jsConstructor {
528 if (_jsConstructorOrInterceptor is Interceptor) { 560 if (_jsConstructorOrInterceptor is Interceptor) {
529 return JS('', '#.constructor', _jsConstructorOrInterceptor); 561 return JS('', '#.constructor', _jsConstructorOrInterceptor);
530 } else { 562 } else {
531 return _jsConstructorOrInterceptor; 563 return _jsConstructorOrInterceptor;
532 } 564 }
533 } 565 }
534 566
535 Map<Symbol, MethodMirror> get constructors { 567 Map<Symbol, MethodMirror> get constructors {
536 var result = new Map<Symbol, MethodMirror>(); 568 if (_cachedConstructors != null) return _cachedConstructors;
569 var result = new Map();
537 for (JsMethodMirror method in _methods) { 570 for (JsMethodMirror method in _methods) {
538 if (method.isConstructor) { 571 if (method.isConstructor) {
539 result[method.simpleName] = method; 572 result[method.simpleName] = method;
540 } 573 }
541 } 574 }
542 return result; 575 return _cachedConstructors =
576 new UnmodifiableMapView<Symbol, MethodMirror>(result);
543 } 577 }
544 578
545 List<JsMethodMirror> get _methods { 579 List<JsMethodMirror> get _methods {
546 if (_cachedMethods != null) return _cachedMethods; 580 if (_cachedMethods != null) return _cachedMethods;
547 var prototype = JS('', '#.prototype', _jsConstructor); 581 var prototype = JS('', '#.prototype', _jsConstructor);
548 List<String> keys = extractKeys(prototype); 582 List<String> keys = extractKeys(prototype);
549 var result = <JsMethodMirror>[]; 583 var result = <JsMethodMirror>[];
550 for (String key in keys) { 584 for (String key in keys) {
551 if (key == '') continue; 585 if (key == '') continue;
552 String simpleName = mangledNames[key]; 586 String simpleName = mangledNames[key];
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 var staticDescriptor = JS('', 'init.statics[#]', _mangledName); 645 var staticDescriptor = JS('', 'init.statics[#]', _mangledName);
612 if (staticDescriptor != null) { 646 if (staticDescriptor != null) {
613 parseCompactFieldSpecification( 647 parseCompactFieldSpecification(
614 this, JS('', '#[""]', staticDescriptor), true, result); 648 this, JS('', '#[""]', staticDescriptor), true, result);
615 } 649 }
616 _cachedFields = result; 650 _cachedFields = result;
617 return _cachedFields; 651 return _cachedFields;
618 } 652 }
619 653
620 Map<Symbol, MethodMirror> get methods { 654 Map<Symbol, MethodMirror> get methods {
621 var result = new Map<Symbol, MethodMirror>(); 655 if (_cachedMethodsMap != null) return _cachedMethodsMap;
656 var result = new Map();
622 for (JsMethodMirror method in _methods) { 657 for (JsMethodMirror method in _methods) {
623 if (!method.isConstructor && !method.isGetter && !method.isSetter) { 658 if (!method.isConstructor && !method.isGetter && !method.isSetter) {
624 result[method.simpleName] = method; 659 result[method.simpleName] = method;
625 } 660 }
626 } 661 }
627 return result; 662 return _cachedMethodsMap =
663 new UnmodifiableMapView<Symbol, MethodMirror>(result);
628 } 664 }
629 665
630 Map<Symbol, MethodMirror> get getters { 666 Map<Symbol, MethodMirror> get getters {
667 if (_cachedGetters != null) return _cachedGetters;
631 // TODO(ahe): This is a hack to remove getters corresponding to a field. 668 // TODO(ahe): This is a hack to remove getters corresponding to a field.
632 var fields = variables; 669 var fields = variables;
633 670
634 var result = new Map<Symbol, MethodMirror>(); 671 var result = new Map();
635 for (JsMethodMirror method in _methods) { 672 for (JsMethodMirror method in _methods) {
636 if (method.isGetter) { 673 if (method.isGetter) {
637 674
638 // TODO(ahe): This is a hack to remove getters corresponding to a field. 675 // TODO(ahe): This is a hack to remove getters corresponding to a field.
639 if (fields[method.simpleName] != null) continue; 676 if (fields[method.simpleName] != null) continue;
640 677
641 result[method.simpleName] = method; 678 result[method.simpleName] = method;
642 } 679 }
643 } 680 }
644 return result; 681 return _cachedGetters =
682 new UnmodifiableMapView<Symbol, MethodMirror>(result);
645 } 683 }
646 684
647 Map<Symbol, MethodMirror> get setters { 685 Map<Symbol, MethodMirror> get setters {
686 if (_cachedSetters != null) return _cachedSetters;
648 // TODO(ahe): This is a hack to remove setters corresponding to a field. 687 // TODO(ahe): This is a hack to remove setters corresponding to a field.
649 var fields = variables; 688 var fields = variables;
650 689
651 var result = new Map<Symbol, MethodMirror>(); 690 var result = new Map();
652 for (JsMethodMirror method in _methods) { 691 for (JsMethodMirror method in _methods) {
653 if (method.isSetter) { 692 if (method.isSetter) {
654 693
655 // TODO(ahe): This is a hack to remove setters corresponding to a field. 694 // TODO(ahe): This is a hack to remove setters corresponding to a field.
656 String name = n(method.simpleName); 695 String name = n(method.simpleName);
657 name = name.substring(0, name.length - 1); // Remove '='. 696 name = name.substring(0, name.length - 1); // Remove '='.
658 if (fields[s(name)] != null) continue; 697 if (fields[s(name)] != null) continue;
659 698
660 result[method.simpleName] = method; 699 result[method.simpleName] = method;
661 } 700 }
662 } 701 }
663 return result; 702 return _cachedSetters =
703 new UnmodifiableMapView<Symbol, MethodMirror>(result);
664 } 704 }
665 705
666 Map<Symbol, VariableMirror> get variables { 706 Map<Symbol, VariableMirror> get variables {
667 var result = new Map<Symbol, VariableMirror>(); 707 if (_cachedVariables != null) return _cachedVariables;
708 var result = new Map();
668 for (JsVariableMirror mirror in _fields) { 709 for (JsVariableMirror mirror in _fields) {
669 result[mirror.simpleName] = mirror; 710 result[mirror.simpleName] = mirror;
670 } 711 }
671 return result; 712 return _cachedVariables =
713 new UnmodifiableMapView<Symbol, VariableMirror>(result);
672 } 714 }
673 715
674 Map<Symbol, Mirror> get members { 716 Map<Symbol, Mirror> get members {
675 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(variables); 717 if (_cachedMembers != null) return _cachedMembers;
718 Map<Symbol, Mirror> result = new Map.from(variables);
676 for (JsMethodMirror method in _methods) { 719 for (JsMethodMirror method in _methods) {
677 if (method.isSetter) { 720 if (method.isSetter) {
678 String name = n(method.simpleName); 721 String name = n(method.simpleName);
679 name = name.substring(0, name.length - 1); 722 name = name.substring(0, name.length - 1);
680 // Filter-out setters corresponding to variables. 723 // Filter-out setters corresponding to variables.
681 if (result[s(name)] is VariableMirror) continue; 724 if (result[s(name)] is VariableMirror) continue;
682 } 725 }
683 // Use putIfAbsent to filter-out getters corresponding to variables. 726 // Use putIfAbsent to filter-out getters corresponding to variables.
684 result.putIfAbsent(method.simpleName, () => method); 727 result.putIfAbsent(method.simpleName, () => method);
685 } 728 }
686 return result; 729 return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result);
687 } 730 }
688 731
689 InstanceMirror setField(Symbol fieldName, Object arg) { 732 InstanceMirror setField(Symbol fieldName, Object arg) {
690 JsVariableMirror mirror = variables[fieldName]; 733 JsVariableMirror mirror = variables[fieldName];
691 if (mirror != null && mirror.isStatic && !mirror.isFinal) { 734 if (mirror != null && mirror.isStatic && !mirror.isFinal) {
692 String jsName = mirror._jsName; 735 String jsName = mirror._jsName;
693 if (!JS('bool', '# in #', jsName, JS_CURRENT_ISOLATE())) { 736 if (!JS('bool', '# in #', jsName, JS_CURRENT_ISOLATE())) {
694 throw new RuntimeError('Cannot find "$jsName" in current isolate.'); 737 throw new RuntimeError('Cannot find "$jsName" in current isolate.');
695 } 738 }
696 JS('void', '#[#] = #', JS_CURRENT_ISOLATE(), jsName, arg); 739 JS('void', '#[#] = #', JS_CURRENT_ISOLATE(), jsName, arg);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 } 806 }
764 } 807 }
765 if (_owner == null) { 808 if (_owner == null) {
766 throw new StateError('Class "${n(simpleName)}" has no owner'); 809 throw new StateError('Class "${n(simpleName)}" has no owner');
767 } 810 }
768 } 811 }
769 return _owner; 812 return _owner;
770 } 813 }
771 814
772 List<InstanceMirror> get metadata { 815 List<InstanceMirror> get metadata {
816 if (_cachedMetadata != null) return _cachedMetadata;
773 if (_metadata == null) { 817 if (_metadata == null) {
774 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor)); 818 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
775 } 819 }
776 return _metadata.map(reflect).toList(); 820 return _cachedMetadata =
821 new UnmodifiableListView<InstanceMirror>(_metadata.map(reflect));
777 } 822 }
778 823
779 ClassMirror get superclass { 824 ClassMirror get superclass {
780 if (_superclass == null) { 825 if (_superclass == null) {
781 var superclassName = _fieldsDescriptor.split(';')[0]; 826 var superclassName = _fieldsDescriptor.split(';')[0];
782 // Use _superclass == this to represent class with no superclass (Object). 827 // Use _superclass == this to represent class with no superclass (Object).
783 _superclass = (superclassName == '') 828 _superclass = (superclassName == '')
784 ? this : reflectClassByMangledName(superclassName); 829 ? this : reflectClassByMangledName(superclassName);
785 } 830 }
786 return _superclass == this ? null : _superclass; 831 return _superclass == this ? null : _superclass;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 final _jsFunction; 1012 final _jsFunction;
968 final int _parameterCount; 1013 final int _parameterCount;
969 final bool isGetter; 1014 final bool isGetter;
970 final bool isSetter; 1015 final bool isSetter;
971 final bool isStatic; 1016 final bool isStatic;
972 final bool isConstructor; 1017 final bool isConstructor;
973 final bool isOperator; 1018 final bool isOperator;
974 DeclarationMirror _owner; 1019 DeclarationMirror _owner;
975 List _metadata; 1020 List _metadata;
976 var _returnType; 1021 var _returnType;
977 var _parameters; 1022 UnmodifiableListView<ParameterMirror> _parameters;
978 1023
979 JsMethodMirror(Symbol simpleName, 1024 JsMethodMirror(Symbol simpleName,
980 this._jsFunction, 1025 this._jsFunction,
981 this._parameterCount, 1026 this._parameterCount,
982 this.isGetter, 1027 this.isGetter,
983 this.isSetter, 1028 this.isSetter,
984 this.isStatic, 1029 this.isStatic,
985 this.isConstructor, 1030 this.isConstructor,
986 this.isOperator) 1031 this.isOperator)
987 : super(simpleName); 1032 : super(simpleName);
(...skipping 21 matching lines...) Expand all
1009 optionalParameterCount = int.parse(info[2]); 1054 optionalParameterCount = int.parse(info[2]);
1010 } 1055 }
1011 return new JsMethodMirror( 1056 return new JsMethodMirror(
1012 s(name), jsFunction, requiredParameterCount + optionalParameterCount, 1057 s(name), jsFunction, requiredParameterCount + optionalParameterCount,
1013 isGetter, isSetter, isStatic, isConstructor, isOperator); 1058 isGetter, isSetter, isStatic, isConstructor, isOperator);
1014 } 1059 }
1015 1060
1016 String get _prettyName => 'MethodMirror'; 1061 String get _prettyName => 'MethodMirror';
1017 1062
1018 List<ParameterMirror> get parameters { 1063 List<ParameterMirror> get parameters {
1064 if (_parameters != null) return _parameters;
1019 metadata; // Compute _parameters as a side-effect of extracting metadata. 1065 metadata; // Compute _parameters as a side-effect of extracting metadata.
1020 return new List<ParameterMirror>.from(_parameters); 1066 return _parameters;
1021 } 1067 }
1022 1068
1023 DeclarationMirror get owner => _owner; 1069 DeclarationMirror get owner => _owner;
1024 1070
1025 TypeMirror get returnType { 1071 TypeMirror get returnType {
1026 metadata; // Compute _returnType as a side-effect of extracting metadata. 1072 metadata; // Compute _returnType as a side-effect of extracting metadata.
1027 return typeMirrorFromRuntimeTypeRepresentation(_returnType); 1073 return typeMirrorFromRuntimeTypeRepresentation(_returnType);
1028 } 1074 }
1029 1075
1030 List<InstanceMirror> get metadata { 1076 List<InstanceMirror> get metadata {
1031 if (_metadata == null) { 1077 if (_metadata == null) {
1032 var raw = extractMetadata(_jsFunction); 1078 var raw = extractMetadata(_jsFunction);
1033 _returnType = raw[0]; 1079 var formals = new List(_parameterCount);
1034 int parameterLength = 1 + _parameterCount * 2; 1080 if (!raw.isEmpty) {
1035 var formals = new List<ParameterMirror>(_parameterCount); 1081 _returnType = raw[0];
1036 int formalsCount = 0; 1082 int parameterLength = 1 + _parameterCount * 2;
1037 for (int i = 1; i < parameterLength; i += 2) { 1083 int formalsCount = 0;
1038 var name = raw[i]; 1084 for (int i = 1; i < parameterLength; i += 2) {
1039 var type = raw[i + 1]; 1085 var name = raw[i];
1040 formals[formalsCount++] = new JsParameterMirror(name, this, type); 1086 var type = raw[i + 1];
1087 formals[formalsCount++] = new JsParameterMirror(name, this, type);
1088 }
1089 raw = raw.sublist(parameterLength);
1090 } else {
1091 for (int i = 0; i < _parameterCount; i++) {
1092 formals[i] = new JsParameterMirror('argument$i', this, null);
1093 }
1041 } 1094 }
1042 _parameters = formals; 1095 _parameters = new UnmodifiableListView<ParameterMirror>(formals);
1043 _metadata = raw.sublist(parameterLength); 1096 _metadata = new UnmodifiableListView(raw.map(reflect));
1044 } 1097 }
1045 return _metadata.map(reflect).toList(); 1098 return _metadata;
1046 } 1099 }
1047 1100
1048 Symbol get constructorName { 1101 Symbol get constructorName {
1049 // TODO(ahe): I believe it is more appropriate to throw an exception or 1102 // TODO(ahe): I believe it is more appropriate to throw an exception or
1050 // return null. 1103 // return null.
1051 if (!isConstructor) return const Symbol(''); 1104 if (!isConstructor) return const Symbol('');
1052 String name = n(simpleName); 1105 String name = n(simpleName);
1053 int index = name.indexOf('.'); 1106 int index = name.indexOf('.');
1054 if (index == -1) return const Symbol(''); 1107 if (index == -1) return const Symbol('');
1055 return s(name.substring(index + 1)); 1108 return s(name.substring(index + 1));
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 case '|': 1268 case '|':
1216 case '-': 1269 case '-':
1217 case 'unary-': 1270 case 'unary-':
1218 case '[]=': 1271 case '[]=':
1219 case '~': 1272 case '~':
1220 return true; 1273 return true;
1221 default: 1274 default:
1222 return false; 1275 return false;
1223 } 1276 }
1224 } 1277 }
1278
1279 // Copied from package "unmodifiable_collection".
1280 // TODO(ahe): Lobby to get it added to dart:collection.
1281 class UnmodifiableMapView<K, V> implements Map<K, V> {
1282 Map<K, V> _source;
1283 UnmodifiableMapView(Map<K, V> source) : _source = source;
1284
1285 static void _throw() {
1286 throw new UnsupportedError("Cannot modify an unmodifiable Map");
1287 }
1288
1289 int get length => _source.length;
1290
1291 bool get isEmpty => _source.isEmpty;
1292
1293 bool get isNotEmpty => _source.isNotEmpty;
1294
1295 V operator [](K key) => _source[key];
1296
1297 bool containsKey(K key) => _source.containsKey(key);
1298
1299 bool containsValue(V value) => _source.containsValue(value);
1300
1301 void forEach(void f(K key, V value)) => _source.forEach(f);
1302
1303 Iterable<K> get keys => _source.keys;
1304
1305 Iterable<V> get values => _source.values;
1306
1307
1308 void operator []=(K key, V value) => _throw();
1309
1310 V putIfAbsent(K key, V ifAbsent()) { _throw(); }
kustermann 2013/08/12 17:07:01 Why do you use once {} and once => ?
ahe 2013/08/12 17:10:21 I don't know, this is a verbatim copy from the pac
1311
1312 void addAll(Map<K, V> other) => _throw();
1313
1314 V remove(K key) { _throw(); }
1315
1316 void clear() => _throw();
1317 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698