OLD | NEW |
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 } | 64 } |
65 | 65 |
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 dynamic _getMixins(type) { |
| 75 return JS('', '#.getMixins(#, [])', _dart, type); |
| 76 } |
| 77 |
74 typedef T _Lazy<T>(); | 78 typedef T _Lazy<T>(); |
75 | 79 |
| 80 dynamic _getESSymbol(Symbol symbol) => |
| 81 _internal.Symbol.getNativeSymbol(symbol as _internal.Symbol); |
| 82 |
| 83 dynamic _getMember(Symbol symbol) { |
| 84 var privateSymbol = _getESSymbol(symbol); |
| 85 if (privateSymbol != null) { |
| 86 return privateSymbol; |
| 87 } |
| 88 return getName(symbol); |
| 89 } |
| 90 |
76 String _getNameForESSymbol(member) { | 91 String _getNameForESSymbol(member) { |
77 // Convert private JS symbol "Symbol(_foo)" to string "_foo". | 92 // Convert private JS symbol "Symbol(_foo)" to string "_foo". |
| 93 assert(JS('bool', 'typeof # == "symbol"', member)); |
78 var str = member.toString(); | 94 var str = member.toString(); |
79 assert(str.startsWith('Symbol(') && str.endsWith(')')); | 95 assert(str.startsWith('Symbol(') && str.endsWith(')')); |
80 return str.substring(7, str.length - 1); | 96 return str.substring(7, str.length - 1); |
81 } | 97 } |
82 | 98 |
83 Map _toDartMap(data) { | 99 Symbol _getSymbolForESSymbol(member) { |
| 100 var name = _getNameForESSymbol(member); |
| 101 return new _internal.Symbol.es6(name, member); |
| 102 } |
| 103 |
| 104 // The [member] must be either a string (public) or an ES6 symbol (private). |
| 105 Symbol _getSymbolForMember(member) { |
| 106 if (member is String) { |
| 107 return new Symbol(member); |
| 108 } else { |
| 109 var name = _getNameForESSymbol(member); |
| 110 return new _internal.Symbol.es6(name, member); |
| 111 } |
| 112 } |
| 113 |
| 114 Map<Symbol, dynamic> _toDartMap(data) { |
84 if (data == null) return {}; | 115 if (data == null) return {}; |
85 var map = JS('Map', '#.map(#)', _dart, data); | 116 var map = new Map<Symbol, dynamic>(); |
86 // Note: we recorded a map from fields/methods to their type and metadata. | 117 // Note: we recorded a map from fields/methods to their type and metadata. |
87 // The key is a string name for public members but an ES6 symbol for private | 118 // The key is a string name for public members but an ES6 symbol for private |
88 // ones. That's works nicely for dynamic operations, but dart:mirrors expects | 119 // ones. That's works nicely for dynamic operations, but dart:mirrors expects |
89 // strings, so we convert back here. | 120 // Dart symbols, so we convert here. |
| 121 var publicMembers = JS('', 'Object.getOwnPropertyNames(#)', data); |
| 122 for (var member in publicMembers) { |
| 123 var symbol = new Symbol(member); |
| 124 map[symbol] = JS('', '#[#]', data, member); |
| 125 } |
| 126 |
90 var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data); | 127 var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data); |
91 for (var member in privateMembers) { | 128 for (var member in privateMembers) { |
92 var name = _getNameForESSymbol(member); | 129 var symbol = _getSymbolForESSymbol(member); |
93 map[name] = JS('', '#[#]', data, member); | 130 map[symbol] = JS('', '#[#]', data, member); |
94 } | 131 } |
95 return map; | 132 return map; |
96 } | 133 } |
97 | 134 |
98 Map _getConstructors(obj) { | 135 Map<Symbol, dynamic> _getConstructors(obj) { |
99 List sig = JS('', '#.getConstructorSig(#)', _dart, obj); | 136 List sig = JS('', '#.getConstructorSig(#)', _dart, obj); |
100 return _toDartMap(sig); | 137 return _toDartMap(sig); |
101 } | 138 } |
102 | 139 |
103 Map _getFields(obj) { | 140 Map<Symbol, dynamic> _getFields(obj) { |
104 List sig = JS('', '#.getFieldSig(#)', _dart, obj); | 141 List sig = JS('', '#.getFieldSig(#)', _dart, obj); |
105 return _toDartMap(sig); | 142 return _toDartMap(sig); |
106 } | 143 } |
107 | 144 |
108 Map _getMethods(obj) { | 145 Map<Symbol, dynamic> _getMethods(obj) { |
109 List sig = JS('', '#.getMethodSig(#)', _dart, obj); | 146 List sig = JS('', '#.getMethodSig(#)', _dart, obj); |
110 return _toDartMap(sig); | 147 return _toDartMap(sig); |
111 } | 148 } |
112 | 149 |
113 Map _getGetters(obj) { | 150 Map<Symbol, dynamic> _getGetters(obj) { |
114 List sig = JS('', '#.getGetterSig(#)', _dart, obj); | 151 List sig = JS('', '#.getGetterSig(#)', _dart, obj); |
115 return _toDartMap(sig); | 152 return _toDartMap(sig); |
116 } | 153 } |
117 | 154 |
118 Map _getSetters(obj) { | 155 Map<Symbol, dynamic> _getSetters(obj) { |
119 List sig = JS('', '#.getSetterSig(#)', _dart, obj); | 156 List sig = JS('', '#.getSetterSig(#)', _dart, obj); |
120 return _toDartMap(sig); | 157 return _toDartMap(sig); |
121 } | 158 } |
122 | 159 |
123 Map _getStaticFields(obj) { | 160 Map<Symbol, dynamic> _getStaticFields(obj) { |
124 List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj); | 161 List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj); |
125 return _toDartMap(sig); | 162 return _toDartMap(sig); |
126 } | 163 } |
127 | 164 |
128 Map _getStatics(obj) { | 165 Map<Symbol, dynamic> _getStatics(obj) { |
129 List sig = JS('', '#.getStaticSig(#)', _dart, obj); | 166 List sig = JS('', '#.getStaticSig(#)', _dart, obj); |
130 return _toDartMap(sig); | 167 return _toDartMap(sig); |
131 } | 168 } |
132 | 169 |
133 Map _getStaticGetters(obj) { | 170 Map<Symbol, dynamic> _getStaticGetters(obj) { |
134 List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj); | 171 List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj); |
135 return _toDartMap(sig); | 172 return _toDartMap(sig); |
136 } | 173 } |
137 | 174 |
138 Map _getStaticSetters(obj) { | 175 Map<Symbol, dynamic> _getStaticSetters(obj) { |
139 List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj); | 176 List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj); |
140 return _toDartMap(sig); | 177 return _toDartMap(sig); |
141 } | 178 } |
142 | 179 |
143 // TODO(vsm): These methods need to validate whether we really have a | 180 // TODO(vsm): These methods need to validate whether we really have a |
144 // WrappedType or a raw type that should be wrapped (as opposed to a | 181 // WrappedType or a raw type that should be wrapped (as opposed to a |
145 // function). | 182 // function). |
146 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); | 183 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); |
147 | 184 |
148 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); | 185 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 | 241 |
205 int get hashCode { | 242 int get hashCode { |
206 // Avoid hash collisions with the reflectee. This constant is in Smi range | 243 // Avoid hash collisions with the reflectee. This constant is in Smi range |
207 // and happens to be the inner padding from RFC 2104. | 244 // and happens to be the inner padding from RFC 2104. |
208 return identityHashCode(reflectee) ^ 0x36363636; | 245 return identityHashCode(reflectee) ^ 0x36363636; |
209 } | 246 } |
210 | 247 |
211 // Returns a String for public members or an ES6 symbol for private members. | 248 // Returns a String for public members or an ES6 symbol for private members. |
212 _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args, | 249 _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args, |
213 Map<Symbol, dynamic> namedArgs]) { | 250 Map<Symbol, dynamic> namedArgs]) { |
214 var name = getName(symbol); | 251 return _getMember(symbol); |
215 if (!name.startsWith('_')) return name; | |
216 | |
217 // TODO(vsm): Ideally, we'd record ES6 symbols properly during codegen if | |
218 // mirrors is enabled. Here, we're trying to recover it from the receiver | |
219 // instead. | |
220 // | |
221 // Get private fields and members. Members are on proto. | |
222 var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', reflectee) | |
223 ..addAll(JS('', 'Object.getOwnPropertySymbols(#.__proto__)', reflectee)); | |
224 for (var member in privateMembers) { | |
225 var privateName = _getNameForESSymbol(member); | |
226 if (name == privateName) return member; | |
227 } | |
228 return new NoSuchMethodError(reflectee, symbol, args, namedArgs); | |
229 } | 252 } |
230 | 253 |
231 InstanceMirror getField(Symbol symbol) { | 254 InstanceMirror getField(Symbol symbol) { |
232 var name = _getAccessor(reflectee, symbol); | 255 var name = _getAccessor(reflectee, symbol); |
233 var field = _dload(reflectee, name); | 256 var field = _dload(reflectee, name); |
234 return reflect(field); | 257 return reflect(field); |
235 } | 258 } |
236 | 259 |
237 InstanceMirror setField(Symbol symbol, Object value) { | 260 InstanceMirror setField(Symbol symbol, Object value) { |
238 var name = _getAccessor(reflectee, symbol); | 261 var name = _getAccessor(reflectee, symbol); |
(...skipping 29 matching lines...) Expand all Loading... |
268 } | 291 } |
269 } | 292 } |
270 | 293 |
271 class JsClassMirror extends JsMirror implements ClassMirror { | 294 class JsClassMirror extends JsMirror implements ClassMirror { |
272 final Type _cls; | 295 final Type _cls; |
273 final Symbol simpleName; | 296 final Symbol simpleName; |
274 // Generic class factory | 297 // Generic class factory |
275 final dynamic _raw; | 298 final dynamic _raw; |
276 | 299 |
277 // TODO(vsm): Do this properly | 300 // TODO(vsm): Do this properly |
278 final ClassMirror mixin = null; | 301 ClassMirror _mixin = null; |
279 List<TypeMirror> _typeArguments; | 302 List<TypeMirror> _typeArguments; |
280 | 303 |
281 List<InstanceMirror> _metadata; | 304 List<InstanceMirror> _metadata; |
282 Map<Symbol, DeclarationMirror> _declarations; | 305 Map<Symbol, DeclarationMirror> _declarations; |
283 | 306 |
284 List<InstanceMirror> get metadata { | 307 List<InstanceMirror> get metadata { |
285 if (_metadata == null) { | 308 if (_metadata == null) { |
286 // Load metadata. | 309 // Load metadata. |
287 var unwrapped = _unwrap(_cls); | 310 var unwrapped = _unwrap(_cls); |
288 // Only get metadata directly embedded on this class, not its | 311 // Only get metadata directly embedded on this class, not its |
289 // superclasses. | 312 // superclasses. |
290 var fn = JS('Function', | 313 var fn = JS('Function', |
291 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null'
, | 314 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null'
, |
292 unwrapped, unwrapped); | 315 unwrapped, unwrapped); |
293 _metadata = (fn == null) | 316 _metadata = (fn == null) |
294 ? const <InstanceMirror>[] | 317 ? const <InstanceMirror>[] |
295 : new List<InstanceMirror>.unmodifiable( | 318 : new List<InstanceMirror>.unmodifiable( |
296 fn().map((i) => reflect(i))); | 319 fn().map((i) => reflect(i))); |
297 } | 320 } |
298 return _metadata; | 321 return _metadata; |
299 } | 322 } |
300 | 323 |
301 Map<Symbol, DeclarationMirror> get declarations { | 324 Map<Symbol, DeclarationMirror> get declarations { |
302 if (_declarations == null) { | 325 if (_declarations == null) { |
303 // Load declarations. | 326 // Load declarations. |
304 // TODO(vsm): This is only populating the default constructor right now. | 327 // TODO(vsm): This is only populating the default constructor right now. |
305 _declarations = new Map<Symbol, DeclarationMirror>(); | 328 _declarations = new Map<Symbol, DeclarationMirror>(); |
306 var unwrapped = _unwrap(_cls); | 329 var unwrapped = _unwrap(_cls); |
307 var constructors = _getConstructors(unwrapped); | 330 var constructors = _getConstructors(unwrapped); |
308 constructors.forEach((String name, ft) { | 331 constructors.forEach((symbol, ft) { |
309 var symbol = new Symbol(name); | 332 var name = getName(symbol); |
310 _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft); | 333 _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft
); |
311 }); | 334 }); |
312 if (constructors.isEmpty) { | 335 if (constructors.isEmpty) { |
313 // Add a default | 336 // Add a default |
314 var name = 'new'; | 337 var name = 'new'; |
315 var ft = _defaultConstructorType(_unwrap(_cls)); | 338 var ft = _defaultConstructorType(_unwrap(_cls)); |
316 var symbol = new Symbol(name); | 339 var symbol = new Symbol(name); |
317 _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft); | 340 _declarations[symbol] = new JsMethodMirror._constructor(this, symbol, ft
); |
318 } | 341 } |
319 var fields = _getFields(unwrapped); | 342 var fields = _getFields(unwrapped); |
320 fields.forEach((String name, t) { | 343 fields.forEach((symbol, t) { |
321 var symbol = new Symbol(name); | |
322 var metadata = []; | 344 var metadata = []; |
323 if (t is List) { | 345 if (t is List) { |
324 metadata = t.skip(1).toList(); | 346 metadata = t.skip(1).toList(); |
325 t = t[0]; | 347 t = t[0]; |
326 } | 348 } |
327 _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata)
; | 349 _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadat
a); |
328 }); | 350 }); |
329 var methods = _getMethods(unwrapped); | 351 var methods = _getMethods(unwrapped); |
330 methods.forEach((String name, ft) { | 352 methods.forEach((symbol, ft) { |
331 var symbol = new Symbol(name); | 353 var name = getName(symbol); |
332 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); | 354 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol,
ft); |
333 }); | 355 }); |
334 var getters = _getGetters(unwrapped); | 356 var getters = _getGetters(unwrapped); |
335 getters.forEach((String name, ft) { | 357 getters.forEach((symbol, ft) { |
336 var symbol = new Symbol(name); | 358 var name = getName(symbol); |
337 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); | 359 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol,
ft); |
338 }); | 360 }); |
339 var setters = _getSetters(unwrapped); | 361 var setters = _getSetters(unwrapped); |
340 setters.forEach((String name, ft) { | 362 setters.forEach((symbol, ft) { |
341 name += '='; | 363 var name = getName(symbol) + '='; |
342 var symbol = new Symbol(name); | 364 // Create a separate symbol for the setter. |
343 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); | 365 symbol = new _internal.Symbol.es6(name, _getESSymbol(symbol)); |
| 366 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, symbol,
ft); |
344 }); | 367 }); |
345 var staticFields = _getStaticFields(unwrapped); | 368 var staticFields = _getStaticFields(unwrapped); |
346 staticFields.forEach((String name, t) { | 369 staticFields.forEach((symbol, t) { |
347 var symbol = new Symbol(name); | 370 var name = getName(symbol); |
348 var metadata = []; | 371 var metadata = []; |
349 if (t is List) { | 372 if (t is List) { |
350 metadata = t.skip(1).toList(); | 373 metadata = t.skip(1).toList(); |
351 t = t[0]; | 374 t = t[0]; |
352 } | 375 } |
353 _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata)
; | 376 _declarations[symbol] = new JsVariableMirror._(symbol, _wrap(t), metadat
a); |
354 }); | 377 }); |
355 var statics = _getStatics(unwrapped); | 378 var statics = _getStatics(unwrapped); |
356 statics.forEach((String name, ft) { | 379 statics.forEach((symbol, ft) { |
357 var symbol = new Symbol(name); | 380 var name = getName(symbol); |
358 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; | 381 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f
t); |
359 }); | 382 }); |
360 var staticGetters = _getStaticGetters(unwrapped); | 383 var staticGetters = _getStaticGetters(unwrapped); |
361 staticGetters.forEach((String name, ft) { | 384 staticGetters.forEach((symbol, ft) { |
362 var symbol = new Symbol(name); | 385 var name = getName(symbol); |
363 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; | 386 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f
t); |
364 }); | 387 }); |
365 var staticSetters = _getStaticSetters(unwrapped); | 388 var staticSetters = _getStaticSetters(unwrapped); |
366 staticSetters.forEach((String name, ft) { | 389 staticSetters.forEach((symbol, ft) { |
367 var symbol = new Symbol(name); | 390 var name = getName(symbol); |
368 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; | 391 _declarations[symbol] = new JsMethodMirror._staticMethod(this, symbol, f
t); |
369 }); | 392 }); |
370 _declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarati
ons); | 393 _declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarati
ons); |
371 } | 394 } |
372 return _declarations; | 395 return _declarations; |
373 } | 396 } |
374 | 397 |
375 JsClassMirror._(Type cls) | 398 JsClassMirror._(Type cls) |
376 : _cls = cls, | 399 : _cls = cls, |
377 _raw = _getGenericClass(_unwrap(cls)), | 400 _raw = _getGenericClass(_unwrap(cls)), |
378 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { | 401 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 } | 471 } |
449 | 472 |
450 ClassMirror get superclass { | 473 ClassMirror get superclass { |
451 if (_cls == Object) { | 474 if (_cls == Object) { |
452 return null; | 475 return null; |
453 } else { | 476 } else { |
454 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); | 477 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); |
455 } | 478 } |
456 } | 479 } |
457 | 480 |
| 481 ClassMirror get mixin { |
| 482 if (_mixin != null) { |
| 483 return _mixin; |
| 484 } |
| 485 var mixins = _getMixins(_unwrap(_cls)); |
| 486 if (mixins == null || mixins.isEmpty) { |
| 487 // If there is no mixin, return this mirror per API. |
| 488 _mixin = this; |
| 489 return _mixin; |
| 490 } |
| 491 if (mixins.length > 1) { |
| 492 throw new UnsupportedError("ClassMirror.mixin not yet supported for " |
| 493 "classes ($_cls) with multiple mixins"); |
| 494 } |
| 495 _mixin = reflectType(_wrap(mixins[0])); |
| 496 return _mixin; |
| 497 } |
| 498 |
458 String toString() => "ClassMirror on '$_cls'"; | 499 String toString() => "ClassMirror on '$_cls'"; |
459 } | 500 } |
460 | 501 |
461 class JsVariableMirror extends JsMirror implements VariableMirror { | 502 class JsVariableMirror extends JsMirror implements VariableMirror { |
| 503 final Symbol _symbol; |
462 final String _name; | 504 final String _name; |
463 final TypeMirror type; | 505 final TypeMirror type; |
464 final List<InstanceMirror> metadata; | 506 final List<InstanceMirror> metadata; |
465 | 507 |
466 // TODO(vsm): Refactor this out. | 508 // TODO(vsm): Refactor this out. |
467 Symbol get simpleName => new Symbol(_name); | 509 Symbol get simpleName => _symbol; |
468 | 510 |
469 // TODO(vsm): Fix this | 511 // TODO(vsm): Fix this |
470 final bool isStatic = false; | 512 final bool isStatic = false; |
471 final bool isFinal = false; | 513 final bool isFinal = false; |
472 | 514 |
473 JsVariableMirror._(this._name, Type t, List annotations) | 515 JsVariableMirror._(Symbol symbol, Type t, List annotations) |
474 : type = reflectType(t), | 516 : _symbol = symbol, |
| 517 _name = getName(symbol), |
| 518 type = reflectType(t), |
475 metadata = new List<InstanceMirror>.unmodifiable( | 519 metadata = new List<InstanceMirror>.unmodifiable( |
476 annotations.map((a) => reflect(a))); | 520 annotations.map((a) => reflect(a))); |
477 | 521 |
478 String toString() => "VariableMirror on '$_name'"; | 522 String toString() => "VariableMirror on '$_name'"; |
479 } | 523 } |
480 | 524 |
481 class JsParameterMirror extends JsVariableMirror implements ParameterMirror { | 525 class JsParameterMirror extends JsVariableMirror implements ParameterMirror { |
482 JsParameterMirror._(String name, Type t, List annotations) | 526 JsParameterMirror._(Symbol member, Type t, List annotations) |
483 : super._(name, t, annotations); | 527 : super._(member, t, annotations); |
484 | 528 |
485 String toString() => "ParameterMirror on '$_name'"; | 529 String toString() => "ParameterMirror on '$_name'"; |
486 } | 530 } |
487 | 531 |
488 class JsMethodMirror extends JsMirror implements MethodMirror { | 532 class JsMethodMirror extends JsMirror implements MethodMirror { |
489 // TODO(vsm): This could be a JS symbol for private methods | 533 final Symbol _symbol; |
490 final String _name; | 534 final String _name; |
491 List<ParameterMirror> _params; | 535 List<ParameterMirror> _params; |
492 List<InstanceMirror> _metadata; | 536 List<InstanceMirror> _metadata; |
493 final bool isConstructor; | 537 final bool isConstructor; |
494 final bool isStatic; | 538 final bool isStatic; |
495 | 539 |
496 // TODO(vsm): Fix this | 540 // TODO(vsm): Fix this |
497 final bool isFinal = false; | 541 final bool isFinal = false; |
498 bool get isSetter => _name.endsWith('='); | 542 bool get isSetter => _name.endsWith('='); |
499 bool get isPrivate => _name.startsWith('_'); | 543 bool get isPrivate => _name.startsWith('_'); |
500 | 544 |
501 // TODO(vsm): Refactor this out. | 545 // TODO(vsm): Refactor this out. |
502 Symbol get simpleName => new Symbol(_name); | 546 Symbol get simpleName => _symbol; |
503 | 547 |
504 JsMethodMirror._constructor(JsClassMirror cls, String name, ftype) | 548 JsMethodMirror._constructor(JsClassMirror cls, Symbol symbol, ftype) |
505 : _name = name, isConstructor = true, isStatic = false { | 549 : _symbol = symbol, _name = getName(symbol), isConstructor = true, isStatic
= false { |
506 _createParameterMirrorList(ftype); | 550 _createParameterMirrorList(ftype); |
507 } | 551 } |
508 | 552 |
509 JsMethodMirror._instanceMethod(JsClassMirror cls, String name, ftype) | 553 JsMethodMirror._instanceMethod(JsClassMirror cls, Symbol symbol, ftype) |
510 : _name = name, isConstructor = false, isStatic = false { | 554 : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic
= false { |
511 _createParameterMirrorList(ftype); | 555 _createParameterMirrorList(ftype); |
512 } | 556 } |
513 | 557 |
514 JsMethodMirror._staticMethod(JsClassMirror cls, String name, ftype) | 558 JsMethodMirror._staticMethod(JsClassMirror cls, Symbol symbol, ftype) |
515 : _name = name, isConstructor = false, isStatic = true { | 559 : _symbol = symbol, _name = getName(symbol), isConstructor = false, isStatic
= true { |
516 _createParameterMirrorList(ftype); | 560 _createParameterMirrorList(ftype); |
517 } | 561 } |
518 | 562 |
519 // TODO(vsm): Support named constructors. | 563 // TODO(vsm): Support named constructors. |
520 Symbol get constructorName => isConstructor ? new Symbol(_name) : null; | 564 Symbol get constructorName => isConstructor ? _symbol : null; |
521 List<ParameterMirror> get parameters => _params; | 565 List<ParameterMirror> get parameters => _params; |
522 List<InstanceMirror> get metadata => _metadata; | 566 List<InstanceMirror> get metadata => _metadata; |
523 | 567 |
524 void _createParameterMirrorList(ftype) { | 568 void _createParameterMirrorList(ftype) { |
525 if (ftype == null) { | 569 if (ftype == null) { |
526 // TODO(vsm): No explicit constructor. Verify this. | 570 // TODO(vsm): No explicit constructor. Verify this. |
527 _params = const []; | 571 _params = const []; |
528 _metadata = const []; | 572 _metadata = const []; |
529 return; | 573 return; |
530 } | 574 } |
(...skipping 18 matching lines...) Expand all Loading... |
549 | 593 |
550 // TODO(vsm): Add named args. | 594 // TODO(vsm): Add named args. |
551 List args = ftype.args; | 595 List args = ftype.args; |
552 List opts = ftype.optionals; | 596 List opts = ftype.optionals; |
553 var params = new List<ParameterMirror>(args.length + opts.length); | 597 var params = new List<ParameterMirror>(args.length + opts.length); |
554 | 598 |
555 for (var i = 0; i < args.length; ++i) { | 599 for (var i = 0; i < args.length; ++i) { |
556 var type = args[i]; | 600 var type = args[i]; |
557 var metadata = ftype.metadata[i]; | 601 var metadata = ftype.metadata[i]; |
558 // TODO(vsm): Recover the param name. | 602 // TODO(vsm): Recover the param name. |
559 var param = new JsParameterMirror._('', _wrap(type), metadata); | 603 var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata)
; |
560 params[i] = param; | 604 params[i] = param; |
561 } | 605 } |
562 | 606 |
563 for (var i = 0; i < opts.length; ++i) { | 607 for (var i = 0; i < opts.length; ++i) { |
564 var type = opts[i]; | 608 var type = opts[i]; |
565 var metadata = ftype.metadata[args.length + i]; | 609 var metadata = ftype.metadata[args.length + i]; |
566 // TODO(vsm): Recover the param name. | 610 // TODO(vsm): Recover the param name. |
567 var param = new JsParameterMirror._('', _wrap(type), metadata); | 611 var param = new JsParameterMirror._(new Symbol(''), _wrap(type), metadata)
; |
568 params[i + args.length] = param; | 612 params[i + args.length] = param; |
569 } | 613 } |
570 | 614 |
571 _params = new List.unmodifiable(params); | 615 _params = new List.unmodifiable(params); |
572 } | 616 } |
573 | 617 |
574 String toString() => "MethodMirror on '$_name'"; | 618 String toString() => "MethodMirror on '$_name'"; |
575 } | 619 } |
OLD | NEW |