OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library mirrors_dart2js; | 5 library mirrors_dart2js; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:uri'; | 8 import 'dart:uri'; |
9 | 9 |
10 import '../../compiler.dart' as diagnostics; | 10 import '../../compiler.dart' as diagnostics; |
11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
12 import '../resolution/resolution.dart' show ResolverTask, ResolverVisitor; | 12 import '../resolution/resolution.dart' show ResolverTask, ResolverVisitor; |
13 import '../apiimpl.dart' as api; | 13 import '../apiimpl.dart' as api; |
14 import '../scanner/scannerlib.dart'; | 14 import '../scanner/scannerlib.dart' hide SourceString; |
15 import '../ssa/ssa.dart'; | 15 import '../ssa/ssa.dart'; |
16 import '../dart2jslib.dart'; | 16 import '../dart2jslib.dart'; |
17 import '../filenames.dart'; | 17 import '../filenames.dart'; |
18 import '../source_file.dart'; | 18 import '../source_file.dart'; |
19 import '../tree/tree.dart'; | 19 import '../tree/tree.dart'; |
20 import '../util/util.dart'; | 20 import '../util/util.dart'; |
21 import '../util/uri_extras.dart'; | 21 import '../util/uri_extras.dart'; |
22 import '../dart2js.dart'; | 22 import '../dart2js.dart'; |
23 import '../util/characters.dart'; | 23 import '../util/characters.dart'; |
24 | 24 |
25 import 'mirrors.dart'; | 25 import 'mirrors.dart'; |
26 import 'mirrors_util.dart'; | |
26 import 'util.dart'; | 27 import 'util.dart'; |
27 | 28 |
28 //------------------------------------------------------------------------------ | 29 //------------------------------------------------------------------------------ |
29 // Utility types and functions for the dart2js mirror system | 30 // Utility types and functions for the dart2js mirror system |
30 //------------------------------------------------------------------------------ | 31 //------------------------------------------------------------------------------ |
31 | 32 |
32 bool _isPrivate(String name) { | 33 bool _isPrivate(String name) { |
33 return name.startsWith('_'); | 34 return name.startsWith('_'); |
34 } | 35 } |
35 | 36 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
384 [Path packageRoot, List<String> opts = const <String>[]]) | 385 [Path packageRoot, List<String> opts = const <String>[]]) |
385 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { | 386 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { |
386 var libraryUri = cwd.resolve(libraryRoot.toString()); | 387 var libraryUri = cwd.resolve(libraryRoot.toString()); |
387 var packageUri; | 388 var packageUri; |
388 if (packageRoot != null) { | 389 if (packageRoot != null) { |
389 packageUri = cwd.resolve(packageRoot.toString()); | 390 packageUri = cwd.resolve(packageRoot.toString()); |
390 } else { | 391 } else { |
391 packageUri = libraryUri; | 392 packageUri = libraryUri; |
392 } | 393 } |
393 _compiler = new api.Compiler(provider, handler, | 394 _compiler = new api.Compiler(provider, handler, |
394 libraryUri, packageUri, <String>[]); | 395 libraryUri, packageUri, opts); |
395 var scriptUri = cwd.resolve(script.toString()); | 396 var scriptUri = cwd.resolve(script.toString()); |
396 // TODO(johnniwinther): Detect file not found | 397 // TODO(johnniwinther): Detect file not found |
397 _compiler.run(scriptUri); | 398 _compiler.run(scriptUri); |
398 } | 399 } |
399 | 400 |
400 Dart2JsCompilation.library(List<Path> libraries, Path libraryRoot, | 401 Dart2JsCompilation.library(List<Path> libraries, Path libraryRoot, |
401 [Path packageRoot, List<String> opts = const <String>[]]) | 402 [Path packageRoot, List<String> opts = const <String>[]]) |
402 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { | 403 : cwd = getCurrentDirectory(), sourceFiles = <String, SourceFile>{} { |
403 var libraryUri = cwd.resolve(libraryRoot.toString()); | 404 var libraryUri = cwd.resolve(libraryRoot.toString()); |
404 var packageUri; | 405 var packageUri; |
405 if (packageRoot != null) { | 406 if (packageRoot != null) { |
406 packageUri = cwd.resolve(packageRoot.toString()); | 407 packageUri = cwd.resolve(packageRoot.toString()); |
407 } else { | 408 } else { |
408 packageUri = libraryUri; | 409 packageUri = libraryUri; |
409 } | 410 } |
410 _compiler = new LibraryCompiler(provider, handler, | 411 _compiler = new LibraryCompiler(provider, handler, |
411 libraryUri, packageUri, <String>[]); | 412 libraryUri, packageUri, opts); |
412 var librariesUri = <Uri>[]; | 413 var librariesUri = <Uri>[]; |
413 for (Path library in libraries) { | 414 for (Path library in libraries) { |
414 librariesUri.add(cwd.resolve(library.toString())); | 415 librariesUri.add(cwd.resolve(library.toString())); |
415 // TODO(johnniwinther): Detect file not found | 416 // TODO(johnniwinther): Detect file not found |
416 } | 417 } |
417 LibraryCompiler libraryCompiler = _compiler; | 418 LibraryCompiler libraryCompiler = _compiler; |
418 libraryCompiler.runList(librariesUri); | 419 libraryCompiler.runList(librariesUri); |
419 } | 420 } |
420 | 421 |
421 MirrorSystem get mirrors => new Dart2JsMirrorSystem(_compiler); | 422 MirrorSystem get mirrors => new Dart2JsMirrorSystem(_compiler); |
(...skipping 12 matching lines...) Expand all Loading... | |
434 } | 435 } |
435 | 436 |
436 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror | 437 abstract class Dart2JsDeclarationMirror extends Dart2JsMirror |
437 implements DeclarationMirror { | 438 implements DeclarationMirror { |
438 | 439 |
439 bool get isTopLevel => owner != null && owner is LibraryMirror; | 440 bool get isTopLevel => owner != null && owner is LibraryMirror; |
440 | 441 |
441 bool get isPrivate => _isPrivate(simpleName); | 442 bool get isPrivate => _isPrivate(simpleName); |
442 | 443 |
443 /** | 444 /** |
444 * Returns the first token for the source of this declaration. | 445 * Returns the first token for the source of this declaration, not including |
446 * metadata annotations. | |
445 */ | 447 */ |
446 Token getBeginToken(); | 448 Token getBeginToken(); |
447 | 449 |
448 /** | 450 /** |
449 * Returns the last token for the source of this declaration. | 451 * Returns the last token for the source of this declaration. |
450 */ | 452 */ |
451 Token getEndToken(); | 453 Token getEndToken(); |
452 | 454 |
453 /** | 455 /** |
454 * Returns the script for the source of this declaration. | 456 * Returns the script for the source of this declaration. |
455 */ | 457 */ |
456 Script getScript(); | 458 Script getScript(); |
457 | |
458 SourceLocation get location { | |
459 Token beginToken = getBeginToken(); | |
460 Script script = getScript(); | |
461 SourceSpan span; | |
462 if (beginToken == null) { | |
463 span = new SourceSpan(script.uri, 0, 0); | |
464 } else { | |
465 Token endToken = getEndToken(); | |
466 span = mirrors.compiler.spanFromTokens(beginToken, endToken, script.uri); | |
467 } | |
468 return new Dart2JsSourceLocation(script, span); | |
469 } | |
470 } | 459 } |
471 | 460 |
472 abstract class Dart2JsMemberMirror extends Dart2JsElementMirror | 461 abstract class Dart2JsMemberMirror extends Dart2JsElementMirror |
473 implements MemberMirror { | 462 implements MemberMirror { |
474 | 463 |
475 Dart2JsMemberMirror(Dart2JsMirrorSystem system, Element element) | 464 Dart2JsMemberMirror(Dart2JsMirrorSystem system, Element element) |
476 : super(system, element); | 465 : super(system, element); |
477 | 466 |
478 bool get isConstructor => false; | 467 bool get isConstructor => false; |
479 | 468 |
480 bool get isVariable => false; | 469 bool get isVariable => false; |
481 | 470 |
482 bool get isMethod => false; | 471 bool get isMethod => false; |
483 | 472 |
484 bool get isStatic => false; | 473 bool get isStatic => false; |
485 | 474 |
486 bool get isParameter => false; | 475 bool get isParameter => false; |
487 } | 476 } |
488 | 477 |
489 abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror | 478 abstract class Dart2JsTypeMirror extends Dart2JsDeclarationMirror |
ahe
2013/01/08 11:59:43
This class defines no behavior, so it has no purpo
Johnni Winther
2013/01/08 13:39:46
It is an 'interface' extending both Dart2JsDeclara
| |
490 implements TypeMirror { | 479 implements TypeMirror { |
491 | 480 |
ahe
2013/01/08 11:59:43
Extra line.
Johnni Winther
2013/01/08 13:39:46
Done.
| |
492 } | 481 } |
493 | 482 |
494 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { | 483 abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror { |
ahe
2013/01/08 11:59:43
Generally, I prefer having the super class first.
Johnni Winther
2013/01/08 13:39:46
Done.
| |
495 final Dart2JsMirrorSystem mirrors; | 484 final Dart2JsMirrorSystem mirrors; |
496 final Element _element; | 485 final Element _element; |
497 List<InstanceMirror> _metadata; | 486 List<InstanceMirror> _metadata; |
498 | 487 |
499 Dart2JsElementMirror(this.mirrors, this._element) { | 488 Dart2JsElementMirror(this.mirrors, this._element) { |
500 assert (mirrors != null); | 489 assert (mirrors != null); |
501 assert (_element != null); | 490 assert (_element != null); |
502 } | 491 } |
503 | 492 |
504 String get simpleName => _element.name.slowToString(); | 493 String get simpleName => _element.name.slowToString(); |
505 | 494 |
506 String get displayName => simpleName; | 495 String get displayName => simpleName; |
507 | 496 |
508 /** | 497 /** |
509 * Computes the first token for this declaration using the first metadata | 498 * Computes the first token for this declaration using the begin token of the |
510 * annotation, the begin token of the element node or element position as | 499 * element node or element position as indicator. |
511 * indicator. | |
512 */ | 500 */ |
513 Token getBeginToken() { | 501 Token getBeginToken() { |
514 if (!_element.metadata.isEmpty) { | |
515 for (MetadataAnnotation metadata in _element.metadata) { | |
516 if (metadata.beginToken != null) { | |
517 return metadata.beginToken; | |
518 } | |
519 } | |
520 } | |
521 // TODO(johnniwinther): Avoid calling [parseNode]. | 502 // TODO(johnniwinther): Avoid calling [parseNode]. |
522 Node node = _element.parseNode(mirrors.compiler); | 503 Node node = _element.parseNode(mirrors.compiler); |
523 if (node == null) { | 504 if (node == null) { |
524 return _element.position(); | 505 return _element.position(); |
525 } | 506 } |
526 return node.getBeginToken(); | 507 return node.getBeginToken(); |
527 } | 508 } |
528 | 509 |
529 /** | 510 /** |
530 * Computes the last token for this declaration using the end token of the | 511 * Computes the last token for this declaration using the end token of the |
531 * element node or element position as indicator. | 512 * element node or element position as indicator. |
532 */ | 513 */ |
533 Token getEndToken() { | 514 Token getEndToken() { |
534 // TODO(johnniwinther): Avoid calling [parseNode]. | 515 // TODO(johnniwinther): Avoid calling [parseNode]. |
535 Node node = _element.parseNode(mirrors.compiler); | 516 Node node = _element.parseNode(mirrors.compiler); |
536 if (node == null) { | 517 if (node == null) { |
537 return _element.position(); | 518 return _element.position(); |
538 } | 519 } |
539 return node.getEndToken(); | 520 return node.getEndToken(); |
540 } | 521 } |
541 | 522 |
523 /** | |
524 * Returns the first token for the source of this declaration, including | |
525 * metadata annotations. | |
526 */ | |
527 Token getFirstToken() { | |
528 if (!_element.metadata.isEmpty) { | |
529 for (MetadataAnnotation metadata in _element.metadata) { | |
530 if (metadata.beginToken != null) { | |
531 return metadata.beginToken; | |
532 } | |
533 } | |
534 } | |
535 return getBeginToken(); | |
536 } | |
537 | |
542 Script getScript() => _element.getCompilationUnit().script; | 538 Script getScript() => _element.getCompilationUnit().script; |
543 | 539 |
540 SourceLocation get location { | |
541 Token beginToken = getFirstToken(); | |
542 Script script = getScript(); | |
543 SourceSpan span; | |
544 if (beginToken == null) { | |
545 span = new SourceSpan(script.uri, 0, 0); | |
546 } else { | |
547 Token endToken = getEndToken(); | |
548 span = mirrors.compiler.spanFromTokens(beginToken, endToken, script.uri); | |
549 } | |
550 return new Dart2JsSourceLocation(script, span); | |
551 } | |
552 | |
544 String toString() => _element.toString(); | 553 String toString() => _element.toString(); |
545 | 554 |
546 int get hashCode => qualifiedName.hashCode; | 555 int get hashCode => qualifiedName.hashCode; |
547 | 556 |
557 void _appendCommentTokens(Token commentToken) { | |
558 while (commentToken != null && commentToken.kind == COMMENT_TOKEN) { | |
559 _metadata.add(new Dart2JsCommentInstanceMirror( | |
560 mirrors, commentToken.slowToString())); | |
561 commentToken = commentToken.next; | |
562 } | |
563 } | |
564 | |
548 List<InstanceMirror> get metadata { | 565 List<InstanceMirror> get metadata { |
549 if (_metadata == null) { | 566 if (_metadata == null) { |
550 _metadata = <InstanceMirror>[]; | 567 _metadata = <InstanceMirror>[]; |
551 for (MetadataAnnotation metadata in _element.metadata) { | 568 for (MetadataAnnotation metadata in _element.metadata) { |
569 _appendCommentTokens(mirrors.compiler.commentMap[metadata.beginToken]); | |
552 metadata.ensureResolved(mirrors.compiler); | 570 metadata.ensureResolved(mirrors.compiler); |
553 _metadata.add( | 571 _metadata.add( |
554 _convertConstantToInstanceMirror(mirrors, metadata.value)); | 572 _convertConstantToInstanceMirror(mirrors, metadata.value)); |
555 } | 573 } |
574 _appendCommentTokens(mirrors.compiler.commentMap[getBeginToken()]); | |
556 } | 575 } |
557 // TODO(johnniwinther): Return an unmodifiable list instead. | 576 // TODO(johnniwinther): Return an unmodifiable list instead. |
558 return new List<InstanceMirror>.from(_metadata); | 577 return new List<InstanceMirror>.from(_metadata); |
559 } | 578 } |
560 } | 579 } |
561 | 580 |
562 //------------------------------------------------------------------------------ | 581 //------------------------------------------------------------------------------ |
563 // Mirror system implementation. | 582 // Mirror system implementation. |
564 //------------------------------------------------------------------------------ | 583 //------------------------------------------------------------------------------ |
565 | 584 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 }); | 742 }); |
724 } | 743 } |
725 } | 744 } |
726 | 745 |
727 Map<String, ClassMirror> get classes { | 746 Map<String, ClassMirror> get classes { |
728 _ensureClasses(); | 747 _ensureClasses(); |
729 return new ImmutableMapWrapper<String, ClassMirror>(_classes); | 748 return new ImmutableMapWrapper<String, ClassMirror>(_classes); |
730 } | 749 } |
731 | 750 |
732 /** | 751 /** |
733 * Computes the first token of this library using the first metadata | 752 * Computes the first token of this library using the first library tag as |
734 * annotation or the first library tag as indicator. | 753 * indicator. |
735 */ | 754 */ |
736 Token getBeginToken() { | 755 Token getBeginToken() { |
737 if (!_element.metadata.isEmpty) { | |
738 for (MetadataAnnotation metadata in _element.metadata) { | |
739 if (metadata.beginToken != null) { | |
740 return metadata.beginToken; | |
741 } | |
742 } | |
743 } | |
744 if (_library.libraryTag != null) { | 756 if (_library.libraryTag != null) { |
745 return _library.libraryTag.getBeginToken(); | 757 return _library.libraryTag.getBeginToken(); |
746 } else if (!_library.tags.isEmpty) { | 758 } else if (!_library.tags.isEmpty) { |
747 return _library.tags.reverse().head.getBeginToken(); | 759 return _library.tags.reverse().head.getBeginToken(); |
748 } | 760 } |
749 return null; | 761 return null; |
750 } | 762 } |
751 | 763 |
752 /** | 764 /** |
753 * Computes the first token of this library using the last library tag as | 765 * Computes the first token of this library using the last library tag as |
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1662 | 1674 |
1663 bool get hasReflectee => true; | 1675 bool get hasReflectee => true; |
1664 | 1676 |
1665 get reflectee => null; | 1677 get reflectee => null; |
1666 } | 1678 } |
1667 | 1679 |
1668 class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { | 1680 class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror { |
1669 Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant) | 1681 Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrors, BoolConstant constant) |
1670 : super(mirrors, constant); | 1682 : super(mirrors, constant); |
1671 | 1683 |
1684 Dart2JsBoolConstantMirror.fromBool(Dart2JsMirrorSystem mirrors, bool value) | |
1685 : super(mirrors, value ? new TrueConstant() : new FalseConstant()); | |
1686 | |
1672 BoolConstant get _constant => super._constant; | 1687 BoolConstant get _constant => super._constant; |
1673 | 1688 |
1674 bool get hasReflectee => true; | 1689 bool get hasReflectee => true; |
1675 | 1690 |
1676 get reflectee => _constant is TrueConstant; | 1691 get reflectee => _constant is TrueConstant; |
1677 } | 1692 } |
1678 | 1693 |
1679 class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { | 1694 class Dart2JsStringConstantMirror extends Dart2JsConstantMirror { |
1680 Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors, | 1695 Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrors, |
1681 StringConstant constant) | 1696 StringConstant constant) |
1682 : super(mirrors, constant); | 1697 : super(mirrors, constant); |
1683 | 1698 |
1699 Dart2JsStringConstantMirror.fromString(Dart2JsMirrorSystem mirrors, | |
1700 String text) | |
1701 : super(mirrors, | |
1702 new StringConstant(new DartString.literal(text), null)); | |
1703 | |
1684 StringConstant get _constant => super._constant; | 1704 StringConstant get _constant => super._constant; |
1685 | 1705 |
1686 bool get hasReflectee => true; | 1706 bool get hasReflectee => true; |
1687 | 1707 |
1688 get reflectee => _constant.value.slowToString(); | 1708 get reflectee => _constant.value.slowToString(); |
1689 } | 1709 } |
1690 | 1710 |
1691 class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { | 1711 class Dart2JsNumConstantMirror extends Dart2JsConstantMirror { |
1692 Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors, | 1712 Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrors, |
1693 NumConstant constant) | 1713 NumConstant constant) |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1794 } | 1814 } |
1795 | 1815 |
1796 Future<InstanceMirror> getField(String fieldName) { | 1816 Future<InstanceMirror> getField(String fieldName) { |
1797 Constant fieldConstant = _fieldMap[fieldName]; | 1817 Constant fieldConstant = _fieldMap[fieldName]; |
1798 if (fieldConstant != null) { | 1818 if (fieldConstant != null) { |
1799 return new Future<InstanceMirror>.immediate( | 1819 return new Future<InstanceMirror>.immediate( |
1800 _convertConstantToInstanceMirror(mirrors, fieldConstant)); | 1820 _convertConstantToInstanceMirror(mirrors, fieldConstant)); |
1801 } | 1821 } |
1802 return super.getField(fieldName); | 1822 return super.getField(fieldName); |
1803 } | 1823 } |
1824 } | |
1825 | |
1826 class Dart2JsCommentInstanceMirror implements CommentInstanceMirror { | |
1827 final Dart2JsMirrorSystem mirrors; | |
1828 final String text; | |
1829 String _trimmedText; | |
1830 | |
1831 Dart2JsCommentInstanceMirror(this.mirrors, this.text); | |
1832 | |
1833 ClassMirror get type { | |
1834 return new Dart2JsClassMirror(mirrors, mirrors.compiler.documentClass); | |
1835 } | |
1836 | |
1837 bool get isDocComment => text.startsWith('/**') || text.startsWith('///'); | |
1838 | |
1839 String get trimmedText { | |
1840 if (_trimmedText == null) { | |
1841 _trimmedText = stripComment(text); | |
1842 } | |
1843 return _trimmedText; | |
1844 } | |
1845 | |
1846 bool get hasReflectee => false; | |
1847 | |
1848 get reflectee { | |
1849 // TODO(johnniwinther): Which exception/error should be thrown here? | |
1850 throw new UnsupportedError('InstanceMirror does not have a reflectee'); | |
1851 } | |
1852 | |
1853 Future<InstanceMirror> getField(String fieldName) { | |
1854 if (fieldName == 'isDocComment') { | |
1855 return new Future.immediate( | |
1856 new Dart2JsBoolConstantMirror.fromBool(mirrors, isDocComment)); | |
1857 } else if (fieldName == 'text') { | |
1858 return new Future.immediate( | |
1859 new Dart2JsStringConstantMirror.fromString(mirrors, text)); | |
1860 } else if (fieldName == 'trimmedText') { | |
1861 return new Future.immediate( | |
1862 new Dart2JsStringConstantMirror.fromString(mirrors, trimmedText)); | |
1863 } | |
1864 // TODO(johnniwinther): Which exception/error should be thrown here? | |
1865 throw new UnsupportedError('InstanceMirror does not have a reflectee'); | |
1866 } | |
1804 } | 1867 } |
OLD | NEW |