OLD | NEW |
---|---|
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 import 'dart:_js_helper' show createInvocationMirror; | 9 import 'dart:_js_helper' show createInvocationMirror; |
10 import 'dart:_interceptors' show Interceptor; | 10 import 'dart:_interceptors' show Interceptor; |
(...skipping 20 matching lines...) Expand all Loading... | |
31 static Map<String, List<LibraryMirror>> computeLibrariesByName() { | 31 static Map<String, List<LibraryMirror>> computeLibrariesByName() { |
32 var result = new Map<String, List<LibraryMirror>>(); | 32 var result = new Map<String, List<LibraryMirror>>(); |
33 var jsLibraries = JS('=List|Null', 'init.libraries'); | 33 var jsLibraries = JS('=List|Null', 'init.libraries'); |
34 if (jsLibraries == null) return result; | 34 if (jsLibraries == null) return result; |
35 for (List data in jsLibraries) { | 35 for (List data in jsLibraries) { |
36 String name = data[0]; | 36 String name = data[0]; |
37 Uri uri = Uri.parse(data[1]); | 37 Uri uri = Uri.parse(data[1]); |
38 List<String> classes = data[2]; | 38 List<String> classes = data[2]; |
39 List<String> functions = data[3]; | 39 List<String> functions = data[3]; |
40 var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]); | 40 var libraries = result.putIfAbsent(name, () => <LibraryMirror>[]); |
41 libraries.add(new _LibraryMirror(name, uri, classes, functions)); | 41 libraries.add(new _LibraryMirror(_s(name), uri, classes, functions)); |
42 } | 42 } |
43 return result; | 43 return result; |
44 } | 44 } |
45 } | 45 } |
46 | 46 |
47 class _TypeMirror implements TypeMirror { | 47 class _TypeMirror implements TypeMirror { |
48 final Symbol simpleName; | 48 final Symbol simpleName; |
49 _TypeMirror(this.simpleName); | 49 _TypeMirror(this.simpleName); |
50 } | 50 } |
51 | 51 |
52 class _LibraryMirror extends _ObjectMirror implements LibraryMirror { | 52 class _LibraryMirror extends _ObjectMirror implements LibraryMirror { |
53 final String _name; | 53 final Symbol simpleName; |
54 final Uri uri; | 54 final Uri uri; |
55 final List<String> _classes; | 55 final List<String> _classes; |
56 final List<String> _functions; | 56 final List<String> _functions; |
57 | 57 |
58 _LibraryMirror(this._name, this.uri, this._classes, this._functions); | 58 _LibraryMirror(this.simpleName, this.uri, this._classes, this._functions); |
59 | |
60 Symbol get qualifiedName => simpleName; | |
59 | 61 |
60 Map<Symbol, ClassMirror> get classes { | 62 Map<Symbol, ClassMirror> get classes { |
61 var result = new Map<Symbol, ClassMirror>(); | 63 var result = new Map<Symbol, ClassMirror>(); |
62 for (int i = 0; i < _classes.length; i += 2) { | 64 for (int i = 0; i < _classes.length; i += 2) { |
63 Symbol symbol = _s(_classes[i]); | 65 Symbol symbol = _s(_classes[i]); |
64 _ClassMirror cls = _reflectClass(symbol, _classes[i + 1]); | 66 _ClassMirror cls = _reflectClass(symbol, _classes[i + 1]); |
65 result[symbol] = cls; | 67 result[symbol] = cls; |
66 cls._owner = this; | 68 cls._owner = this; |
67 } | 69 } |
68 return result; | 70 return result; |
69 } | 71 } |
70 | 72 |
71 InstanceMirror setField(Symbol fieldName, Object arg) { | 73 InstanceMirror setField(Symbol fieldName, Object arg) { |
72 // TODO(ahe): This is extremely dangerous!!! | 74 // TODO(ahe): This is extremely dangerous!!! |
73 JS('void', r'$[#] = #', _n(fieldName), arg); | 75 JS('void', r'$[#] = #', _n(fieldName), arg); |
74 return _reflect(arg); | 76 return _reflect(arg); |
75 } | 77 } |
76 | 78 |
77 InstanceMirror getField(Symbol fieldName) { | 79 InstanceMirror getField(Symbol fieldName) { |
78 // TODO(ahe): This is extremely dangerous!!! | 80 // TODO(ahe): This is extremely dangerous!!! |
79 return _reflect(JS('', r'$[#]', _n(fieldName))); | 81 return _reflect(JS('', r'$[#]', _n(fieldName))); |
80 } | 82 } |
83 | |
84 Map<Symbol, MethodMirror> get functions { | |
85 var result = new Map<Symbol, MethodMirror>(); | |
86 for (int i = 0; i < _functions.length; i++) { | |
87 String name = _functions[i]; | |
88 Symbol symbol = _s(name); | |
89 int parameterCount = null; // TODO(ahe): Compute this. | |
90 _MethodMirror mirror = | |
91 new _MethodMirror(symbol, JS('', r'$[#]', name), parameterCount); | |
kasperl
2013/05/27 12:15:33
Create helpers for reading and writing to fields o
ahe
2013/05/27 13:55:55
Added TODO (a big cleanup).
| |
92 // TODO(ahe): Cache mirrors. | |
93 result[symbol] = mirror; | |
94 mirror._owner = this; | |
95 } | |
96 return result; | |
97 } | |
98 | |
99 Map<Symbol, MethodMirror> get getters { | |
100 var result = new Map<Symbol, MethodMirror>(); | |
101 // TODO(ahe): Implement this. | |
102 return result; | |
103 } | |
104 | |
105 Map<Symbol, MethodMirror> get setters { | |
106 var result = new Map<Symbol, MethodMirror>(); | |
107 // TODO(ahe): Implement this. | |
108 return result; | |
109 } | |
110 | |
111 Map<Symbol, VariableMirror> get variables { | |
112 var result = new Map<Symbol, VariableMirror>(); | |
113 // TODO(ahe): Implement this. | |
114 return result; | |
115 } | |
116 | |
117 Map<Symbol, Mirror> get members { | |
118 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(classes); | |
119 addToResult(Symbol key, Mirror value) { | |
120 result[key] = value; | |
121 } | |
122 functions.forEach(addToResult); | |
123 getters.forEach(addToResult); | |
124 setters.forEach(addToResult); | |
125 variables.forEach(addToResult); | |
126 return result; | |
127 } | |
81 } | 128 } |
82 | 129 |
83 String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); | 130 String _n(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); |
84 | 131 |
85 Symbol _s(String name) { | 132 Symbol _s(String name) { |
86 if (name == null) return null; | 133 if (name == null) return null; |
87 return new _symbol_dev.Symbol.unvalidated(name); | 134 return new _symbol_dev.Symbol.unvalidated(name); |
88 } | 135 } |
89 | 136 |
90 patch MirrorSystem currentMirrorSystem() => _currentMirrorSystem; | 137 patch MirrorSystem currentMirrorSystem() => _currentMirrorSystem; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 | 252 |
206 class _ClassMirror extends _ObjectMirror implements ClassMirror { | 253 class _ClassMirror extends _ObjectMirror implements ClassMirror { |
207 final Symbol simpleName; | 254 final Symbol simpleName; |
208 final _jsConstructor; | 255 final _jsConstructor; |
209 final String _fields; | 256 final String _fields; |
210 // Set as side-effect of accessing _LibraryMirror.classes. | 257 // Set as side-effect of accessing _LibraryMirror.classes. |
211 _LibraryMirror _owner; | 258 _LibraryMirror _owner; |
212 | 259 |
213 _ClassMirror(this.simpleName, this._jsConstructor, this._fields); | 260 _ClassMirror(this.simpleName, this._jsConstructor, this._fields); |
214 | 261 |
215 Map<Symbol, Mirror> get members { | 262 Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); |
216 var result = new Map<Symbol, Mirror>(); | 263 |
264 Map<Symbol, MethodMirror> get functions { | |
265 var result = new Map<Symbol, MethodMirror>(); | |
266 // TODO(ahe): Implement this. | |
267 return result; | |
268 } | |
269 | |
270 Map<Symbol, MethodMirror> get getters { | |
271 var result = new Map<Symbol, MethodMirror>(); | |
272 // TODO(ahe): Implement this. | |
273 return result; | |
274 } | |
275 | |
276 Map<Symbol, MethodMirror> get setters { | |
277 var result = new Map<Symbol, MethodMirror>(); | |
278 // TODO(ahe): Implement this. | |
279 return result; | |
280 } | |
281 | |
282 Map<Symbol, VariableMirror> get variables { | |
283 var result = new Map<Symbol, VariableMirror>(); | |
217 var s = _fields.split(";"); | 284 var s = _fields.split(";"); |
218 var fields = s[1] == "" ? [] : s[1].split(","); | 285 var fields = s[1] == "" ? [] : s[1].split(","); |
219 for (String field in fields) { | 286 for (String field in fields) { |
220 _VariableMirror mirror = new _VariableMirror.from(field); | 287 _VariableMirror mirror = new _VariableMirror.from(field); |
221 result[mirror.simpleName] = mirror; | 288 result[mirror.simpleName] = mirror; |
289 mirror._owner = this; | |
222 } | 290 } |
223 return result; | 291 return result; |
224 } | 292 } |
225 | 293 |
294 Map<Symbol, Mirror> get members { | |
295 Map<Symbol, Mirror> result = new Map<Symbol, Mirror>.from(functions); | |
296 addToResult(Symbol key, Mirror value) { | |
297 result[key] = value; | |
298 } | |
299 getters.forEach(addToResult); | |
300 setters.forEach(addToResult); | |
301 variables.forEach(addToResult); | |
302 return result; | |
303 } | |
304 | |
226 InstanceMirror setField(Symbol fieldName, Object arg) { | 305 InstanceMirror setField(Symbol fieldName, Object arg) { |
227 // TODO(ahe): This is extremely dangerous!!! | 306 // TODO(ahe): This is extremely dangerous!!! |
228 JS('void', r'$[#] = #', '${_n(simpleName)}_${_n(fieldName)}', arg); | 307 JS('void', r'$[#] = #', '${_n(simpleName)}_${_n(fieldName)}', arg); |
229 return _reflect(arg); | 308 return _reflect(arg); |
230 } | 309 } |
231 | 310 |
232 InstanceMirror getField(Symbol fieldName) { | 311 InstanceMirror getField(Symbol fieldName) { |
233 // TODO(ahe): This is extremely dangerous!!! | 312 // TODO(ahe): This is extremely dangerous!!! |
234 return _reflect( | 313 return _reflect( |
235 JS('', r'$[#]', '${_n(simpleName)}_${_n(fieldName)}')); | 314 JS('', r'$[#]', '${_n(simpleName)}_${_n(fieldName)}')); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 } | 359 } |
281 | 360 |
282 String toString() => 'ClassMirror(${_n(simpleName)})'; | 361 String toString() => 'ClassMirror(${_n(simpleName)})'; |
283 } | 362 } |
284 | 363 |
285 class _VariableMirror implements VariableMirror { | 364 class _VariableMirror implements VariableMirror { |
286 // TODO(ahe): The values in these fields are virtually untested. | 365 // TODO(ahe): The values in these fields are virtually untested. |
287 final Symbol simpleName; | 366 final Symbol simpleName; |
288 final String _jsName; | 367 final String _jsName; |
289 final bool _readOnly; | 368 final bool _readOnly; |
369 DeclarationMirror _owner; | |
290 | 370 |
291 _VariableMirror(this.simpleName, this._jsName, this._readOnly); | 371 _VariableMirror(this.simpleName, this._jsName, this._readOnly); |
292 | 372 |
293 factory _VariableMirror.from(String descriptor) { | 373 factory _VariableMirror.from(String descriptor) { |
294 int length = descriptor.length; | 374 int length = descriptor.length; |
295 var code = fieldCode(descriptor.codeUnitAt(length - 1)); | 375 var code = fieldCode(descriptor.codeUnitAt(length - 1)); |
296 if (code == 0) { | 376 if (code == 0) { |
297 throw new RuntimeError('Bad field descriptor: $descriptor'); | 377 throw new RuntimeError('Bad field descriptor: $descriptor'); |
298 } | 378 } |
299 bool hasGetter = (code & 3) != 0; | 379 bool hasGetter = (code & 3) != 0; |
300 bool hasSetter = (code >> 2) != 0; | 380 bool hasSetter = (code >> 2) != 0; |
301 String jsName; | 381 String jsName; |
302 String accessorName = jsName = descriptor.substring(0, length - 1); | 382 String accessorName = jsName = descriptor.substring(0, length - 1); |
303 int divider = descriptor.indexOf(":"); | 383 int divider = descriptor.indexOf(":"); |
304 if (divider > 0) { | 384 if (divider > 0) { |
305 accessorName = accessorName.substring(0, divider); | 385 accessorName = accessorName.substring(0, divider); |
306 jsName = accessorName.substring(divider + 1); | 386 jsName = accessorName.substring(divider + 1); |
307 } | 387 } |
308 bool readOnly = !hasSetter; | 388 bool readOnly = !hasSetter; |
309 return new _VariableMirror(_s(accessorName), jsName, readOnly); | 389 return new _VariableMirror(_s(accessorName), jsName, readOnly); |
310 } | 390 } |
311 | 391 |
312 TypeMirror get type => _MirrorSystem._dynamicType; | 392 TypeMirror get type => _MirrorSystem._dynamicType; |
313 | 393 |
394 DeclarationMirror get owner => _owner; | |
395 | |
396 Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); | |
397 | |
314 static int fieldCode(int code) { | 398 static int fieldCode(int code) { |
315 if (code >= 60 && code <= 64) return code - 59; | 399 if (code >= 60 && code <= 64) return code - 59; |
316 if (code >= 123 && code <= 126) return code - 117; | 400 if (code >= 123 && code <= 126) return code - 117; |
317 if (code >= 37 && code <= 43) return code - 27; | 401 if (code >= 37 && code <= 43) return code - 27; |
318 return 0; | 402 return 0; |
319 } | 403 } |
320 } | 404 } |
321 | 405 |
322 class _ClosureMirror extends _InstanceMirror implements ClosureMirror { | 406 class _ClosureMirror extends _InstanceMirror implements ClosureMirror { |
323 _ClosureMirror(reflectee) : super(reflectee); | 407 _ClosureMirror(reflectee) : super(reflectee); |
324 | 408 |
325 MethodMirror get function { | 409 MethodMirror get function { |
326 // TODO(ahe): What about optional parameters (named or not). | 410 // TODO(ahe): What about optional parameters (named or not). |
327 var extractCallName = JS('', r''' | 411 var extractCallName = JS('', r''' |
328 function(reflectee) { | 412 function(reflectee) { |
329 for (var property in reflectee) { | 413 for (var property in reflectee) { |
330 if ("call$" == property.substring(0, 5)) return property; | 414 if ("call$" == property.substring(0, 5)) return property; |
331 } | 415 } |
332 return null; | 416 return null; |
333 } | 417 } |
334 '''); | 418 '''); |
335 String callName = JS('String|Null', '#(#)', extractCallName, reflectee); | 419 String callName = JS('String|Null', '#(#)', extractCallName, reflectee); |
336 if (callName == null) { | 420 if (callName == null) { |
337 throw new RuntimeError('Cannot find callName on "$reflectee"'); | 421 throw new RuntimeError('Cannot find callName on "$reflectee"'); |
338 } | 422 } |
339 var jsFunction = JS('', '#[#]', reflectee, callName); | 423 var jsFunction = JS('', '#[#]', reflectee, callName); |
340 int parameterCount = int.parse(callName.split(r'$')[1]); | 424 int parameterCount = int.parse(callName.split(r'$')[1]); |
341 return new _MethodMirror(jsFunction, parameterCount); | 425 return new _MethodMirror(_s(callName), jsFunction, parameterCount); |
342 } | 426 } |
343 | 427 |
344 InstanceMirror apply(List positionalArguments, | 428 InstanceMirror apply(List positionalArguments, |
345 [Map<Symbol, dynamic> namedArguments]) { | 429 [Map<Symbol, dynamic> namedArguments]) { |
346 return _reflect( | 430 return _reflect( |
347 Function.apply(reflectee, positionalArguments, namedArguments)); | 431 Function.apply(reflectee, positionalArguments, namedArguments)); |
348 } | 432 } |
349 | 433 |
350 Future<InstanceMirror> applyAsync(List positionalArguments, | 434 Future<InstanceMirror> applyAsync(List positionalArguments, |
351 [Map<Symbol, dynamic> namedArguments]) { | 435 [Map<Symbol, dynamic> namedArguments]) { |
352 return new Future<InstanceMirror>( | 436 return new Future<InstanceMirror>( |
353 () => apply(positionalArguments, namedArguments)); | 437 () => apply(positionalArguments, namedArguments)); |
354 } | 438 } |
355 } | 439 } |
356 | 440 |
357 class _MethodMirror implements MethodMirror { | 441 class _MethodMirror implements MethodMirror { |
442 final Symbol simpleName; | |
358 final _jsFunction; | 443 final _jsFunction; |
359 final int _parameterCount; | 444 final int _parameterCount; |
445 DeclarationMirror _owner; | |
360 | 446 |
361 _MethodMirror(this._jsFunction, this._parameterCount); | 447 _MethodMirror(this.simpleName, this._jsFunction, this._parameterCount); |
362 | 448 |
363 List<ParameterMirror> get parameters { | 449 List<ParameterMirror> get parameters { |
364 // TODO(ahe): Fill the list with parameter mirrors. | 450 // TODO(ahe): Fill the list with parameter mirrors. |
365 return new List<ParameterMirror>(_parameterCount); | 451 return new List<ParameterMirror>(_parameterCount); |
366 } | 452 } |
453 | |
454 DeclarationMirror get owner => _owner; | |
455 | |
456 Symbol get qualifiedName => _computeQualifiedName(owner, simpleName); | |
367 } | 457 } |
458 | |
459 Symbol _computeQualifiedName(DeclarationMirror owner, Symbol simpleName) { | |
460 if (owner == null || _n(owner.qualifiedName) == '') return simpleName; | |
kasperl
2013/05/27 12:15:33
Consider using ? :.
ahe
2013/05/27 13:55:55
Did something else :-)
| |
461 return _s('${_n(owner.qualifiedName)}.${_n(simpleName)}'); | |
462 } | |
OLD | NEW |