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

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

Issue 23707046: Support typeArguments, isOriginalDeclaration, and get originalDeclaration in ClassMirror. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments. Created 7 years, 3 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 | sdk/lib/_internal/lib/mirrors_patch.dart » ('j') | 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:collection' show UnmodifiableListView;
9 import 'dart:mirrors'; 9 import 'dart:mirrors';
10 10
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 411
412 InstanceMirror reflect(Object reflectee) { 412 InstanceMirror reflect(Object reflectee) {
413 if (reflectee is Closure) { 413 if (reflectee is Closure) {
414 return new JsClosureMirror(reflectee); 414 return new JsClosureMirror(reflectee);
415 } else { 415 } else {
416 return new JsInstanceMirror(reflectee); 416 return new JsInstanceMirror(reflectee);
417 } 417 }
418 } 418 }
419 419
420 ClassMirror reflectType(Type key) { 420 ClassMirror reflectType(Type key) {
421 // TODO(ahe): Don't discard type arguments to support 421 return reflectClassByMangledName(getMangledTypeName(key));
422 // [ClassMirror.isOriginalDeclaration] and [ClassMirror.originalDeclaration]
423 // correctly.
424 return reflectClassByMangledName(getMangledTypeName(key).split('<')[0]);
425 } 422 }
426 423
427 ClassMirror reflectClassByMangledName(String mangledName) { 424 ClassMirror reflectClassByMangledName(String mangledName) {
428 String unmangledName = mangledGlobalNames[mangledName]; 425 String unmangledName = mangledGlobalNames[mangledName];
429 if (unmangledName == null) unmangledName = mangledName; 426 if (unmangledName == null) unmangledName = mangledName;
430 return reflectClassByName(s(unmangledName), mangledName); 427 return reflectClassByName(s(unmangledName), mangledName);
431 } 428 }
432 429
433 var classMirrors; 430 var classMirrors;
434 431
435 ClassMirror reflectClassByName(Symbol symbol, String mangledName) { 432 ClassMirror reflectClassByName(Symbol symbol, String mangledName) {
436 if (classMirrors == null) classMirrors = JsCache.allocate(); 433 if (classMirrors == null) classMirrors = JsCache.allocate();
437 var mirror = JsCache.fetch(classMirrors, mangledName); 434 var mirror = JsCache.fetch(classMirrors, mangledName);
438 if (mirror != null) return mirror; 435 if (mirror != null) return mirror;
439 disableTreeShaking(); 436 disableTreeShaking();
437 int typeArgIndex = mangledName.indexOf("<");
438 if (typeArgIndex != -1) {
439 mirror = new JsTypeBoundClassMirror(
440 reflectClassByMangledName(mangledName.substring(0, typeArgIndex)),
441 // Remove the angle brackets enclosing the type arguments.
442 mangledName.substring(typeArgIndex + 1, mangledName.length - 1));
443 JsCache.update(classMirrors, mangledName, mirror);
444 return mirror;
445 }
440 var constructorOrInterceptor = 446 var constructorOrInterceptor =
441 Primitives.getConstructorOrInterceptor(mangledName); 447 Primitives.getConstructorOrInterceptor(mangledName);
442 if (constructorOrInterceptor == null) { 448 if (constructorOrInterceptor == null) {
443 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); 449 int index = JS('int|Null', 'init.functionAliases[#]', mangledName);
444 if (index != null) { 450 if (index != null) {
445 mirror = new JsTypedefMirror( 451 mirror = new JsTypedefMirror(
446 symbol, mangledName, JS('=Object', 'init.metadata[#]', index)); 452 symbol, mangledName, JS('=Object', 'init.metadata[#]', index));
447 JsCache.update(classMirrors, mangledName, mirror); 453 JsCache.update(classMirrors, mangledName, mirror);
448 return mirror; 454 return mirror;
449 } 455 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 [Map<Symbol, dynamic> namedArguments]) { 580 [Map<Symbol, dynamic> namedArguments]) {
575 return new Future<InstanceMirror>( 581 return new Future<InstanceMirror>(
576 () => this.newInstance( 582 () => this.newInstance(
577 constructorName, positionalArguments, namedArguments)); 583 constructorName, positionalArguments, namedArguments));
578 } 584 }
579 585
580 bool get isOriginalDeclaration => true; 586 bool get isOriginalDeclaration => true;
581 587
582 ClassMirror get originalDeclaration => this; 588 ClassMirror get originalDeclaration => this;
583 589
584 // TODO(ahe): Implement these. 590 // TODO(ahe): Implement this.
585 Map<Symbol, TypeVariableMirror> get typeVariables { 591 List<TypeVariableMirror> get typeVariables {
586 throw new UnimplementedError(); 592 throw new UnimplementedError();
587 } 593 }
588 Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); 594
595 List<TypeMirror> get typeArguments => new List();
589 } 596 }
590 597
591 abstract class JsObjectMirror implements ObjectMirror { 598 abstract class JsObjectMirror implements ObjectMirror {
592 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { 599 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
593 return new Future<InstanceMirror>(() => this.setField(fieldName, value)); 600 return new Future<InstanceMirror>(() => this.setField(fieldName, value));
594 } 601 }
595 602
596 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { 603 Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
597 return new Future<InstanceMirror>(() => this.getField(fieldName)); 604 return new Future<InstanceMirror>(() => this.getField(fieldName));
598 } 605 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 return other is JsInstanceMirror && 709 return other is JsInstanceMirror &&
703 identical(reflectee, other.reflectee); 710 identical(reflectee, other.reflectee);
704 } 711 }
705 712
706 int get hashCode { 713 int get hashCode {
707 // If the reflectee is a built-in type, use the base-level hashCode to 714 // If the reflectee is a built-in type, use the base-level hashCode to
708 // preserve the illusion that, e.g. doubles, with the same value are 715 // preserve the illusion that, e.g. doubles, with the same value are
709 // identical. Otherwise, use the primitive identity hash to maintain 716 // identical. Otherwise, use the primitive identity hash to maintain
710 // correctness even if a user-defined hashCode returns different values for 717 // correctness even if a user-defined hashCode returns different values for
711 // successive invocations. 718 // successive invocations.
712 var h = ((JS('bool', 'typeof # != "object"', reflectee)) || 719 var h = ((JS('bool', 'typeof # != "object"', reflectee)) ||
713 (reflectee == null)) 720 (reflectee == null))
714 ? reflectee.hashCode 721 ? reflectee.hashCode
715 : Primitives.objectHashCode(reflectee); 722 : Primitives.objectHashCode(reflectee);
716 // Avoid hash collisions with the reflectee. This constant is in Smi range 723 // Avoid hash collisions with the reflectee. This constant is in Smi range
717 // and happens to be the inner padding from RFC 2104. 724 // and happens to be the inner padding from RFC 2104.
718 return h ^ 0x36363636; 725 return h ^ 0x36363636;
719 } 726 }
720 727
721 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}'; 728 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}';
722 729
723 // TODO(ahe): Remove this method from the API. 730 // TODO(ahe): Remove this method from the API.
724 MirrorSystem get mirrors => currentJsMirrorSystem; 731 MirrorSystem get mirrors => currentJsMirrorSystem;
725 } 732 }
726 733
734 /**
735 * ClassMirror for generic classes where the type parameters are bound.
736 *
737 * [typeArguments] will return a list of the type arguments, in constrast
738 * to JsCLassMirror that returns an empty list since it represents original
739 * declarations and classes that are not generic.
740 */
741 class JsTypeBoundClassMirror implements ClassMirror {
742 final JsClassMirror _class;
743
744 /**
745 * When instantiated this field will hold a string representing the list of
746 * type arguments for the class, i.e. what is inside the outermost angle
747 * brackets. Then, when get typeArguments is called the first time, the string
748 * is parsed into the actual list of TypeMirrors, and the field is overridden
749 * with this value.
750 */
751 var _typeArgs;
752
753 JsTypeBoundClassMirror(this._class, this._typeArgs);
754
755 List<TypeVariableMirror> get typeVariables => _class.typeVariables;
756
757 List<TypeMirror> get typeArguments {
758 if (_typeArgs is! String) return _typeArgs;
759 List result = new List();
760 if (_typeArgs.indexOf('<') == -1) {
761 for (String s in _typeArgs.split(',')) {
762 result.add(reflectClassByMangledName(s.trim()));
763 }
764 } else {
765 int level = 0;
766 StringBuffer currentTypeArg = new StringBuffer();
767
768 addCurrentTypeArg() {
769 var classMirror = reflectClassByMangledName(currentTypeArg.toString());
770 result.add(classMirror);
771 currentTypeArg.clear();
772 }
773
774 for (int i = 0; i < _typeArgs.length; i++) {
775 var character = _typeArgs[i];
776 if (character == ' ') {
777 continue;
778 } else if (character == '<') {
779 currentTypeArg.write(character);
780 level++;
781 } else if (character == '>') {
782 currentTypeArg.write(character);
783 level--;
784 } else if (character == ',') {
785 if (level > 0) {
786 currentTypeArg.write(character);
787 } else {
788 addCurrentTypeArg();
789 }
790 } else {
791 currentTypeArg.write(character);
792 }
793 }
794 addCurrentTypeArg();
795 }
796 return _typeArgs = new UnmodifiableListView(result);
797 }
798
799 Map<Symbol, MethodMirror> get constructors => _class.constructors;
800
801 Map<Symbol, MethodMirror> get methods => _class.methods;
802
803 Map<Symbol, MethodMirror> get getters => _class.getters;
804
805 Map<Symbol, MethodMirror> get setters => _class.setters;
806
807 Map<Symbol, VariableMirror> get variables => _class.variables;
808
809 Map<Symbol, Mirror> get members => _class.members;
810
811 InstanceMirror setField(Symbol fieldName, Object arg) {
812 return _class.setField(fieldName, arg);
813 }
814
815 InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName);
816
817 InstanceMirror newInstance(Symbol constructorName,
818 List positionalArguments,
819 [Map<Symbol, dynamic> namedArguments]) {
820 return _class.newInstance(constructorName,
821 positionalArguments,
822 namedArguments);
823 }
824
825 Future<InstanceMirror> newInstanceAsync(
826 Symbol constructorName,
827 List positionalArguments,
828 [Map<Symbol, dynamic> namedArguments]) {
829 return _class.newInstanceAsync(constructorName,
830 positionalArguments,
831 namedArguments);
832 }
833
834 JsLibraryMirror get owner => _class.owner;
835
836 List<InstanceMirror> get metadata => _class.metadata;
837
838 ClassMirror get superclass => _class.superclass;
839
840 InstanceMirror invoke(Symbol memberName,
841 List positionalArguments,
842 [Map<Symbol,dynamic> namedArguments]) {
843 return _class.invoke(memberName, positionalArguments, namedArguments);
844 }
845
846 bool get isOriginalDeclaration => false;
847
848 ClassMirror get originalDeclaration => _class;
849
850 List<ClassMirror> get superinterfaces => _class.superinterfaces;
851
852 Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
853 return _class.getFieldAsync(fieldName);
854 }
855
856 bool get hasReflectedType => _class.hasReflectedType;
857
858 Future<InstanceMirror> invokeAsync(Symbol memberName,
859 List positionalArguments,
860 [Map<Symbol, dynamic> namedArguments]) {
861 return _class.invokeAsync(memberName, positionalArguments, namedArguments);
862 }
863
864 bool get isPrivate => _class.isPrivate;
865
866 bool get isTopLevel => _class.isTopLevel;
867
868 SourceLocation get location => _class.location;
869
870 MirrorSystem get mirrors => _class.mirrors;
871
872 Symbol get qualifiedName => _class.qualifiedName;
873
874 Type get reflectedType => _class.reflectedType;
875
876 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
877 return _class.setFieldAsync(fieldName, value);
878 }
879
880 Symbol get simpleName => _class.simpleName;
881 }
882
727 class JsClassMirror extends JsTypeMirror with JsObjectMirror 883 class JsClassMirror extends JsTypeMirror with JsObjectMirror
728 implements ClassMirror { 884 implements ClassMirror {
729 final String _mangledName; 885 final String _mangledName;
730 final _jsConstructorOrInterceptor; 886 final _jsConstructorOrInterceptor;
731 final String _fieldsDescriptor; 887 final String _fieldsDescriptor;
732 final List _fieldsMetadata; 888 final List _fieldsMetadata;
733 final _jsConstructorCache = JsCache.allocate(); 889 final _jsConstructorCache = JsCache.allocate();
734 List _metadata; 890 List _metadata;
735 ClassMirror _superclass; 891 ClassMirror _superclass;
736 List<JsMethodMirror> _cachedMethods; 892 List<JsMethodMirror> _cachedMethods;
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 var type = JS('=Object', 'init.metadata[#]', i); 1237 var type = JS('=Object', 'init.metadata[#]', i);
1082 return typeMirrorFromRuntimeTypeRepresentation(type); 1238 return typeMirrorFromRuntimeTypeRepresentation(type);
1083 } 1239 }
1084 result = interfaces.map(lookupType).toList(); 1240 result = interfaces.map(lookupType).toList();
1085 } 1241 }
1086 return _cachedSuperinterfaces = 1242 return _cachedSuperinterfaces =
1087 new UnmodifiableListView<ClassMirror>(result); 1243 new UnmodifiableListView<ClassMirror>(result);
1088 } 1244 }
1089 1245
1090 // TODO(ahe): Implement these. 1246 // TODO(ahe): Implement these.
1091 Map<Symbol, TypeVariableMirror> get typeVariables 1247 List<TypeVariableMirror> get typeVariables
1092 => throw new UnimplementedError(); 1248 => throw new UnimplementedError();
1093 Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); 1249 List<TypeMirror> get typeArguments => new List();
1094 } 1250 }
1095 1251
1096 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { 1252 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror {
1097 static final int REFLECTION_MARKER = 45; 1253 static final int REFLECTION_MARKER = 45;
1098 1254
1099 // TODO(ahe): The values in these fields are virtually untested. 1255 // TODO(ahe): The values in these fields are virtually untested.
1100 final String _jsName; 1256 final String _jsName;
1101 final bool isFinal; 1257 final bool isFinal;
1102 final bool isStatic; 1258 final bool isStatic;
1103 final _metadataFunction; 1259 final _metadataFunction;
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 final String _mangledName; 1609 final String _mangledName;
1454 final JsFunctionTypeMirror referent; 1610 final JsFunctionTypeMirror referent;
1455 1611
1456 JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData) 1612 JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData)
1457 : referent = new JsFunctionTypeMirror(_typeData), 1613 : referent = new JsFunctionTypeMirror(_typeData),
1458 super(simpleName); 1614 super(simpleName);
1459 1615
1460 JsFunctionTypeMirror get value => referent; 1616 JsFunctionTypeMirror get value => referent;
1461 1617
1462 String get _prettyName => 'TypedefMirror'; 1618 String get _prettyName => 'TypedefMirror';
1619
1620 // TODO(zarah): This method doesn't belong here, since TypedefMirror shouldn't
1621 // be a subtype of ClassMirror.
1622 ClassMirror get originalDeclaration => this;
1463 } 1623 }
1464 1624
1465 class JsFunctionTypeMirror implements FunctionTypeMirror { 1625 class JsFunctionTypeMirror implements FunctionTypeMirror {
1466 final _typeData; 1626 final _typeData;
1467 String _cachedToString; 1627 String _cachedToString;
1468 TypeMirror _cachedReturnType; 1628 TypeMirror _cachedReturnType;
1469 UnmodifiableListView<ParameterMirror> _cachedParameters; 1629 UnmodifiableListView<ParameterMirror> _cachedParameters;
1470 1630
1471 JsFunctionTypeMirror(this._typeData); 1631 JsFunctionTypeMirror(this._typeData);
1472 1632
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 void operator []=(K key, V value) => _throw(); 1844 void operator []=(K key, V value) => _throw();
1685 1845
1686 V putIfAbsent(K key, V ifAbsent()) { _throw(); } 1846 V putIfAbsent(K key, V ifAbsent()) { _throw(); }
1687 1847
1688 void addAll(Map<K, V> other) => _throw(); 1848 void addAll(Map<K, V> other) => _throw();
1689 1849
1690 V remove(K key) { _throw(); } 1850 V remove(K key) { _throw(); }
1691 1851
1692 void clear() => _throw(); 1852 void clear() => _throw();
1693 } 1853 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/lib/mirrors_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698