OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 part of dart2js.mirrors; | |
6 | |
7 abstract class ClassMirrorMixin implements ClassSourceMirror { | |
8 bool get hasReflectedType => false; | |
9 Type get reflectedType { | |
10 throw new UnsupportedError("ClassMirror.reflectedType is not supported."); | |
11 } | |
12 InstanceMirror newInstance(Symbol constructorName, | |
13 List positionalArguments, | |
14 [Map<Symbol, dynamic> namedArguments]) { | |
15 throw new UnsupportedError("ClassMirror.newInstance is not supported."); | |
16 } | |
17 } | |
18 | |
19 abstract class Dart2JsTypeMirror | |
20 implements Dart2JsDeclarationMirror, TypeSourceMirror { | |
21 DartType get _type; | |
22 | |
23 String get _simpleNameString => _type.name; | |
24 | |
25 Dart2JsDeclarationMirror get owner => library; | |
26 | |
27 Dart2JsLibraryMirror get library; | |
28 | |
29 bool get hasReflectedType => throw new UnimplementedError(); | |
30 | |
31 Type get reflectedType => throw new UnimplementedError(); | |
32 | |
33 bool get isOriginalDeclaration => true; | |
34 | |
35 TypeMirror get originalDeclaration => this; | |
36 | |
37 List<TypeMirror> get typeArguments => const <TypeMirror>[]; | |
38 | |
39 List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[]; | |
40 | |
41 TypeMirror createInstantiation(List<TypeMirror> typeArguments) { | |
42 if (typeArguments.isEmpty) return this; | |
43 throw new ArgumentError('Cannot create generic instantiation of $_type.'); | |
44 } | |
45 | |
46 bool get isVoid => false; | |
47 | |
48 bool get isDynamic => false; | |
49 | |
50 bool isSubtypeOf(TypeMirror other) { | |
51 if (other is Dart2JsTypeMirror) { | |
52 return mirrorSystem.compiler.types.isSubtype(this._type, other._type); | |
53 } else { | |
54 throw new ArgumentError(other); | |
55 } | |
56 } | |
57 | |
58 bool isAssignableTo(TypeMirror other) { | |
59 if (other is Dart2JsTypeMirror) { | |
60 return mirrorSystem.compiler.types.isAssignable(this._type, other._type); | |
61 } else { | |
62 throw new ArgumentError(other); | |
63 } | |
64 } | |
65 | |
66 String toString() => _type.toString(); | |
67 | |
68 } | |
69 | |
70 /// Base implementations for mirrors on element based types. | |
71 abstract class Dart2JsTypeElementMirror | |
72 extends Dart2JsElementMirror | |
73 with Dart2JsTypeMirror | |
74 implements TypeSourceMirror { | |
75 final DartType _type; | |
76 | |
77 Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, DartType type) | |
78 : super(system, type.element), | |
79 this._type = type; | |
80 | |
81 Dart2JsLibraryMirror get library { | |
82 return mirrorSystem._getLibrary(_type.element.library); | |
83 } | |
84 } | |
85 | |
86 abstract class DeclarationMixin implements TypeMirror { | |
87 | |
88 bool get isOriginalDeclaration => true; | |
89 | |
90 TypeMirror get originalDeclaration => this; | |
91 | |
92 List<TypeMirror> get typeArguments => const <TypeMirror>[]; | |
93 } | |
94 | |
95 abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeElementMirror { | |
96 List<TypeMirror> _typeArguments; | |
97 List<TypeVariableMirror> _typeVariables; | |
98 | |
99 Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type) | |
100 : super(system, type); | |
101 | |
102 TypeDeclarationElement get _element => super._element; | |
103 | |
104 GenericType get _type => super._type; | |
105 | |
106 bool get isOriginalDeclaration => false; | |
107 | |
108 TypeMirror get originalDeclaration => | |
109 mirrorSystem._getTypeDeclarationMirror(_element); | |
110 | |
111 List<TypeMirror> get typeArguments { | |
112 if (_typeArguments == null) { | |
113 _typeArguments = <TypeMirror>[]; | |
114 if (!_type.isRaw) { | |
115 for (DartType type in _type.typeArguments) { | |
116 _typeArguments.add(_getTypeMirror(type)); | |
117 } | |
118 } | |
119 } | |
120 return _typeArguments; | |
121 } | |
122 | |
123 List<TypeVariableMirror> get typeVariables { | |
124 if (_typeVariables == null) { | |
125 _typeVariables = <TypeVariableMirror>[]; | |
126 for (TypeVariableType typeVariable in _element.typeVariables) { | |
127 _typeVariables.add( | |
128 new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable)); | |
129 } | |
130 } | |
131 return _typeVariables; | |
132 } | |
133 | |
134 Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) { | |
135 if (element.isTypeVariable) { | |
136 assert(invariant(_element, _element == element.enclosingElement, | |
137 message: 'Foreigned type variable element $element.')); | |
138 for (Dart2JsTypeVariableMirror mirror in typeVariables) { | |
139 if (mirror._element == element) return [mirror]; | |
140 } | |
141 } | |
142 return super._getDeclarationMirrors(element); | |
143 } | |
144 | |
145 TypeMirror _getTypeMirror(DartType type) { | |
146 return super._getTypeMirror( | |
147 type.subst(_type.typeArguments, _type.element.typeVariables)); | |
148 } | |
149 | |
150 TypeSourceMirror createInstantiation( | |
151 List<TypeSourceMirror> newTypeArguments) { | |
152 if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw()); | |
153 if (newTypeArguments.length != typeVariables.length) { | |
154 throw new ArgumentError('Cannot create generic instantiation of $_type ' | |
155 'with ${newTypeArguments.length} arguments, ' | |
156 'expect ${typeVariables.length} arguments.'); | |
157 } | |
158 List<DartType> builder = <DartType>[]; | |
159 for (TypeSourceMirror newTypeArgument in newTypeArguments) { | |
160 if (newTypeArgument.isVoid) { | |
161 throw new ArgumentError('Cannot use void as type argument.'); | |
162 } | |
163 if (newTypeArgument is Dart2JsTypeMirror) { | |
164 builder.add(newTypeArgument._type); | |
165 } else { | |
166 throw new UnsupportedError( | |
167 'Cannot create instantiation using a type ' | |
168 'mirror from a different mirrorSystem implementation.'); | |
169 } | |
170 } | |
171 return owner._getTypeMirror(_type.createInstantiation(builder)); | |
172 } | |
173 } | |
174 | |
175 class Dart2JsInterfaceTypeMirror | |
176 extends Dart2JsGenericTypeMirror | |
177 with ObjectMirrorMixin, ClassMirrorMixin, ContainerMixin | |
178 implements ClassMirror { | |
179 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system, | |
180 InterfaceType interfaceType) | |
181 : super(system, interfaceType); | |
182 | |
183 ClassElement get _element => super._element; | |
184 | |
185 InterfaceType get _type => super._type; | |
186 | |
187 bool get isNameSynthetic { | |
188 if (_element.isMixinApplication) { | |
189 MixinApplicationElement mixinApplication = _element; | |
190 return mixinApplication.isUnnamedMixinApplication; | |
191 } | |
192 return false; | |
193 } | |
194 | |
195 void _forEachElement(f(Element element)) { | |
196 _element.forEachMember((_, element) => f(element)); | |
197 } | |
198 | |
199 ClassMirror get superclass { | |
200 if (_element.supertype != null) { | |
201 return _getTypeMirror(_element.supertype); | |
202 } | |
203 return null; | |
204 } | |
205 | |
206 bool isSubclassOf(Mirror other) { | |
207 if (other is Dart2JsTypeMirror) { | |
208 return other._type.element != null && | |
209 _element.isSubclassOf(other._type.element); | |
210 } else { | |
211 throw new ArgumentError(other); | |
212 } | |
213 } | |
214 | |
215 ClassMirror get mixin { | |
216 if (_element.isMixinApplication) { | |
217 MixinApplicationElement mixinApplication = _element; | |
218 return _getTypeMirror(mixinApplication.mixinType); | |
219 } | |
220 return this; | |
221 } | |
222 | |
223 List<ClassMirror> get superinterfaces { | |
224 var list = <ClassMirror>[]; | |
225 Link<DartType> link = _element.interfaces; | |
226 while (!link.isEmpty) { | |
227 var type = _getTypeMirror(link.head); | |
228 list.add(type); | |
229 link = link.tail; | |
230 } | |
231 return list; | |
232 } | |
233 | |
234 Map<Symbol, MethodMirror> get instanceMembers => null; | |
235 Map<Symbol, MethodMirror> get staticMembers => null; | |
236 | |
237 bool get isAbstract => _element.isAbstract; | |
238 | |
239 bool operator ==(other) { | |
240 if (identical(this, other)) { | |
241 return true; | |
242 } | |
243 if (other is! ClassMirror) { | |
244 return false; | |
245 } | |
246 return _type == other._type; | |
247 } | |
248 | |
249 String toString() => 'Mirror on interface type $_type'; | |
250 } | |
251 | |
252 class Dart2JsClassDeclarationMirror | |
253 extends Dart2JsInterfaceTypeMirror | |
254 with DeclarationMixin { | |
255 | |
256 Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system, | |
257 InterfaceType type) | |
258 : super(system, type); | |
259 | |
260 bool isSubclassOf(ClassMirror other) { | |
261 if (other is Dart2JsClassDeclarationMirror) { | |
262 Dart2JsClassDeclarationMirror otherDeclaration = | |
263 other.originalDeclaration; | |
264 return _element.isSubclassOf(otherDeclaration._element); | |
265 } else if (other is FunctionTypeMirror) { | |
266 return false; | |
267 } | |
268 throw new ArgumentError(other); | |
269 } | |
270 | |
271 String toString() => 'Mirror on class ${_type.name}'; | |
272 } | |
273 | |
274 class Dart2JsTypedefMirror | |
275 extends Dart2JsGenericTypeMirror | |
276 implements TypedefMirror { | |
277 final Dart2JsLibraryMirror _library; | |
278 List<TypeVariableMirror> _typeVariables; | |
279 var _definition; | |
280 | |
281 Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef) | |
282 : this._library = system._getLibrary(_typedef.element.library), | |
283 super(system, _typedef); | |
284 | |
285 Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library, | |
286 TypedefType _typedef) | |
287 : this._library = library, | |
288 super(library.mirrorSystem, _typedef); | |
289 | |
290 TypedefType get _typedef => _type; | |
291 | |
292 LibraryMirror get library => _library; | |
293 | |
294 bool get isTypedef => true; | |
295 | |
296 FunctionTypeMirror get referent { | |
297 if (_definition == null) { | |
298 _definition = _getTypeMirror(_typedef.element.alias); | |
299 } | |
300 return _definition; | |
301 } | |
302 | |
303 bool get isClass => false; | |
304 | |
305 bool get isAbstract => false; | |
306 | |
307 String toString() => 'Mirror on typedef $_type'; | |
308 } | |
309 | |
310 class Dart2JsTypedefDeclarationMirror | |
311 extends Dart2JsTypedefMirror | |
312 with DeclarationMixin { | |
313 Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system, | |
314 TypedefType type) | |
315 : super(system, type); | |
316 | |
317 String toString() => 'Mirror on typedef ${_type.name}'; | |
318 } | |
319 | |
320 class Dart2JsTypeVariableMirror extends Dart2JsTypeElementMirror | |
321 implements TypeVariableMirror { | |
322 Dart2JsDeclarationMirror _owner; | |
323 | |
324 Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system, | |
325 TypeVariableType typeVariableType) | |
326 : super(system, typeVariableType); | |
327 | |
328 TypeVariableType get _type => super._type; | |
329 | |
330 Dart2JsDeclarationMirror get owner { | |
331 if (_owner == null) { | |
332 _owner = mirrorSystem._getTypeDeclarationMirror( | |
333 _type.element.typeDeclaration); | |
334 } | |
335 return _owner; | |
336 } | |
337 | |
338 bool get isStatic => false; | |
339 | |
340 TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound); | |
341 | |
342 bool operator ==(var other) { | |
343 if (identical(this, other)) { | |
344 return true; | |
345 } | |
346 if (other is! TypeVariableMirror) { | |
347 return false; | |
348 } | |
349 if (owner != other.owner) { | |
350 return false; | |
351 } | |
352 return qualifiedName == other.qualifiedName; | |
353 } | |
354 | |
355 String toString() => 'Mirror on type variable $_type'; | |
356 } | |
357 | |
358 class Dart2JsFunctionTypeMirror extends Dart2JsTypeElementMirror | |
359 with ObjectMirrorMixin, ClassMirrorMixin, DeclarationMixin | |
360 implements FunctionTypeMirror { | |
361 List<ParameterMirror> _parameters; | |
362 | |
363 Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system, | |
364 FunctionType functionType) | |
365 : super(system, functionType) { | |
366 assert (functionType.element != null); | |
367 } | |
368 | |
369 FunctionType get _type => super._type; | |
370 | |
371 // TODO(johnniwinther): Is this the qualified name of a function type? | |
372 Symbol get qualifiedName => originalDeclaration.qualifiedName; | |
373 | |
374 // TODO(johnniwinther): Substitute type arguments for type variables. | |
375 Map<Symbol, DeclarationMirror> get declarations { | |
376 var method = callMethod; | |
377 if (method != null) { | |
378 var map = new Map<Symbol, DeclarationMirror>.from( | |
379 originalDeclaration.declarations); | |
380 var name = method.qualifiedName; | |
381 assert(!map.containsKey(name)); | |
382 map[name] = method; | |
383 return new UnmodifiableMapView<Symbol, DeclarationMirror>(map); | |
384 } | |
385 return originalDeclaration.declarations; | |
386 } | |
387 | |
388 bool get isFunction => true; | |
389 | |
390 MethodMirror get callMethod => _convertElementMethodToMethodMirror( | |
391 mirrorSystem._getLibrary(_type.element.library), | |
392 _type.element); | |
393 | |
394 ClassMirror get originalDeclaration => | |
395 mirrorSystem._getTypeDeclarationMirror( | |
396 mirrorSystem.compiler.functionClass); | |
397 | |
398 // TODO(johnniwinther): Substitute type arguments for type variables. | |
399 ClassMirror get superclass => originalDeclaration.superclass; | |
400 | |
401 // TODO(johnniwinther): Substitute type arguments for type variables. | |
402 List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces; | |
403 | |
404 Map<Symbol, MethodMirror> get instanceMembers => null; | |
405 Map<Symbol, MethodMirror> get staticMembers => null; | |
406 | |
407 ClassMirror get mixin => this; | |
408 | |
409 bool get isPrivate => false; | |
410 | |
411 bool get isAbstract => false; | |
412 | |
413 List<TypeVariableMirror> get typeVariables => | |
414 originalDeclaration.typeVariables; | |
415 | |
416 TypeMirror get returnType => owner._getTypeMirror(_type.returnType); | |
417 | |
418 List<ParameterMirror> get parameters { | |
419 if (_parameters == null) { | |
420 _parameters = _parametersFromFunctionSignature( | |
421 owner, _type.element.functionSignature); | |
422 } | |
423 return _parameters; | |
424 } | |
425 | |
426 String toString() => 'Mirror on function type $_type'; | |
427 | |
428 bool isSubclassOf(ClassMirror other) => false; | |
429 } | |
430 | |
431 /// Common superclass for mirrors on `dynamic` and `void`. | |
432 abstract class Dart2JsBuiltinTypeMirror extends Dart2JsDeclarationMirror | |
433 with Dart2JsTypeMirror | |
434 implements TypeSourceMirror { | |
435 final Dart2JsMirrorSystem mirrorSystem; | |
436 final DartType _type; | |
437 | |
438 Dart2JsBuiltinTypeMirror(Dart2JsMirrorSystem this.mirrorSystem, | |
439 DartType this._type); | |
440 | |
441 Symbol get qualifiedName => simpleName; | |
442 | |
443 /** | |
444 * The builtin types have has no location. | |
445 */ | |
446 SourceLocation get location => null; | |
447 | |
448 /** | |
449 * The builtin types have has no owner. | |
450 */ | |
451 Dart2JsDeclarationMirror get owner => null; | |
452 | |
453 /** | |
454 * The builtin types have no library. | |
455 */ | |
456 Dart2JsLibraryMirror get library => null; | |
457 | |
458 /** | |
459 * The builtin types have no metadata. | |
460 */ | |
461 List<InstanceMirror> get metadata => const <InstanceMirror>[]; | |
462 } | |
463 | |
464 class Dart2JsVoidMirror extends Dart2JsBuiltinTypeMirror { | |
465 Dart2JsVoidMirror(Dart2JsMirrorSystem mirrorSystem, VoidType type) | |
466 : super(mirrorSystem, type); | |
467 | |
468 bool get isVoid => true; | |
469 | |
470 bool operator ==(other) { | |
471 if (identical(this, other)) { | |
472 return true; | |
473 } | |
474 if (other is! TypeMirror) { | |
475 return false; | |
476 } | |
477 return other.isVoid; | |
478 } | |
479 | |
480 int get hashCode => 13 * _type.hashCode; | |
481 | |
482 String toString() => 'Mirror on void'; | |
483 } | |
484 | |
485 class Dart2JsDynamicMirror extends Dart2JsBuiltinTypeMirror { | |
486 Dart2JsDynamicMirror(Dart2JsMirrorSystem mirrorSystem, DynamicType type) | |
487 : super(mirrorSystem, type); | |
488 | |
489 bool get isDynamic => true; | |
490 | |
491 bool operator ==(other) { | |
492 if (identical(this, other)) { | |
493 return true; | |
494 } | |
495 if (other is! TypeMirror) { | |
496 return false; | |
497 } | |
498 return other.isDynamic; | |
499 } | |
500 | |
501 int get hashCode => 13 * _type.hashCode; | |
502 | |
503 String toString() => 'Mirror on dynamic'; | |
504 } | |
OLD | NEW |