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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart

Issue 2410453002: Handle private members in dart:mirrors (Closed)
Patch Set: More fixes Created 4 years, 2 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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:mirrors'; 7 import 'dart:mirrors';
8 import 'dart:_foreign_helper' show JS; 8 import 'dart:_foreign_helper' show JS;
9 import 'dart:_internal' as _internal; 9 import 'dart:_internal' as _internal;
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 dynamic _getGenericArgs(obj) { 66 dynamic _getGenericArgs(obj) {
67 return JS('', '#.getGenericArgs(#)', _dart, obj); 67 return JS('', '#.getGenericArgs(#)', _dart, obj);
68 } 68 }
69 69
70 dynamic _defaultConstructorType(type) { 70 dynamic _defaultConstructorType(type) {
71 return JS('', '#.definiteFunctionType(#, [])', _dart, type); 71 return JS('', '#.definiteFunctionType(#, [])', _dart, type);
72 } 72 }
73 73
74 typedef T _Lazy<T>(); 74 typedef T _Lazy<T>();
75 75
76 Map _toDartMap(data) {
77 if (data == null) return {};
78 Map m = JS('', '#.map(#)', _dart, data);
Bob Nystrom 2016/10/10 22:43:58 The first argument to JS is the return type, right
vsm 2016/10/10 22:56:19 Done.
79 // Note: we recorded a map from fields/methods to their type and metadata.
80 // The key is a string name for public members but an ES6 symbol for private
81 // ones. That's works nicely for dynamic operations, but dart:mirrors expects
82 // strings, so we convert back here.
83 var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data);
84 for (var member in privateMembers) {
85 // Convert private JS symbol "Symbol(_foo)" to string "_foo".
86 var str = member.toString();
87 assert(str.startsWith('Symbol(') && str.endsWith(')'));
88 var name = str.substring(7, str.length - 1);
89 m[name] = JS('', '#[#]', data, member);
90 }
91 return m;
92 }
93
76 Map _getConstructors(obj) { 94 Map _getConstructors(obj) {
77 List sig = JS('', '#.getConstructorSig(#)', _dart, obj); 95 List sig = JS('', '#.getConstructorSig(#)', _dart, obj);
78 if (sig == null) return {}; 96 return _toDartMap(sig);
79 return JS('', '#.map(#)', _dart, sig);
80 } 97 }
81 98
82 Map _getFields(obj) { 99 Map _getFields(obj) {
83 List sig = JS('', '#.getFieldSig(#)', _dart, obj); 100 List sig = JS('', '#.getFieldSig(#)', _dart, obj);
84 if (sig == null) return {}; 101 return _toDartMap(sig);
85 return JS('', '#.map(#)', _dart, sig);
86 } 102 }
87 103
88 Map _getMethods(obj) { 104 Map _getMethods(obj) {
89 List sig = JS('', '#.getMethodSig(#)', _dart, obj); 105 List sig = JS('', '#.getMethodSig(#)', _dart, obj);
90 if (sig == null) return {}; 106 return _toDartMap(sig);
91 return JS('', '#.map(#)', _dart, sig);
92 } 107 }
93 108
94 Map _getGetters(obj) { 109 Map _getGetters(obj) {
95 List sig = JS('', '#.getGetterSig(#)', _dart, obj); 110 List sig = JS('', '#.getGetterSig(#)', _dart, obj);
96 if (sig == null) return {}; 111 return _toDartMap(sig);
97 return JS('', '#.map(#)', _dart, sig);
98 } 112 }
99 113
100 Map _getSetters(obj) { 114 Map _getSetters(obj) {
101 List sig = JS('', '#.getSetterSig(#)', _dart, obj); 115 List sig = JS('', '#.getSetterSig(#)', _dart, obj);
102 if (sig == null) return {}; 116 return _toDartMap(sig);
103 return JS('', '#.map(#)', _dart, sig);
104 } 117 }
105 118
106 Map _getStaticFields(obj) { 119 Map _getStaticFields(obj) {
107 List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj); 120 List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj);
108 if (sig == null) return {}; 121 return _toDartMap(sig);
109 return JS('', '#.map(#)', _dart, sig);
110 } 122 }
111 123
112 Map _getStatics(obj) { 124 Map _getStatics(obj) {
113 List sig = JS('', '#.getStaticSig(#)', _dart, obj); 125 List sig = JS('', '#.getStaticSig(#)', _dart, obj);
114 if (sig == null) return {}; 126 return _toDartMap(sig);
115 return JS('', '#.map(#)', _dart, sig);
116 } 127 }
117 128
118 Map _getStaticGetters(obj) { 129 Map _getStaticGetters(obj) {
119 List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj); 130 List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj);
120 if (sig == null) return {}; 131 return _toDartMap(sig);
121 return JS('', '#.map(#)', _dart, sig);
122 } 132 }
123 133
124 Map _getStaticSetters(obj) { 134 Map _getStaticSetters(obj) {
125 List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj); 135 List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj);
126 if (sig == null) return {}; 136 return _toDartMap(sig);
127 return JS('', '#.map(#)', _dart, sig);
128 } 137 }
129 138
130 // TODO(vsm): These methods need to validate whether we really have a 139 // TODO(vsm): These methods need to validate whether we really have a
131 // WrappedType or a raw type that should be wrapped (as opposed to a 140 // WrappedType or a raw type that should be wrapped (as opposed to a
132 // function). 141 // function).
133 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); 142 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj);
134 143
135 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); 144 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj);
136 145
137 _unimplemented(Type t, Invocation i) { 146 _unimplemented(Type t, Invocation i) {
138 throw new UnimplementedError('$t.${i.memberName} unimplemented'); 147 throw new UnimplementedError('$t.${getName(i.memberName)} unimplemented');
148 }
149
150 dynamic _toJsMap(Map<Symbol, dynamic> map) {
151 var obj = JS('', '{}');
152 map.forEach((Symbol key, value) {
153 JS('', '#[#] = #', obj, getName(key), value);
154 });
155 return obj;
139 } 156 }
140 157
141 class JsMirror implements Mirror { 158 class JsMirror implements Mirror {
142 noSuchMethod(Invocation i) { 159 noSuchMethod(Invocation i) {
143 _unimplemented(this.runtimeType, i); 160 _unimplemented(this.runtimeType, i);
144 } 161 }
145 } 162 }
146 163
147 class JsCombinatorMirror extends JsMirror implements CombinatorMirror { 164 class JsCombinatorMirror extends JsMirror implements CombinatorMirror {
148 } 165 }
(...skipping 28 matching lines...) Expand all
177 bool operator==(Object other) { 194 bool operator==(Object other) {
178 return (other is JsInstanceMirror) && identical(reflectee, other.reflectee); 195 return (other is JsInstanceMirror) && identical(reflectee, other.reflectee);
179 } 196 }
180 197
181 int get hashCode { 198 int get hashCode {
182 // Avoid hash collisions with the reflectee. This constant is in Smi range 199 // Avoid hash collisions with the reflectee. This constant is in Smi range
183 // and happens to be the inner padding from RFC 2104. 200 // and happens to be the inner padding from RFC 2104.
184 return identityHashCode(reflectee) ^ 0x36363636; 201 return identityHashCode(reflectee) ^ 0x36363636;
185 } 202 }
186 203
204 // Returns a String for public members or an ES6 symbol for private members.
205 _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args,
206 Map<Symbol, dynamic> namedArgs]) {
207 var name = getName(symbol);
208 if (!name.startsWith('_')) return name;
209
210 // TODO(vsm): Ideally, we'd record ES6 symbols properly during codegen if
211 // mirrors is enabled. Here, we're trying to recover it from the receiver
212 // instead.
213 //
214 // Get private fields and members. Members are on proto.
215 var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', reflectee)
216 ..addAll(JS('', 'Object.getOwnPropertySymbols(#.__proto__)', reflectee));
217 for (var member in privateMembers) {
218 // Convert private JS symbol "Symbol(_foo)" to string "_foo".
219 var str = member.toString();
220 assert(str.startsWith('Symbol(') && str.endsWith(')'));
221 var privateName = str.substring(7, str.length - 1);
Bob Nystrom 2016/10/10 22:43:58 You have the same logic above. Make a helper funct
vsm 2016/10/10 22:56:19 Done.
222 if (name == privateName) return member;
223 }
224 return new NoSuchMethodError(reflectee, symbol, args, namedArgs);
225 }
226
187 InstanceMirror getField(Symbol symbol) { 227 InstanceMirror getField(Symbol symbol) {
188 var name = getName(symbol); 228 var name = _getAccessor(reflectee, symbol);
189 var field = _dload(reflectee, name); 229 var field = _dload(reflectee, name);
190 return reflect(field); 230 return reflect(field);
191 } 231 }
192 232
193 InstanceMirror setField(Symbol symbol, Object value) { 233 InstanceMirror setField(Symbol symbol, Object value) {
194 var name = getName(symbol); 234 var name = _getAccessor(reflectee, symbol);
195 _dput(reflectee, name, value); 235 _dput(reflectee, name, value);
196 return reflect(value); 236 return reflect(value);
197 } 237 }
198 238
199 InstanceMirror invoke(Symbol symbol, List<dynamic> args, 239 InstanceMirror invoke(Symbol symbol, List<dynamic> args,
200 [Map<Symbol, dynamic> namedArgs]) { 240 [Map<Symbol, dynamic> namedArgs]) {
201 var name = getName(symbol); 241 var name = _getAccessor(reflectee, symbol, args, namedArgs);
202 if (namedArgs != null) { 242 if (namedArgs != null) {
203 args = new List.from(args); 243 args = new List.from(args);
204 args.add(_toJsMap(namedArgs)); 244 args.add(_toJsMap(namedArgs));
205 } 245 }
206 var result = _dsend(reflectee, name, args); 246 var result = _dsend(reflectee, name, args);
207 return reflect(result); 247 return reflect(result);
208 } 248 }
209 249
210 dynamic _toJsMap(Map<Symbol, dynamic> map) { 250 String toString() => "InstanceMirror on '$reflectee'";
211 var obj = JS('', '{}');
212 map.forEach((Symbol key, value) {
213 JS('', '#[#] = #', obj, getName(key), value);
214 });
215 return obj;
216 }
217 } 251 }
218 252
219 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { 253 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
220 JsClosureMirror._(reflectee) : super._(reflectee); 254 JsClosureMirror._(reflectee) : super._(reflectee);
221 255
222 InstanceMirror apply(List<dynamic> args, 256 InstanceMirror apply(List<dynamic> args,
223 [Map<Symbol, dynamic> namedArgs]) { 257 [Map<Symbol, dynamic> namedArgs]) {
224 if (namedArgs != null) { 258 if (namedArgs != null) {
225 args = new List.from(args); 259 args = new List.from(args);
226 args.add(_toJsMap(namedArgs)); 260 args.add(_toJsMap(namedArgs));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 [Map<Symbol, dynamic> namedArgs]) { 379 [Map<Symbol, dynamic> namedArgs]) {
346 // TODO(vsm): Support factory constructors and named arguments. 380 // TODO(vsm): Support factory constructors and named arguments.
347 var name = getName(constructorName); 381 var name = getName(constructorName);
348 assert(namedArgs == null || namedArgs.isEmpty); 382 assert(namedArgs == null || namedArgs.isEmpty);
349 var instance = (name == 'new' || name == '') 383 var instance = (name == 'new' || name == '')
350 ? JS('', 'new #(...#)', _unwrap(_cls), args) 384 ? JS('', 'new #(...#)', _unwrap(_cls), args)
351 : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args); 385 : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args);
352 return reflect(instance); 386 return reflect(instance);
353 } 387 }
354 388
389 // TODO(vsm): Need to check for NSM, types on accessors below. Unlike the
390 // InstanceMirror case, there are no dynamic helper to delegate to - we never
Bob Nystrom 2016/10/10 22:43:58 "are" -> "is".
vsm 2016/10/10 22:56:19 Done.
391 // need a dload, etc. on a static.
392
393 InstanceMirror getField(Symbol symbol) {
394 var name = getName(symbol);
395 return reflect(JS('', '#[#]', _unwrap(_cls), name));
396 }
397
398 InstanceMirror setField(Symbol symbol, Object value) {
399 var name = getName(symbol);
400 JS('', '#[#] = #', _unwrap(_cls), name, value);
401 return reflect(value);
402 }
403
404 InstanceMirror invoke(Symbol symbol, List<dynamic> args,
405 [Map<Symbol, dynamic> namedArgs]) {
406 var name = getName(symbol);
407 if (namedArgs != null) {
408 args = new List.from(args);
409 args.add(_toJsMap(namedArgs));
410 }
411 var result = JS('', '#.#(...#)', _unwrap(_cls), name, args);
412 return reflect(result);
413 }
414
355 List<ClassMirror> get superinterfaces { 415 List<ClassMirror> get superinterfaces {
356 _Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls )); 416 _Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls ));
357 if (interfaceThunk == null) { 417 if (interfaceThunk == null) {
358 return []; 418 return [];
359 } else { 419 } else {
360 List<Type> interfaces = interfaceThunk(); 420 List<Type> interfaces = interfaceThunk();
361 return interfaces.map((t) => reflectType(t)).toList(); 421 return interfaces.map((t) => reflectType(t)).toList();
362 } 422 }
363 } 423 }
364 424
(...skipping 13 matching lines...) Expand all
378 throw new UnimplementedError("ClassMirror.originalDeclaration unimplemented" ); 438 throw new UnimplementedError("ClassMirror.originalDeclaration unimplemented" );
379 } 439 }
380 440
381 ClassMirror get superclass { 441 ClassMirror get superclass {
382 if (_cls == Object) { 442 if (_cls == Object) {
383 return null; 443 return null;
384 } else { 444 } else {
385 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); 445 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls))));
386 } 446 }
387 } 447 }
448
449 String toString() => "ClassMirror on '$_cls'";
388 } 450 }
389 451
390 class JsVariableMirror extends JsMirror implements VariableMirror { 452 class JsVariableMirror extends JsMirror implements VariableMirror {
391 final String _name; 453 final String _name;
392 final TypeMirror type; 454 final TypeMirror type;
393 final List<InstanceMirror> metadata; 455 final List<InstanceMirror> metadata;
394 456
395 // TODO(vsm): Refactor this out. 457 // TODO(vsm): Refactor this out.
396 Symbol get simpleName => new Symbol(_name); 458 Symbol get simpleName => new Symbol(_name);
397 459
398 // TODO(vsm): Fix this 460 // TODO(vsm): Fix this
399 final bool isStatic = false; 461 final bool isStatic = false;
400 final bool isFinal = false; 462 final bool isFinal = false;
401 463
402 JsVariableMirror._(this._name, Type t, List annotations) 464 JsVariableMirror._(this._name, Type t, List annotations)
403 : type = reflectType(t), 465 : type = reflectType(t),
404 metadata = new List<InstanceMirror>.unmodifiable( 466 metadata = new List<InstanceMirror>.unmodifiable(
405 annotations.map((a) => reflect(a))); 467 annotations.map((a) => reflect(a)));
468
469 String toString() => "VariableMirror on '$_name'";
406 } 470 }
407 471
408 class JsParameterMirror extends JsVariableMirror implements ParameterMirror { 472 class JsParameterMirror extends JsVariableMirror implements ParameterMirror {
409 JsParameterMirror._(String name, Type t, List annotations) 473 JsParameterMirror._(String name, Type t, List annotations)
410 : super._(name, t, annotations); 474 : super._(name, t, annotations);
475
476 String toString() => "ParameterMirror on '$_name'";
411 } 477 }
412 478
413 class JsMethodMirror extends JsMirror implements MethodMirror { 479 class JsMethodMirror extends JsMirror implements MethodMirror {
414 // TODO(vsm): This could be a JS symbol for private methods 480 // TODO(vsm): This could be a JS symbol for private methods
415 final String _name; 481 final String _name;
416 List<ParameterMirror> _params; 482 List<ParameterMirror> _params;
417 List<InstanceMirror> _metadata; 483 List<InstanceMirror> _metadata;
418 final bool isConstructor; 484 final bool isConstructor;
419 final bool isStatic; 485 final bool isStatic;
420 486
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 for (var i = 0; i < opts.length; ++i) { 544 for (var i = 0; i < opts.length; ++i) {
479 var type = opts[i]; 545 var type = opts[i];
480 var metadata = ftype.metadata[args.length + i]; 546 var metadata = ftype.metadata[args.length + i];
481 // TODO(vsm): Recover the param name. 547 // TODO(vsm): Recover the param name.
482 var param = new JsParameterMirror._('', _wrap(type), metadata); 548 var param = new JsParameterMirror._('', _wrap(type), metadata);
483 params[i + args.length] = param; 549 params[i + args.length] = param;
484 } 550 }
485 551
486 _params = new List.unmodifiable(params); 552 _params = new List.unmodifiable(params);
487 } 553 }
554
555 String toString() => "MethodMirror on '$_name'";
488 } 556 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/test/browser/language_tests.js ('k') | pkg/dev_compiler/tool/sdk_expected_errors.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698