Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(327)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/mirrors/dart2js_mirror.dart

Issue 119913002: Align source mirrors with runtime mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments + small fix. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library mirrors_dart2js;
6
7 import 'dart:async';
8
9 import '../../compiler.dart' as api;
10 import '../elements/elements.dart';
11 import '../apiimpl.dart' as apiimpl;
12 import '../scanner/scannerlib.dart';
13 import '../resolution/resolution.dart' show Scope;
14 import '../dart2jslib.dart';
15 import '../dart_types.dart';
16 import '../tree/tree.dart';
17 import '../util/util.dart' show Spannable, Link;
18 import '../util/characters.dart' show $CR, $LF;
19
20 import 'mirrors.dart';
21 import 'mirrors_util.dart';
22 import 'util.dart';
23
24 //------------------------------------------------------------------------------
25 // Utility types and functions for the dart2js mirror system
26 //------------------------------------------------------------------------------
27
28 bool _isPrivate(String name) {
29 return name.startsWith('_');
30 }
31
32 List<ParameterMirror> _parametersFromFunctionSignature(
33 Dart2JsMirrorSystem system,
34 Dart2JsMethodMirror method,
35 FunctionSignature signature) {
36 var parameters = <ParameterMirror>[];
37 Link<Element> link = signature.requiredParameters;
38 while (!link.isEmpty) {
39 parameters.add(new Dart2JsParameterMirror(
40 system, method, link.head, isOptional: false, isNamed: false));
41 link = link.tail;
42 }
43 link = signature.optionalParameters;
44 bool isNamed = signature.optionalParametersAreNamed;
45 while (!link.isEmpty) {
46 parameters.add(new Dart2JsParameterMirror(
47 system, method, link.head, isOptional: true, isNamed: isNamed));
48 link = link.tail;
49 }
50 return parameters;
51 }
52
53 Dart2JsTypeMirror _convertTypeToTypeMirror(
54 Dart2JsMirrorSystem system,
55 DartType type,
56 InterfaceType defaultType,
57 [FunctionSignature functionSignature]) {
58 if (type == null) {
59 return new Dart2JsInterfaceTypeMirror(system, defaultType);
60 } else if (type is InterfaceType) {
61 if (type == system.compiler.types.dynamicType) {
62 return new Dart2JsDynamicMirror(system, type);
63 } else {
64 return new Dart2JsInterfaceTypeMirror(system, type);
65 }
66 } else if (type is TypeVariableType) {
67 return new Dart2JsTypeVariableMirror(system, type);
68 } else if (type is FunctionType) {
69 return new Dart2JsFunctionTypeMirror(system, type, functionSignature);
70 } else if (type is VoidType) {
71 return new Dart2JsVoidMirror(system, type);
72 } else if (type is TypedefType) {
73 return new Dart2JsTypedefMirror(system, type);
74 } else if (type is MalformedType) {
75 // TODO(johnniwinther): We need a mirror on malformed types.
76 return system.dynamicType;
77 }
78 system.compiler.internalError("Unexpected type $type of kind ${type.kind}");
79 }
80
81 Iterable<Dart2JsMemberMirror> _convertElementMemberToMemberMirrors(
82 Dart2JsContainerMirror library, Element element) {
83 if (element.isSynthesized) {
84 return const <Dart2JsMemberMirror>[];
85 } else if (element is VariableElement) {
86 return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(library, element)];
87 } else if (element is FunctionElement) {
88 return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(library, element)];
89 } else if (element is AbstractFieldElement) {
90 var members = <Dart2JsMemberMirror>[];
91 AbstractFieldElement field = element;
92 if (field.getter != null) {
93 members.add(new Dart2JsMethodMirror(library, field.getter));
94 }
95 if (field.setter != null) {
96 members.add(new Dart2JsMethodMirror(library, field.setter));
97 }
98 return members;
99 }
100 library.mirrors.compiler.internalError(
101 "Unexpected member type $element ${element.kind}");
102 }
103
104 MethodMirror _convertElementMethodToMethodMirror(Dart2JsContainerMirror library,
105 Element element) {
106 if (element is FunctionElement) {
107 return new Dart2JsMethodMirror(library, element);
108 } else {
109 return null;
110 }
111 }
112
113 InstanceMirror _convertConstantToInstanceMirror(Dart2JsMirrorSystem mirrors,
114 Constant constant) {
115 if (constant is BoolConstant) {
116 return new Dart2JsBoolConstantMirror(mirrors, constant);
117 } else if (constant is NumConstant) {
118 return new Dart2JsNumConstantMirror(mirrors, constant);
119 } else if (constant is StringConstant) {
120 return new Dart2JsStringConstantMirror(mirrors, constant);
121 } else if (constant is ListConstant) {
122 return new Dart2JsListConstantMirror(mirrors, constant);
123 } else if (constant is MapConstant) {
124 return new Dart2JsMapConstantMirror(mirrors, constant);
125 } else if (constant is TypeConstant) {
126 return new Dart2JsTypeConstantMirror(mirrors, constant);
127 } else if (constant is FunctionConstant) {
128 return new Dart2JsConstantMirror(mirrors, constant);
129 } else if (constant is NullConstant) {
130 return new Dart2JsNullConstantMirror(mirrors, constant);
131 } else if (constant is ConstructedConstant) {
132 return new Dart2JsConstructedConstantMirror(mirrors, constant);
133 }
134 mirrors.compiler.internalError("Unexpected constant $constant");
135 }
136
137 class Dart2JsMethodKind {
138 static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular");
139 static const Dart2JsMethodKind GENERATIVE =
140 const Dart2JsMethodKind("generative");
141 static const Dart2JsMethodKind REDIRECTING =
142 const Dart2JsMethodKind("redirecting");
143 static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const");
144 static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory");
145 static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter");
146 static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter");
147 static const Dart2JsMethodKind OPERATOR = const Dart2JsMethodKind("operator");
148
149 final String text;
150
151 const Dart2JsMethodKind(this.text);
152
153 String toString() => text;
154 }
155
156
157 String _getOperatorFromOperatorName(String name) {
158 Map<String, String> mapping = const {
159 'eq': '==',
160 'not': '~',
161 'index': '[]',
162 'indexSet': '[]=',
163 'mul': '*',
164 'div': '/',
165 'mod': '%',
166 'tdiv': '~/',
167 'add': '+',
168 'sub': '-',
169 'shl': '<<',
170 'shr': '>>',
171 'ge': '>=',
172 'gt': '>',
173 'le': '<=',
174 'lt': '<',
175 'and': '&',
176 'xor': '^',
177 'or': '|',
178 };
179 String newName = mapping[name];
180 if (newName == null) {
181 throw new Exception('Unhandled operator name: $name');
182 }
183 return newName;
184 }
185
186 //------------------------------------------------------------------------------
187 // Analysis entry point.
188 //------------------------------------------------------------------------------
189
190 /**
191 * Analyzes set of libraries and provides a mirror system which can be used for
192 * static inspection of the source code.
193 */
194 // TODO(johnniwinther): Move this to [compiler/compiler.dart].
195 Future<MirrorSystem> analyze(List<Uri> libraries,
196 Uri libraryRoot,
197 Uri packageRoot,
198 api.CompilerInputProvider inputProvider,
199 api.DiagnosticHandler diagnosticHandler,
200 [List<String> options = const <String>[]]) {
201 if (!libraryRoot.path.endsWith("/")) {
202 throw new ArgumentError("libraryRoot must end with a /");
203 }
204 if (packageRoot != null && !packageRoot.path.endsWith("/")) {
205 throw new ArgumentError("packageRoot must end with a /");
206 }
207 options = new List<String>.from(options);
208 options.add('--analyze-only');
209 options.add('--analyze-signatures-only');
210 options.add('--analyze-all');
211 options.add('--categories=Client,Server');
212
213 bool compilationFailed = false;
214 void internalDiagnosticHandler(Uri uri, int begin, int end,
215 String message, api.Diagnostic kind) {
216 if (kind == api.Diagnostic.ERROR ||
217 kind == api.Diagnostic.CRASH) {
218 compilationFailed = true;
219 }
220 diagnosticHandler(uri, begin, end, message, kind);
221 }
222
223 Compiler compiler = new apiimpl.Compiler(inputProvider,
224 null,
225 internalDiagnosticHandler,
226 libraryRoot, packageRoot,
227 options,
228 const {});
229 compiler.librariesToAnalyzeWhenRun = libraries;
230 return compiler.run(null).then((bool success) {
231 if (success && !compilationFailed) {
232 return new Dart2JsMirrorSystem(compiler);
233 } else {
234 throw new StateError('Failed to create mirror system.');
235 }
236 });
237 }
238
239 //------------------------------------------------------------------------------
240 // Dart2Js specific extensions of mirror interfaces
241 //------------------------------------------------------------------------------
242
243 abstract class Dart2JsMirror implements Mirror {
244 Dart2JsMirrorSystem get mirrors;
245 }
246
247 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror
248 implements DeclarationMirror {
249
250 bool get isTopLevel => owner != null && owner is LibraryMirror;
251
252 bool get isPrivate => _isPrivate(simpleName);
253
254 /**
255 * Returns the first token for the source of this declaration, not including
256 * metadata annotations.
257 */
258 Token getBeginToken();
259
260 /**
261 * Returns the last token for the source of this declaration.
262 */
263 Token getEndToken();
264
265 /**
266 * Returns the script for the source of this declaration.
267 */
268 Script getScript();
269 }
270
271 abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror
272 implements TypeMirror {
273 }
274
275 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror {
276 final Dart2JsMirrorSystem mirrors;
277 final Element _element;
278 List<InstanceMirror> _metadata;
279
280 Dart2JsElementMirror(this.mirrors, this._element) {
281 assert (mirrors != null);
282 assert (_element != null);
283 }
284
285 /**
286 * Returns the element to be used to determine the begin token of this
287 * declaration and the metadata associated with this declaration.
288 *
289 * This indirection is needed to use the [VariableListElement] as the location
290 * for type and metadata information on a [VariableElement].
291 */
292 Element get _beginElement => _element;
293
294 String get simpleName => _element.name;
295
296 bool get isNameSynthetic => false;
297
298 /**
299 * Computes the first token for this declaration using the begin token of the
300 * element node or element position as indicator.
301 */
302 Token getBeginToken() {
303 // TODO(johnniwinther): Avoid calling [parseNode].
304 Node node = _beginElement.parseNode(mirrors.compiler);
305 if (node == null) {
306 return _beginElement.position();
307 }
308 return node.getBeginToken();
309 }
310
311 /**
312 * Computes the last token for this declaration using the end token of the
313 * element node or element position as indicator.
314 */
315 Token getEndToken() {
316 // TODO(johnniwinther): Avoid calling [parseNode].
317 Node node = _element.parseNode(mirrors.compiler);
318 if (node == null) {
319 return _element.position();
320 }
321 return node.getEndToken();
322 }
323
324 /**
325 * Returns the first token for the source of this declaration, including
326 * metadata annotations.
327 */
328 Token getFirstToken() {
329 if (!_beginElement.metadata.isEmpty) {
330 for (MetadataAnnotation metadata in _beginElement.metadata) {
331 if (metadata.beginToken != null) {
332 return metadata.beginToken;
333 }
334 }
335 }
336 return getBeginToken();
337 }
338
339 Script getScript() => _element.getCompilationUnit().script;
340
341 SourceLocation get location {
342 Token beginToken = getFirstToken();
343 Script script = getScript();
344 SourceSpan span;
345 if (beginToken == null) {
346 span = new SourceSpan(script.uri, 0, 0);
347 } else {
348 Token endToken = getEndToken();
349 span = mirrors.compiler.spanFromTokens(beginToken, endToken, script.uri);
350 }
351 return new Dart2JsSourceLocation(script, span);
352 }
353
354 String toString() => _element.toString();
355
356 void _appendCommentTokens(Token commentToken) {
357 while (commentToken != null && commentToken.kind == COMMENT_TOKEN) {
358 _metadata.add(new Dart2JsCommentInstanceMirror(
359 mirrors, commentToken.value));
360 commentToken = commentToken.next;
361 }
362 }
363
364 List<InstanceMirror> get metadata {
365 if (_metadata == null) {
366 _metadata = <InstanceMirror>[];
367 for (MetadataAnnotation metadata in _element.metadata) {
368 _appendCommentTokens(mirrors.compiler.commentMap[metadata.beginToken]);
369 metadata.ensureResolved(mirrors.compiler);
370 _metadata.add(
371 _convertConstantToInstanceMirror(mirrors, metadata.value));
372 }
373 _appendCommentTokens(mirrors.compiler.commentMap[getBeginToken()]);
374 }
375 // TODO(johnniwinther): Return an unmodifiable list instead.
376 return new List<InstanceMirror>.from(_metadata);
377 }
378
379 DeclarationMirror lookupInScope(String name) {
380 // TODO(11653): Support lookup of constructors.
381 Scope scope = _element.buildScope();
382 Element result;
383 int index = name.indexOf('.');
384 if (index != -1) {
385 // Lookup [: prefix.id :].
386 String prefix = name.substring(0, index);
387 String id = name.substring(index+1);
388 result = scope.lookup(prefix);
389 if (result != null && result.isPrefix()) {
390 PrefixElement prefix = result;
391 result = prefix.lookupLocalMember(id);
392 } else {
393 result = null;
394 }
395 } else {
396 // Lookup [: id :].
397 result = scope.lookup(name);
398 }
399 if (result == null || result.isPrefix()) return null;
400 return _convertElementToDeclarationMirror(mirrors, result);
401 }
402
403 bool operator ==(var other) {
404 if (identical(this, other)) return true;
405 if (other == null) return false;
406 if (other is! Dart2JsElementMirror) return false;
407 return _element == other._element &&
408 owner == other.owner;
409 }
410
411 int get hashCode {
412 return 13 * _element.hashCode + 17 * owner.hashCode;
413 }
414 }
415
416 abstract class Dart2JsMemberMirror extends Dart2JsElementMirror
417 implements MemberMirror {
418
419 Dart2JsMemberMirror(Dart2JsMirrorSystem system, Element element)
420 : super(system, element);
421
422 bool get isConstructor => false;
423
424 bool get isVariable => false;
425
426 bool get isMethod => false;
427
428 bool get isStatic => false;
429
430 bool get isParameter => false;
431 }
432
433 //------------------------------------------------------------------------------
434 // Mirror system implementation.
435 //------------------------------------------------------------------------------
436
437 class Dart2JsMirrorSystem extends MirrorSystem {
438 final Compiler compiler;
439 Map<Uri, Dart2JsLibraryMirror> _libraries;
440 Map<LibraryElement, Dart2JsLibraryMirror> _libraryMap;
441
442 Dart2JsMirrorSystem(this.compiler)
443 : _libraryMap = new Map<LibraryElement, Dart2JsLibraryMirror>();
444
445 void _ensureLibraries() {
446 if (_libraries == null) {
447 _libraries = new Map<Uri, Dart2JsLibraryMirror>();
448 compiler.libraries.forEach((_, LibraryElement v) {
449 var mirror = new Dart2JsLibraryMirror(mirrors, v);
450 _libraries[mirror.uri] = mirror;
451 _libraryMap[v] = mirror;
452 });
453 }
454 }
455
456 Map<Uri, LibraryMirror> get libraries {
457 _ensureLibraries();
458 return new FilteredImmutableMap<Uri, LibraryMirror>(_libraries,
459 (library) => new bool.fromEnvironment("list_all_libraries") ||
460 !library._element.isInternalLibrary);
461 }
462
463 Dart2JsLibraryMirror _getLibrary(LibraryElement element) =>
464 _libraryMap[element];
465
466 Dart2JsMirrorSystem get mirrors => this;
467
468 TypeMirror get dynamicType =>
469 _convertTypeToTypeMirror(this, compiler.types.dynamicType, null);
470
471 TypeMirror get voidType =>
472 _convertTypeToTypeMirror(this, compiler.types.voidType, null);
473 }
474
475 abstract class Dart2JsContainerMirror extends Dart2JsElementMirror
476 implements ContainerMirror {
477 Map<String, MemberMirror> _members;
478
479 Dart2JsContainerMirror(Dart2JsMirrorSystem system, Element element)
480 : super(system, element);
481
482 void _ensureMembers();
483
484 Map<String, MemberMirror> get members {
485 _ensureMembers();
486 return new ImmutableMapWrapper<String, MemberMirror>(_members);
487 }
488
489 Map<String, MethodMirror> get functions {
490 _ensureMembers();
491 return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
492 _members,
493 (MemberMirror member) => member is MethodMirror ? member : null);
494 }
495
496 Map<String, MethodMirror> get getters {
497 _ensureMembers();
498 return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
499 _members,
500 (MemberMirror member) =>
501 member is MethodMirror && member.isGetter ? member : null);
502 }
503
504 Map<String, MethodMirror> get setters {
505 _ensureMembers();
506 return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
507 _members,
508 (MemberMirror member) =>
509 member is MethodMirror && member.isSetter ? member : null);
510 }
511
512 Map<String, VariableMirror> get variables {
513 _ensureMembers();
514 return new AsFilteredImmutableMap<String, MemberMirror, VariableMirror>(
515 _members,
516 (MemberMirror member) => member is VariableMirror ? member : null);
517 }
518 }
519
520 class Dart2JsLibraryMirror extends Dart2JsContainerMirror
521 implements LibraryMirror {
522 Map<String, ClassMirror> _classes;
523 List<LibraryDependencyMirror> _libraryDependencies;
524
525
526 Dart2JsLibraryMirror(Dart2JsMirrorSystem system, LibraryElement library)
527 : super(system, library);
528
529 LibraryElement get _library => _element;
530
531 Uri get uri => _library.canonicalUri;
532
533 DeclarationMirror get owner => null;
534
535 bool get isPrivate => false;
536
537 LibraryMirror library() => this;
538
539 /**
540 * Returns the library name (for libraries with a library tag) or the script
541 * file name (for scripts without a library tag). The latter case is used to
542 * provide a 'library name' for scripts, to use for instance in dartdoc.
543 */
544 String get simpleName {
545 if (_library.libraryTag != null) {
546 return _library.libraryTag.name.toString();
547 } else {
548 // Use the file name as script name.
549 String path = _library.canonicalUri.path;
550 return path.substring(path.lastIndexOf('/') + 1);
551 }
552 }
553
554 String get qualifiedName => simpleName;
555
556 void _ensureClasses() {
557 if (_classes == null) {
558 _classes = <String, ClassMirror>{};
559 _library.forEachLocalMember((Element e) {
560 if (e.isClass()) {
561 ClassElement classElement = e;
562 classElement.ensureResolved(mirrors.compiler);
563 var type = new Dart2JsClassMirror.fromLibrary(this, classElement);
564 assert(invariant(_library, !_classes.containsKey(type.simpleName),
565 message: "Type name '${type.simpleName}' "
566 "is not unique in $_library."));
567 _classes[type.simpleName] = type;
568 } else if (e.isTypedef()) {
569 var type = new Dart2JsTypedefMirror.fromLibrary(this,
570 e.computeType(mirrors.compiler));
571 assert(invariant(_library, !_classes.containsKey(type.simpleName),
572 message: "Type name '${type.simpleName}' "
573 "is not unique in $_library."));
574 _classes[type.simpleName] = type;
575 }
576 });
577 }
578 }
579
580 void _ensureMembers() {
581 if (_members == null) {
582 _members = <String, MemberMirror>{};
583 _library.forEachLocalMember((Element e) {
584 if (!e.isClass() && !e.isTypedef()) {
585 // TODO(ahe): I think it is incorrect to filter out classes
586 // and typedefs. See http://dartbug.com/10371.
587 for (var member in _convertElementMemberToMemberMirrors(this, e)) {
588 assert(!_members.containsKey(member.simpleName));
589 _members[member.simpleName] = member;
590 }
591 }
592 });
593 }
594 }
595
596 Map<String, ClassMirror> get classes {
597 _ensureClasses();
598 return new ImmutableMapWrapper<String, ClassMirror>(_classes);
599 }
600
601 /**
602 * Computes the first token of this library using the first library tag as
603 * indicator.
604 */
605 Token getBeginToken() {
606 if (_library.libraryTag != null) {
607 return _library.libraryTag.getBeginToken();
608 } else if (!_library.tags.isEmpty) {
609 return _library.tags.reverse().head.getBeginToken();
610 }
611 return null;
612 }
613
614 /**
615 * Computes the first token of this library using the last library tag as
616 * indicator.
617 */
618 Token getEndToken() {
619 if (!_library.tags.isEmpty) {
620 return _library.tags.head.getEndToken();
621 }
622 return null;
623 }
624
625 void _ensureLibraryDependenciesAnalyzed() {
626 if (_libraryDependencies == null) {
627 _libraryDependencies = <LibraryDependencyMirror>[];
628 for (LibraryTag node in _library.tags.reverse()) {
629 LibraryDependency libraryDependency = node.asLibraryDependency();
630 if (libraryDependency != null) {
631 LibraryElement targetLibraryElement =
632 _library.getLibraryFromTag(libraryDependency);
633 assert(targetLibraryElement != null);
634 LibraryMirror targetLibrary =
635 mirrors._getLibrary(targetLibraryElement);
636 _libraryDependencies.add(new Dart2JsLibraryDependencyMirror(
637 libraryDependency, this, targetLibrary));
638 }
639 }
640 }
641 }
642
643 List<LibraryDependencyMirror> get libraryDependencies {
644 _ensureLibraryDependenciesAnalyzed();
645 return _libraryDependencies;
646 }
647 }
648
649 class Dart2JsLibraryDependencyMirror implements LibraryDependencyMirror {
650 final LibraryDependency _node;
651 final Dart2JsLibraryMirror _sourceLibrary;
652 final Dart2JsLibraryMirror _targetLibrary;
653 List<CombinatorMirror> _combinators;
654
655 Dart2JsLibraryDependencyMirror(this._node,
656 this._sourceLibrary,
657 this._targetLibrary);
658
659 SourceLocation get location {
660 return new Dart2JsSourceLocation(
661 _sourceLibrary._library.entryCompilationUnit.script,
662 _sourceLibrary.mirrors.compiler.spanFromNode(_node));
663 }
664
665 List<CombinatorMirror> get combinators {
666 if (_combinators == null) {
667 _combinators = <CombinatorMirror>[];
668 if (_node.combinators != null) {
669 for (Combinator combinator in _node.combinators.nodes) {
670 List<String> identifiers = <String>[];
671 for (Identifier identifier in combinator.identifiers.nodes) {
672 identifiers.add(identifier.source);
673 }
674 _combinators.add(new Dart2JsCombinatorMirror(
675 identifiers, isShow: combinator.isShow));
676 }
677 }
678 }
679 return _combinators;
680 }
681
682 LibraryMirror get sourceLibrary => _sourceLibrary;
683
684 LibraryMirror get targetLibrary => _targetLibrary;
685
686 String get prefix {
687 Import import = _node.asImport();
688 if (import != null && import.prefix != null) {
689 return import.prefix.source;
690 }
691 return null;
692 }
693
694 bool get isImport => _node.asImport() != null;
695
696 bool get isExport => _node.asExport() != null;
697 }
698
699 class Dart2JsCombinatorMirror implements CombinatorMirror {
700 final List<String> identifiers;
701 final bool isShow;
702
703 Dart2JsCombinatorMirror(this.identifiers, {bool isShow: true})
704 : this.isShow = isShow;
705
706 bool get isHide => !isShow;
707 }
708
709 class Dart2JsSourceLocation implements SourceLocation {
710 final Script _script;
711 final SourceSpan _span;
712 int _line;
713 int _column;
714
715 Dart2JsSourceLocation(this._script, this._span);
716
717 int _computeLine() {
718 var sourceFile = _script.file;
719 if (sourceFile != null) {
720 return sourceFile.getLine(offset) + 1;
721 }
722 var index = 0;
723 var lineNumber = 0;
724 while (index <= offset && index < sourceText.length) {
725 index = sourceText.indexOf('\n', index) + 1;
726 if (index <= 0) break;
727 lineNumber++;
728 }
729 return lineNumber;
730 }
731
732 int get line {
733 if (_line == null) {
734 _line = _computeLine();
735 }
736 return _line;
737 }
738
739 int _computeColumn() {
740 if (length == 0) return 0;
741
742 var sourceFile = _script.file;
743 if (sourceFile != null) {
744 return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;
745 }
746 int index = offset - 1;
747 var columnNumber = 0;
748 while (0 <= index && index < sourceText.length) {
749 columnNumber++;
750 var codeUnit = sourceText.codeUnitAt(index);
751 if (codeUnit == $CR || codeUnit == $LF) {
752 break;
753 }
754 index--;
755 }
756 return columnNumber;
757 }
758
759 int get column {
760 if (_column == null) {
761 _column = _computeColumn();
762 }
763 return _column;
764 }
765
766 int get offset => _span.begin;
767
768 int get length => _span.end - _span.begin;
769
770 String get text => _script.text.substring(_span.begin, _span.end);
771
772 Uri get sourceUri => _script.uri;
773
774 String get sourceText => _script.text;
775 }
776
777 class Dart2JsParameterMirror extends Dart2JsMemberMirror
778 implements ParameterMirror {
779 final MethodMirror _method;
780 final bool isOptional;
781 final bool isNamed;
782
783 factory Dart2JsParameterMirror(Dart2JsMirrorSystem system,
784 MethodMirror method,
785 VariableElement element,
786 {bool isOptional: false,
787 bool isNamed: false}) {
788 if (element is FieldParameterElement) {
789 return new Dart2JsFieldParameterMirror(system,
790 method, element, isOptional, isNamed);
791 }
792 return new Dart2JsParameterMirror._normal(system,
793 method, element, isOptional, isNamed);
794 }
795
796 Dart2JsParameterMirror._normal(Dart2JsMirrorSystem system,
797 this._method,
798 VariableElement element,
799 this.isOptional,
800 this.isNamed)
801 : super(system, element);
802
803 Element get _beginElement => _variableElement.variables;
804
805 DeclarationMirror get owner => _method;
806
807 VariableElement get _variableElement => _element;
808
809 String get qualifiedName => '${_method.qualifiedName}#${simpleName}';
810
811 TypeMirror get type => _convertTypeToTypeMirror(mirrors,
812 _variableElement.computeType(mirrors.compiler),
813 mirrors.compiler.types.dynamicType,
814 _variableElement.variables.functionSignature);
815
816
817 bool get isFinal => false;
818
819 bool get isConst => false;
820
821 String get defaultValue {
822 if (hasDefaultValue) {
823 SendSet expression = _variableElement.cachedNode.asSendSet();
824 return unparse(expression.arguments.head);
825 }
826 return null;
827 }
828
829 bool get hasDefaultValue {
830 return _variableElement.cachedNode != null &&
831 _variableElement.cachedNode is SendSet;
832 }
833
834 bool get isInitializingFormal => false;
835
836 VariableMirror get initializedField => null;
837 }
838
839 class Dart2JsFieldParameterMirror extends Dart2JsParameterMirror {
840
841 Dart2JsFieldParameterMirror(Dart2JsMirrorSystem system,
842 MethodMirror method,
843 FieldParameterElement element,
844 bool isOptional,
845 bool isNamed)
846 : super._normal(system, method, element, isOptional, isNamed);
847
848 FieldParameterElement get _fieldParameterElement => _element;
849
850 TypeMirror get type {
851 VariableListElement variables = _fieldParameterElement.variables;
852 VariableDefinitions node = variables.parseNode(mirrors.compiler);
853 if (node.type != null) {
854 return super.type;
855 }
856 // Use the field type for initializing formals with no type annotation.
857 return _convertTypeToTypeMirror(mirrors,
858 _fieldParameterElement.fieldElement.computeType(mirrors.compiler),
859 mirrors.compiler.types.dynamicType,
860 _variableElement.variables.functionSignature);
861 }
862
863 bool get isInitializingFormal => true;
864
865 VariableMirror get initializedField => new Dart2JsFieldMirror(
866 _method.owner, _fieldParameterElement.fieldElement);
867 }
868
869 //------------------------------------------------------------------------------
870 // Declarations
871 //------------------------------------------------------------------------------
872 class Dart2JsClassMirror extends Dart2JsContainerMirror
873 implements Dart2JsTypeMirror, ClassMirror {
874 final Dart2JsLibraryMirror library;
875 List<TypeVariableMirror> _typeVariables;
876
877 Dart2JsClassMirror(Dart2JsMirrorSystem system, ClassElement _class)
878 : this.library = system._getLibrary(_class.getLibrary()),
879 super(system, _class);
880
881 ClassElement get _class => _element;
882
883 Dart2JsClassMirror.fromLibrary(Dart2JsLibraryMirror library,
884 ClassElement _class)
885 : this.library = library,
886 super(library.mirrors, _class);
887
888 DeclarationMirror get owner => library;
889
890 String get qualifiedName => '${library.qualifiedName}.${simpleName}';
891
892 void _ensureMembers() {
893 if (_members == null) {
894 _members = <String, Dart2JsMemberMirror>{};
895 _class.forEachMember((_, e) {
896 for (var member in _convertElementMemberToMemberMirrors(this, e)) {
897 assert(!_members.containsKey(member.simpleName));
898 _members[member.simpleName] = member;
899 }
900 });
901 }
902 }
903
904 Map<String, MethodMirror> get methods => functions;
905
906 Map<String, MethodMirror> get constructors {
907 _ensureMembers();
908 return new AsFilteredImmutableMap<String, MemberMirror, MethodMirror>(
909 _members, (m) => m.isConstructor ? m : null);
910 }
911
912 bool get isObject => _class == mirrors.compiler.objectClass;
913
914 bool get isDynamic => false;
915
916 bool get isVoid => false;
917
918 bool get isTypeVariable => false;
919
920 bool get isTypedef => false;
921
922 bool get isFunction => false;
923
924 ClassMirror get originalDeclaration => this;
925
926 ClassMirror get superclass {
927 if (_class.supertype != null) {
928 return new Dart2JsInterfaceTypeMirror(mirrors, _class.supertype);
929 }
930 return null;
931 }
932
933 ClassMirror get mixin {
934 if (_class.isMixinApplication) {
935 MixinApplicationElement mixinApplication = _class;
936 return new Dart2JsInterfaceTypeMirror(mirrors,
937 mixinApplication.mixinType);
938 }
939 return this;
940 }
941
942 bool get isNameSynthetic {
943 if (_class.isMixinApplication) {
944 MixinApplicationElement mixinApplication = _class;
945 return mixinApplication.isUnnamedMixinApplication;
946 }
947 return false;
948 }
949
950 List<ClassMirror> get superinterfaces {
951 var list = <ClassMirror>[];
952 Link<DartType> link = _class.interfaces;
953 while (!link.isEmpty) {
954 var type = _convertTypeToTypeMirror(mirrors, link.head,
955 mirrors.compiler.types.dynamicType);
956 list.add(type);
957 link = link.tail;
958 }
959 return list;
960 }
961
962 bool get isClass => true;
963
964 bool get isAbstract => _class.modifiers.isAbstract();
965
966 bool get isOriginalDeclaration => true;
967
968 List<TypeMirror> get typeArguments {
969 throw new UnsupportedError(
970 'Declarations do not have type arguments');
971 }
972
973 List<TypeVariableMirror> get typeVariables {
974 if (_typeVariables == null) {
975 _typeVariables = <TypeVariableMirror>[];
976 _class.ensureResolved(mirrors.compiler);
977 for (TypeVariableType typeVariable in _class.typeVariables) {
978 _typeVariables.add(
979 new Dart2JsTypeVariableMirror(mirrors, typeVariable));
980 }
981 }
982 return _typeVariables;
983 }
984
985 bool operator ==(other) {
986 if (identical(this, other)) {
987 return true;
988 }
989 if (other is! ClassMirror) {
990 return false;
991 }
992 if (library != other.library) {
993 return false;
994 }
995 if (!identical(isOriginalDeclaration, other.isOriginalDeclaration)) {
996 return false;
997 }
998 return qualifiedName == other.qualifiedName;
999 }
1000 }
1001
1002 class Dart2JsTypedefMirror extends Dart2JsTypeElementMirror
1003 implements Dart2JsTypeMirror, TypedefMirror {
1004 final Dart2JsLibraryMirror _library;
1005 List<TypeVariableMirror> _typeVariables;
1006 TypeMirror _definition;
1007
1008 Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef)
1009 : this._library = system._getLibrary(_typedef.element.getLibrary()),
1010 super(system, _typedef);
1011
1012 Dart2JsTypedefMirror.fromLibrary(Dart2JsLibraryMirror library,
1013 TypedefType _typedef)
1014 : this._library = library,
1015 super(library.mirrors, _typedef);
1016
1017 TypedefType get _typedef => _type;
1018
1019 String get qualifiedName => '${library.qualifiedName}.${simpleName}';
1020
1021 LibraryMirror get library => _library;
1022
1023 bool get isTypedef => true;
1024
1025 List<TypeMirror> get typeArguments {
1026 throw new UnsupportedError(
1027 'Declarations do not have type arguments');
1028 }
1029
1030 List<TypeVariableMirror> get typeVariables {
1031 if (_typeVariables == null) {
1032 _typeVariables = <TypeVariableMirror>[];
1033 for (TypeVariableType typeVariable in _typedef.typeArguments) {
1034 _typeVariables.add(
1035 new Dart2JsTypeVariableMirror(mirrors, typeVariable));
1036 }
1037 }
1038 return _typeVariables;
1039 }
1040
1041 TypeMirror get value {
1042 if (_definition == null) {
1043 // TODO(johnniwinther): Should be [ensureResolved].
1044 mirrors.compiler.resolveTypedef(_typedef.element);
1045 _definition = _convertTypeToTypeMirror(
1046 mirrors,
1047 _typedef.element.alias,
1048 mirrors.compiler.types.dynamicType,
1049 _typedef.element.functionSignature);
1050 }
1051 return _definition;
1052 }
1053
1054 ClassMirror get originalDeclaration => this;
1055
1056 // TODO(johnniwinther): How should a typedef respond to these?
1057 ClassMirror get superclass => null;
1058
1059 List<ClassMirror> get superinterfaces => const <ClassMirror>[];
1060
1061 // TODO(johnniwinther): Refactor [TypedefMirror] to not extend [ClassMirror]
1062 // and remove this.
1063 ClassMirror get mixin => this;
1064
1065 bool get isClass => false;
1066
1067 bool get isOriginalDeclaration => true;
1068
1069 bool get isAbstract => false;
1070 }
1071
1072 class Dart2JsTypeVariableMirror extends Dart2JsTypeElementMirror
1073 implements TypeVariableMirror {
1074 final TypeVariableType _typeVariableType;
1075 ClassMirror _declarer;
1076
1077 Dart2JsTypeVariableMirror(Dart2JsMirrorSystem system,
1078 TypeVariableType typeVariableType)
1079 : this._typeVariableType = typeVariableType,
1080 super(system, typeVariableType) {
1081 assert(_typeVariableType != null);
1082 }
1083
1084
1085 String get qualifiedName => '${declarer.qualifiedName}.${simpleName}';
1086
1087 ClassMirror get declarer {
1088 if (_declarer == null) {
1089 if (_typeVariableType.element.enclosingElement.isClass()) {
1090 _declarer = new Dart2JsClassMirror(mirrors,
1091 _typeVariableType.element.enclosingElement);
1092 } else if (_typeVariableType.element.enclosingElement.isTypedef()) {
1093 _declarer = new Dart2JsTypedefMirror(mirrors,
1094 _typeVariableType.element.enclosingElement.computeType(
1095 mirrors.compiler));
1096 }
1097 }
1098 return _declarer;
1099 }
1100
1101 LibraryMirror get library => declarer.library;
1102
1103 DeclarationMirror get owner => declarer;
1104
1105 bool get isTypeVariable => true;
1106
1107 TypeMirror get upperBound => _convertTypeToTypeMirror(
1108 mirrors,
1109 _typeVariableType.element.bound,
1110 mirrors.compiler.objectClass.computeType(mirrors.compiler));
1111
1112 bool operator ==(var other) {
1113 if (identical(this, other)) {
1114 return true;
1115 }
1116 if (other is! TypeVariableMirror) {
1117 return false;
1118 }
1119 if (declarer != other.declarer) {
1120 return false;
1121 }
1122 return qualifiedName == other.qualifiedName;
1123 }
1124 }
1125
1126
1127 //------------------------------------------------------------------------------
1128 // Types
1129 //------------------------------------------------------------------------------
1130
1131 abstract class Dart2JsTypeElementMirror extends Dart2JsElementMirror
1132 implements Dart2JsTypeMirror {
1133 final DartType _type;
1134
1135 Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, DartType type)
1136 : super(system, type.element),
1137 this._type = type;
1138
1139 String get simpleName => _type.name;
1140
1141 DeclarationMirror get owner => library;
1142
1143 LibraryMirror get library {
1144 return mirrors._getLibrary(_type.element.getLibrary());
1145 }
1146
1147 bool get isObject => false;
1148
1149 bool get isVoid => false;
1150
1151 bool get isDynamic => false;
1152
1153 bool get isTypeVariable => false;
1154
1155 bool get isTypedef => false;
1156
1157 bool get isFunction => false;
1158
1159 String toString() => _type.toString();
1160
1161 Map<String, MemberMirror> get members => const <String, MemberMirror>{};
1162
1163 Map<String, MethodMirror> get constructors => const <String, MethodMirror>{};
1164
1165 Map<String, MethodMirror> get methods => const <String, MethodMirror>{};
1166
1167 Map<String, MethodMirror> get getters => const <String, MethodMirror>{};
1168
1169 Map<String, MethodMirror> get setters => const <String, MethodMirror>{};
1170
1171 Map<String, VariableMirror> get variables => const <String, VariableMirror>{};
1172 }
1173
1174 class Dart2JsInterfaceTypeMirror extends Dart2JsTypeElementMirror
1175 implements ClassMirror {
1176 List<TypeMirror> _typeArguments;
1177
1178 Dart2JsInterfaceTypeMirror(Dart2JsMirrorSystem system,
1179 InterfaceType interfaceType)
1180 : super(system, interfaceType);
1181
1182 InterfaceType get _interfaceType => _type;
1183
1184 bool get isNameSynthetic => originalDeclaration.isNameSynthetic;
1185
1186 String get qualifiedName => originalDeclaration.qualifiedName;
1187
1188 // TODO(johnniwinther): Substitute type arguments for type variables.
1189 Map<String, MemberMirror> get members => originalDeclaration.members;
1190
1191 bool get isObject => mirrors.compiler.objectClass == _type.element;
1192
1193 // TODO(johnniwinther): How to show malformed types?
1194 bool get isDynamic => _type.isDynamic;
1195
1196 ClassMirror get originalDeclaration
1197 => new Dart2JsClassMirror(mirrors, _type.element);
1198
1199 // TODO(johnniwinther): Substitute type arguments for type variables.
1200 ClassMirror get superclass => originalDeclaration.superclass;
1201
1202 // TODO(johnniwinther): Substitute type arguments for type variables.
1203 List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;
1204
1205 // TODO(johnniwinther): Substitute type arguments for type variables.
1206 ClassMirror get mixin {
1207 if (originalDeclaration.mixin == originalDeclaration) {
1208 return this;
1209 }
1210 return originalDeclaration.mixin;
1211 }
1212
1213 bool get isClass => originalDeclaration.isClass;
1214
1215 bool get isAbstract => originalDeclaration.isAbstract;
1216
1217 bool get isPrivate => originalDeclaration.isPrivate;
1218
1219 bool get isOriginalDeclaration => false;
1220
1221 List<TypeMirror> get typeArguments {
1222 if (_typeArguments == null) {
1223 _typeArguments = <TypeMirror>[];
1224 if (!_interfaceType.isRaw) {
1225 Link<DartType> type = _interfaceType.typeArguments;
1226 while (type != null && type.head != null) {
1227 _typeArguments.add(_convertTypeToTypeMirror(mirrors, type.head,
1228 mirrors.compiler.types.dynamicType));
1229 type = type.tail;
1230 }
1231 }
1232 }
1233 return _typeArguments;
1234 }
1235
1236 List<TypeVariableMirror> get typeVariables =>
1237 originalDeclaration.typeVariables;
1238
1239 // TODO(johnniwinther): Substitute type arguments for type variables.
1240 Map<String, MethodMirror> get constructors =>
1241 originalDeclaration.constructors;
1242
1243 // TODO(johnniwinther): Substitute type arguments for type variables.
1244 Map<String, MethodMirror> get methods => originalDeclaration.methods;
1245
1246 // TODO(johnniwinther): Substitute type arguments for type variables.
1247 Map<String, MethodMirror> get setters => originalDeclaration.setters;
1248
1249 // TODO(johnniwinther): Substitute type arguments for type variables.
1250 Map<String, MethodMirror> get getters => originalDeclaration.getters;
1251
1252 // TODO(johnniwinther): Substitute type arguments for type variables.
1253 Map<String, VariableMirror> get variables => originalDeclaration.variables;
1254
1255 bool operator ==(other) {
1256 if (identical(this, other)) {
1257 return true;
1258 }
1259 if (other is! ClassMirror) {
1260 return false;
1261 }
1262 if (other.isOriginalDeclaration) {
1263 return false;
1264 }
1265 if (originalDeclaration != other.originalDeclaration) {
1266 return false;
1267 }
1268 var thisTypeArguments = typeArguments.iterator;
1269 var otherTypeArguments = other.typeArguments.iterator;
1270 while (thisTypeArguments.moveNext()) {
1271 if (!otherTypeArguments.moveNext()) return false;
1272 if (thisTypeArguments.current != otherTypeArguments.current) {
1273 return false;
1274 }
1275 }
1276 return !otherTypeArguments.moveNext();
1277 }
1278 }
1279
1280
1281 class Dart2JsFunctionTypeMirror extends Dart2JsTypeElementMirror
1282 implements FunctionTypeMirror {
1283 final FunctionSignature _functionSignature;
1284 List<ParameterMirror> _parameters;
1285
1286 Dart2JsFunctionTypeMirror(Dart2JsMirrorSystem system,
1287 FunctionType functionType, this._functionSignature)
1288 : super(system, functionType) {
1289 assert (_functionSignature != null);
1290 }
1291
1292 FunctionType get _functionType => _type;
1293
1294 // TODO(johnniwinther): Is this the qualified name of a function type?
1295 String get qualifiedName => originalDeclaration.qualifiedName;
1296
1297 // TODO(johnniwinther): Substitute type arguments for type variables.
1298 Map<String, MemberMirror> get members {
1299 var method = callMethod;
1300 if (method != null) {
1301 var map = new Map<String, MemberMirror>.from(
1302 originalDeclaration.members);
1303 var name = method.qualifiedName;
1304 assert(!map.containsKey(name));
1305 map[name] = method;
1306 return new ImmutableMapWrapper<String, MemberMirror>(map);
1307 }
1308 return originalDeclaration.members;
1309 }
1310
1311 bool get isFunction => true;
1312
1313 MethodMirror get callMethod => _convertElementMethodToMethodMirror(
1314 mirrors._getLibrary(_functionType.element.getLibrary()),
1315 _functionType.element);
1316
1317 ClassMirror get originalDeclaration
1318 => new Dart2JsClassMirror(mirrors, mirrors.compiler.functionClass);
1319
1320 // TODO(johnniwinther): Substitute type arguments for type variables.
1321 ClassMirror get superclass => originalDeclaration.superclass;
1322
1323 // TODO(johnniwinther): Substitute type arguments for type variables.
1324 List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;
1325
1326 ClassMirror get mixin => this;
1327
1328 bool get isClass => originalDeclaration.isClass;
1329
1330 bool get isPrivate => originalDeclaration.isPrivate;
1331
1332 bool get isOriginalDeclaration => false;
1333
1334 bool get isAbstract => false;
1335
1336 List<TypeMirror> get typeArguments => const <TypeMirror>[];
1337
1338 List<TypeVariableMirror> get typeVariables =>
1339 originalDeclaration.typeVariables;
1340
1341 TypeMirror get returnType {
1342 return _convertTypeToTypeMirror(mirrors, _functionType.returnType,
1343 mirrors.compiler.types.dynamicType);
1344 }
1345
1346 List<ParameterMirror> get parameters {
1347 if (_parameters == null) {
1348 _parameters = _parametersFromFunctionSignature(mirrors, callMethod,
1349 _functionSignature);
1350 }
1351 return _parameters;
1352 }
1353 }
1354
1355 class Dart2JsVoidMirror extends Dart2JsTypeElementMirror {
1356
1357 Dart2JsVoidMirror(Dart2JsMirrorSystem system, VoidType voidType)
1358 : super(system, voidType);
1359
1360 VoidType get _voidType => _type;
1361
1362 String get qualifiedName => simpleName;
1363
1364 /**
1365 * The void type has no location.
1366 */
1367 SourceLocation get location => null;
1368
1369 /**
1370 * The void type has no library.
1371 */
1372 LibraryMirror get library => null;
1373
1374 bool get isVoid => true;
1375
1376 bool operator ==(other) {
1377 if (identical(this, other)) {
1378 return true;
1379 }
1380 if (other is! TypeMirror) {
1381 return false;
1382 }
1383 return other.isVoid;
1384 }
1385 }
1386
1387
1388 class Dart2JsDynamicMirror extends Dart2JsTypeElementMirror {
1389 Dart2JsDynamicMirror(Dart2JsMirrorSystem system, InterfaceType voidType)
1390 : super(system, voidType);
1391
1392 InterfaceType get _dynamicType => _type;
1393
1394 String get qualifiedName => simpleName;
1395
1396 /**
1397 * The dynamic type has no location.
1398 */
1399 SourceLocation get location => null;
1400
1401 /**
1402 * The dynamic type has no library.
1403 */
1404 LibraryMirror get library => null;
1405
1406 bool get isDynamic => true;
1407
1408 bool operator ==(other) {
1409 if (identical(this, other)) {
1410 return true;
1411 }
1412 if (other is! TypeMirror) {
1413 return false;
1414 }
1415 return other.isDynamic;
1416 }
1417 }
1418
1419 //------------------------------------------------------------------------------
1420 // Member mirrors implementation.
1421 //------------------------------------------------------------------------------
1422
1423 class Dart2JsMethodMirror extends Dart2JsMemberMirror
1424 implements MethodMirror {
1425 final Dart2JsContainerMirror _objectMirror;
1426 final String simpleName;
1427 final Dart2JsMethodKind _kind;
1428
1429 Dart2JsMethodMirror._internal(Dart2JsContainerMirror objectMirror,
1430 FunctionElement function,
1431 String this.simpleName,
1432 Dart2JsMethodKind this._kind)
1433 : this._objectMirror = objectMirror,
1434 super(objectMirror.mirrors, function);
1435
1436 factory Dart2JsMethodMirror(Dart2JsContainerMirror objectMirror,
1437 FunctionElement function) {
1438 String realName = function.name;
1439 // TODO(ahe): This method should not be calling
1440 // Elements.operatorNameToIdentifier.
1441 String simpleName =
1442 Elements.operatorNameToIdentifier(function.name);
1443 Dart2JsMethodKind kind;
1444 if (function.kind == ElementKind.GETTER) {
1445 kind = Dart2JsMethodKind.GETTER;
1446 } else if (function.kind == ElementKind.SETTER) {
1447 kind = Dart2JsMethodKind.SETTER;
1448 simpleName = '$simpleName=';
1449 } else if (function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
1450 // TODO(johnniwinther): Support detection of redirecting constructors.
1451 if (function.modifiers.isConst()) {
1452 kind = Dart2JsMethodKind.CONST;
1453 } else {
1454 kind = Dart2JsMethodKind.GENERATIVE;
1455 }
1456 } else if (function.modifiers.isFactory()) {
1457 kind = Dart2JsMethodKind.FACTORY;
1458 } else if (realName == 'unary-') {
1459 kind = Dart2JsMethodKind.OPERATOR;
1460 // Simple name is 'unary-'.
1461 simpleName = Mirror.UNARY_MINUS;
1462 } else if (simpleName.startsWith('operator\$')) {
1463 String str = simpleName.substring(9);
1464 simpleName = 'operator';
1465 kind = Dart2JsMethodKind.OPERATOR;
1466 simpleName = _getOperatorFromOperatorName(str);
1467 } else {
1468 kind = Dart2JsMethodKind.REGULAR;
1469 }
1470 return new Dart2JsMethodMirror._internal(objectMirror, function,
1471 simpleName, kind);
1472 }
1473
1474 FunctionElement get _function => _element;
1475
1476 String get qualifiedName
1477 => '${owner.qualifiedName}.$simpleName';
1478
1479 DeclarationMirror get owner => _objectMirror;
1480
1481 bool get isTopLevel => _objectMirror is LibraryMirror;
1482
1483 bool get isConstructor
1484 => isGenerativeConstructor || isConstConstructor ||
1485 isFactoryConstructor || isRedirectingConstructor;
1486
1487 bool get isMethod => !isConstructor;
1488
1489 bool get isStatic => _function.modifiers.isStatic();
1490
1491 List<ParameterMirror> get parameters {
1492 return _parametersFromFunctionSignature(mirrors, this,
1493 _function.computeSignature(mirrors.compiler));
1494 }
1495
1496 TypeMirror get returnType => _convertTypeToTypeMirror(
1497 mirrors, _function.computeSignature(mirrors.compiler).returnType,
1498 mirrors.compiler.types.dynamicType);
1499
1500 bool get isAbstract => _function.isAbstract;
1501
1502 bool get isRegularMethod => !(isGetter || isSetter || isConstructor);
1503
1504 bool get isConstConstructor => _kind == Dart2JsMethodKind.CONST;
1505
1506 bool get isGenerativeConstructor => _kind == Dart2JsMethodKind.GENERATIVE;
1507
1508 bool get isRedirectingConstructor => _kind == Dart2JsMethodKind.REDIRECTING;
1509
1510 bool get isFactoryConstructor => _kind == Dart2JsMethodKind.FACTORY;
1511
1512 bool get isGetter => _kind == Dart2JsMethodKind.GETTER;
1513
1514 bool get isSetter => _kind == Dart2JsMethodKind.SETTER;
1515
1516 bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR;
1517
1518 DeclarationMirror lookupInScope(String name) {
1519 for (ParameterMirror parameter in parameters) {
1520 if (parameter.simpleName == name) {
1521 return parameter;
1522 }
1523 }
1524 return super.lookupInScope(name);
1525 }
1526 }
1527
1528 class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror {
1529 Dart2JsContainerMirror _objectMirror;
1530 VariableElement _variable;
1531
1532 Dart2JsFieldMirror(Dart2JsContainerMirror objectMirror,
1533 VariableElement variable)
1534 : this._objectMirror = objectMirror,
1535 this._variable = variable,
1536 super(objectMirror.mirrors, variable);
1537
1538 Element get _beginElement => _variable.variables;
1539
1540 String get qualifiedName
1541 => '${owner.qualifiedName}.$simpleName';
1542
1543 DeclarationMirror get owner => _objectMirror;
1544
1545 bool get isTopLevel => _objectMirror is LibraryMirror;
1546
1547 bool get isVariable => true;
1548
1549 bool get isStatic => _variable.modifiers.isStatic();
1550
1551 bool get isFinal => _variable.modifiers.isFinal();
1552
1553 bool get isConst => _variable.modifiers.isConst();
1554
1555 TypeMirror get type => _convertTypeToTypeMirror(mirrors,
1556 _variable.computeType(mirrors.compiler),
1557 mirrors.compiler.types.dynamicType);
1558 }
1559
1560 ////////////////////////////////////////////////////////////////////////////////
1561 // Mirrors on constant values used for metadata.
1562 ////////////////////////////////////////////////////////////////////////////////
1563
1564 class Dart2JsConstantMirror extends InstanceMirror {
1565 final Dart2JsMirrorSystem mirrors;
1566 final Constant _constant;
1567
1568 Dart2JsConstantMirror(this.mirrors, this._constant);
1569
1570 ClassMirror get type {
1571 return new Dart2JsClassMirror(mirrors,
1572 _constant.computeType(mirrors.compiler).element);
1573 }
1574
1575 bool get hasReflectee => false;
1576
1577 get reflectee {
1578 // TODO(johnniwinther): Which exception/error should be thrown here?
1579 throw new UnsupportedError('InstanceMirror does not have a reflectee');
1580 }
1581
1582 InstanceMirror getField(String fieldName) {
1583 // TODO(johnniwinther): Which exception/error should be thrown here?
1584 throw new UnsupportedError('InstanceMirror does not have a reflectee');
1585 }
1586 }
1587
1588 class Dart2JsNullConstantMirror extends Dart2JsConstantMirror {
1589 Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrors, NullConstant constant)
1590 : super(mirrors, constant);
1591
1592 NullConstant get _constant => super._constant;
1593
1594 bool get hasReflectee => true;
1595
1596 get reflectee => null;
1597 }
1598
1599 class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror {
1600 Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant)
1601 : super(mirrors, constant);
1602
1603 Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrors, bool value)
1604 : super(mirrors, value ? new TrueConstant() : new FalseConstant());
1605
1606 BoolConstant get _constant => super._constant;
1607
1608 bool get hasReflectee => true;
1609
1610 get reflectee => _constant is TrueConstant;
1611 }
1612
1613 class Dart2JsStringConstantMirror extends Dart2JsConstantMirror {
1614 Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors,
1615 StringConstant constant)
1616 : super(mirrors, constant);
1617
1618 Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrors,
1619 String text)
1620 : super(mirrors, new StringConstant(new DartString.literal(text)));
1621
1622 StringConstant get _constant => super._constant;
1623
1624 bool get hasReflectee => true;
1625
1626 get reflectee => _constant.value.slowToString();
1627 }
1628
1629 class Dart2JsNumConstantMirror extends Dart2JsConstantMirror {
1630 Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors,
1631 NumConstant constant)
1632 : super(mirrors, constant);
1633
1634 NumConstant get _constant => super._constant;
1635
1636 bool get hasReflectee => true;
1637
1638 get reflectee => _constant.value;
1639 }
1640
1641 class Dart2JsListConstantMirror extends Dart2JsConstantMirror
1642 implements ListInstanceMirror {
1643 Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrors,
1644 ListConstant constant)
1645 : super(mirrors, constant);
1646
1647 ListConstant get _constant => super._constant;
1648
1649 int get length => _constant.length;
1650
1651 InstanceMirror operator[](int index) {
1652 if (index < 0) throw new RangeError('Negative index');
1653 if (index >= _constant.length) throw new RangeError('Index out of bounds');
1654 return _convertConstantToInstanceMirror(mirrors, _constant.entries[index]);
1655 }
1656 }
1657
1658 class Dart2JsMapConstantMirror extends Dart2JsConstantMirror
1659 implements MapInstanceMirror {
1660 List<String> _listCache;
1661
1662 Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrors,
1663 MapConstant constant)
1664 : super(mirrors, constant);
1665
1666 MapConstant get _constant => super._constant;
1667
1668 List<String> get _list {
1669 if (_listCache == null) {
1670 _listCache = new List<String>(_constant.keys.entries.length);
1671 int index = 0;
1672 for (StringConstant keyConstant in _constant.keys.entries) {
1673 _listCache[index] = keyConstant.value.slowToString();
1674 index++;
1675 }
1676 }
1677 return _listCache;
1678 }
1679
1680 int get length => _constant.length;
1681
1682 Iterable<String> get keys {
1683 // TODO(johnniwinther): Return an unmodifiable list instead.
1684 return new List<String>.from(_list);
1685 }
1686
1687 InstanceMirror operator[](String key) {
1688 int index = _list.indexOf(key);
1689 if (index == -1) return null;
1690 return _convertConstantToInstanceMirror(mirrors, _constant.values[index]);
1691 }
1692 }
1693
1694 class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror
1695 implements TypeInstanceMirror {
1696
1697 Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrors,
1698 TypeConstant constant)
1699 : super(mirrors, constant);
1700
1701 TypeConstant get _constant => super._constant;
1702
1703 TypeMirror get representedType => _convertTypeToTypeMirror(
1704 mirrors, _constant.representedType, mirrors.compiler.types.dynamicType);
1705 }
1706
1707 class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror {
1708 Map<String,Constant> _fieldMapCache;
1709
1710 Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrors,
1711 ConstructedConstant constant)
1712 : super(mirrors, constant);
1713
1714 ConstructedConstant get _constant => super._constant;
1715
1716 Map<String,Constant> get _fieldMap {
1717 if (_fieldMapCache == null) {
1718 _fieldMapCache = new Map<String,Constant>();
1719 if (identical(_constant.type.element.kind, ElementKind.CLASS)) {
1720 var index = 0;
1721 ClassElement element = _constant.type.element;
1722 element.forEachInstanceField((_, Element field) {
1723 String fieldName = field.name;
1724 _fieldMapCache.putIfAbsent(fieldName, () => _constant.fields[index]);
1725 index++;
1726 }, includeSuperAndInjectedMembers: true);
1727 }
1728 }
1729 return _fieldMapCache;
1730 }
1731
1732 InstanceMirror getField(String fieldName) {
1733 Constant fieldConstant = _fieldMap[fieldName];
1734 if (fieldConstant != null) {
1735 return _convertConstantToInstanceMirror(mirrors, fieldConstant);
1736 }
1737 return super.getField(fieldName);
1738 }
1739 }
1740
1741 class Dart2JsCommentInstanceMirror implements CommentInstanceMirror {
1742 final Dart2JsMirrorSystem mirrors;
1743 final String text;
1744 String _trimmedText;
1745
1746 Dart2JsCommentInstanceMirror(this.mirrors, this.text);
1747
1748 ClassMirror get type {
1749 return new Dart2JsClassMirror(mirrors, mirrors.compiler.documentClass);
1750 }
1751
1752 bool get isDocComment => text.startsWith('/**') || text.startsWith('///');
1753
1754 String get trimmedText {
1755 if (_trimmedText == null) {
1756 _trimmedText = stripComment(text);
1757 }
1758 return _trimmedText;
1759 }
1760
1761 bool get hasReflectee => false;
1762
1763 get reflectee {
1764 // TODO(johnniwinther): Which exception/error should be thrown here?
1765 throw new UnsupportedError('InstanceMirror does not have a reflectee');
1766 }
1767
1768 InstanceMirror getField(String fieldName) {
1769 if (fieldName == 'isDocComment') {
1770 return new Dart2JsBoolConstantMirror.fromBool(mirrors, isDocComment);
1771 } else if (fieldName == 'text') {
1772 return new Dart2JsStringConstantMirror.fromString(mirrors, text);
1773 } else if (fieldName == 'trimmedText') {
1774 return new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText);
1775 }
1776 // TODO(johnniwinther): Which exception/error should be thrown here?
1777 throw new UnsupportedError('InstanceMirror does not have a reflectee');
1778 }
1779 }
1780
1781 _convertElementToMembers(Dart2JsLibraryMirror library, Element e) {
1782 // TODO(ahe): This method creates new mirror objects which is not correct.
1783 if (e.isClass()) {
1784 ClassElement classElement = e;
1785 classElement.ensureResolved(library.mirrors.compiler);
1786 return [new Dart2JsClassMirror.fromLibrary(library, classElement)];
1787 } else if (e.isTypedef()) {
1788 return [new Dart2JsTypedefMirror.fromLibrary(
1789 library, e.computeType(library.mirrors.compiler))];
1790 } else {
1791 return _convertElementMemberToMemberMirrors(library, e);
1792 }
1793 }
1794
1795 /**
1796 * Converts [element] into its corresponding [DeclarationMirror], if any.
1797 *
1798 * If [element] is an [AbstractFieldElement] the mirror for its getter is
1799 * returned or, if not present, the mirror for its setter.
1800 */
1801 DeclarationMirror _convertElementToDeclarationMirror(Dart2JsMirrorSystem system,
1802 Element element) {
1803 if (element.isTypeVariable()) {
1804 return new Dart2JsTypeVariableMirror(
1805 system, element.computeType(system.compiler));
1806 }
1807
1808 Dart2JsLibraryMirror library = system._libraryMap[element.getLibrary()];
1809 if (element.isLibrary()) return library;
1810 if (element.isTypedef()) {
1811 return new Dart2JsTypedefMirror.fromLibrary(
1812 library, element.computeType(system.compiler));
1813 }
1814
1815 Dart2JsContainerMirror container = library;
1816 if (element.getEnclosingClass() != null) {
1817 container = new Dart2JsClassMirror.fromLibrary(
1818 library, element.getEnclosingClass());
1819 }
1820 if (element.isClass()) return container;
1821 if (element.isParameter()) {
1822 MethodMirror method = _convertElementMethodToMethodMirror(
1823 container, element.getOutermostEnclosingMemberOrTopLevel());
1824 // TODO(johnniwinther): Find the right info for [isOptional] and [isNamed].
1825 return new Dart2JsParameterMirror(
1826 system, method, element, isOptional: false, isNamed: false);
1827 }
1828 Iterable<MemberMirror> members =
1829 _convertElementMemberToMemberMirrors(container, element);
1830 if (members.isEmpty) return null;
1831 return members.first;
1832 }
1833
1834 /**
1835 * Experimental API for accessing compilation units defined in a
1836 * library.
1837 */
1838 // TODO(ahe): Superclasses? Is this really a mirror?
1839 class Dart2JsCompilationUnitMirror extends Dart2JsMirror {
1840 final Dart2JsLibraryMirror _library;
1841 final CompilationUnitElement _element;
1842
1843 Dart2JsCompilationUnitMirror(this._element, this._library);
1844
1845 Dart2JsMirrorSystem get mirrors => _library.mirrors;
1846
1847 List<DeclarationMirror> get members {
1848 // TODO(ahe): Should return an immutable List.
1849 // TODO(johnniwinther): make sure that these are returned in declaration
1850 // order.
1851 List<DeclarationMirror> members= <DeclarationMirror>[];
1852 _element.forEachLocalMember((m) {
1853 members.addAll(_convertElementToMembers(_library, m));
1854 });
1855 return members;
1856 }
1857
1858 Uri get uri => _element.script.uri;
1859 }
1860
1861 /**
1862 * Transitional class that allows access to features that have not yet
1863 * made it to the mirror API.
1864 *
1865 * All API in this class is experimental.
1866 */
1867 class BackDoor {
1868 /// Return the compilation units comprising [library].
1869 static List<Mirror> compilationUnitsOf(Dart2JsLibraryMirror library) {
1870 return library._library.compilationUnits.toList().map(
1871 (cu) => new Dart2JsCompilationUnitMirror(cu, library)).toList();
1872 }
1873 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698