OLD | NEW |
1 // Copyright (c) 2013, 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 getName(symbol) { | 7 import 'dart:collection'; |
8 throw new UnimplementedError("MirrorSystem.getName unimplemented"); | 8 import 'dart:mirrors'; |
| 9 import 'dart:_foreign_helper' show JS; |
| 10 import 'dart:_internal' as _internal; |
| 11 |
| 12 // TODO(vsm): This a workaround for: |
| 13 // https://github.com/dart-lang/dev_compiler/issues/219 |
| 14 import 'dart:js'; |
| 15 |
| 16 String getName(Symbol symbol) => |
| 17 _internal.Symbol.getName(symbol as _internal.Symbol); |
| 18 |
| 19 Symbol getSymbol(name, library) => |
| 20 throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); |
| 21 |
| 22 final currentJsMirrorSystem = throw new UnimplementedError( |
| 23 "MirrorSystem.currentJsMirrorSystem unimplemented"); |
| 24 |
| 25 InstanceMirror reflect(reflectee) => new JsInstanceMirror._(reflectee); |
| 26 |
| 27 TypeMirror reflectType(Type key) { |
| 28 // TODO(vsm): Might not be a class. |
| 29 return new JsClassMirror._(key); |
9 } | 30 } |
10 | 31 |
11 getSymbol(name, library) { | 32 final dynamic _dart = JS('', 'dart'); |
12 throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); | 33 final _metadata = JS('', '#.metadata', _dart); |
| 34 |
| 35 dynamic _dload(obj, String name) { |
| 36 return JS('', '#.dload(#, #)', _dart, obj, name); |
13 } | 37 } |
14 | 38 |
15 final currentJsMirrorSystem = | 39 void _dput(obj, String name, val) { |
16 throw new UnimplementedError( | 40 JS('', '#.dput(#, #, #)', _dart, obj, name, val); |
17 "MirrorSystem.currentJsMirrorSystem unimplemented"); | |
18 | |
19 | |
20 reflect(reflectee) { | |
21 throw new UnimplementedError("MirrorSystem.reflect unimplemented"); | |
22 } | 41 } |
23 | 42 |
24 reflectType(Type key) { | 43 dynamic _dsend(obj, String name, List args) { |
25 throw new UnimplementedError("MirrorSystem.reflectType unimplemented"); | 44 return JS('', '#.dsendArray(#, #, #)', _dart, obj, name, args); |
26 } | 45 } |
| 46 |
| 47 class JsInstanceMirror implements InstanceMirror { |
| 48 final Object reflectee; |
| 49 |
| 50 JsInstanceMirror._(this.reflectee); |
| 51 |
| 52 InstanceMirror getField(Symbol symbol) { |
| 53 var name = getName(symbol); |
| 54 var field = _dload(reflectee, name); |
| 55 return new JsInstanceMirror._(field); |
| 56 } |
| 57 |
| 58 InstanceMirror setField(Symbol symbol, Object value) { |
| 59 var name = getName(symbol); |
| 60 var field = _dput(reflectee, name, value); |
| 61 return new JsInstanceMirror._(field); |
| 62 } |
| 63 |
| 64 InstanceMirror invoke(Symbol symbol, List<dynamic> args, |
| 65 [Map<Symbol, dynamic> namedArgs]) { |
| 66 var name = getName(symbol); |
| 67 if (namedArgs != null) { |
| 68 args = new List.from(args); |
| 69 args.add(_toJsMap(namedArgs)); |
| 70 } |
| 71 var result = _dsend(reflectee, name, args); |
| 72 return new JsInstanceMirror._(result); |
| 73 } |
| 74 |
| 75 dynamic _toJsMap(Map<Symbol, dynamic> map) { |
| 76 var obj = JS('', '{}'); |
| 77 map.forEach((Symbol key, value) { |
| 78 JS('', '#[#] = #', obj, getName(key), value); |
| 79 }); |
| 80 return obj; |
| 81 } |
| 82 } |
| 83 |
| 84 class JsClassMirror implements ClassMirror { |
| 85 final Type _cls; |
| 86 final Symbol simpleName; |
| 87 |
| 88 List<InstanceMirror> _metadata; |
| 89 Map<Symbol, MethodMirror> _declarations; |
| 90 |
| 91 // TODO(vsm):These need to be immutable when escaping from this class. |
| 92 List<InstanceMirror> get metadata => _metadata; |
| 93 Map<Symbol, MethodMirror> get declarations => _declarations; |
| 94 |
| 95 JsClassMirror._(Type cls) |
| 96 : _cls = cls, |
| 97 simpleName = new Symbol(JS('String', '#.name', cls)) { |
| 98 // Load metadata. |
| 99 var fn = JS('List<InstanceMirror>', '#[dart.metadata]', _cls); |
| 100 _metadata = (fn == null) |
| 101 ? <InstanceMirror>[] |
| 102 : new List<InstanceMirror>.from(fn().map((i) => new JsInstanceMirror._(i
))); |
| 103 |
| 104 // Load declarations. |
| 105 // TODO(vsm): This is only populating the default constructor right now. |
| 106 _declarations = new Map<Symbol, MethodMirror>(); |
| 107 _declarations[simpleName] = new JsMethodMirror._(this, _cls); |
| 108 } |
| 109 |
| 110 InstanceMirror newInstance(Symbol constructorName, List args, |
| 111 [Map<Symbol, dynamic> namedArgs]) { |
| 112 // TODO(vsm): Support named constructors and named arguments. |
| 113 assert(getName(constructorName) == ""); |
| 114 assert(namedArgs == null || namedArgs.isEmpty); |
| 115 var instance = JS('', '#.instantiate(#, #)', _dart, _cls, args); |
| 116 return new JsInstanceMirror._(instance); |
| 117 } |
| 118 } |
| 119 |
| 120 class JsTypeMirror implements TypeMirror { |
| 121 final Type reflectedType; |
| 122 |
| 123 JsTypeMirror._(this.reflectedType); |
| 124 } |
| 125 |
| 126 class JsParameterMirror implements ParameterMirror { |
| 127 final String _name; |
| 128 final TypeMirror type; |
| 129 final List<InstanceMirror> metadata = []; |
| 130 |
| 131 JsParameterMirror._(this._name, Type t) : type = new JsTypeMirror._(t); |
| 132 } |
| 133 |
| 134 class JsMethodMirror implements MethodMirror { |
| 135 final String _name; |
| 136 final dynamic _method; |
| 137 List<ParameterMirror> _params; |
| 138 |
| 139 JsMethodMirror._(JsClassMirror cls, this._method) |
| 140 : _name = getName(cls.simpleName) { |
| 141 var ftype = JS('', '#.classGetConstructorType(#)', _dart, cls._cls); |
| 142 _params = _createParameterMirrorList(ftype); |
| 143 } |
| 144 |
| 145 // TODO(vsm): Support named constructors. |
| 146 Symbol get constructorName => new Symbol(''); |
| 147 List<ParameterMirror> get parameters => _params; |
| 148 |
| 149 List<ParameterMirror> _createParameterMirrorList(ftype) { |
| 150 if (ftype == null) { |
| 151 // TODO(vsm): No explicit constructor. Verify this. |
| 152 return []; |
| 153 } |
| 154 |
| 155 // TODO(vsm): Add named args. |
| 156 List args = ftype.args; |
| 157 List opts = ftype.optionals; |
| 158 var params = new List<ParameterMirror>(args.length + opts.length); |
| 159 |
| 160 for (var i = 0; i < args.length; ++i) { |
| 161 var type = args[i]; |
| 162 // TODO(vsm): Recover the param name. |
| 163 var param = new JsParameterMirror._('', type); |
| 164 params[i] = param; |
| 165 } |
| 166 |
| 167 for (var i = 0; i < opts.length; ++i) { |
| 168 var type = opts[i]; |
| 169 // TODO(vsm): Recover the param name. |
| 170 var param = new JsParameterMirror._('', type); |
| 171 params[i + args.length] = param; |
| 172 } |
| 173 |
| 174 return params; |
| 175 } |
| 176 } |
OLD | NEW |