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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/lib/mirrors_patch.dart

Issue 14646031: Implement invoke, setField, and getField (unminified). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 // Patch library for dart:mirrors. 5 // Patch library for dart:mirrors.
6 6
7 import 'dart:_foreign_helper' show JS; 7 import 'dart:_foreign_helper' show JS;
8 import "dart:_collection-dev" as _symbol_dev; 8 import 'dart:_collection-dev' as _symbol_dev;
9 9 import 'dart:_js_helper' show createInvocationMirror;
10 // Yeah, seriously: mirrors in dart2js are experimental... 10 import 'dart:_interceptors' show getInterceptor;
11 const String _MIRROR_OPT_IN_MESSAGE = """
12
13 This program is using an experimental feature called \"mirrors\". As
14 currently implemented, mirrors do not work with minification, and will
15 cause spurious errors depending on how code was optimized.
16
17 The authors of this program are aware of these problems and have
18 decided the thrill of using an experimental feature is outweighing the
19 risks. Furthermore, the authors of this program understand that
20 long-term, to fix the problems mentioned above, mirrors may have
21 negative impact on size and performance of Dart programs compiled to
22 JavaScript.
23 """;
24
25 bool _mirrorsEnabled = false;
26 11
27 patch class MirrorSystem { 12 patch class MirrorSystem {
28 patch static String getName(Symbol symbol) { 13 patch static String getName(Symbol symbol) => _n(symbol);
29 return _symbol_dev.Symbol.getName(symbol);
30 }
31 } 14 }
32 15
33 /** 16 class _MirrorSystem implements MirrorSystem {
34 * Stub class for the mirror system.
35 */
36 patch MirrorSystem currentMirrorSystem() {
37 _ensureEnabled();
38 throw new UnsupportedError("MirrorSystem not implemented");
39 } 17 }
40 18
19 String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
20
21 patch MirrorSystem currentMirrorSystem() => _currentMirrorSystem;
22
23 final _MirrorSystem _currentMirrorSystem = new _MirrorSystem();
24
41 patch Future<MirrorSystem> mirrorSystemOf(SendPort port) { 25 patch Future<MirrorSystem> mirrorSystemOf(SendPort port) {
42 _ensureEnabled();
43 throw new UnsupportedError("MirrorSystem not implemented"); 26 throw new UnsupportedError("MirrorSystem not implemented");
44 } 27 }
45 28
46 patch InstanceMirror reflect(Object reflectee) { 29 patch InstanceMirror reflect(Object reflectee) {
47 if (!_mirrorsEnabled && (_MIRROR_OPT_IN_MESSAGE == reflectee)) {
48 // Turn on mirrors and warn that it is an experimental feature.
49 _mirrorsEnabled = true;
50 print(reflectee);
51 }
52 return new _InstanceMirror(reflectee); 30 return new _InstanceMirror(reflectee);
53 } 31 }
54 32
55 patch ClassMirror reflectClass(Type key) { 33 final Expando<ClassMirror> _classMirrors = new Expando<ClassMirror>();
56 throw new UnimplementedError('reflectClass is not yet implemented' 34
57 'in dart2js'); 35 patch ClassMirror reflectClass(Type key) => _reflectClass(key);
36
37 // TODO(ahe): This is a workaround for http://dartbug.com/10543
38 ClassMirror _reflectClass(Type key) {
39 String className = '$key';
40 var constructor = Primitives.getConstructor(className);
41 if (constructor == null) {
42 // Probably an intercepted class.
43 // TODO(ahe): How to handle intercepted classes?
44 throw new UnsupportedError('Cannot find class for: $className');
45 }
46 var mirror = _classMirrors[constructor];
47 if (mirror == null) {
48 mirror = new _ClassMirror(className, constructor);
49 _classMirrors[constructor] = mirror;
50 }
51 return mirror;
58 } 52 }
59 53
60 class _InstanceMirror extends InstanceMirror { 54 class _InstanceMirror extends InstanceMirror {
61 static final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>();
62 55
63 final reflectee; 56 final reflectee;
64 57
65 _InstanceMirror(this.reflectee); 58 _InstanceMirror(this.reflectee);
66 59
67 bool get hasReflectee => true; 60 bool get hasReflectee => true;
68 61
69 ClassMirror get type { 62 ClassMirror get type => _reflectClass(reflectee.runtimeType);
70 _ensureEnabled(); 63
71 String className = Primitives.objectTypeName(reflectee); 64 Future<InstanceMirror> invokeAsync(Symbol memberName,
72 var constructor = Primitives.getConstructor(className); 65 List<Object> positionalArguments,
73 var mirror = classMirrors[constructor]; 66 [Map<String,Object> namedArguments]) {
74 if (mirror == null) { 67 if (namedArguments != null && !namedArguments.isEmpty) {
75 mirror = new _ClassMirror(className, constructor); 68 throw new UnsupportedError('Named arguments are not implemented');
76 classMirrors[constructor] = mirror;
77 } 69 }
78 return mirror; 70 return
71 new Future<InstanceMirror>(
72 () => invoke(memberName, positionalArguments, namedArguments));
79 } 73 }
80 74
81 Future<InstanceMirror> invokeAsync(String memberName, 75 InstanceMirror invoke(Symbol memberName,
82 List<Object> positionalArguments, 76 List positionalArguments,
83 [Map<String,Object> namedArguments]) { 77 [Map<Symbol,dynamic> namedArguments]) {
84 _ensureEnabled();
85 if (namedArguments != null && !namedArguments.isEmpty) { 78 if (namedArguments != null && !namedArguments.isEmpty) {
86 throw new UnsupportedError('Named arguments are not implemented'); 79 throw new UnsupportedError('Named arguments are not implemented');
87 } 80 }
88 // Copy the list to ensure that it can safely be passed to 81 // Copy the list to ensure that it can safely be passed to
89 // JavaScript. 82 // JavaScript.
90 var jsList = new List.from(positionalArguments); 83 var jsList = new List.from(positionalArguments);
91 var mangledName = '${memberName}\$${positionalArguments.length}'; 84 return _invoke(
92 var method = JS('var', '#[#]', reflectee, mangledName); 85 memberName, JSInvocationMirror.METHOD,
93 var completer = new Completer<InstanceMirror>(); 86 '${_n(memberName)}\$${positionalArguments.length}', jsList);
94 // TODO(ahe): [Completer] or [Future] should have API to create a 87 }
95 // delayed action. Simulating with a [Timer]. 88
96 Timer.run(() { 89 InstanceMirror _invoke(Symbol name,
97 if (JS('String', 'typeof #', method) == 'function') { 90 int type,
98 var result = 91 String mangledName,
99 JS('var', '#.apply(#, #)', method, reflectee, jsList); 92 List arguments) {
100 completer.complete(new _InstanceMirror(result)); 93 // TODO(ahe): Get the argument names.
101 } else { 94 List<String> argumentNames = [];
102 completer.completeError('not a method $memberName'); 95 Invocation invocation = createInvocationMirror(
103 } 96 _n(name), mangledName, type, arguments, argumentNames);
104 }); 97
105 return completer.future; 98 return new _InstanceMirror(delegate(invocation));
99 }
100
101 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
102 return new Future<InstanceMirror>(() => setField(fieldName, value));
103 }
104
105 InstanceMirror setField(Symbol fieldName, Object arg) {
106 _invoke(
107 fieldName, JSInvocationMirror.SETTER, 'set\$${_n(fieldName)}', [arg]);
108 return new _InstanceMirror(arg);
109 }
110
111 InstanceMirror getField(Symbol fieldName) {
112 return _invoke(
113 fieldName, JSInvocationMirror.GETTER, 'get\$${_n(fieldName)}', []);
114 }
115
116 Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
117 return new Future<InstanceMirror>(() => getField(fieldName));
106 } 118 }
107 119
108 delegate(Invocation invocation) { 120 delegate(Invocation invocation) {
109 return JSInvocationMirror.invokeFromMirror(invocation, reflectee); 121 return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
110 } 122 }
111 123
112 String toString() => 'InstanceMirror($reflectee)'; 124 String toString() => 'InstanceMirror($reflectee)';
113 } 125 }
114 126
115 class _ClassMirror extends ClassMirror { 127 class _ClassMirror extends ClassMirror {
116 final String _name; 128 final String _name;
117 final _jsConstructor; 129 final _jsConstructor;
118 130
119 _ClassMirror(this._name, this._jsConstructor) { 131 _ClassMirror(this._name, this._jsConstructor) {
120 _ensureEnabled();
121 } 132 }
122 133
123 String toString() => 'ClassMirror($_name)'; 134 String toString() => 'ClassMirror($_name)';
124 } 135 }
125
126 _ensureEnabled() {
127 if (_mirrorsEnabled) return;
128 throw new UnsupportedError('dart:mirrors is an experimental feature');
129 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698