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

Side by Side Diff: pkg/analysis_server/lib/src/context_manager.dart

Issue 1258473003: Introduce FolderDisposition class hierarchy for use in ContextManagerCallback. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
OLDNEW
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 context.directory.manager; 5 library context.directory.manager;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:core' hide Resource; 10 import 'dart:core' hide Resource;
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 * created, destroyed or updated, (b) inform the client when "pub list" 237 * created, destroyed or updated, (b) inform the client when "pub list"
238 * operations are in progress, and (c) determine which files should be 238 * operations are in progress, and (c) determine which files should be
239 * analyzed. 239 * analyzed.
240 * 240 *
241 * TODO(paulberry): eliminate this interface, and instead have [ContextManager] 241 * TODO(paulberry): eliminate this interface, and instead have [ContextManager]
242 * operations return data structures describing how context state should be 242 * operations return data structures describing how context state should be
243 * modified. 243 * modified.
244 */ 244 */
245 abstract class ContextManagerCallbacks { 245 abstract class ContextManagerCallbacks {
246 /** 246 /**
247 * Create and return a new analysis context. 247 * Create and return a new analysis context, allowing [disposition] to govern
248 * details of how the context is to be created.
248 */ 249 */
249 AnalysisContext addContext( 250 AnalysisContext addContext(Folder folder, FolderDisposition disposition);
250 Folder folder, UriResolver packageUriResolver, Packages packages);
251 251
252 /** 252 /**
253 * Called when the set of files associated with a context have changed (or 253 * Called when the set of files associated with a context have changed (or
254 * some of those files have been modified). [changeSet] is the set of 254 * some of those files have been modified). [changeSet] is the set of
255 * changes that need to be applied to the context. 255 * changes that need to be applied to the context.
256 */ 256 */
257 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); 257 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
258 258
259 /** 259 /**
260 * Called when the ContextManager is about to start computing the package 260 * Called when the ContextManager is about to start computing the package
(...skipping 16 matching lines...) Expand all
277 * (they will no longer be analyzed by any context). 277 * (they will no longer be analyzed by any context).
278 */ 278 */
279 void removeContext(Folder folder, List<String> flushedFiles); 279 void removeContext(Folder folder, List<String> flushedFiles);
280 280
281 /** 281 /**
282 * Return `true` if the given [file] should be analyzed. 282 * Return `true` if the given [file] should be analyzed.
283 */ 283 */
284 bool shouldFileBeAnalyzed(File file); 284 bool shouldFileBeAnalyzed(File file);
285 285
286 /** 286 /**
287 * Called when the package map for a context has changed. 287 * Called when the disposition for a context has changed.
288 */ 288 */
289 void updateContextPackageUriResolver( 289 void updateContextPackageUriResolver(
290 Folder contextFolder, UriResolver packageUriResolver, Packages packages); 290 Folder contextFolder, FolderDisposition disposition);
291 } 291 }
292 292
293 /** 293 /**
294 * Class that maintains a mapping from included/excluded paths to a set of 294 * Class that maintains a mapping from included/excluded paths to a set of
295 * folders that should correspond to analysis contexts. 295 * folders that should correspond to analysis contexts.
296 */ 296 */
297 class ContextManagerImpl implements ContextManager { 297 class ContextManagerImpl implements ContextManager {
298 /** 298 /**
299 * Temporary flag to hide WIP .packages support (DEP 5). 299 * Temporary flag to hide WIP .packages support (DEP 5).
300 */ 300 */
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 }); 526 });
527 if (!isIncluded) { 527 if (!isIncluded) {
528 _destroyContext(contextInfo); 528 _destroyContext(contextInfo);
529 } 529 }
530 } 530 }
531 // Update package roots for existing contexts 531 // Update package roots for existing contexts
532 for (ContextInfo info in _rootInfo.descendants) { 532 for (ContextInfo info in _rootInfo.descendants) {
533 String newPackageRoot = normalizedPackageRoots[info.folder.path]; 533 String newPackageRoot = normalizedPackageRoots[info.folder.path];
534 if (info.packageRoot != newPackageRoot) { 534 if (info.packageRoot != newPackageRoot) {
535 info.packageRoot = newPackageRoot; 535 info.packageRoot = newPackageRoot;
536 _recomputePackageUriResolver(info); 536 _recomputeFolderDisposition(info);
537 } 537 }
538 } 538 }
539 // create new contexts 539 // create new contexts
540 for (Folder includedFolder in includedFolders) { 540 for (Folder includedFolder in includedFolders) {
541 bool wasIncluded = contextInfos.any((info) { 541 bool wasIncluded = contextInfos.any((info) {
542 return info.folder.isOrContains(includedFolder.path); 542 return info.folder.isOrContains(includedFolder.path);
543 }); 543 });
544 if (!wasIncluded) { 544 if (!wasIncluded) {
545 _createContexts(_rootInfo, includedFolder, false); 545 _createContexts(_rootInfo, includedFolder, false);
546 } 546 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 void _checkForPackagespecUpdate( 670 void _checkForPackagespecUpdate(
671 String path, ContextInfo info, Folder folder) { 671 String path, ContextInfo info, Folder folder) {
672 // Check to see if this is the .packages file for this context and if so, 672 // Check to see if this is the .packages file for this context and if so,
673 // update the context's source factory. 673 // update the context's source factory.
674 if (pathContext.basename(path) == PACKAGE_SPEC_NAME && 674 if (pathContext.basename(path) == PACKAGE_SPEC_NAME &&
675 info.isPathToPackageDescription(path)) { 675 info.isPathToPackageDescription(path)) {
676 File packagespec = resourceProvider.getFile(path); 676 File packagespec = resourceProvider.getFile(path);
677 if (packagespec.exists) { 677 if (packagespec.exists) {
678 Packages packages = _readPackagespec(packagespec); 678 Packages packages = _readPackagespec(packagespec);
679 if (packages != null) { 679 if (packages != null) {
680 callbacks.updateContextPackageUriResolver(folder, null, packages); 680 callbacks.updateContextPackageUriResolver(
681 folder, new PackagesFileDisposition(packages));
681 } 682 }
682 } 683 }
683 } 684 }
684 } 685 }
685 686
686 /** 687 /**
687 * Compute the set of files that are being flushed, this is defined as 688 * Compute the set of files that are being flushed, this is defined as
688 * the set of sources in the removed context (context.sources), that are 689 * the set of sources in the removed context (context.sources), that are
689 * orphaned by this context being removed (no other context includes this 690 * orphaned by this context being removed (no other context includes this
690 * file.) 691 * file.)
691 */ 692 */
692 List<String> _computeFlushedFiles(ContextInfo info) { 693 List<String> _computeFlushedFiles(ContextInfo info) {
693 AnalysisContext context = info.context; 694 AnalysisContext context = info.context;
694 HashSet<String> flushedFiles = new HashSet<String>(); 695 HashSet<String> flushedFiles = new HashSet<String>();
695 for (Source source in context.sources) { 696 for (Source source in context.sources) {
696 flushedFiles.add(source.fullName); 697 flushedFiles.add(source.fullName);
697 } 698 }
698 for (ContextInfo contextInfo in _rootInfo.descendants) { 699 for (ContextInfo contextInfo in _rootInfo.descendants) {
699 AnalysisContext contextN = contextInfo.context; 700 AnalysisContext contextN = contextInfo.context;
700 if (context != contextN) { 701 if (context != contextN) {
701 for (Source source in contextN.sources) { 702 for (Source source in contextN.sources) {
702 flushedFiles.remove(source.fullName); 703 flushedFiles.remove(source.fullName);
703 } 704 }
704 } 705 }
705 } 706 }
706 return flushedFiles.toList(growable: false); 707 return flushedFiles.toList(growable: false);
707 } 708 }
708 709
709 /** 710 /**
710 * Compute the appropriate package URI resolver for [folder], and store 711 * Compute the appropriate [FolderDisposition] for [folder], and store
711 * dependency information in [info]. Return `null` if no package map can 712 * dependency information in [info].
712 * be computed.
713 */ 713 */
714 UriResolver _computePackageUriResolver(Folder folder, ContextInfo info) { 714 FolderDisposition _computeFolderDisposition(Folder folder, ContextInfo info) {
715 _cancelDependencySubscriptions(info); 715 _cancelDependencySubscriptions(info);
716 if (info.packageRoot != null) { 716 if (info.packageRoot != null) {
717 info.packageMapInfo = null; 717 info.packageMapInfo = null;
718 // TODO(paulberry): We shouldn't be using JavaFile here because it 718 // TODO(paulberry): We shouldn't be using JavaFile here because it
719 // makes the code untestable (see dartbug.com/23909). 719 // makes the code untestable (see dartbug.com/23909).
720 JavaFile packagesDir = new JavaFile(info.packageRoot); 720 JavaFile packagesDir = new JavaFile(info.packageRoot);
721 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>(); 721 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>();
722 if (packagesDir.isDirectory()) { 722 if (packagesDir.isDirectory()) {
723 for (JavaFile file in packagesDir.listFiles()) { 723 for (JavaFile file in packagesDir.listFiles()) {
724 // Ensure symlinks in packages directory are canonicalized 724 // Ensure symlinks in packages directory are canonicalized
725 // to prevent 'type X cannot be assigned to type X' warnings 725 // to prevent 'type X cannot be assigned to type X' warnings
726 String path; 726 String path;
727 try { 727 try {
728 path = file.getCanonicalPath(); 728 path = file.getCanonicalPath();
729 } catch (e, s) { 729 } catch (e, s) {
730 // Ignore packages that do not exist 730 // Ignore packages that do not exist
731 _instrumentationService.logException(e, s); 731 _instrumentationService.logException(e, s);
732 continue; 732 continue;
733 } 733 }
734 Resource res = resourceProvider.getResource(path); 734 Resource res = resourceProvider.getResource(path);
735 if (res is Folder) { 735 if (res is Folder) {
736 packageMap[file.getName()] = <Folder>[res]; 736 packageMap[file.getName()] = <Folder>[res];
737 } 737 }
738 } 738 }
739 return new PackageMapUriResolver(resourceProvider, packageMap); 739 return new PackageMapDisposition(packageMap);
740 } 740 }
741 // The package root does not exist (or is not a folder). Since 741 // The package root does not exist (or is not a folder). Since
742 // [setRoots] ignores any package roots that don't exist (or aren't 742 // [setRoots] ignores any package roots that don't exist (or aren't
743 // folders), the only way we should be able to get here is due to a race 743 // folders), the only way we should be able to get here is due to a race
744 // condition. In any case, the package root folder is gone, so we can't 744 // condition. In any case, the package root folder is gone, so we can't
745 // resolve packages. 745 // resolve packages.
746 return null; 746 return new NoPackageFolderDisposition();
747 } else { 747 } else {
748 callbacks.beginComputePackageMap(); 748 callbacks.beginComputePackageMap();
749 if (packageResolverProvider != null) { 749 if (packageResolverProvider != null) {
750 UriResolver resolver = packageResolverProvider(folder); 750 UriResolver resolver = packageResolverProvider(folder);
751 if (resolver != null) { 751 if (resolver != null) {
752 return resolver; 752 return new CustomPackageResolverDisposition(resolver);
753 } 753 }
754 } 754 }
755 OptimizingPubPackageMapInfo packageMapInfo; 755 OptimizingPubPackageMapInfo packageMapInfo;
756 ServerPerformanceStatistics.pub.makeCurrentWhile(() { 756 ServerPerformanceStatistics.pub.makeCurrentWhile(() {
757 packageMapInfo = 757 packageMapInfo =
758 _packageMapProvider.computePackageMap(folder, info.packageMapInfo); 758 _packageMapProvider.computePackageMap(folder, info.packageMapInfo);
759 }); 759 });
760 callbacks.endComputePackageMap(); 760 callbacks.endComputePackageMap();
761 for (String dependencyPath in packageMapInfo.dependencies) { 761 for (String dependencyPath in packageMapInfo.dependencies) {
762 Resource resource = resourceProvider.getResource(dependencyPath); 762 Resource resource = resourceProvider.getResource(dependencyPath);
763 if (resource is File) { 763 if (resource is File) {
764 StreamSubscription<WatchEvent> subscription; 764 StreamSubscription<WatchEvent> subscription;
765 subscription = resource.changes.listen((WatchEvent event) { 765 subscription = resource.changes.listen((WatchEvent event) {
766 if (info.packageMapInfo != null && 766 if (info.packageMapInfo != null &&
767 info.packageMapInfo.isChangedDependency( 767 info.packageMapInfo.isChangedDependency(
768 dependencyPath, resourceProvider)) { 768 dependencyPath, resourceProvider)) {
769 _recomputePackageUriResolver(info); 769 _recomputeFolderDisposition(info);
770 } 770 }
771 }, onError: (error, StackTrace stackTrace) { 771 }, onError: (error, StackTrace stackTrace) {
772 // Gracefully degrade if file is or becomes unwatchable 772 // Gracefully degrade if file is or becomes unwatchable
773 _instrumentationService.logException(error, stackTrace); 773 _instrumentationService.logException(error, stackTrace);
774 subscription.cancel(); 774 subscription.cancel();
775 info.dependencySubscriptions.remove(subscription); 775 info.dependencySubscriptions.remove(subscription);
776 }); 776 });
777 info.dependencySubscriptions.add(subscription); 777 info.dependencySubscriptions.add(subscription);
778 } 778 }
779 } 779 }
780 info.packageMapInfo = packageMapInfo; 780 info.packageMapInfo = packageMapInfo;
781 if (packageMapInfo.packageMap == null) { 781 if (packageMapInfo.packageMap == null) {
782 return null; 782 return new NoPackageFolderDisposition();
783 } 783 }
784 return new PackageMapUriResolver( 784 return new PackageMapDisposition(packageMapInfo.packageMap);
785 resourceProvider, packageMapInfo.packageMap);
786 // TODO(paulberry): if any of the dependencies is outside of [folder],
787 // we'll need to watch their parent folders as well.
788 } 785 }
789 } 786 }
790 787
791 /** 788 /**
792 * Create a new empty context associated with [folder], having parent 789 * Create a new empty context associated with [folder], having parent
793 * [parent] and using [packagespecFile] to resolve package URI's. 790 * [parent] and using [packagespecFile] to resolve package URI's.
794 */ 791 */
795 ContextInfo _createContext( 792 ContextInfo _createContext(
796 ContextInfo parent, Folder folder, File packagespecFile) { 793 ContextInfo parent, Folder folder, File packagespecFile) {
797 ContextInfo info = new ContextInfo( 794 ContextInfo info = new ContextInfo(
798 parent, folder, packagespecFile, normalizedPackageRoots[folder.path]); 795 parent, folder, packagespecFile, normalizedPackageRoots[folder.path]);
799 Map<String, YamlNode> options = analysisOptionsProvider.getOptions(folder); 796 Map<String, YamlNode> options = analysisOptionsProvider.getOptions(folder);
800 processOptionsForContext(info, options); 797 processOptionsForContext(info, options);
801 info.changeSubscription = folder.changes.listen((WatchEvent event) { 798 info.changeSubscription = folder.changes.listen((WatchEvent event) {
802 _handleWatchEvent(folder, info, event); 799 _handleWatchEvent(folder, info, event);
803 }); 800 });
804 try { 801 try {
805 Packages packages; 802 FolderDisposition disposition;
806 UriResolver packageUriResolver;
807 803
808 if (ENABLE_PACKAGESPEC_SUPPORT) { 804 if (ENABLE_PACKAGESPEC_SUPPORT) {
809 // Try .packages first. 805 // Try .packages first.
810 if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) { 806 if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
811 packages = _readPackagespec(packagespecFile); 807 Packages packages = _readPackagespec(packagespecFile);
808 disposition = new PackagesFileDisposition(packages);
812 } 809 }
813 } 810 }
814 811
815 // Next resort to a package uri resolver. 812 // Next resort to a package uri resolver.
816 if (packages == null) { 813 if (disposition == null) {
817 packageUriResolver = _computePackageUriResolver(folder, info); 814 disposition = _computeFolderDisposition(folder, info);
818 } 815 }
819 816
820 info.context = callbacks.addContext(folder, packageUriResolver, packages); 817 info.context = callbacks.addContext(folder, disposition);
821 info.context.name = folder.path; 818 info.context.name = folder.path;
822 } catch (_) { 819 } catch (_) {
823 info.changeSubscription.cancel(); 820 info.changeSubscription.cancel();
824 rethrow; 821 rethrow;
825 } 822 }
826 return info; 823 return info;
827 } 824 }
828 825
829 /** 826 /**
830 * Potentially create a new context associated with the given [folder]. 827 * Potentially create a new context associated with the given [folder].
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 callbacks.applyChangesToContext(folder, changeSet); 1083 callbacks.applyChangesToContext(folder, changeSet);
1087 } 1084 }
1088 break; 1085 break;
1089 } 1086 }
1090 1087
1091 //TODO(pquitslund): find the right place for this 1088 //TODO(pquitslund): find the right place for this
1092 _checkForPackagespecUpdate(path, info, folder); 1089 _checkForPackagespecUpdate(path, info, folder);
1093 1090
1094 if (info.packageMapInfo != null && 1091 if (info.packageMapInfo != null &&
1095 info.packageMapInfo.isChangedDependency(path, resourceProvider)) { 1092 info.packageMapInfo.isChangedDependency(path, resourceProvider)) {
1096 _recomputePackageUriResolver(info); 1093 _recomputeFolderDisposition(info);
1097 } 1094 }
1098 } 1095 }
1099 1096
1100 /** 1097 /**
1101 * Returns `true` if the given [path] is excluded by [excludedPaths]. 1098 * Returns `true` if the given [path] is excluded by [excludedPaths].
1102 */ 1099 */
1103 bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path); 1100 bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path);
1104 1101
1105 /** 1102 /**
1106 * Returns `true` if the given [path] is excluded by [excludedPaths]. 1103 * Returns `true` if the given [path] is excluded by [excludedPaths].
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 Map<String, Uri> map = 1151 Map<String, Uri> map =
1155 pkgfile.parse(UTF8.encode(contents), new Uri.file(specFile.path)); 1152 pkgfile.parse(UTF8.encode(contents), new Uri.file(specFile.path));
1156 return new MapPackages(map); 1153 return new MapPackages(map);
1157 } catch (_) { 1154 } catch (_) {
1158 //TODO(pquitslund): consider creating an error for the spec file. 1155 //TODO(pquitslund): consider creating an error for the spec file.
1159 return null; 1156 return null;
1160 } 1157 }
1161 } 1158 }
1162 1159
1163 /** 1160 /**
1164 * Recompute the package URI resolver for the context described by [info], 1161 * Recompute the [FolderDisposition] for the context described by [info],
1165 * and update the client appropriately. 1162 * and update the client appropriately.
1166 */ 1163 */
1167 void _recomputePackageUriResolver(ContextInfo info) { 1164 void _recomputeFolderDisposition(ContextInfo info) {
1168 // TODO(paulberry): when computePackageMap is changed into an 1165 // TODO(paulberry): when computePackageMap is changed into an
1169 // asynchronous API call, we'll want to suspend analysis for this context 1166 // asynchronous API call, we'll want to suspend analysis for this context
1170 // while we're rerunning "pub list", since any analysis we complete while 1167 // while we're rerunning "pub list", since any analysis we complete while
1171 // "pub list" is in progress is just going to get thrown away anyhow. 1168 // "pub list" is in progress is just going to get thrown away anyhow.
1172 UriResolver packageUriResolver = 1169 FolderDisposition disposition =
1173 _computePackageUriResolver(info.folder, info); 1170 _computeFolderDisposition(info.folder, info);
1174 callbacks.updateContextPackageUriResolver( 1171 callbacks.updateContextPackageUriResolver(info.folder, disposition);
1175 info.folder, packageUriResolver, null);
1176 } 1172 }
1177 1173
1178 /** 1174 /**
1179 * Create and return a source representing the given [file] within the given 1175 * Create and return a source representing the given [file] within the given
1180 * [context]. 1176 * [context].
1181 */ 1177 */
1182 static Source createSourceInContext(AnalysisContext context, File file) { 1178 static Source createSourceInContext(AnalysisContext context, File file) {
1183 // TODO(brianwilkerson) Optimize this, by allowing support for source 1179 // TODO(brianwilkerson) Optimize this, by allowing support for source
1184 // factories to restore URI's from a file path rather than a source. 1180 // factories to restore URI's from a file path rather than a source.
1185 Source source = file.createSource(); 1181 Source source = file.createSource();
(...skipping 29 matching lines...) Expand all
1215 */ 1211 */
1216 final List<AnalysisContext> removed; 1212 final List<AnalysisContext> removed;
1217 1213
1218 /** 1214 /**
1219 * Initialize a newly created event to indicate which contexts have changed. 1215 * Initialize a newly created event to indicate which contexts have changed.
1220 */ 1216 */
1221 ContextsChangedEvent({this.added: AnalysisContext.EMPTY_LIST, 1217 ContextsChangedEvent({this.added: AnalysisContext.EMPTY_LIST,
1222 this.changed: AnalysisContext.EMPTY_LIST, 1218 this.changed: AnalysisContext.EMPTY_LIST,
1223 this.removed: AnalysisContext.EMPTY_LIST}); 1219 this.removed: AnalysisContext.EMPTY_LIST});
1224 } 1220 }
1221
1222 /**
1223 * Concrete [FolderDisposition] object indicating that the context for a given
1224 * folder should resolve package URIs using a custom URI resolver.
1225 */
1226 class CustomPackageResolverDisposition extends FolderDisposition {
1227 /**
1228 * The [UriResolver] that should be used to resolve package URIs.
1229 */
1230 UriResolver resolver;
1231
1232 CustomPackageResolverDisposition(this.resolver);
1233
1234 @override
1235 Packages get packages => null;
1236
1237 @override
1238 Iterable<UriResolver> createPackageUriResolvers(
1239 ResourceProvider resourceProvider) => <UriResolver>[resolver];
1240 }
1241
1242 /**
1243 * An instance of the class [FolderDisposition] represents the information
1244 * gathered by the [ContextManagerImpl] to determine how to create an
1245 * [AnalysisContext] for a given folder.
1246 *
1247 * Note: [ContextManagerImpl] may use equality testing and hash codes to
1248 * determine when two folders should share the same context, so derived classes
1249 * may need to override operator== and hashCode() if object identity is
1250 * insufficient.
1251 *
1252 * TODO(paulberry): consider adding a flag to indicate that it is not necessary
1253 * to recurse into the given folder looking for additional contexts to create
1254 * or files to analyze (this could help avoid unnecessarily weighing down the
1255 * system with file watchers).
1256 */
1257 abstract class FolderDisposition {
1258 /**
1259 * If contexts governed by this [FolderDisposition] should resolve packages
1260 * using the ".packages" file mechanism (DEP 5), retrieve the [Packages]
1261 * object that resulted from parsing the ".packages" file.
1262 */
1263 Packages get packages;
1264
1265 /**
1266 * Create all the [UriResolver]s which should be used to resolve packages in
1267 * contexts governed by this [FolderDisposition].
1268 *
1269 * [resourceProvider] is provided since it is needed to construct most
1270 * [UriResolver]s.
1271 */
1272 Iterable<UriResolver> createPackageUriResolvers(
1273 ResourceProvider resourceProvider);
1274 }
1275
1276 /**
1277 * Concrete [FolderDisposition] object indicating that the context for a given
1278 * folder should not resolve "package:" URIs at all.
1279 *
1280 * TODO(paulberry): consider making this a singleton object (which would cause
1281 * all folders that don't resolve "package:" URIs to share the same context).
1282 */
1283 class NoPackageFolderDisposition extends FolderDisposition {
1284 @override
1285 Packages get packages => null;
1286
1287 @override
1288 Iterable<UriResolver> createPackageUriResolvers(
1289 ResourceProvider resourceProvider) => const <UriResolver>[];
1290 }
1291
1292 /**
1293 * Concrete [FolderDisposition] object indicating that the context for a given
1294 * folder should resolve packages using a package map.
1295 */
1296 class PackageMapDisposition extends FolderDisposition {
1297 final Map<String, List<Folder>> packageMap;
1298
1299 PackageMapDisposition(this.packageMap);
1300
1301 @override
1302 Packages get packages => null;
1303
1304 @override
1305 Iterable<UriResolver> createPackageUriResolvers(
1306 ResourceProvider resourceProvider) =>
1307 <UriResolver>[new PackageMapUriResolver(resourceProvider, packageMap)];
1308 }
1309
1310 /**
1311 * Concrete [FolderDisposition] object indicating that the context for a given
1312 * folder should resolve packages using a ".packages" file.
1313 */
1314 class PackagesFileDisposition extends FolderDisposition {
1315 @override
1316 final Packages packages;
1317
1318 PackagesFileDisposition(this.packages) {}
1319
1320 @override
1321 Iterable<UriResolver> createPackageUriResolvers(
1322 ResourceProvider resourceProvider) => const <UriResolver>[];
1323 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698