| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 analyzer.src.generated.source; | 5 library analyzer.src.generated.source; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| 11 import 'package:analyzer/file_system/physical_file_system.dart'; | 11 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 12 import 'package:analyzer/source/package_map_resolver.dart'; | 12 import 'package:analyzer/source/package_map_resolver.dart'; |
| 13 import 'package:analyzer/src/context/source.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 14 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/java_core.dart'; | 15 import 'package:analyzer/src/generated/java_core.dart'; |
| 15 import 'package:analyzer/src/generated/java_engine.dart'; | 16 import 'package:analyzer/src/generated/java_engine.dart'; |
| 16 import 'package:analyzer/src/generated/java_io.dart' show JavaFile; | 17 import 'package:analyzer/src/generated/java_io.dart' show JavaFile; |
| 17 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; | 18 import 'package:analyzer/src/generated/sdk.dart' show DartSdk; |
| 18 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource; | 19 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource; |
| 19 import 'package:analyzer/src/generated/utilities_dart.dart' as utils; | 20 import 'package:analyzer/src/generated/utilities_dart.dart' as utils; |
| 20 import 'package:analyzer/task/model.dart'; | 21 import 'package:analyzer/task/model.dart'; |
| 21 import 'package:package_config/packages.dart'; | 22 import 'package:package_config/packages.dart'; |
| 22 import 'package:path/path.dart' as pathos; | 23 import 'package:path/path.dart' as pathos; |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 * @param source the source in question | 597 * @param source the source in question |
| 597 * @return `true` if the receiver contains the source, else `false` | 598 * @return `true` if the receiver contains the source, else `false` |
| 598 */ | 599 */ |
| 599 bool contains(Source source); | 600 bool contains(Source source); |
| 600 } | 601 } |
| 601 | 602 |
| 602 /** | 603 /** |
| 603 * Instances of the class `SourceFactory` resolve possibly relative URI's agains
t an existing | 604 * Instances of the class `SourceFactory` resolve possibly relative URI's agains
t an existing |
| 604 * [Source]. | 605 * [Source]. |
| 605 */ | 606 */ |
| 606 class SourceFactory { | 607 abstract class SourceFactory { |
| 607 /** | 608 /** |
| 608 * The analysis context that this source factory is associated with. | 609 * The analysis context that this source factory is associated with. |
| 609 */ | 610 */ |
| 610 AnalysisContext context; | 611 AnalysisContext context; |
| 611 | 612 |
| 612 /** | 613 /** |
| 613 * URI processor used to find mappings for `package:` URIs found in a `.packag
es` config | 614 * Initialize a newly created source factory with the given absolute URI |
| 614 * file. | 615 * [resolvers] and optional [packages] resolution helper. |
| 615 */ | 616 */ |
| 616 final Packages _packages; | 617 factory SourceFactory(List<UriResolver> resolvers, |
| 618 [Packages packages, |
| 619 ResourceProvider resourceProvider]) = SourceFactoryImpl; |
| 617 | 620 |
| 618 /** | 621 /** |
| 619 * Resource provider used in working with package maps. | 622 * Return the [DartSdk] associated with this [SourceFactory], or `null` if |
| 620 */ | 623 * there is no such SDK. |
| 621 final ResourceProvider _resourceProvider; | |
| 622 | |
| 623 /** | |
| 624 * The resolvers used to resolve absolute URI's. | |
| 625 */ | |
| 626 final List<UriResolver> _resolvers; | |
| 627 | |
| 628 /** | |
| 629 * The predicate to determine is [Source] is local. | |
| 630 */ | |
| 631 LocalSourcePredicate _localSourcePredicate = LocalSourcePredicate.NOT_SDK; | |
| 632 | |
| 633 /** | |
| 634 * Initialize a newly created source factory with the given absolute URI [reso
lvers] and | |
| 635 * optional [packages] resolution helper. | |
| 636 */ | |
| 637 SourceFactory(this._resolvers, | |
| 638 [this._packages, ResourceProvider resourceProvider]) | |
| 639 : _resourceProvider = resourceProvider != null | |
| 640 ? resourceProvider | |
| 641 : PhysicalResourceProvider.INSTANCE; | |
| 642 | |
| 643 /** | |
| 644 * Return the [DartSdk] associated with this [SourceFactory], or `null` if the
re | |
| 645 * is no such SDK. | |
| 646 * | 624 * |
| 647 * @return the [DartSdk] associated with this [SourceFactory], or `null` if | 625 * @return the [DartSdk] associated with this [SourceFactory], or `null` if |
| 648 * there is no such SDK | 626 * there is no such SDK |
| 649 */ | 627 */ |
| 650 DartSdk get dartSdk { | 628 DartSdk get dartSdk; |
| 651 for (UriResolver resolver in _resolvers) { | |
| 652 if (resolver is DartUriResolver) { | |
| 653 DartUriResolver dartUriResolver = resolver; | |
| 654 return dartUriResolver.dartSdk; | |
| 655 } | |
| 656 } | |
| 657 return null; | |
| 658 } | |
| 659 | 629 |
| 660 /** | 630 /** |
| 661 * Sets the [LocalSourcePredicate]. | 631 * Sets the [LocalSourcePredicate]. |
| 662 * | 632 * |
| 663 * @param localSourcePredicate the predicate to determine is [Source] is local | 633 * @param localSourcePredicate the predicate to determine is [Source] is local |
| 664 */ | 634 */ |
| 665 void set localSourcePredicate(LocalSourcePredicate localSourcePredicate) { | 635 void set localSourcePredicate(LocalSourcePredicate localSourcePredicate); |
| 666 this._localSourcePredicate = localSourcePredicate; | |
| 667 } | |
| 668 | 636 |
| 669 /// A table mapping package names to paths of directories containing | 637 /// A table mapping package names to paths of directories containing |
| 670 /// the package (or [null] if there is no registered package URI resolver). | 638 /// the package (or [null] if there is no registered package URI resolver). |
| 671 Map<String, List<Folder>> get packageMap { | 639 Map<String, List<Folder>> get packageMap; |
| 672 // Start by looking in .packages. | |
| 673 if (_packages != null) { | |
| 674 Map<String, List<Folder>> packageMap = <String, List<Folder>>{}; | |
| 675 _packages.asMap().forEach((String name, Uri uri) { | |
| 676 if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) { | |
| 677 packageMap[name] = <Folder>[ | |
| 678 _resourceProvider.getFolder(uri.toFilePath()) | |
| 679 ]; | |
| 680 } | |
| 681 }); | |
| 682 return packageMap; | |
| 683 } | |
| 684 | |
| 685 // Default to the PackageMapUriResolver. | |
| 686 PackageMapUriResolver resolver = _resolvers | |
| 687 .firstWhere((r) => r is PackageMapUriResolver, orElse: () => null); | |
| 688 return resolver != null ? resolver.packageMap : null; | |
| 689 } | |
| 690 | 640 |
| 691 /** | 641 /** |
| 692 * Return a source factory that will resolve URI's in the same way that this | 642 * Return a source factory that will resolve URI's in the same way that this |
| 693 * source factory does. | 643 * source factory does. |
| 694 */ | 644 */ |
| 695 SourceFactory clone() { | 645 SourceFactory clone(); |
| 696 SourceFactory factory = | |
| 697 new SourceFactory(_resolvers, _packages, _resourceProvider); | |
| 698 factory.localSourcePredicate = _localSourcePredicate; | |
| 699 return factory; | |
| 700 } | |
| 701 | 646 |
| 702 /** | 647 /** |
| 703 * Return a source object representing the given absolute URI, or `null` if th
e URI is not a | 648 * Return a source object representing the given absolute URI, or `null` if |
| 704 * valid URI or if it is not an absolute URI. | 649 * the URI is not a valid URI or if it is not an absolute URI. |
| 705 * | 650 * |
| 706 * @param absoluteUri the absolute URI to be resolved | 651 * @param absoluteUri the absolute URI to be resolved |
| 707 * @return a source object representing the absolute URI | 652 * @return a source object representing the absolute URI |
| 708 */ | 653 */ |
| 709 Source forUri(String absoluteUri) { | 654 Source forUri(String absoluteUri); |
| 710 try { | |
| 711 Uri uri = parseUriWithException(absoluteUri); | |
| 712 if (uri.isAbsolute) { | |
| 713 return _internalResolveUri(null, uri); | |
| 714 } | |
| 715 } catch (exception, stackTrace) { | |
| 716 AnalysisEngine.instance.logger.logError( | |
| 717 "Could not resolve URI: $absoluteUri", | |
| 718 new CaughtException(exception, stackTrace)); | |
| 719 } | |
| 720 return null; | |
| 721 } | |
| 722 | 655 |
| 723 /** | 656 /** |
| 724 * Return a source object representing the given absolute URI, or `null` if th
e URI is not | 657 * Return a source object representing the given absolute URI, or `null` if |
| 725 * an absolute URI. | 658 * the URI is not an absolute URI. |
| 726 * | 659 * |
| 727 * @param absoluteUri the absolute URI to be resolved | 660 * @param absoluteUri the absolute URI to be resolved |
| 728 * @return a source object representing the absolute URI | 661 * @return a source object representing the absolute URI |
| 729 */ | 662 */ |
| 730 Source forUri2(Uri absoluteUri) { | 663 Source forUri2(Uri absoluteUri); |
| 731 if (absoluteUri.isAbsolute) { | |
| 732 try { | |
| 733 return _internalResolveUri(null, absoluteUri); | |
| 734 } on AnalysisException catch (exception, stackTrace) { | |
| 735 AnalysisEngine.instance.logger.logError( | |
| 736 "Could not resolve URI: $absoluteUri", | |
| 737 new CaughtException(exception, stackTrace)); | |
| 738 } | |
| 739 } | |
| 740 return null; | |
| 741 } | |
| 742 | 664 |
| 743 /** | 665 /** |
| 744 * Return a source object that is equal to the source object used to obtain th
e given encoding. | 666 * Return a source object that is equal to the source object used to obtain |
| 667 * the given encoding. |
| 745 * | 668 * |
| 746 * @param encoding the encoding of a source object | 669 * @param encoding the encoding of a source object |
| 747 * @return a source object that is described by the given encoding | 670 * @return a source object that is described by the given encoding |
| 748 * @throws IllegalArgumentException if the argument is not a valid encoding | 671 * @throws IllegalArgumentException if the argument is not a valid encoding |
| 749 * See [Source.encoding]. | 672 * See [Source.encoding]. |
| 750 */ | 673 */ |
| 751 Source fromEncoding(String encoding) { | 674 Source fromEncoding(String encoding); |
| 752 Source source = forUri(encoding); | |
| 753 if (source == null) { | |
| 754 throw new IllegalArgumentException( | |
| 755 "Invalid source encoding: '$encoding'"); | |
| 756 } | |
| 757 return source; | |
| 758 } | |
| 759 | 675 |
| 760 /** | 676 /** |
| 761 * Determines if the given [Source] is local. | 677 * Determines if the given [Source] is local. |
| 762 * | 678 * |
| 763 * @param source the [Source] to analyze | 679 * @param source the [Source] to analyze |
| 764 * @return `true` if the given [Source] is local | 680 * @return `true` if the given [Source] is local |
| 765 */ | 681 */ |
| 766 bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source); | 682 bool isLocalSource(Source source); |
| 767 | 683 |
| 768 /** | 684 /** |
| 769 * Return a source representing the URI that results from resolving the given | 685 * Return a source representing the URI that results from resolving the given |
| 770 * (possibly relative) [containedUri] against the URI associated with the | 686 * (possibly relative) [containedUri] against the URI associated with the |
| 771 * [containingSource], whether or not the resulting source exists, or `null` | 687 * [containingSource], whether or not the resulting source exists, or `null` |
| 772 * if either the [containedUri] is invalid or if it cannot be resolved against | 688 * if either the [containedUri] is invalid or if it cannot be resolved against |
| 773 * the [containingSource]'s URI. | 689 * the [containingSource]'s URI. |
| 774 */ | 690 */ |
| 775 Source resolveUri(Source containingSource, String containedUri) { | 691 Source resolveUri(Source containingSource, String containedUri); |
| 776 if (containedUri == null || containedUri.isEmpty) { | |
| 777 return null; | |
| 778 } | |
| 779 try { | |
| 780 // Force the creation of an escaped URI to deal with spaces, etc. | |
| 781 return _internalResolveUri( | |
| 782 containingSource, parseUriWithException(containedUri)); | |
| 783 } on URISyntaxException { | |
| 784 return null; | |
| 785 } catch (exception, stackTrace) { | |
| 786 String containingFullName = | |
| 787 containingSource != null ? containingSource.fullName : '<null>'; | |
| 788 AnalysisEngine.instance.logger.logInformation( | |
| 789 "Could not resolve URI ($containedUri) relative to source ($containing
FullName)", | |
| 790 new CaughtException(exception, stackTrace)); | |
| 791 return null; | |
| 792 } | |
| 793 } | |
| 794 | 692 |
| 795 /** | 693 /** |
| 796 * Return an absolute URI that represents the given source, or `null` if a val
id URI cannot | 694 * Return an absolute URI that represents the given source, or `null` if a |
| 797 * be computed. | 695 * valid URI cannot be computed. |
| 798 * | 696 * |
| 799 * @param source the source to get URI for | 697 * @param source the source to get URI for |
| 800 * @return the absolute URI representing the given source | 698 * @return the absolute URI representing the given source |
| 801 */ | 699 */ |
| 802 Uri restoreUri(Source source) { | 700 Uri restoreUri(Source source); |
| 803 // First see if a resolver can restore the URI. | |
| 804 for (UriResolver resolver in _resolvers) { | |
| 805 Uri uri = resolver.restoreAbsolute(source); | |
| 806 if (uri != null) { | |
| 807 // Now see if there's a package mapping. | |
| 808 Uri packageMappedUri = _getPackageMapping(uri); | |
| 809 if (packageMappedUri != null) { | |
| 810 return packageMappedUri; | |
| 811 } | |
| 812 // Fall back to the resolver's computed URI. | |
| 813 return uri; | |
| 814 } | |
| 815 } | |
| 816 | |
| 817 return null; | |
| 818 } | |
| 819 | |
| 820 Uri _getPackageMapping(Uri sourceUri) { | |
| 821 if (_packages == null) { | |
| 822 return null; | |
| 823 } | |
| 824 if (sourceUri.scheme != 'file') { | |
| 825 //TODO(pquitslund): verify this works for non-file URIs. | |
| 826 return null; | |
| 827 } | |
| 828 | |
| 829 Uri packageUri; | |
| 830 _packages.asMap().forEach((String name, Uri uri) { | |
| 831 if (packageUri == null) { | |
| 832 if (utils.startsWith(sourceUri, uri)) { | |
| 833 packageUri = Uri.parse( | |
| 834 'package:$name/${sourceUri.path.substring(uri.path.length)}'); | |
| 835 } | |
| 836 } | |
| 837 }); | |
| 838 return packageUri; | |
| 839 } | |
| 840 | |
| 841 /** | |
| 842 * Return a source object representing the URI that results from resolving the
given (possibly | |
| 843 * relative) contained URI against the URI associated with an existing source
object, or | |
| 844 * `null` if the URI could not be resolved. | |
| 845 * | |
| 846 * @param containingSource the source containing the given URI | |
| 847 * @param containedUri the (possibly relative) URI to be resolved against the
containing source | |
| 848 * @return the source representing the contained URI | |
| 849 * @throws AnalysisException if either the contained URI is invalid or if it c
annot be resolved | |
| 850 * against the source object's URI | |
| 851 */ | |
| 852 Source _internalResolveUri(Source containingSource, Uri containedUri) { | |
| 853 if (!containedUri.isAbsolute) { | |
| 854 if (containingSource == null) { | |
| 855 throw new AnalysisException( | |
| 856 "Cannot resolve a relative URI without a containing source: $contain
edUri"); | |
| 857 } | |
| 858 containedUri = containingSource.resolveRelativeUri(containedUri); | |
| 859 } | |
| 860 | |
| 861 Uri actualUri = containedUri; | |
| 862 | |
| 863 // Check .packages and update target and actual URIs as appropriate. | |
| 864 if (_packages != null && containedUri.scheme == 'package') { | |
| 865 Uri packageUri = null; | |
| 866 try { | |
| 867 packageUri = | |
| 868 _packages.resolve(containedUri, notFound: (Uri packageUri) => null); | |
| 869 } on ArgumentError { | |
| 870 // Fall through to try resolvers. | |
| 871 } | |
| 872 | |
| 873 if (packageUri != null) { | |
| 874 // Ensure scheme is set. | |
| 875 if (packageUri.scheme == '') { | |
| 876 packageUri = packageUri.replace(scheme: 'file'); | |
| 877 } | |
| 878 containedUri = packageUri; | |
| 879 } | |
| 880 } | |
| 881 | |
| 882 for (UriResolver resolver in _resolvers) { | |
| 883 Source result = resolver.resolveAbsolute(containedUri, actualUri); | |
| 884 if (result != null) { | |
| 885 return result; | |
| 886 } | |
| 887 } | |
| 888 | |
| 889 return null; | |
| 890 } | |
| 891 } | 701 } |
| 892 | 702 |
| 893 /** | 703 /** |
| 894 * The enumeration `SourceKind` defines the different kinds of sources that are
known to the | 704 * The enumeration `SourceKind` defines the different kinds of sources that are |
| 895 * analysis engine. | 705 * known to the analysis engine. |
| 896 */ | 706 */ |
| 897 class SourceKind extends Enum<SourceKind> { | 707 class SourceKind extends Enum<SourceKind> { |
| 898 /** | 708 /** |
| 899 * A source containing HTML. The HTML might or might not contain Dart scripts. | 709 * A source containing HTML. The HTML might or might not contain Dart scripts. |
| 900 */ | 710 */ |
| 901 static const SourceKind HTML = const SourceKind('HTML', 0); | 711 static const SourceKind HTML = const SourceKind('HTML', 0); |
| 902 | 712 |
| 903 /** | 713 /** |
| 904 * A Dart compilation unit that is not a part of another library. Libraries mi
ght or might not | 714 * A Dart compilation unit that is not a part of another library. Libraries |
| 905 * contain any directives, including a library directive. | 715 * might or might not contain any directives, including a library directive. |
| 906 */ | 716 */ |
| 907 static const SourceKind LIBRARY = const SourceKind('LIBRARY', 1); | 717 static const SourceKind LIBRARY = const SourceKind('LIBRARY', 1); |
| 908 | 718 |
| 909 /** | 719 /** |
| 910 * A Dart compilation unit that is part of another library. Parts contain a pa
rt-of directive. | 720 * A Dart compilation unit that is part of another library. Parts contain a |
| 721 * part-of directive. |
| 911 */ | 722 */ |
| 912 static const SourceKind PART = const SourceKind('PART', 2); | 723 static const SourceKind PART = const SourceKind('PART', 2); |
| 913 | 724 |
| 914 /** | 725 /** |
| 915 * An unknown kind of source. Used both when it is not possible to identify th
e kind of a source | 726 * An unknown kind of source. Used both when it is not possible to identify |
| 916 * and also when the kind of a source is not known without performing a comput
ation and the client | 727 * the kind of a source and also when the kind of a source is not known |
| 917 * does not want to spend the time to identify the kind. | 728 * without performing a computation and the client does not want to spend the |
| 729 * time to identify the kind. |
| 918 */ | 730 */ |
| 919 static const SourceKind UNKNOWN = const SourceKind('UNKNOWN', 3); | 731 static const SourceKind UNKNOWN = const SourceKind('UNKNOWN', 3); |
| 920 | 732 |
| 921 static const List<SourceKind> values = const [HTML, LIBRARY, PART, UNKNOWN]; | 733 static const List<SourceKind> values = const [HTML, LIBRARY, PART, UNKNOWN]; |
| 922 | 734 |
| 923 const SourceKind(String name, int ordinal) : super(name, ordinal); | 735 const SourceKind(String name, int ordinal) : super(name, ordinal); |
| 924 } | 736 } |
| 925 | 737 |
| 926 /** | 738 /** |
| 927 * A source range defines an [Element]'s source coordinates relative to its [Sou
rce]. | 739 * A source range defines an [Element]'s source coordinates relative to its [Sou
rce]. |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 Source resolveAbsolute(Uri uri, [Uri actualUri]); | 936 Source resolveAbsolute(Uri uri, [Uri actualUri]); |
| 1125 | 937 |
| 1126 /** | 938 /** |
| 1127 * Return an absolute URI that represents the given [source], or `null` if a | 939 * Return an absolute URI that represents the given [source], or `null` if a |
| 1128 * valid URI cannot be computed. | 940 * valid URI cannot be computed. |
| 1129 * | 941 * |
| 1130 * The computation should be based solely on [source.fullName]. | 942 * The computation should be based solely on [source.fullName]. |
| 1131 */ | 943 */ |
| 1132 Uri restoreAbsolute(Source source) => null; | 944 Uri restoreAbsolute(Source source) => null; |
| 1133 } | 945 } |
| OLD | NEW |