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 |
11 String getName(Symbol symbol) => | 11 String getName(Symbol symbol) => |
12 _internal.Symbol.getName(symbol as _internal.Symbol); | 12 _internal.Symbol.getName(symbol as _internal.Symbol); |
13 | 13 |
14 Symbol getSymbol(name, library) => | 14 Symbol getSymbol(name, library) => |
15 throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); | 15 throw new UnimplementedError("MirrorSystem.getSymbol unimplemented"); |
16 | 16 |
17 final currentJsMirrorSystem = throw new UnimplementedError( | 17 final currentJsMirrorSystem = throw new UnimplementedError( |
18 "MirrorSystem.currentJsMirrorSystem unimplemented"); | 18 "MirrorSystem.currentJsMirrorSystem unimplemented"); |
19 | 19 |
20 InstanceMirror reflect(reflectee) => new JsInstanceMirror._(reflectee); | 20 final _typeMirror = JS('', 'Symbol("_typeMirror")'); |
| 21 |
| 22 InstanceMirror reflect(reflectee) { |
| 23 // TODO(vsm): Consider caching the mirror here. Unlike the type below, |
| 24 // reflectee may be a primitive - i.e., we can't just add an expando. |
| 25 if (reflectee is Function) { |
| 26 return new JsClosureMirror._(reflectee); |
| 27 } else { |
| 28 return new JsInstanceMirror._(reflectee); |
| 29 } |
| 30 } |
21 | 31 |
22 TypeMirror reflectType(Type key) { | 32 TypeMirror reflectType(Type key) { |
| 33 var unwrapped = _unwrap(key); |
| 34 var property = JS('', 'Object.getOwnPropertyDescriptor(#, #)', unwrapped, _typ
eMirror); |
| 35 if (property != null) { |
| 36 return JS('', '#.value', property); |
| 37 } |
23 // TODO(vsm): Might not be a class. | 38 // TODO(vsm): Might not be a class. |
24 return new JsClassMirror._(key); | 39 var mirror = new JsClassMirror._(key); |
| 40 JS('', '#[#] = #', unwrapped, _typeMirror, mirror); |
| 41 return mirror; |
25 } | 42 } |
26 | 43 |
27 final dynamic _dart = JS('', 'dart'); | 44 final dynamic _dart = JS('', 'dart'); |
28 | 45 |
29 dynamic _dload(obj, String name) { | 46 dynamic _dload(obj, String name) { |
30 return JS('', '#.dload(#, #)', _dart, obj, name); | 47 return JS('', '#.dload(#, #)', _dart, obj, name); |
31 } | 48 } |
32 | 49 |
33 void _dput(obj, String name, val) { | 50 void _dput(obj, String name, val) { |
34 JS('', '#.dput(#, #, #)', _dart, obj, name, val); | 51 JS('', '#.dput(#, #, #)', _dart, obj, name, val); |
35 } | 52 } |
36 | 53 |
| 54 dynamic _dcall(obj, List args) { |
| 55 return JS('', '#.dcall(#, ...#)', _dart, obj, args); |
| 56 } |
| 57 |
37 dynamic _dsend(obj, String name, List args) { | 58 dynamic _dsend(obj, String name, List args) { |
38 return JS('', '#.dsend(#, #, ...#)', _dart, obj, name, args); | 59 return JS('', '#.dsend(#, #, ...#)', _dart, obj, name, args); |
39 } | 60 } |
40 | 61 |
| 62 dynamic _getGenericClass(obj) { |
| 63 return JS('', '#.getGenericClass(#)', _dart, obj); |
| 64 } |
| 65 |
| 66 dynamic _getGenericArgs(obj) { |
| 67 return JS('', '#.getGenericArgs(#)', _dart, obj); |
| 68 } |
| 69 |
| 70 dynamic _defaultConstructorType(type) { |
| 71 return JS('', '#.definiteFunctionType(#, [])', _dart, type); |
| 72 } |
| 73 |
| 74 typedef T _Lazy<T>(); |
| 75 |
| 76 Map _getConstructors(obj) { |
| 77 List sig = JS('', '#.getConstructorSig(#)', _dart, obj); |
| 78 if (sig == null) return {}; |
| 79 return JS('', '#.map(#)', _dart, sig); |
| 80 } |
| 81 |
| 82 Map _getFields(obj) { |
| 83 List sig = JS('', '#.getFieldSig(#)', _dart, obj); |
| 84 if (sig == null) return {}; |
| 85 return JS('', '#.map(#)', _dart, sig); |
| 86 } |
| 87 |
| 88 Map _getMethods(obj) { |
| 89 List sig = JS('', '#.getMethodSig(#)', _dart, obj); |
| 90 if (sig == null) return {}; |
| 91 return JS('', '#.map(#)', _dart, sig); |
| 92 } |
| 93 |
| 94 Map _getGetters(obj) { |
| 95 List sig = JS('', '#.getGetterSig(#)', _dart, obj); |
| 96 if (sig == null) return {}; |
| 97 return JS('', '#.map(#)', _dart, sig); |
| 98 } |
| 99 |
| 100 Map _getSetters(obj) { |
| 101 List sig = JS('', '#.getSetterSig(#)', _dart, obj); |
| 102 if (sig == null) return {}; |
| 103 return JS('', '#.map(#)', _dart, sig); |
| 104 } |
| 105 |
| 106 Map _getStaticFields(obj) { |
| 107 List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj); |
| 108 if (sig == null) return {}; |
| 109 return JS('', '#.map(#)', _dart, sig); |
| 110 } |
| 111 |
| 112 Map _getStatics(obj) { |
| 113 List sig = JS('', '#.getStaticSig(#)', _dart, obj); |
| 114 if (sig == null) return {}; |
| 115 return JS('', '#.map(#)', _dart, sig); |
| 116 } |
| 117 |
| 118 Map _getStaticGetters(obj) { |
| 119 List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj); |
| 120 if (sig == null) return {}; |
| 121 return JS('', '#.map(#)', _dart, sig); |
| 122 } |
| 123 |
| 124 Map _getStaticSetters(obj) { |
| 125 List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj); |
| 126 if (sig == null) return {}; |
| 127 return JS('', '#.map(#)', _dart, sig); |
| 128 } |
| 129 |
41 // TODO(vsm): These methods need to validate whether we really have a | 130 // TODO(vsm): These methods need to validate whether we really have a |
42 // WrappedType or a raw type that should be wrapped (as opposed to a | 131 // WrappedType or a raw type that should be wrapped (as opposed to a |
43 // function). | 132 // function). |
44 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); | 133 dynamic _unwrap(obj) => JS('', '#.unwrapType(#)', _dart, obj); |
45 | 134 |
46 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); | 135 dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj); |
47 | 136 |
48 class JsInstanceMirror implements InstanceMirror { | 137 _unimplemented(Type t, Invocation i) { |
49 final Object reflectee; | 138 throw new UnimplementedError('$t.${i.memberName} unimplemented'); |
| 139 } |
| 140 |
| 141 class JsMirror implements Mirror { |
| 142 noSuchMethod(Invocation i) { |
| 143 _unimplemented(this.runtimeType, i); |
| 144 } |
| 145 } |
| 146 |
| 147 class JsCombinatorMirror extends JsMirror implements CombinatorMirror { |
| 148 } |
| 149 |
| 150 class JsDeclarationMirror extends JsMirror implements DeclarationMirror { |
| 151 } |
| 152 |
| 153 class JsIsolateMirror extends JsMirror implements IsolateMirror { |
| 154 } |
| 155 |
| 156 class JsLibraryDependencyMirror extends JsMirror implements LibraryDependencyMir
ror { |
| 157 } |
| 158 |
| 159 class JsObjectMirror extends JsMirror implements ObjectMirror { |
| 160 } |
| 161 |
| 162 class JsInstanceMirror extends JsObjectMirror implements InstanceMirror { |
| 163 |
| 164 // Reflected object |
| 165 final reflectee; |
| 166 bool get hasReflectee => true; |
| 167 |
| 168 ClassMirror get type { |
| 169 // The spec guarantees that `null` is the singleton instance of the `Null` |
| 170 // class. |
| 171 if (reflectee == null) return reflectClass(Null); |
| 172 return reflectType(reflectee.runtimeType); |
| 173 } |
50 | 174 |
51 JsInstanceMirror._(this.reflectee); | 175 JsInstanceMirror._(this.reflectee); |
52 | 176 |
53 ClassMirror get type => | 177 bool operator==(Object other) { |
54 throw new UnimplementedError("ClassMirror.type unimplemented"); | 178 return (other is JsInstanceMirror) && identical(reflectee, other.reflectee); |
55 bool get hasReflectee => | 179 } |
56 throw new UnimplementedError("ClassMirror.hasReflectee unimplemented"); | 180 |
57 delegate(Invocation invocation) => | 181 int get hashCode { |
58 throw new UnimplementedError("ClassMirror.delegate unimplemented"); | 182 // Avoid hash collisions with the reflectee. This constant is in Smi range |
| 183 // and happens to be the inner padding from RFC 2104. |
| 184 return identityHashCode(reflectee) ^ 0x36363636; |
| 185 } |
59 | 186 |
60 InstanceMirror getField(Symbol symbol) { | 187 InstanceMirror getField(Symbol symbol) { |
61 var name = getName(symbol); | 188 var name = getName(symbol); |
62 var field = _dload(reflectee, name); | 189 var field = _dload(reflectee, name); |
63 return new JsInstanceMirror._(field); | 190 return reflect(field); |
64 } | 191 } |
65 | 192 |
66 InstanceMirror setField(Symbol symbol, Object value) { | 193 InstanceMirror setField(Symbol symbol, Object value) { |
67 var name = getName(symbol); | 194 var name = getName(symbol); |
68 _dput(reflectee, name, value); | 195 _dput(reflectee, name, value); |
69 return new JsInstanceMirror._(value); | 196 return reflect(value); |
70 } | 197 } |
71 | 198 |
72 InstanceMirror invoke(Symbol symbol, List<dynamic> args, | 199 InstanceMirror invoke(Symbol symbol, List<dynamic> args, |
73 [Map<Symbol, dynamic> namedArgs]) { | 200 [Map<Symbol, dynamic> namedArgs]) { |
74 var name = getName(symbol); | 201 var name = getName(symbol); |
75 if (namedArgs != null) { | 202 if (namedArgs != null) { |
76 args = new List.from(args); | 203 args = new List.from(args); |
77 args.add(_toJsMap(namedArgs)); | 204 args.add(_toJsMap(namedArgs)); |
78 } | 205 } |
79 var result = _dsend(reflectee, name, args); | 206 var result = _dsend(reflectee, name, args); |
80 return new JsInstanceMirror._(result); | 207 return reflect(result); |
81 } | 208 } |
82 | 209 |
83 dynamic _toJsMap(Map<Symbol, dynamic> map) { | 210 dynamic _toJsMap(Map<Symbol, dynamic> map) { |
84 var obj = JS('', '{}'); | 211 var obj = JS('', '{}'); |
85 map.forEach((Symbol key, value) { | 212 map.forEach((Symbol key, value) { |
86 JS('', '#[#] = #', obj, getName(key), value); | 213 JS('', '#[#] = #', obj, getName(key), value); |
87 }); | 214 }); |
88 return obj; | 215 return obj; |
89 } | 216 } |
90 } | 217 } |
91 | 218 |
92 class JsClassMirror implements ClassMirror { | 219 class JsClosureMirror extends JsInstanceMirror implements ClosureMirror { |
| 220 JsClosureMirror._(reflectee) : super._(reflectee); |
| 221 |
| 222 InstanceMirror apply(List<dynamic> args, |
| 223 [Map<Symbol, dynamic> namedArgs]) { |
| 224 if (namedArgs != null) { |
| 225 args = new List.from(args); |
| 226 args.add(_toJsMap(namedArgs)); |
| 227 } |
| 228 var result = _dcall(reflectee, args); |
| 229 return reflect(result); |
| 230 } |
| 231 } |
| 232 |
| 233 class JsClassMirror extends JsMirror implements ClassMirror { |
93 final Type _cls; | 234 final Type _cls; |
94 final Symbol simpleName; | 235 final Symbol simpleName; |
| 236 // Generic class factory |
| 237 final dynamic _raw; |
| 238 |
| 239 // TODO(vsm): Do this properly |
| 240 final ClassMirror mixin = null; |
| 241 List<TypeMirror> _typeArguments; |
95 | 242 |
96 List<InstanceMirror> _metadata; | 243 List<InstanceMirror> _metadata; |
97 Map<Symbol, MethodMirror> _declarations; | 244 Map<Symbol, DeclarationMirror> _declarations; |
98 | 245 |
99 // TODO(vsm):These need to be immutable when escaping from this class. | 246 List<InstanceMirror> get metadata { |
100 List<InstanceMirror> get metadata => _metadata; | 247 if (_metadata == null) { |
101 Map<Symbol, MethodMirror> get declarations => _declarations; | 248 // Load metadata. |
| 249 var fn = JS('Function', '#[dart.metadata]', _unwrap(_cls)); |
| 250 _metadata = (fn == null) |
| 251 ? const <InstanceMirror>[] |
| 252 : new List<InstanceMirror>.unmodifiable( |
| 253 fn().map((i) => reflect(i))); |
| 254 } |
| 255 return _metadata; |
| 256 } |
| 257 |
| 258 Map<Symbol, DeclarationMirror> get declarations { |
| 259 if (_declarations == null) { |
| 260 // Load declarations. |
| 261 // TODO(vsm): This is only populating the default constructor right now. |
| 262 _declarations = new Map<Symbol, DeclarationMirror>(); |
| 263 var unwrapped = _unwrap(_cls); |
| 264 var constructors = _getConstructors(unwrapped); |
| 265 constructors.forEach((String name, ft) { |
| 266 var symbol = new Symbol(name); |
| 267 _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft); |
| 268 }); |
| 269 if (constructors.isEmpty) { |
| 270 // Add a default |
| 271 var name = 'new'; |
| 272 var ft = _defaultConstructorType(_unwrap(_cls)); |
| 273 var symbol = new Symbol(name); |
| 274 _declarations[symbol] = new JsMethodMirror._constructor(this, name, ft); |
| 275 } |
| 276 var fields = _getFields(unwrapped); |
| 277 fields.forEach((String name, t) { |
| 278 var symbol = new Symbol(name); |
| 279 var metadata = []; |
| 280 if (t is List) { |
| 281 metadata = t.skip(1).toList(); |
| 282 t = t[0]; |
| 283 } |
| 284 _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata)
; |
| 285 }); |
| 286 var methods = _getMethods(unwrapped); |
| 287 methods.forEach((String name, ft) { |
| 288 var symbol = new Symbol(name); |
| 289 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); |
| 290 }); |
| 291 var getters = _getGetters(unwrapped); |
| 292 getters.forEach((String name, ft) { |
| 293 var symbol = new Symbol(name); |
| 294 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); |
| 295 }); |
| 296 var setters = _getSetters(unwrapped); |
| 297 setters.forEach((String name, ft) { |
| 298 name += '='; |
| 299 var symbol = new Symbol(name); |
| 300 _declarations[symbol] = new JsMethodMirror._instanceMethod(this, name, f
t); |
| 301 }); |
| 302 var staticFields = _getStaticFields(unwrapped); |
| 303 staticFields.forEach((String name, t) { |
| 304 var symbol = new Symbol(name); |
| 305 var metadata = []; |
| 306 if (t is List) { |
| 307 metadata = t.skip(1).toList(); |
| 308 t = t[0]; |
| 309 } |
| 310 _declarations[symbol] = new JsVariableMirror._(name, _wrap(t), metadata)
; |
| 311 }); |
| 312 var statics = _getStatics(unwrapped); |
| 313 statics.forEach((String name, ft) { |
| 314 var symbol = new Symbol(name); |
| 315 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; |
| 316 }); |
| 317 var staticGetters = _getStaticGetters(unwrapped); |
| 318 staticGetters.forEach((String name, ft) { |
| 319 var symbol = new Symbol(name); |
| 320 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; |
| 321 }); |
| 322 var staticSetters = _getStaticSetters(unwrapped); |
| 323 staticSetters.forEach((String name, ft) { |
| 324 var symbol = new Symbol(name); |
| 325 _declarations[symbol] = new JsMethodMirror._staticMethod(this, name, ft)
; |
| 326 }); |
| 327 _declarations = new Map<Symbol, DeclarationMirror>.unmodifiable(_declarati
ons); |
| 328 } |
| 329 return _declarations; |
| 330 } |
102 | 331 |
103 JsClassMirror._(Type cls) | 332 JsClassMirror._(Type cls) |
104 : _cls = cls, | 333 : _cls = cls, |
| 334 _raw = _getGenericClass(_unwrap(cls)), |
105 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { | 335 simpleName = new Symbol(JS('String', '#.name', _unwrap(cls))) { |
106 // Load metadata. | 336 var typeArgs = _getGenericArgs(_unwrap(cls)); |
107 var fn = JS('Function', '#[dart.metadata]', _unwrap(_cls)); | 337 if (typeArgs == null) { |
108 _metadata = (fn == null) | 338 _typeArguments = const[]; |
109 ? <InstanceMirror>[] | 339 } else { |
110 : new List<InstanceMirror>.from( | 340 _typeArguments = new List.unmodifiable(typeArgs.map((t) => reflectType(_wr
ap(t)))); |
111 fn().map((i) => new JsInstanceMirror._(i))); | 341 } |
112 | |
113 // Load declarations. | |
114 // TODO(vsm): This is only populating the default constructor right now. | |
115 _declarations = new Map<Symbol, MethodMirror>(); | |
116 _declarations[simpleName] = new JsMethodMirror._(this, _cls); | |
117 } | 342 } |
118 | 343 |
119 InstanceMirror newInstance(Symbol constructorName, List args, | 344 InstanceMirror newInstance(Symbol constructorName, List args, |
120 [Map<Symbol, dynamic> namedArgs]) { | 345 [Map<Symbol, dynamic> namedArgs]) { |
121 // TODO(vsm): Support named constructors and named arguments. | 346 // TODO(vsm): Support factory constructors and named arguments. |
122 assert(getName(constructorName) == ""); | 347 var name = getName(constructorName); |
123 assert(namedArgs == null || namedArgs.isEmpty); | 348 assert(namedArgs == null || namedArgs.isEmpty); |
124 var instance = JS('', 'new #(...#)', _unwrap(_cls), args); | 349 var instance = (name == 'new' || name == '') |
125 return new JsInstanceMirror._(instance); | 350 ? JS('', 'new #(...#)', _unwrap(_cls), args) |
| 351 : JS('', 'new (#.#)(...#)', _unwrap(_cls), name, args); |
| 352 return reflect(instance); |
126 } | 353 } |
127 | 354 |
128 List<ClassMirror> get superinterfaces { | 355 List<ClassMirror> get superinterfaces { |
129 var interfaceThunk = JS('Function', '#[dart.implements]', _unwrap(_cls)); | 356 _Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls
)); |
130 if (interfaceThunk == null) { | 357 if (interfaceThunk == null) { |
131 return []; | 358 return []; |
132 } else { | 359 } else { |
133 List<Type> interfaces = interfaceThunk(); | 360 List<Type> interfaces = interfaceThunk(); |
134 return interfaces.map((t) => new JsClassMirror._(t)).toList(); | 361 return interfaces.map((t) => reflectType(t)).toList(); |
135 } | 362 } |
136 } | 363 } |
137 | 364 |
138 // TODO(vsm): Implement | 365 bool get hasReflectedType => true; |
139 InstanceMirror getField(Symbol fieldName) => | 366 Type get reflectedType { return _cls; } |
140 throw new UnimplementedError("ClassMirror.getField unimplemented"); | 367 |
141 InstanceMirror invoke(Symbol memberName, List positionalArguments, | 368 bool get isOriginalDeclaration => _raw == null; |
142 [Map<Symbol, dynamic> namedArguments]) => | 369 |
143 throw new UnimplementedError("ClassMirror.invoke unimplemented"); | 370 List<TypeMirror> get typeArguments => _typeArguments; |
144 bool isAssignableTo(TypeMirror other) => | 371 |
145 throw new UnimplementedError("ClassMirror.isAssignable unimplemented"); | |
146 bool isSubclassOf(ClassMirror other) => | |
147 throw new UnimplementedError("ClassMirror.isSubclassOf unimplemented"); | |
148 bool isSubtypeOf(TypeMirror other) => | |
149 throw new UnimplementedError("ClassMirror.isSubtypeOf unimplemented"); | |
150 InstanceMirror setField(Symbol fieldName, Object value) => | |
151 throw new UnimplementedError("ClassMirror.setField unimplemented"); | |
152 bool get hasReflectedType => throw new UnimplementedError( | |
153 "ClassMirror.hasReflectedType unimplemented"); | |
154 Map<Symbol, MethodMirror> get instanceMembers => | |
155 throw new UnimplementedError("ClassMirror.instanceMembers unimplemented"); | |
156 bool get isAbstract => | |
157 throw new UnimplementedError("ClassMirror.isAbstract unimplemented"); | |
158 bool get isEnum => | |
159 throw new UnimplementedError("ClassMirror.isEnum unimplemented"); | |
160 bool get isOriginalDeclaration => throw new UnimplementedError( | |
161 "ClassMirror.isOriginalDeclaration unimplemented"); | |
162 bool get isPrivate => | |
163 throw new UnimplementedError("ClassMirror.isPrivate unimplemented"); | |
164 bool get isTopLevel => | |
165 throw new UnimplementedError("ClassMirror.isTopLevel unimplemented"); | |
166 SourceLocation get location => | |
167 throw new UnimplementedError("ClassMirror.location unimplemented"); | |
168 ClassMirror get mixin => | |
169 throw new UnimplementedError("ClassMirror.mixin unimplemented"); | |
170 TypeMirror get originalDeclaration { | 372 TypeMirror get originalDeclaration { |
171 // TODO(vsm): Handle generic case. How should we represent an original | 373 // TODO(vsm): Handle generic case. How should we represent an original |
172 // declaration for a generic class? | 374 // declaration for a generic class? |
173 return this; | 375 if (_raw == null) { |
174 } | 376 return this; |
175 DeclarationMirror get owner => | 377 } |
176 throw new UnimplementedError("ClassMirror.owner unimplemented"); | 378 throw new UnimplementedError("ClassMirror.originalDeclaration unimplemented"
); |
177 Symbol get qualifiedName => | 379 } |
178 throw new UnimplementedError("ClassMirror.qualifiedName unimplemented"); | 380 |
179 Type get reflectedType { return _cls; } | |
180 Map<Symbol, MethodMirror> get staticMembers => | |
181 throw new UnimplementedError("ClassMirror.staticMembers unimplemented"); | |
182 ClassMirror get superclass { | 381 ClassMirror get superclass { |
183 if (_cls == Object) { | 382 if (_cls == Object) { |
184 return null; | 383 return null; |
185 } else { | 384 } else { |
186 return new JsClassMirror._(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))
); | 385 return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls)))); |
187 } | 386 } |
188 } | 387 } |
189 List<TypeMirror> get typeArguments => | 388 } |
190 throw new UnimplementedError("ClassMirror.typeArguments unimplemented"); | 389 |
191 List<TypeVariableMirror> get typeVariables => | 390 class JsVariableMirror extends JsMirror implements VariableMirror { |
192 throw new UnimplementedError("ClassMirror.typeVariables unimplemented"); | |
193 } | |
194 | |
195 class JsTypeMirror implements TypeMirror { | |
196 // TODO(vsm): Support original declarations, etc., where there is no actual | |
197 // reflected type. | |
198 final Type reflectedType; | |
199 final bool hasReflectedType = true; | |
200 | |
201 JsTypeMirror._(this.reflectedType); | |
202 | |
203 // TODO(vsm): Implement | |
204 bool isAssignableTo(TypeMirror other) => | |
205 throw new UnimplementedError("TypeMirror.isAssignable unimplemented"); | |
206 bool isSubtypeOf(TypeMirror other) => | |
207 throw new UnimplementedError("TypeMirror.isSubtypeOf unimplemented"); | |
208 bool get isOriginalDeclaration => throw new UnimplementedError( | |
209 "TypeMirror.isOriginalDeclaration unimplemented"); | |
210 bool get isPrivate => | |
211 throw new UnimplementedError("TypeMirror.isPrivate unimplemented"); | |
212 bool get isTopLevel => | |
213 throw new UnimplementedError("TypeMirror.isTopLevel unimplemented"); | |
214 SourceLocation get location => | |
215 throw new UnimplementedError("TypeMirror.location unimplemented"); | |
216 List<InstanceMirror> get metadata => | |
217 throw new UnimplementedError("TypeMirror.metadata unimplemented"); | |
218 TypeMirror get originalDeclaration => throw new UnimplementedError( | |
219 "TypeMirror.originalDeclaration unimplemented"); | |
220 DeclarationMirror get owner => | |
221 throw new UnimplementedError("TypeMirror.owner unimplemented"); | |
222 Symbol get qualifiedName => | |
223 throw new UnimplementedError("TypeMirror.qualifiedName unimplemented"); | |
224 Symbol get simpleName => | |
225 throw new UnimplementedError("TypeMirror.simpleName unimplemented"); | |
226 List<TypeMirror> get typeArguments => | |
227 throw new UnimplementedError("TypeMirror.typeArguments unimplemented"); | |
228 List<TypeVariableMirror> get typeVariables => | |
229 throw new UnimplementedError("TypeMirror.typeVariables unimplemented"); | |
230 } | |
231 | |
232 class JsParameterMirror implements ParameterMirror { | |
233 final String _name; | 391 final String _name; |
234 final TypeMirror type; | 392 final TypeMirror type; |
235 final List<InstanceMirror> metadata; | 393 final List<InstanceMirror> metadata; |
236 | 394 |
237 JsParameterMirror._(this._name, Type t, List annotations) | 395 // TODO(vsm): Refactor this out. |
238 : type = new JsTypeMirror._(t), | 396 Symbol get simpleName => new Symbol(_name); |
239 metadata = new List<InstanceMirror>.from( | 397 |
240 annotations.map((a) => new JsInstanceMirror._(a))); | 398 // TODO(vsm): Fix this |
241 | 399 final bool isStatic = false; |
242 // TODO(vsm): Implement | 400 final bool isFinal = false; |
243 InstanceMirror get defaultValue => throw new UnimplementedError( | 401 |
244 "ParameterMirror.defaultValues unimplemented"); | 402 JsVariableMirror._(this._name, Type t, List annotations) |
245 bool get hasDefaultValue => throw new UnimplementedError( | 403 : type = reflectType(t), |
246 "ParameterMirror.hasDefaultValue unimplemented"); | 404 metadata = new List<InstanceMirror>.unmodifiable( |
247 bool get isConst => | 405 annotations.map((a) => reflect(a))); |
248 throw new UnimplementedError("ParameterMirror.isConst unimplemented"); | 406 } |
249 bool get isFinal => | 407 |
250 throw new UnimplementedError("ParameterMirror.isFinal unimplemented"); | 408 class JsParameterMirror extends JsVariableMirror implements ParameterMirror { |
251 bool get isNamed => | 409 JsParameterMirror._(String name, Type t, List annotations) |
252 throw new UnimplementedError("ParameterMirror.isNamed unimplemented"); | 410 : super._(name, t, annotations); |
253 bool get isOptional => | 411 } |
254 throw new UnimplementedError("ParameterMirror.isOptional unimplemented"); | 412 |
255 bool get isPrivate => | 413 class JsMethodMirror extends JsMirror implements MethodMirror { |
256 throw new UnimplementedError("ParameterMirror.isPrivate unimplemented"); | 414 // TODO(vsm): This could be a JS symbol for private methods |
257 bool get isStatic => | |
258 throw new UnimplementedError("ParameterMirror.isStatic unimplemented"); | |
259 bool get isTopLevel => | |
260 throw new UnimplementedError("ParameterMirror.isTopLevel unimplemented"); | |
261 SourceLocation get location => | |
262 throw new UnimplementedError("ParameterMirror.location unimplemented"); | |
263 DeclarationMirror get owner => | |
264 throw new UnimplementedError("ParameterMirror.owner unimplemented"); | |
265 Symbol get qualifiedName => throw new UnimplementedError( | |
266 "ParameterMirror.qualifiedName unimplemented"); | |
267 Symbol get simpleName => | |
268 throw new UnimplementedError("ParameterMirror.simpleName unimplemented"); | |
269 } | |
270 | |
271 class JsMethodMirror implements MethodMirror { | |
272 final String _name; | 415 final String _name; |
273 final dynamic _method; | |
274 List<ParameterMirror> _params; | 416 List<ParameterMirror> _params; |
275 | 417 List<InstanceMirror> _metadata; |
276 JsMethodMirror._(JsClassMirror cls, this._method) | 418 final bool isConstructor; |
277 : _name = getName(cls.simpleName) { | 419 final bool isStatic; |
278 var ftype = JS('', '#.classGetConstructorType(#)', _dart, _unwrap(cls._cls))
; | 420 |
279 _params = _createParameterMirrorList(ftype); | 421 // TODO(vsm): Fix this |
| 422 final bool isFinal = false; |
| 423 bool get isSetter => _name.endsWith('='); |
| 424 bool get isPrivate => _name.startsWith('_'); |
| 425 |
| 426 // TODO(vsm): Refactor this out. |
| 427 Symbol get simpleName => new Symbol(_name); |
| 428 |
| 429 JsMethodMirror._constructor(JsClassMirror cls, String name, ftype) |
| 430 : _name = name, isConstructor = true, isStatic = false { |
| 431 _createParameterMirrorList(ftype); |
| 432 } |
| 433 |
| 434 JsMethodMirror._instanceMethod(JsClassMirror cls, String name, ftype) |
| 435 : _name = name, isConstructor = false, isStatic = false { |
| 436 _createParameterMirrorList(ftype); |
| 437 } |
| 438 |
| 439 JsMethodMirror._staticMethod(JsClassMirror cls, String name, ftype) |
| 440 : _name = name, isConstructor = false, isStatic = true { |
| 441 _createParameterMirrorList(ftype); |
280 } | 442 } |
281 | 443 |
282 // TODO(vsm): Support named constructors. | 444 // TODO(vsm): Support named constructors. |
283 Symbol get constructorName => new Symbol(''); | 445 Symbol get constructorName => isConstructor ? new Symbol(_name) : null; |
284 List<ParameterMirror> get parameters => _params; | 446 List<ParameterMirror> get parameters => _params; |
285 | 447 List<InstanceMirror> get metadata => _metadata; |
286 List<ParameterMirror> _createParameterMirrorList(ftype) { | 448 |
| 449 void _createParameterMirrorList(ftype) { |
287 if (ftype == null) { | 450 if (ftype == null) { |
288 // TODO(vsm): No explicit constructor. Verify this. | 451 // TODO(vsm): No explicit constructor. Verify this. |
289 return []; | 452 _params = const []; |
| 453 _metadata = const []; |
| 454 return; |
| 455 } |
| 456 if (ftype is List) { |
| 457 // Record metadata |
| 458 _metadata = new List<InstanceMirror>.unmodifiable( |
| 459 ftype.skip(1).map((a) => reflect(a))); |
| 460 ftype = ftype[0]; |
| 461 } else { |
| 462 _metadata = const []; |
290 } | 463 } |
291 | 464 |
292 // TODO(vsm): Add named args. | 465 // TODO(vsm): Add named args. |
293 List args = ftype.args; | 466 List args = ftype.args; |
294 List opts = ftype.optionals; | 467 List opts = ftype.optionals; |
295 var params = new List<ParameterMirror>(args.length + opts.length); | 468 var params = new List<ParameterMirror>(args.length + opts.length); |
296 | 469 |
297 for (var i = 0; i < args.length; ++i) { | 470 for (var i = 0; i < args.length; ++i) { |
298 var type = args[i]; | 471 var type = args[i]; |
299 var metadata = ftype.metadata[i]; | 472 var metadata = ftype.metadata[i]; |
300 // TODO(vsm): Recover the param name. | 473 // TODO(vsm): Recover the param name. |
301 var param = new JsParameterMirror._('', _wrap(type), metadata); | 474 var param = new JsParameterMirror._('', _wrap(type), metadata); |
302 params[i] = param; | 475 params[i] = param; |
303 } | 476 } |
304 | 477 |
305 for (var i = 0; i < opts.length; ++i) { | 478 for (var i = 0; i < opts.length; ++i) { |
306 var type = opts[i]; | 479 var type = opts[i]; |
307 var metadata = ftype.metadata[args.length + i]; | 480 var metadata = ftype.metadata[args.length + i]; |
308 // TODO(vsm): Recover the param name. | 481 // TODO(vsm): Recover the param name. |
309 var param = new JsParameterMirror._('', _wrap(type), metadata); | 482 var param = new JsParameterMirror._('', _wrap(type), metadata); |
310 params[i + args.length] = param; | 483 params[i + args.length] = param; |
311 } | 484 } |
312 | 485 |
313 return params; | 486 _params = new List.unmodifiable(params); |
314 } | 487 } |
315 | |
316 // TODO(vsm): Implement | |
317 bool get isAbstract => | |
318 throw new UnimplementedError("MethodMirror.isAbstract unimplemented"); | |
319 bool get isConstConstructor => throw new UnimplementedError( | |
320 "MethodMirror.isConstConstructor unimplemented"); | |
321 bool get isConstructor => | |
322 throw new UnimplementedError("MethodMirror.isConstructor unimplemented"); | |
323 bool get isFactoryConstructor => throw new UnimplementedError( | |
324 "MethodMirror.isFactoryConstructor unimplemented"); | |
325 bool get isGenerativeConstructor => throw new UnimplementedError( | |
326 "MethodMirror.isGenerativeConstructor unimplemented"); | |
327 bool get isGetter => | |
328 throw new UnimplementedError("MethodMirror.isGetter unimplemented"); | |
329 bool get isOperator => | |
330 throw new UnimplementedError("MethodMirror.isOperator unimplemented"); | |
331 bool get isPrivate => | |
332 throw new UnimplementedError("MethodMirror.isPrivate unimplemented"); | |
333 bool get isRedirectingConstructor => throw new UnimplementedError( | |
334 "MethodMirror.isRedirectingConstructor unimplemented"); | |
335 bool get isRegularMethod => throw new UnimplementedError( | |
336 "MethodMirror.isRegularMethod unimplemented"); | |
337 bool get isSetter => | |
338 throw new UnimplementedError("MethodMirror.isSetter unimplemented"); | |
339 bool get isStatic => | |
340 throw new UnimplementedError("MethodMirror.isStatic unimplemented"); | |
341 bool get isSynthetic => | |
342 throw new UnimplementedError("MethodMirror.isSynthetic unimplemented"); | |
343 bool get isTopLevel => | |
344 throw new UnimplementedError("MethodMirror.isTopLevel unimplemented"); | |
345 SourceLocation get location => | |
346 throw new UnimplementedError("MethodMirror.location unimplemented"); | |
347 List<InstanceMirror> get metadata { | |
348 // TODO(vsm): Parse and store method metadata | |
349 return <InstanceMirror>[]; | |
350 } | |
351 DeclarationMirror get owner => | |
352 throw new UnimplementedError("MethodMirror.owner unimplemented"); | |
353 Symbol get qualifiedName => | |
354 throw new UnimplementedError("MethodMirror.qualifiedName unimplemented"); | |
355 TypeMirror get returnType => | |
356 throw new UnimplementedError("MethodMirror.returnType unimplemented"); | |
357 Symbol get simpleName => | |
358 throw new UnimplementedError("MethodMirror.simpleName unimplemented"); | |
359 String get source => | |
360 throw new UnimplementedError("MethodMirror.source unimplemented"); | |
361 } | 488 } |
OLD | NEW |