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

Side by Side Diff: lib/dartdoc/mirrors/dart2js_mirror.dart

Issue 10692040: Mirrors prototype added to dartdoc. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Utility libraries added Created 8 years, 5 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('../../compiler/compiler.dart', prefix: 'diagnostics');
8 #import('../../compiler/implementation/elements/elements.dart');
9 #import('../../compiler/implementation/apiimpl.dart', prefix: 'api');
10 #import('../../compiler/implementation/scanner/scannerlib.dart');
11 #import('../../compiler/implementation/leg.dart');
12 #import('../../compiler/implementation/filenames.dart');
13 #import('../../compiler/implementation/source_file.dart');
14 #import('../../compiler/implementation/tree/tree.dart');
15 #import('../../compiler/implementation/util/util.dart');
16 #import('../../compiler/implementation/util/uri_extras.dart');
17 #import('../../compiler/implementation/dart2js.dart');
18 #import('mirrors.dart');
19 #import('util.dart');
20 #import('dart:io');
21 #import('dart:uri');
22
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(system, method,
40 link.head, false));
41 link = link.tail;
42 }
43 link = signature.optionalParameters;
44 while (!link.isEmpty()) {
45 parameters.add(new Dart2jsParameterMirror(system, method,
46 link.head, true));
47 link = link.tail;
48 }
49 return parameters;
50 }
51
52 Dart2jsTypeMirror _convertTypeToTypeMirror(
53 Dart2jsMirrorSystem system,
54 Type type,
55 InterfaceType defaultType,
56 [FunctionSignature functionSignature]) {
57 if (type === null) {
58 return new Dart2jsInterfaceTypeMirror(system, defaultType);
59 } else if (type is InterfaceType) {
60 return new Dart2jsInterfaceTypeMirror(system, type);
61 } else if (type is TypeVariableType) {
62 return new Dart2jsTypeVariableMirror(system, type);
63 } else if (type is FunctionType) {
64 if (type.element is TypedefElement) {
65 return new Dart2jsTypedefMirror(system, type.element);
66 } else {
67 return new Dart2jsFunctionTypeMirror(system, type, functionSignature);
68 }
69 } else if (type is VoidType) {
70 return new Dart2jsVoidMirror(system, type);
71 }
72 throw new IllegalArgumentException("Unexpected interface type $type");
73 }
74
75 Collection<Dart2jsMemberMirror> _convertElementMemberToMemberMirrors(
76 Dart2jsObjectMirror library, Element element) {
77 if (element is SynthesizedConstructorElement) {
78 return const <Dart2jsMemberMirror>[];
79 } else if (element is VariableElement) {
80 return [new Dart2jsFieldMirror(library, element)];
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Type the literal with <Dart2jsMemberMirror>. Or pe
Johnni Winther 2012/07/04 13:19:17 Done.
81 } else if (element is FunctionElement) {
82 return [new Dart2jsMethodMirror(library, element)];
Lasse Reichstein Nielsen 2012/07/04 10:58:59 ditto
Johnni Winther 2012/07/04 13:19:17 Done.
83 } else if (element is AbstractFieldElement) {
84 var members = <Dart2jsMemberMirror>[];
85 if (element.getter !== null) {
86 members.add(new Dart2jsMethodMirror(library, element.getter,
87 Dart2jsMethodKind.GETTER));
88 }
89 if (element.setter !== null) {
90 members.add(new Dart2jsMethodMirror(library, element.setter,
91 Dart2jsMethodKind.SETTER));
92 }
93 return members;
94 }
95 throw new IllegalArgumentException(
96 "Unexpected member type $element ${element.kind}");
97 }
98
99 MethodMirror _convertElementMethodToMethodMirror(Dart2jsObjectMirror library,
100 Element element) {
Lasse Reichstein Nielsen 2012/07/04 10:58:59 indent.
Johnni Winther 2012/07/04 13:19:17 Done.
101 if (element is FunctionElement) {
102 return new Dart2jsMethodMirror(library, element);
103 } else {
104 return null;
105 }
106 }
107
108 class Dart2jsMethodKind {
109 static final Dart2jsMethodKind NORMAL = const Dart2jsMethodKind("normal");
110 static final Dart2jsMethodKind CONSTRUCTOR
111 = const Dart2jsMethodKind("constructor");
112 static final Dart2jsMethodKind CONST = const Dart2jsMethodKind("const");
113 static final Dart2jsMethodKind FACTORY = const Dart2jsMethodKind("factory");
114 static final Dart2jsMethodKind GETTER = const Dart2jsMethodKind("getter");
115 static final Dart2jsMethodKind SETTER = const Dart2jsMethodKind("setter");
116 static final Dart2jsMethodKind OPERATOR = const Dart2jsMethodKind("operator");
117
118 final String text;
119
120 const Dart2jsMethodKind(this.text);
121
122 String toString() => text;
123 }
124
125 String _getOperatorFromOperatorName(String str) {
Lasse Reichstein Nielsen 2012/07/04 10:58:59 "str"->"name" It's not just a string, it's an oper
Johnni Winther 2012/07/04 13:19:17 Done.
126 if (str == 'eq') return '==';
127 else if (str == 'not') return '~';
128 else if (str == 'negate') return 'negate';
129 else if (str == 'index') return '[]';
130 else if (str == 'indexSet') return '[]=';
131 else if (str == 'mul') return '*';
132 else if (str == 'div') return '/';
133 else if (str == 'mod') return '%';
134 else if (str == 'tdiv') return '~/';
135 else if (str == 'add') return '+';
136 else if (str == 'sub') return '-';
137 else if (str == 'shl') return '<<';
138 else if (str == 'shr') return '>>';
139 else if (str == 'ge') return '>=';
140 else if (str == 'gt') return '>';
141 else if (str == 'le') return '<=';
142 else if (str == 'lt') return '<';
143 else if (str == 'and') return '&';
144 else if (str == 'xor') return '^';
145 else if (str == 'or') return '|';
Lasse Reichstein Nielsen 2012/07/04 10:58:59 You could have a constant Map<String, String> to c
Johnni Winther 2012/07/04 13:19:17 Done. (Using : instead of => in the constant map!)
146 else {
147 throw new Exception('Unhandled operator name: $str');
148 }
149 }
150
151 final DiagnosticListener _diagnosticListener
152 = const Dart2jsDiagnosticListener();
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Consider making it a getter instead of a field. No
Johnni Winther 2012/07/04 13:19:17 Done.
153
154 class Dart2jsDiagnosticListener implements DiagnosticListener {
155 const Dart2jsDiagnosticListener();
156
157 void cancel([String reason, node, token, instruction, element]) {
158 print(reason);
159 }
160
161 void log(message) {
162 print(message);
163 }
164 }
165
166 //------------------------------------------------------------------------------
167 // Compilation implementation
168 //------------------------------------------------------------------------------
169
170 class Dart2jsCompilation implements Compilation {
171 api.Compiler _compiler;
172 Uri cwd;
173 bool isAborting = false;
174 Map<String, SourceFile> sourceFiles;
175
176 Future<String> provider(Uri uri) {
177 if (uri.scheme != 'file') {
178 throw new IllegalArgumentException(uri);
179 }
180 String source;
181 try {
182 source = readAll(uriPathToNative(uri.path));
183 } catch (FileIOException ex) {
184 throw 'Error: Cannot read "${relativize(cwd, uri)}" (${ex.osError}).';
185 }
186 sourceFiles[uri.toString()] =
187 new SourceFile(relativize(cwd, uri), source);
188 return new Future.immediate(source);
189 }
190
191 void handler(Uri uri, int begin, int end,
192 String message, diagnostics.Diagnostic kind) {
193 if (isAborting) return;
194 bool fatal =
195 kind === diagnostics.Diagnostic.CRASH ||
196 kind === diagnostics.Diagnostic.ERROR;
197 if (uri === null) {
198 if (!fatal) {
199 return;
200 }
201 assert(fatal);
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Drop this assert. It's only checking that the 'if'
Johnni Winther 2012/07/04 13:19:17 Done.
202 print(message);
203 throw message;
204 } else if (fatal) {
205 SourceFile file = sourceFiles[uri.toString()];
206 print(file.getLocationMessage(message, begin, end, true, (s) => s));
207 throw message;
208 }
209 }
210
211 Dart2jsCompilation(String script, String libraryRoot,
212 [String packageRoot, List<String> opts = const []])
213 : cwd = getCurrentDirectory(),
Lasse Reichstein Nielsen 2012/07/04 10:58:59 indentation.
Johnni Winther 2012/07/04 13:19:17 Ignored!
214 sourceFiles = <SourceFile>{} {
215 var libraryUri = cwd.resolve(nativeToUriPath(libraryRoot));
216 var packageUri;
217 if (packageRoot !== null) {
218 packageUri = cwd.resolve(nativeToUriPath(packageRoot));
219 } else {
220 packageUri = libraryUri;
221 }
222 _compiler = new api.Compiler(provider, handler,
223 libraryUri, packageUri, <String>[]);
224 var scriptUri = cwd.resolve(nativeToUriPath(script));
225 // TODO(johnniwinther): Detect file not found
226 _compiler.run(scriptUri);
227 }
228
229 void addLibrary(String path) {
230 var uri = cwd.resolve(nativeToUriPath(path));
231 _compiler.scanner.loadLibrary(uri, null);
232 }
233
234 MirrorSystem mirrors() => new Dart2jsMirrorSystem(_compiler);
235 }
236
237
238 //------------------------------------------------------------------------------
239 // Dart2js specific extensions of mirror interfaces
240 //------------------------------------------------------------------------------
241
242 interface Dart2jsMirror extends Mirror {
243 /**
244 * A unique name used as the key in maps.
245 */
246 final String canonicalName;
247 final Dart2jsMirrorSystem system;
248 }
249
250 interface Dart2jsMemberMirror extends Dart2jsMirror, MemberMirror {
251
252 }
253
254 interface Dart2jsTypeMirror extends Dart2jsMirror, TypeMirror {
255
256 }
257
258 abstract class Dart2jsElementMirror implements Dart2jsMirror {
259 final Dart2jsMirrorSystem system;
260 final Element _element;
261
262 Dart2jsElementMirror(this.system, this._element) {
263 assert (system !== null);
264 assert (_element !== null);
265 }
266
267 String simpleName() => _element.name.slowToString();
268
269 Location location() => new Dart2jsLocation(
270 _element.getCompilationUnit().script,
271 system.compiler.spanFromElement(_element));
272
273 String toString() => _element.toString();
274 }
275
276 abstract class Dart2jsProxyMirror implements Dart2jsMirror {
277 final Dart2jsMirrorSystem system;
278
279 Dart2jsProxyMirror(this.system);
280 }
281
282 ///////////////////////////////////////////////////////
283 // implementation
284 ///////////////////////////////////////////////////////
285
286 class Dart2jsMirrorSystem implements MirrorSystem, Dart2jsMirror {
287 final api.Compiler compiler;
288 Map<String, Dart2jsLibraryMirror> _libraries;
289 Map<LibraryElement, Dart2jsLibraryMirror> _libraryMap;
290
291 Dart2jsMirrorSystem(this.compiler)
292 : _libraryMap = new Map<LibraryElement, Dart2jsLibraryMirror>();
293
294 void _ensureLibraries() {
295 if (_libraries == null) {
296 _libraries = <Dart2jsLibraryMirror>{};
297 compiler.libraries.forEach((_, LibraryElement v) {
298 var mirror = new Dart2jsLibraryMirror(system, v);
299 _libraries[mirror.canonicalName] = mirror;
300 _libraryMap[v] = mirror;
301 });
302 }
303 }
304
305 Map<Object, LibraryMirror> libraries() {
306 _ensureLibraries();
307 return new ImmutableMapWrapper<Object, LibraryMirror>(_libraries);
308 }
309
310 Dart2jsLibraryMirror getLibrary(LibraryElement element) {
311 return _libraryMap[element];
312 }
313
314 Dart2jsMirrorSystem get system() => this;
315
316 String simpleName() => "mirror";
317 String qualifiedName() => simpleName();
318
319 String get canonicalName() => simpleName();
320 }
321
322 abstract class Dart2jsObjectMirror extends Dart2jsElementMirror
323 implements ObjectMirror {
324 Dart2jsObjectMirror(Dart2jsMirrorSystem system, Element element)
325 : super(system, element);
Lasse Reichstein Nielsen 2012/07/04 10:58:59 indentation.
Johnni Winther 2012/07/04 13:19:17 Done.
326 }
327
328 class Dart2jsLibraryMirror extends Dart2jsObjectMirror
329 implements LibraryMirror {
330 Map<String, InterfaceMirror> _types;
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Do we really need to make these fields private? We
Johnni Winther 2012/07/04 13:19:17 I like that they are private when the need initial
331 Map<String, MemberMirror> _members;
332
333 Dart2jsLibraryMirror(Dart2jsMirrorSystem system, LibraryElement library)
334 : super(system, library);
335
336 LibraryElement get _library() => _element;
337
338 String get canonicalName() => simpleName();
339
340 /**
341 * Returns the library name (for libraries with a #library tag) or the script
342 * file name (for scripts without a #library tag). The latter case is used to
343 * provide a 'library name' for scripts, to use for instance in dartdoc.
344 */
345 String simpleName() {
346 if (_library.libraryTag !== null) {
347 return _library.libraryTag.argument.dartString.slowToString();
348 } else {
349 // Use the file name as script name.
350 String path = _library.script.uri.path;
351 return path.substring(path.lastIndexOf('/') + 1);
352 }
353 }
354
355 String qualifiedName() => simpleName();
356
357 void _ensureTypes() {
358 if (_types == null) {
359 _types = <InterfaceMirror>{};
360 _library.forEachExport((Element e) {
361 if (e.getLibrary() == _library) {
362 if (e.isClass()) {
363 var type = new Dart2jsInterfaceMirror.fromLibrary(this, e);
364 _types[type.canonicalName] = type;
365 } else if (e.isTypedef()) {
366 var type = new Dart2jsTypedefMirror.fromLibrary(this, e);
367 _types[type.canonicalName] = type;
368 }
369 }
370 });
371 }
372 }
373
374 void _ensureMembers() {
375 if (_members == null) {
376 _members = <MemberMirror>{};
377 _library.forEachExport((Element e) {
378 if (!e.isClass() && !e.isTypedef()) {
379 for (var member in _convertElementMemberToMemberMirrors(this, e)) {
380 _members[member.canonicalName] = member;
381 }
382 }
383 });
384 }
385 }
386
387 Map<Object, MemberMirror> declaredMembers() {
388 _ensureMembers();
389 return new ImmutableMapWrapper<Object,MemberMirror>(_members);
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Space after comma. More cases below.
Johnni Winther 2012/07/04 13:19:17 Done.
390 }
391
392 Map<Object, InterfaceMirror> types() {
393 _ensureTypes();
394 return new ImmutableMapWrapper<Object,InterfaceMirror>(_types);
395 }
396
397 Location location() {
398 var script = _library.getCompilationUnit().script;
399 return new Dart2jsLocation(
400 script,
401 new SourceSpan(script.uri, 0, script.text.length));
402 }
403 }
404
405 class Dart2jsLocation implements Location {
406 Script _script;
407 SourceSpan _span;
408
409 Dart2jsLocation(this._script, this._span);
410
411 int start() => _span.begin;
412 int end() => _span.end;
413 Source source() => new Dart2jsSource(_script);
414
415 String text() => _script.text.substring(start(), end());
416 }
417
418 class Dart2jsSource implements Source {
419 Script _script;
420
421 Dart2jsSource(this._script);
422
423 Uri uri() => _script.uri;
424 String text() => _script.text;
425 }
426
427 class Dart2jsParameterMirror extends Dart2jsElementMirror
428 implements ParameterMirror {
429 final MethodMirror _method;
430 final bool _isOptional;
431
432 Dart2jsParameterMirror(Dart2jsMirrorSystem system,
433 this._method,
434 VariableElement element,
435 this._isOptional)
436 : super(system, element);
437
438 VariableElement get _variableElement() => _element;
439
440 String get canonicalName() => simpleName();
441
442 String qualifiedName() => '${_method.qualifiedName()}#${simpleName()}';
443
444 // TODO(johnniwinther): Provide
445 // [:_variableElement.variables.functionSignature:] instead of [:null:].
446 TypeMirror type() => _convertTypeToTypeMirror(system,
447 _variableElement.computeType(system.compiler),
448 system.compiler.dynamicClass.computeType(system.compiler),
449 null);
450
451 String defaultValue() => null; // TODO(johnniwinther): How to compute this?
452
453 bool hasDefaultValue() => false; // TODO(johnniwinther): How to compute this?
454
455 bool isOptional() => _isOptional;
456 }
457
458 ///////////////////////////////////////////////////////
459 // declarations
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Capitalize comment.
Johnni Winther 2012/07/04 13:19:17 Done.
460 ///////////////////////////////////////////////////////
461
462 class Dart2jsInterfaceMirror extends Dart2jsObjectMirror
463 implements Dart2jsTypeMirror, InterfaceMirror {
464 final Dart2jsLibraryMirror _library;
465 Map<String, Dart2jsMemberMirror> _members;
466 List<TypeVariableMirror> _typeVariables;
467
468 Dart2jsInterfaceMirror(Dart2jsMirrorSystem system, ClassElement _class)
469 : this._library = system.getLibrary(_class.getLibrary()),
470 super(system, _class);
471
472 ClassElement get _class() => _element;
473
474
475 Dart2jsInterfaceMirror.fromLibrary(Dart2jsLibraryMirror library,
476 ClassElement _class)
477 : this._library = library,
478 super(library.system, _class);
479
480 String get canonicalName() => simpleName();
481
482 String qualifiedName() => '${library().qualifiedName()}.${simpleName()}';
483
484 Location location() {
485 if (_class is PartialClassElement) {
486 var node = _class.parseNode(_diagnosticListener);
487 if (node !== null) {
488 var script = _class.getCompilationUnit().script;
489 var span = system.compiler.spanFromNode(node, script.uri);
490 return new Dart2jsLocation(script, span);
491 }
492 }
493 return super.location();
494 }
495
496 void _ensureMembers() {
497 if (_members == null) {
498 _members = <Dart2jsMemberMirror>{};
499 _class.constructors.forEach((_, e) {
500 for (var member in _convertElementMemberToMemberMirrors(this, e)) {
501 _members[member.canonicalName] = member;
502 }
503 });
504 _class.localMembers.forEach((_, e) {
505 for (var member in _convertElementMemberToMemberMirrors(this, e)) {
506 _members[member.canonicalName] = member;
507 }
508 });
509 }
510 }
511
512 Map<Object, MemberMirror> declaredMembers() {
513 _ensureMembers();
514 return new ImmutableMapWrapper<Object,MemberMirror>(_members);
515 }
516
517 LibraryMirror library() {
518 return _library;
519 }
520
521 bool get isObject() => _class == system.compiler.objectClass;
522
523 bool get isDynamic() => _class == system.compiler.dynamicClass;
524
525 bool get isVoid() => false;
526
527 bool get isTypeVariable() => false;
528
529 bool get isTypedef() => false;
530
531 bool get isFunction() => false;
532
533 InterfaceMirror get declaration() => this;
534
535 InterfaceMirror superclass() {
536 if (_class.supertype != null) {
537 return new Dart2jsInterfaceTypeMirror(system, _class.supertype);
538 }
539 return null;
540 }
541
542 Map<Object, InterfaceMirror> interfaces() {
543 var map = new Map<String, InterfaceMirror>();
544 var link = _class.interfaces;
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Type on "link". I assume it's Link<Something>, but
Johnni Winther 2012/07/04 13:19:17 Done.
545 while (!link.isEmpty()) {
546 var type = _convertTypeToTypeMirror(system, link.head,
547 system.compiler.dynamicClass.computeType(system.compiler));
548 map[type.canonicalName] = type;
549 link = link.tail;
550 }
551 return new ImmutableMapWrapper<Object,InterfaceMirror>(map);
552 }
553
554 bool get isClass() => !_class.isInterface();
555
556 bool get isInterface() => _class.isInterface();
557
558 bool get isPrivate() => _isPrivate(simpleName());
559
560 bool get isDeclaration() => true;
561
562 List<TypeMirror> typeArguments() {
563 throw new UnsupportedOperationException(
564 'Declarations do not have type arguments');
565 }
566
567 List<TypeVariableMirror> typeVariables() {
568 if (_typeVariables == null) {
569 _typeVariables = <TypeVariableMirror>[];
570 _class.typeParameters.forEach((_,parameter) {
571 _typeVariables.add(
572 new Dart2jsTypeVariableMirror(system,
573 parameter.computeType(system.compiler)));
574 });
575 }
576 return _typeVariables;
577 }
578
579 Map<Object, MethodMirror> constructors() {
580 _ensureMembers();
581 return new AsFilteredImmutableMapWrapper<Object, MemberMirror, MethodMirror> (
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Line length > 80. No, there is no way to make this
Johnni Winther 2012/07/04 13:19:17 Done.
582 _members, (m) => m.isConstructor ? m : null);
583 }
584
585 /**
586 * Returns the default type for this interface.
587 */
588 InterfaceMirror defaultType() {
589 if (_class.defaultClass != null) {
590 return new Dart2jsInterfaceTypeMirror(system, _class.defaultClass);
591 }
592 return null;
593 }
594
595 bool operator ==(Object other) {
596 if (this === other) {
597 return true;
598 }
599 if (other is! InterfaceMirror) {
600 return false;
601 }
602 if (library() != other.library()) {
603 return false;
604 }
605 if (isDeclaration !== other.isDeclaration) {
606 return false;
607 }
608 return qualifiedName() == other.qualifiedName();
609 }
610 }
611
612 class Dart2jsTypedefMirror extends Dart2jsElementMirror
613 implements Dart2jsTypeMirror, TypedefMirror {
614 final Dart2jsLibraryMirror _library;
615 List<TypeVariableMirror> _typeVariables;
616 TypeMirror _definition;
617
618 Dart2jsTypedefMirror(Dart2jsMirrorSystem system, TypedefElement _typedef)
619 : this._library = system.getLibrary(_typedef.getLibrary()),
620 super(system, _typedef);
621
622 Dart2jsTypedefMirror.fromLibrary(Dart2jsLibraryMirror library,
623 TypedefElement _typedef)
624 : this._library = library,
625 super(library.system, _typedef);
626
627 TypedefElement get _typedef() => _element;
628
629 String get canonicalName() => simpleName();
630
631 String qualifiedName() => '${library().qualifiedName()}.${simpleName()}';
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Make this, "location", "library", "typeArguments",
Johnni Winther 2012/07/04 13:19:17 This issue will be considered for the whole mirror
632
633 Location location() {
634 var node = _typedef.parseNode(_diagnosticListener);
635 if (node !== null) {
636 var script = _typedef.getCompilationUnit().script;
637 var span = system.compiler.spanFromNode(node, script.uri);
638 return new Dart2jsLocation(script, span);
639 }
640 return super.location();
641 }
642
643 LibraryMirror library() => _library;
644
645 bool get isObject() => false;
646
647 bool get isDynamic() => false;
648
649 bool get isVoid() => false;
650
651 bool get isTypeVariable() => false;
652
653 bool get isTypedef() => true;
654
655 bool get isFunction() => false;
656
657 List<TypeMirror> typeArguments() {
658 throw new UnsupportedOperationException(
659 'Declarations do not have type arguments');
660 }
661
662 List<TypeVariableMirror> typeVariables() {
663 if (_typeVariables == null) {
664 _typeVariables = <TypeVariableMirror>[];
665 // TODO(johnniwinther): Equip [Typedef] with a [typeParameters] map, just
666 // like [ClassElement].
667 }
668 return _typeVariables;
669 }
670
671 TypeMirror definition() {
672 if (_definition === null) {
673 // TODO(johnniwinther): Provide access to the functionSignature of the
674 // aliased function definition.
675 }
676 return _definition;
677 }
678
679 Map<Object, MemberMirror> declaredMembers() => const <MemberMirror>{};
680
681 InterfaceMirror get declaration() => this;
682
683 // TODO(johnniwinther): How should a typedef respond to these?
684 InterfaceMirror superclass() => null;
685
686 Map<Object, InterfaceMirror> interfaces() => const <InterfaceMirror>{};
687
688 bool get isClass() => false;
689
690 bool get isInterface() => false;
691
692 bool get isPrivate() => _isPrivate(simpleName());
693
694 bool get isDeclaration() => true;
695
696 Map<Object, MethodMirror> constructors() => const <MethodMirror>{};
697
698 InterfaceMirror defaultType() => null;
699 }
700
701 class Dart2jsTypeVariableMirror extends Dart2jsTypeElementMirror
702 implements TypeVariableMirror {
703 final TypeVariableType _typeVariableType;
704 InterfaceMirror _declarer;
705
706 Dart2jsTypeVariableMirror(Dart2jsMirrorSystem system,
707 TypeVariableType typeVariableType)
708 : this._typeVariableType = typeVariableType,
709 super(system, typeVariableType)
710 {
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Brace on previous line (and indentation of initial
Johnni Winther 2012/07/04 13:19:17 Done.
711 assert (_typeVariableType !== null);
Lasse Reichstein Nielsen 2012/07/04 10:58:59 No space after assert. It's written as a function
Johnni Winther 2012/07/04 13:19:17 Done.
712 }
713
714
715 String qualifiedName() => '${declarer().qualifiedName()}.${simpleName()}';
716
717 InterfaceMirror declarer() {
718 if (_declarer === null) {
719 if (_typeVariableType.element.enclosingElement.isClass()) {
720 _declarer = new Dart2jsInterfaceMirror(system,
721 _typeVariableType.element.enclosingElement);
722 } else if (_typeVariableType.element.enclosingElement.isTypedef()) {
723 _declarer = new Dart2jsTypedefMirror(system,
724 _typeVariableType.element.enclosingElement);
725 }
726 }
727 return _declarer;
728 }
729
730 LibraryMirror library() => declarer().library();
731
732 bool get isObject() => false;
733
734 bool get isDynamic() => false;
735
736 bool get isVoid() => false;
737
738 bool get isTypeVariable() => true;
739
740 bool get isTypedef() => false;
741
742 bool get isFunction() => false;
743
744 TypeMirror bound() => _convertTypeToTypeMirror(
745 system,
746 _typeVariableType.element.bound,
747 system.compiler.objectClass.computeType(system.compiler));
748
749 bool operator ==(Object other) {
750 if (this === other) {
751 return true;
752 }
753 if (other is! TypeVariableMirror) {
754 return false;
755 }
756 if (declarer() != other.declarer()) {
757 print('${declarer()} != ${other.declarer()}');
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Debug-print?
Johnni Winther 2012/07/04 13:19:17 Yes, the one that got away!
758 return false;
759 }
760 return qualifiedName() == other.qualifiedName();
761 }
762 }
763
764
765 ///////////////////////////////////////////////////////
766 // types
767 ///////////////////////////////////////////////////////
768
769 abstract class Dart2jsTypeElementMirror extends Dart2jsProxyMirror
770 implements Dart2jsTypeMirror {
771 final Type _type;
772
773 Dart2jsTypeElementMirror(Dart2jsMirrorSystem system, this._type)
774 : super(system);
775
776 String simpleName() => _type.name.slowToString();
777
778 String get canonicalName() => simpleName();
779
780 Location location() {
781 var script = _type.element.getCompilationUnit().script;
782 return new Dart2jsLocation(script,
783 system.compiler.spanFromElement(_type.element));
784 }
785
786 LibraryMirror library() {
787 return system.getLibrary(_type.element.getLibrary());
788 }
789
790 String toString() => _type.element.toString();
791 }
792
793 class Dart2jsInterfaceTypeMirror extends Dart2jsTypeElementMirror
794 implements InterfaceMirror {
795 List<TypeMirror> _typeArguments;
796
797 Dart2jsInterfaceTypeMirror(Dart2jsMirrorSystem system,
798 InterfaceType interfaceType)
799 : super(system, interfaceType);
800
801 InterfaceType get _interfaceType() => _type;
802
803 String qualifiedName() => declaration.qualifiedName();
804
805 // TODO(johnniwinther): Substitute type arguments for type variables.
806 Map<Object, MemberMirror> declaredMembers() => declaration.declaredMembers();
807
808 bool get isObject() => system.compiler.objectClass == _type.element;
809
810 bool get isDynamic() => system.compiler.dynamicClass == _type.element;
811
812 bool get isTypeVariable() => false;
813
814 bool get isVoid() => false;
815
816 bool get isTypedef() => false;
817
818 bool get isFunction() => false;
819
820 InterfaceMirror get declaration()
821 => new Dart2jsInterfaceMirror(system, _type.element);
822
823 // TODO(johnniwinther): Substitute type arguments for type variables.
824 InterfaceMirror superclass() => declaration.superclass();
825
826 // TODO(johnniwinther): Substitute type arguments for type variables.
827 Map<Object, InterfaceMirror> interfaces() => declaration.interfaces();
828
829 bool get isClass() => declaration.isClass;
830
831 bool get isInterface() => declaration.isInterface;
832
833 bool get isPrivate() => declaration.isPrivate;
834
835 bool get isDeclaration() => false;
836
837 List<TypeMirror> typeArguments() {
838 if (_typeArguments == null) {
839 _typeArguments = <TypeMirror>[];
840 Link<Type> type = _interfaceType.arguments;
841 while (type != null && type.head != null) {
842 _typeArguments.add(_convertTypeToTypeMirror(system, type.head,
843 system.compiler.dynamicClass.computeType(system.compiler)));
844 type = type.tail;
845 }
846 }
847 return _typeArguments;
848 }
849
850 List<TypeVariableMirror> typeVariables() => declaration.typeVariables();
851
852 // TODO(johnniwinther): Substitute type arguments for type variables.
853 Map<Object, MethodMirror> constructors() => declaration.constructors();
854
855 // TODO(johnniwinther): Substitute type arguments for type variables?
856 InterfaceMirror defaultType() => declaration.defaultType();
857
858 bool operator ==(Object other) {
859 if (this === other) {
860 return true;
861 }
862 if (other is! InterfaceMirror) {
863 return false;
864 }
865 if (other.isDeclaration) {
866 return false;
867 }
868 if (declaration != other.declaration) {
869 return false;
870 }
871 var thisTypeArguments = typeArguments().iterator();
872 var otherTypeArguments = other.typeArguments().iterator();
873 while (thisTypeArguments.hasNext() && otherTypeArguments.hasNext()) {
874 if (thisTypeArguments.next() != otherTypeArguments.next()) {
875 return false;
876 }
877 }
878 return !thisTypeArguments.hasNext() && !otherTypeArguments.hasNext();
879 }
880 }
881
882
883 class Dart2jsFunctionTypeMirror extends Dart2jsTypeElementMirror
884 implements FunctionTypeMirror {
885 final FunctionSignature _functionSignature;
886 List<ParameterMirror> _parameters;
887
888 Dart2jsFunctionTypeMirror(Dart2jsMirrorSystem system,
889 FunctionType functionType, this._functionSignature)
890 : super(system, functionType) {
891 assert (_functionSignature !== null);
892 }
893
894 FunctionType get _functionType() => _type;
895
896 // TODO(johnniwinther): Is this the qualified name of a function type?
897 String qualifiedName() => declaration.qualifiedName();
898
899 // TODO(johnniwinther): Substitute type arguments for type variables.
900 Map<Object, MemberMirror> declaredMembers() {
901 var method = callMethod();
902 if (method !== null) {
903 var map = new Map<String, MemberMirror>.from(
904 declaration.declaredMembers());
905 var name = method.qualifiedName();
906 map[name] = method;
907 Function func = null;
908 return new ImmutableMapWrapper<Object,MemberMirror>(map);
909 }
910 return declaration.declaredMembers();
911 }
912
913 bool get isObject() => system.compiler.objectClass == _type.element;
914
915 bool get isDynamic() => system.compiler.dynamicClass == _type.element;
916
917 bool get isVoid() => false;
918
919 bool get isTypeVariable() => false;
920
921 bool get isTypedef() => false;
922
923 bool get isFunction() => true;
924
925 MethodMirror callMethod() => _convertElementMethodToMethodMirror(
926 system.getLibrary(_functionType.element.getLibrary()),
927 _functionType.element);
928
929 InterfaceMirror get declaration()
930 => new Dart2jsInterfaceMirror(system, system.compiler.functionClass);
931
932 // TODO(johnniwinther): Substitute type arguments for type variables.
933 InterfaceMirror superclass() => declaration.superclass();
934
935 // TODO(johnniwinther): Substitute type arguments for type variables.
936 Map<Object, InterfaceMirror> interfaces() => declaration.interfaces();
937
938 bool get isClass() => declaration.isClass;
939
940 bool get isInterface() => declaration.isInterface;
941
942 bool get isPrivate() => declaration.isPrivate;
943
944 bool get isDeclaration() => false;
945
946 List<TypeMirror> typeArguments() => const <TypeMirror>[];
947
948 List<TypeVariableMirror> typeVariables() => declaration.typeVariables();
949
950 Map<Object, MethodMirror> constructors() => <MethodMirror>{};
951
952 InterfaceMirror defaultType() => null;
953
954 TypeMirror returnType() {
955 return _convertTypeToTypeMirror(system, _functionType.returnType,
956 system.compiler.dynamicClass.computeType(system.compiler));
957 }
958
959 List<ParameterMirror> parameters() {
960 if (_parameters === null) {
961 _parameters = _parametersFromFunctionSignature(system, callMethod(),
962 _functionSignature);
963 }
964 return _parameters;
965 }
966 }
967
968 class Dart2jsVoidMirror extends Dart2jsTypeElementMirror {
969
970 Dart2jsVoidMirror(Dart2jsMirrorSystem system, VoidType voidType)
971 : super(system, voidType);
972
973 VoidType get _voidType() => _type;
974
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Extra empty line.
Johnni Winther 2012/07/04 13:19:17 Done.
975
976 String qualifiedName() => simpleName();
977
978 /**
979 * The void type has no location.
980 */
981 Location location() => null;
982
983 /**
984 * The void type has no library.
985 */
986 LibraryMirror getLibrary() => null;
987
988 bool get isObject() => false;
989
990 bool get isVoid() => true;
991
992 bool get isDynamic() => false;
993
994 bool get isTypeVariable() => false;
995
996 bool get isTypedef() => false;
997
998 bool get isFunction() => false;
999
1000 bool operator ==(Object other) {
1001 if (this === other) {
1002 return true;
1003 }
1004 if (other is! TypeMirror) {
1005 return false;
1006 }
1007 return other.isVoid;
1008 }
1009 }
1010
1011 ///////////////////////////////////////////////////////
1012 // members
1013 ///////////////////////////////////////////////////////
1014
1015 class Dart2jsMethodMirror extends Dart2jsElementMirror
1016 implements Dart2jsMemberMirror, MethodMirror {
1017 final Dart2jsObjectMirror _objectMirror;
1018 String _name;
1019 String _constructorName;
1020 String _operatorName;
1021 Dart2jsMethodKind _kind;
1022 String _canonicalName;
1023
1024 Dart2jsMethodMirror(Dart2jsObjectMirror objectMirror,
1025 FunctionElement function,
1026 [Dart2jsMethodKind kind = null])
1027 : this._objectMirror = objectMirror,
1028 this._kind = kind,
1029 super(objectMirror.system, function) {
1030 _name = _element.name.slowToString();
1031 if (kind == null) {
1032 if (_function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
1033 _constructorName = '';
1034 var dollarPos = _name.indexOf('\$');
Lasse Reichstein Nielsen 2012/07/04 10:58:59 "var" => "int". No need not to. Really, don't use
Johnni Winther 2012/07/04 13:19:17 Done.
1035 if (dollarPos != -1) {
1036 _constructorName = _name.substring(dollarPos+1);
1037 _name = _name.substring(0, dollarPos);
1038 // canonical name is TypeName.constructorName
1039 _canonicalName = '$_name.$_constructorName';
1040 } else {
1041 // canonical name is TypeName
1042 _canonicalName = _name;
1043 }
1044 if (_function.modifiers !== null && _function.modifiers.isConst()) {
1045 _kind = Dart2jsMethodKind.CONST;
1046 } else {
1047 _kind = Dart2jsMethodKind.CONSTRUCTOR;
1048 }
1049 } else if (_function.modifiers !== null
1050 && _function.modifiers.isFactory())
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Indent to paren.
Johnni Winther 2012/07/04 13:19:17 Done.
1051 {
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Brace on previous line.
Johnni Winther 2012/07/04 13:19:17 Done.
1052 _constructorName = '';
1053 var dollarPos = _name.indexOf('\$');
1054 if (dollarPos != -1) {
1055 _constructorName = _name.substring(dollarPos+1);
1056 _name = _name.substring(0, dollarPos);
1057 }
1058 _kind = Dart2jsMethodKind.FACTORY;
1059 // canonical name is TypeName.constructorName
1060 _canonicalName = '$_name.$_constructorName';
1061 } else if (_name.startsWith('operator\$')) {
1062 var str = _name.substring(9);
1063 _name = 'operator';
1064 _kind = Dart2jsMethodKind.OPERATOR;
1065 _operatorName = _getOperatorFromOperatorName(str);
1066 // canonical name is 'operator operatorName'
1067 _canonicalName = 'operator $_operatorName';
1068 } else {
1069 _kind = Dart2jsMethodKind.NORMAL;
1070 _canonicalName = _name;
1071 }
1072 } else if (kind == Dart2jsMethodKind.GETTER) {
1073 _canonicalName = _name;
1074 } else if (kind == Dart2jsMethodKind.SETTER) {
1075 _canonicalName = '$_name=';
1076 } else {
1077 assert(false);
1078 }
1079 }
1080
1081 FunctionElement get _function() => _element;
1082
1083 String simpleName() => _name;
1084
1085 String qualifiedName()
1086 => '${surroundingDeclaration().qualifiedName()}.$canonicalName';
1087
1088 String get canonicalName() => _canonicalName;
1089
1090 ObjectMirror surroundingDeclaration() => _objectMirror;
1091
1092 bool get isTopLevel() => _objectMirror is LibraryMirror;
1093
1094 bool get isConstructor()
1095 => _kind == Dart2jsMethodKind.CONSTRUCTOR || isConst || isFactory;
1096
1097 bool get isField() => false;
1098
1099 bool get isMethod() => !isConstructor;
1100
1101 bool get isPrivate() => _isPrivate(simpleName());
1102
1103 bool get isStatic() =>
1104 _function.modifiers !== null && _function.modifiers.isStatic();
1105
1106 List<ParameterMirror> parameters() {
1107 return _parametersFromFunctionSignature(system, this,
1108 _function.computeSignature(system.compiler));
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Indentation.
Johnni Winther 2012/07/04 13:19:17 Done.
1109 }
1110
1111 TypeMirror returnType() => _convertTypeToTypeMirror(
1112 system, _function.computeSignature(system.compiler).returnType,
1113 system.compiler.dynamicClass.computeType(system.compiler));
1114
1115 bool get isConst() => _kind == Dart2jsMethodKind.CONST;
1116
1117 bool get isFactory() => _kind == Dart2jsMethodKind.FACTORY;
1118
1119 String get constructorName() => _constructorName;
1120
1121 bool get isGetter() => _kind == Dart2jsMethodKind.GETTER;
1122
1123 bool get isSetter() => _kind == Dart2jsMethodKind.SETTER;
1124
1125 bool get isOperator() => _kind == Dart2jsMethodKind.OPERATOR;
1126
1127 String get operatorName() => _operatorName;
1128
1129 Location location() {
1130 var node = _function.parseNode(_diagnosticListener);
1131 if (node !== null) {
1132 var script = _function.getCompilationUnit().script;
1133 var span = system.compiler.spanFromNode(node, script.uri);
1134 return new Dart2jsLocation(script, span);
1135 }
1136 return super.location();
1137 }
1138
1139 }
1140
1141 class Dart2jsFieldMirror extends Dart2jsElementMirror
1142 implements Dart2jsMemberMirror, FieldMirror
1143 {
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Brace on previous line.
Johnni Winther 2012/07/04 13:19:17 Done.
1144 Dart2jsObjectMirror _objectMirror;
1145 VariableElement _variable;
1146
1147 Dart2jsFieldMirror(Dart2jsObjectMirror objectMirror,
1148 VariableElement variable)
1149 : this._objectMirror = objectMirror,
Lasse Reichstein Nielsen 2012/07/04 10:58:59 Indentation, both parameter and ':'.
Johnni Winther 2012/07/04 13:19:17 Done.
1150 this._variable = variable,
1151 super(objectMirror.system, variable);
1152
1153 String qualifiedName()
1154 => '${surroundingDeclaration().qualifiedName()}.$canonicalName';
1155
1156 String get canonicalName() => simpleName();
1157
1158 ObjectMirror surroundingDeclaration() => _objectMirror;
1159
1160 bool get isTopLevel() => _objectMirror is LibraryMirror;
1161
1162 bool get isConstructor() => false;
1163
1164 bool get isField() => true;
1165
1166 bool get isMethod() => false;
1167
1168 bool get isPrivate() => _isPrivate(simpleName());
1169
1170 bool get isStatic() => _variable.modifiers.isStatic();
1171
1172 bool get isFinal() => _variable.modifiers.isFinal();
1173
1174 TypeMirror type() => _convertTypeToTypeMirror(system,
1175 _variable.computeType(system.compiler),
1176 system.compiler.dynamicClass.computeType(system.compiler));
1177
1178 Location location() {
1179 var script = _variable.getCompilationUnit().script;
1180 var node = _variable.variables.parseNode(_diagnosticListener);
1181 if (node !== null) {
1182 var span = system.compiler.spanFromNode(node, script.uri);
1183 return new Dart2jsLocation(script, span);
1184 } else {
1185 var span = system.compiler.spanFromElement(_variable);
1186 return new Dart2jsLocation(script, span);
1187 }
1188 }
1189 }
1190
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698