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

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: Make expando private 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 {
ngeoffray 2013/05/08 12:34:06 What can you do with an instance of this class?
ahe 2013/05/08 21:47:53 Not much yet. But all the tests in mirrors_test.d
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 _MirrorSystem _currentMirrorSystem = new _MirrorSystem();
Johnni Winther 2013/05/08 08:22:08 How about making this final so it will be created
ahe 2013/05/08 08:57:43 I think making it final is a good idea, but I don'
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
33 final Expando<ClassMirror> _classMirrors = new Expando<ClassMirror>();
34
55 patch ClassMirror reflectClass(Type key) { 35 patch ClassMirror reflectClass(Type key) {
56 throw new UnimplementedError('reflectClass is not yet implemented' 36 String className = '$key';
57 'in dart2js'); 37 var constructor = Primitives.getConstructor(className);
38 if (constructor == null) {
39 // Probably an incepted class.
ngeoffray 2013/05/08 12:34:06 intercepted
40 // TODO(ahe): How to handle intercepted classes?
41 throw new UnsupportedError('Cannot find constructor for: $className');
Johnni Winther 2013/05/08 08:22:08 The error message seems a bit internal. Maybe chan
ahe 2013/05/08 08:57:43 No problem, but this is a short-term solution. Th
42 }
43 var mirror = _classMirrors[constructor];
44 if (mirror == null) {
45 mirror = new _ClassMirror(className, constructor);
46 _classMirrors[constructor] = mirror;
47 }
48 return mirror;
58 } 49 }
59 50
60 class _InstanceMirror extends InstanceMirror { 51 class _InstanceMirror extends InstanceMirror {
61 static final Expando<ClassMirror> classMirrors = new Expando<ClassMirror>();
62 52
63 final reflectee; 53 final reflectee;
64 54
65 _InstanceMirror(this.reflectee); 55 _InstanceMirror(this.reflectee);
66 56
67 bool get hasReflectee => true; 57 bool get hasReflectee => true;
68 58
69 ClassMirror get type { 59 ClassMirror get type => reflectClass(reflectee.runtimeType);
Johnni Winther 2013/05/08 08:22:08 What about reflection on [:null:]?
ahe 2013/05/08 08:57:43 The object "null" is an instance of a subclass of
70 _ensureEnabled(); 60
71 String className = Primitives.objectTypeName(reflectee); 61 Future<InstanceMirror> invokeAsync(Symbol memberName,
72 var constructor = Primitives.getConstructor(className); 62 List<Object> positionalArguments,
73 var mirror = classMirrors[constructor]; 63 [Map<String,Object> namedArguments]) {
Johnni Winther 2013/05/08 08:22:08 I think we have an inconsistency in the signatures
ahe 2013/05/08 21:47:53 I should clean this up in the VM as well, but I'd
74 if (mirror == null) { 64 if (namedArguments != null && !namedArguments.isEmpty) {
75 mirror = new _ClassMirror(className, constructor); 65 throw new UnsupportedError('Named arguments are not implemented');
76 classMirrors[constructor] = mirror;
77 } 66 }
78 return mirror; 67 return
68 new Future<InstanceMirror>(
69 () => invoke(memberName, positionalArguments, namedArguments));
79 } 70 }
80 71
81 Future<InstanceMirror> invokeAsync(String memberName, 72 InstanceMirror invoke(Symbol memberName,
82 List<Object> positionalArguments, 73 List positionalArguments,
83 [Map<String,Object> namedArguments]) { 74 [Map<Symbol,dynamic> namedArguments]) {
84 _ensureEnabled();
85 if (namedArguments != null && !namedArguments.isEmpty) { 75 if (namedArguments != null && !namedArguments.isEmpty) {
86 throw new UnsupportedError('Named arguments are not implemented'); 76 throw new UnsupportedError('Named arguments are not implemented');
87 } 77 }
88 // Copy the list to ensure that it can safely be passed to 78 // Copy the list to ensure that it can safely be passed to
89 // JavaScript. 79 // JavaScript.
90 var jsList = new List.from(positionalArguments); 80 var jsList = new List.from(positionalArguments);
91 var mangledName = '${memberName}\$${positionalArguments.length}'; 81 return _invoke(
92 var method = JS('var', '#[#]', reflectee, mangledName); 82 memberName, JSInvocationMirror.METHOD,
93 var completer = new Completer<InstanceMirror>(); 83 '${_n(memberName)}\$${positionalArguments.length}', jsList);
94 // TODO(ahe): [Completer] or [Future] should have API to create a 84 }
95 // delayed action. Simulating with a [Timer]. 85
96 Timer.run(() { 86 InstanceMirror _invoke(Symbol name,
97 if (JS('String', 'typeof #', method) == 'function') { 87 int type,
98 var result = 88 String mangledName,
99 JS('var', '#.apply(#, #)', method, reflectee, jsList); 89 List arguments) {
100 completer.complete(new _InstanceMirror(result)); 90 // TODO(ahe): Get the argument names.
101 } else { 91 List<String> argumentNames = [];
102 completer.completeError('not a method $memberName'); 92 Invocation invocation = createInvocationMirror(
103 } 93 _n(name), mangledName, type, arguments, argumentNames);
104 }); 94
105 return completer.future; 95 return new _InstanceMirror(delegate(invocation));
96 }
97
98 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) {
99 return new Future<InstanceMirror>(() => setField(fieldName, value));
100 }
101
102 InstanceMirror setField(Symbol fieldName, Object arg) {
103 _invoke(
104 fieldName, JSInvocationMirror.SETTER, 'set\$${_n(fieldName)}', [arg]);
Johnni Winther 2013/05/08 08:22:08 'set\$...' doesn't work for minification, right?
ahe 2013/05/08 08:57:43 Yes. That could have been clearer. The CL descri
105 return new _InstanceMirror(arg);
106 }
107
108 InstanceMirror getField(Symbol fieldName) {
109 return _invoke(
110 fieldName, JSInvocationMirror.GETTER, 'get\$${_n(fieldName)}', []);
Johnni Winther 2013/05/08 08:22:08 Ditto.
111 }
112
113 Future<InstanceMirror> getFieldAsync(Symbol fieldName) {
114 return new Future<InstanceMirror>(() => getField(fieldName));
106 } 115 }
107 116
108 delegate(Invocation invocation) { 117 delegate(Invocation invocation) {
109 return JSInvocationMirror.invokeFromMirror(invocation, reflectee); 118 return JSInvocationMirror.invokeFromMirror(invocation, reflectee);
110 } 119 }
111 120
112 String toString() => 'InstanceMirror($reflectee)'; 121 String toString() => 'InstanceMirror($reflectee)';
113 } 122 }
114 123
115 class _ClassMirror extends ClassMirror { 124 class _ClassMirror extends ClassMirror {
116 final String _name; 125 final String _name;
117 final _jsConstructor; 126 final _jsConstructor;
118 127
119 _ClassMirror(this._name, this._jsConstructor) { 128 _ClassMirror(this._name, this._jsConstructor) {
120 _ensureEnabled();
121 } 129 }
122 130
123 String toString() => 'ClassMirror($_name)'; 131 String toString() => 'ClassMirror($_name)';
124 } 132 }
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