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

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

Issue 19405002: Implement reflecting on static fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix a long line. Created 7 years, 5 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
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:mirrors'; 8 import 'dart:mirrors';
9 9
10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE; 10 import 'dart:_foreign_helper' show JS, JS_CURRENT_ISOLATE;
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}'; 397 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
398 398
399 // TODO(ahe): Remove this method from the API. 399 // TODO(ahe): Remove this method from the API.
400 MirrorSystem get mirrors => currentJsMirrorSystem; 400 MirrorSystem get mirrors => currentJsMirrorSystem;
401 } 401 }
402 402
403 class JsClassMirror extends JsTypeMirror with JsObjectMirror 403 class JsClassMirror extends JsTypeMirror with JsObjectMirror
404 implements ClassMirror { 404 implements ClassMirror {
405 final String _mangledName; 405 final String _mangledName;
406 final _jsConstructorOrInterceptor; 406 final _jsConstructorOrInterceptor;
407 final String _fields; 407 final String _fieldsDescriptor;
408 final List _fieldsMetadata; 408 final List _fieldsMetadata;
409 List _metadata; 409 List _metadata;
410 JsClassMirror _superclass; 410 JsClassMirror _superclass;
411 List<JsMethodMirror> _cachedMethods; 411 List<JsMethodMirror> _cachedMethods;
412 List<JsVariableMirror> _cachedFields;
412 413
413 // Set as side-effect of accessing JsLibraryMirror.classes. 414 // Set as side-effect of accessing JsLibraryMirror.classes.
414 JsLibraryMirror _owner; 415 JsLibraryMirror _owner;
415 416
416 JsClassMirror(Symbol simpleName, 417 JsClassMirror(Symbol simpleName,
417 this._mangledName, 418 this._mangledName,
418 this._jsConstructorOrInterceptor, 419 this._jsConstructorOrInterceptor,
419 this._fields, 420 this._fieldsDescriptor,
420 this._fieldsMetadata) 421 this._fieldsMetadata)
421 : super(simpleName); 422 : super(simpleName);
422 423
423 String get _prettyName => 'ClassMirror'; 424 String get _prettyName => 'ClassMirror';
424 425
425 get _jsConstructor { 426 get _jsConstructor {
426 if (_jsConstructorOrInterceptor is Interceptor) { 427 if (_jsConstructorOrInterceptor is Interceptor) {
427 return JS('', '#.constructor', _jsConstructorOrInterceptor); 428 return JS('', '#.constructor', _jsConstructorOrInterceptor);
428 } else { 429 } else {
429 return _jsConstructorOrInterceptor; 430 return _jsConstructorOrInterceptor;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 JsMethodMirror mirror = 488 JsMethodMirror mirror =
488 new JsMethodMirror.fromUnmangledName( 489 new JsMethodMirror.fromUnmangledName(
489 unmangledName, jsFunction, isStatic, isConstructor); 490 unmangledName, jsFunction, isStatic, isConstructor);
490 result.add(mirror); 491 result.add(mirror);
491 mirror._owner = this; 492 mirror._owner = this;
492 } 493 }
493 494
494 return _cachedMethods = result; 495 return _cachedMethods = result;
495 } 496 }
496 497
498 List<VariableMirror> get _fields {
499 if (_cachedFields != null) return _cachedFields;
500 var result = <VariableMirror>[];
501 var s = _fieldsDescriptor.split(';');
502 var fields = s[1] == '' ? [] : s[1].split(',');
503 int fieldNumber = 0;
504 for (String field in fields) {
505 var metadata;
506 if (_fieldsMetadata != null) {
507 metadata = _fieldsMetadata[fieldNumber++];
508 }
509 JsVariableMirror mirror =
510 new JsVariableMirror.from(field, metadata, this, false);
511 if (mirror != null) {
512 result.add(mirror);
513 }
514 }
515
516 var staticDescriptor = JS('', 'init.statics[#]', _mangledName);
517 if (staticDescriptor != null) {
518 var staticFieldsDescriptor = JS('', '#[""]', staticDescriptor);
519 var staticFieldsMetadata = null;
520 var staticFields;
521 if (staticFieldsDescriptor is List) {
522 staticFields = staticFieldsDescriptor[0].split(',');
523 staticFieldsMetadata = staticFieldsDescriptor.sublist(1);
524 } else if (staticFieldsDescriptor is String) {
525 staticFields = staticFieldsDescriptor.split(',');
526 } else {
527 staticFields = [];
528 }
529 fieldNumber = 0;
530 for (String staticField in staticFields) {
531 var metadata;
532 if (staticFieldsMetadata != null) {
533 metadata = staticFieldsMetadata[fieldNumber++];
534 }
535 JsVariableMirror mirror =
536 new JsVariableMirror.from(staticField, metadata, this, true);
537 if (mirror != null) {
538 result.add(mirror);
539 }
540 }
541 }
542 _cachedFields = result;
543 return _cachedFields;
544 }
545
497 Map<Symbol, MethodMirror> get methods { 546 Map<Symbol, MethodMirror> get methods {
498 var result = new Map<Symbol, MethodMirror>(); 547 var result = new Map<Symbol, MethodMirror>();
499 for (JsMethodMirror method in _methods) { 548 for (JsMethodMirror method in _methods) {
500 if (!method.isConstructor && !method.isGetter && !method.isSetter) { 549 if (!method.isConstructor && !method.isGetter && !method.isSetter) {
501 result[method.simpleName] = method; 550 result[method.simpleName] = method;
502 } 551 }
503 } 552 }
504 return result; 553 return result;
505 } 554 }
506 555
(...skipping 29 matching lines...) Expand all
536 if (fields[s(name)] != null) continue; 585 if (fields[s(name)] != null) continue;
537 586
538 result[method.simpleName] = method; 587 result[method.simpleName] = method;
539 } 588 }
540 } 589 }
541 return result; 590 return result;
542 } 591 }
543 592
544 Map<Symbol, VariableMirror> get variables { 593 Map<Symbol, VariableMirror> get variables {
545 var result = new Map<Symbol, VariableMirror>(); 594 var result = new Map<Symbol, VariableMirror>();
546 var s = _fields.split(';'); 595 for (JsVariableMirror mirror in _fields) {
547 var fields = s[1] == '' ? [] : s[1].split(','); 596 result[mirror.simpleName] = mirror;
548 int fieldNumber = 0;
549 for (String field in fields) {
550 var metadata;
551 if (_fieldsMetadata != null) {
552 metadata = _fieldsMetadata[fieldNumber++];
553 }
554 JsVariableMirror mirror =
555 new JsVariableMirror.from(field, metadata, this);
556 if (mirror != null) {
557 result[mirror.simpleName] = mirror;
558 }
559 } 597 }
560 return result; 598 return result;
561 } 599 }
562 600
563 Map<Symbol, Mirror> get members { 601 Map<Symbol, Mirror> get members {
564 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(variables); 602 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(variables);
565 for (JsMethodMirror method in _methods) { 603 for (JsMethodMirror method in _methods) {
566 if (method.isSetter) { 604 if (method.isSetter) {
567 String name = n(method.simpleName); 605 String name = n(method.simpleName);
568 name = name.substring(0, name.length - 1); 606 name = name.substring(0, name.length - 1);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 689
652 List<InstanceMirror> get metadata { 690 List<InstanceMirror> get metadata {
653 if (_metadata == null) { 691 if (_metadata == null) {
654 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor)); 692 _metadata = extractMetadata(JS('', '#.prototype', _jsConstructor));
655 } 693 }
656 return _metadata.map(reflect).toList(); 694 return _metadata.map(reflect).toList();
657 } 695 }
658 696
659 ClassMirror get superclass { 697 ClassMirror get superclass {
660 if (_superclass == null) { 698 if (_superclass == null) {
661 var superclassName = _fields.split(';')[0]; 699 var superclassName = _fieldsDescriptor.split(';')[0];
662 // Use _superclass == this to represent class with no superclass (Object). 700 // Use _superclass == this to represent class with no superclass (Object).
663 _superclass = (superclassName == '') 701 _superclass = (superclassName == '')
664 ? this : reflectClassByMangledName(superclassName); 702 ? this : reflectClassByMangledName(superclassName);
665 } 703 }
666 return _superclass == this ? null : _superclass; 704 return _superclass == this ? null : _superclass;
667 } 705 }
668 706
669 // TODO(ahe): Implement these; 707 // TODO(ahe): Implement these;
670 InstanceMirror invoke(Symbol memberName, 708 InstanceMirror invoke(Symbol memberName,
671 List positionalArguments, 709 List positionalArguments,
(...skipping 22 matching lines...) Expand all
694 JsVariableMirror(Symbol simpleName, 732 JsVariableMirror(Symbol simpleName,
695 this._jsName, 733 this._jsName,
696 this.isFinal, 734 this.isFinal,
697 this.isStatic, 735 this.isStatic,
698 this._metadataFunction, 736 this._metadataFunction,
699 this._owner) 737 this._owner)
700 : super(simpleName); 738 : super(simpleName);
701 739
702 factory JsVariableMirror.from(String descriptor, 740 factory JsVariableMirror.from(String descriptor,
703 metadataFunction, 741 metadataFunction,
704 JsClassMirror owner) { 742 JsClassMirror owner,
743 bool isStatic) {
705 int length = descriptor.length; 744 int length = descriptor.length;
706 var code = fieldCode(descriptor.codeUnitAt(length - 1)); 745 var code = fieldCode(descriptor.codeUnitAt(length - 1));
707 bool isFinal = false; 746 bool isFinal = false;
708 if (code == 0) return null; // Inherited field. 747 if (code == 0) return null; // Inherited field.
709 bool hasGetter = (code & 3) != 0; 748 bool hasGetter = (code & 3) != 0;
710 bool hasSetter = (code >> 2) != 0; 749 bool hasSetter = (code >> 2) != 0;
711 isFinal = !hasSetter; 750 isFinal = !hasSetter;
712 length--; 751 length--;
713 String jsName; 752 String jsName;
714 String accessorName = jsName = descriptor.substring(0, length); 753 String accessorName = jsName = descriptor.substring(0, length);
715 int divider = descriptor.indexOf(':'); 754 int divider = descriptor.indexOf(':');
716 if (divider > 0) { 755 if (divider > 0) {
717 accessorName = accessorName.substring(0, divider); 756 accessorName = accessorName.substring(0, divider);
718 jsName = accessorName.substring(divider + 1); 757 jsName = accessorName.substring(divider + 1);
719 } 758 }
759 var unmangledName =
760 (isStatic ? mangledGlobalNames : mangledNames)[accessorName];
761 if (unmangledName == null) unmangledName = accessorName;
720 if (!hasSetter) { 762 if (!hasSetter) {
721 // TODO(ahe): This is a hack to handle checked setters in checked mode. 763 // TODO(ahe): This is a hack to handle checked setters in checked mode.
722 var setterName = s('$accessorName='); 764 var setterName = s('$accessorName=');
723 for (JsMethodMirror method in owner._methods) { 765 for (JsMethodMirror method in owner._methods) {
724 if (method.simpleName == setterName) { 766 if (method.simpleName == setterName) {
725 isFinal = false; 767 isFinal = false;
726 break; 768 break;
727 } 769 }
728 } 770 }
729 } 771 }
730 return new JsVariableMirror( 772 return new JsVariableMirror(
731 s(accessorName), jsName, isFinal, false, metadataFunction, owner); 773 s(unmangledName), jsName, isFinal, isStatic, metadataFunction, owner);
732 } 774 }
733 775
734 String get _prettyName => 'VariableMirror'; 776 String get _prettyName => 'VariableMirror';
735 777
736 // TODO(ahe): Improve this information and test it. 778 // TODO(ahe): Improve this information and test it.
737 TypeMirror get type => JsMirrorSystem._dynamicType; 779 TypeMirror get type => JsMirrorSystem._dynamicType;
738 780
739 DeclarationMirror get owner => _owner; 781 DeclarationMirror get owner => _owner;
740 782
741 List<InstanceMirror> get metadata { 783 List<InstanceMirror> get metadata {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 var metadataFunction = JS('', '#["@"]', victim); 1000 var metadataFunction = JS('', '#["@"]', victim);
959 if (metadataFunction != null) return JS('', '#()', metadataFunction); 1001 if (metadataFunction != null) return JS('', '#()', metadataFunction);
960 String source = JS('String', 'Function.prototype.toString.call(#)', victim); 1002 String source = JS('String', 'Function.prototype.toString.call(#)', victim);
961 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}')); 1003 int index = source.lastIndexOf(new RegExp('"[0-9,]*";?[ \n\r]*}'));
962 if (index == -1) return const []; 1004 if (index == -1) return const [];
963 index++; 1005 index++;
964 int endQuote = source.indexOf('"', index); 1006 int endQuote = source.indexOf('"', index);
965 return source.substring(index, endQuote).split(',').map(int.parse).map( 1007 return source.substring(index, endQuote).split(',').map(int.parse).map(
966 (int i) => JS('', 'init.metadata[#]', i)).toList(); 1008 (int i) => JS('', 'init.metadata[#]', i)).toList();
967 } 1009 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698