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 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 | 9 |
10 import 'package:analysis_server/src/analysis_server.dart'; | 10 import 'package:analysis_server/src/analysis_server.dart'; |
| 11 import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.d
art'; |
11 import 'package:analyzer/file_system/file_system.dart'; | 12 import 'package:analyzer/file_system/file_system.dart'; |
12 import 'package:analyzer/instrumentation/instrumentation.dart'; | 13 import 'package:analyzer/instrumentation/instrumentation.dart'; |
13 import 'package:analyzer/source/package_map_provider.dart'; | |
14 import 'package:analyzer/source/package_map_resolver.dart'; | 14 import 'package:analyzer/source/package_map_resolver.dart'; |
15 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
16 import 'package:analyzer/src/generated/java_io.dart'; | 16 import 'package:analyzer/src/generated/java_io.dart'; |
17 import 'package:analyzer/src/generated/source.dart'; | 17 import 'package:analyzer/src/generated/source.dart'; |
18 import 'package:analyzer/src/generated/source_io.dart'; | 18 import 'package:analyzer/src/generated/source_io.dart'; |
19 import 'package:path/path.dart' as pathos; | 19 import 'package:path/path.dart' as pathos; |
20 import 'package:watcher/watcher.dart'; | 20 import 'package:watcher/watcher.dart'; |
21 | 21 |
22 /** | 22 /** |
23 * The name of `packages` folders. | 23 * The name of `packages` folders. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 /** | 75 /** |
76 * Same as [packageRoots], except that source folders have been normalized | 76 * Same as [packageRoots], except that source folders have been normalized |
77 * and non-folders have been removed. | 77 * and non-folders have been removed. |
78 */ | 78 */ |
79 Map<String, String> normalizedPackageRoots = <String, String>{}; | 79 Map<String, String> normalizedPackageRoots = <String, String>{}; |
80 | 80 |
81 /** | 81 /** |
82 * Provider which is used to determine the mapping from package name to | 82 * Provider which is used to determine the mapping from package name to |
83 * package folder. | 83 * package folder. |
84 */ | 84 */ |
85 final PackageMapProvider _packageMapProvider; | 85 final OptimizingPubPackageMapProvider _packageMapProvider; |
86 | 86 |
87 /** | 87 /** |
88 * The instrumentation service used to report instrumentation data. | 88 * The instrumentation service used to report instrumentation data. |
89 */ | 89 */ |
90 final InstrumentationService _instrumentationService; | 90 final InstrumentationService _instrumentationService; |
91 | 91 |
92 ContextManager(this.resourceProvider, this._packageMapProvider, | 92 ContextManager(this.resourceProvider, this._packageMapProvider, |
93 this._instrumentationService) { | 93 this._instrumentationService) { |
94 pathContext = resourceProvider.pathContext; | 94 pathContext = resourceProvider.pathContext; |
95 } | 95 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 if (context != contextN) { | 130 if (context != contextN) { |
131 for (Source source in contextN.sources) { | 131 for (Source source in contextN.sources) { |
132 flushedFiles.remove(source.fullName); | 132 flushedFiles.remove(source.fullName); |
133 } | 133 } |
134 } | 134 } |
135 } | 135 } |
136 return flushedFiles.toList(growable: false); | 136 return flushedFiles.toList(growable: false); |
137 } | 137 } |
138 | 138 |
139 /** | 139 /** |
| 140 * Return a list containing all of the contexts contained in the given |
| 141 * [analysisRoot]. |
| 142 */ |
| 143 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) { |
| 144 List<AnalysisContext> contexts = <AnalysisContext>[]; |
| 145 _contexts.forEach((Folder contextFolder, _ContextInfo info) { |
| 146 if (analysisRoot.isOrContains(contextFolder.path)) { |
| 147 contexts.add(info.context); |
| 148 } |
| 149 }); |
| 150 return contexts; |
| 151 } |
| 152 |
| 153 /** |
140 * We have finished computing the package map. | 154 * We have finished computing the package map. |
141 */ | 155 */ |
142 void endComputePackageMap() { | 156 void endComputePackageMap() { |
143 // Do nothing. | 157 // Do nothing. |
144 } | 158 } |
145 | 159 |
146 /** | 160 /** |
147 * Returns `true` if the given absolute [path] is in one of the current | 161 * Returns `true` if the given absolute [path] is in one of the current |
148 * root folders and is not excluded. | 162 * root folders and is not excluded. |
149 */ | 163 */ |
150 bool isInAnalysisRoot(String path) { | 164 bool isInAnalysisRoot(String path) { |
151 // check if excluded | 165 // check if excluded |
152 if (_isExcluded(path)) { | 166 if (_isExcluded(path)) { |
153 return false; | 167 return false; |
154 } | 168 } |
155 // check if in of the roots | 169 // check if in of the roots |
156 for (Folder root in _contexts.keys) { | 170 for (Folder root in _contexts.keys) { |
157 if (root.contains(path)) { | 171 if (root.contains(path)) { |
158 return true; | 172 return true; |
159 } | 173 } |
160 } | 174 } |
161 // no | 175 // no |
162 return false; | 176 return false; |
163 } | 177 } |
164 | 178 |
165 /** | 179 /** |
166 * Return a list containing all of the contexts contained in the given | |
167 * [analysisRoot]. | |
168 */ | |
169 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) { | |
170 List<AnalysisContext> contexts = <AnalysisContext>[]; | |
171 _contexts.forEach((Folder contextFolder, _ContextInfo info) { | |
172 if (analysisRoot.isOrContains(contextFolder.path)) { | |
173 contexts.add(info.context); | |
174 } | |
175 }); | |
176 return contexts; | |
177 } | |
178 | |
179 /** | |
180 * Rebuild the set of contexts from scratch based on the data last sent to | 180 * Rebuild the set of contexts from scratch based on the data last sent to |
181 * setRoots(). Only contexts contained in the given list of analysis [roots] | 181 * setRoots(). Only contexts contained in the given list of analysis [roots] |
182 * will be rebuilt, unless the list is `null`, in which case every context | 182 * will be rebuilt, unless the list is `null`, in which case every context |
183 * will be rebuilt. | 183 * will be rebuilt. |
184 */ | 184 */ |
185 void refresh(List<Resource> roots) { | 185 void refresh(List<Resource> roots) { |
186 // Destroy old contexts | 186 // Destroy old contexts |
187 List<Folder> contextFolders = _contexts.keys.toList(); | 187 List<Folder> contextFolders = _contexts.keys.toList(); |
188 if (roots == null) { | 188 if (roots == null) { |
189 contextFolders.forEach(_destroyContext); | 189 contextFolders.forEach(_destroyContext); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 } | 381 } |
382 } | 382 } |
383 | 383 |
384 /** | 384 /** |
385 * Compute the appropriate package URI resolver for [folder], and store | 385 * Compute the appropriate package URI resolver for [folder], and store |
386 * dependency information in [info]. Return `null` if no package map can | 386 * dependency information in [info]. Return `null` if no package map can |
387 * be computed. | 387 * be computed. |
388 */ | 388 */ |
389 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { | 389 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { |
390 if (info.packageRoot != null) { | 390 if (info.packageRoot != null) { |
391 info.packageMapDependencies = new Set<String>(); | 391 info.packageMapInfo = null; |
392 return new PackageUriResolver([new JavaFile(info.packageRoot)]); | 392 return new PackageUriResolver([new JavaFile(info.packageRoot)]); |
393 } else { | 393 } else { |
394 beginComputePackageMap(); | 394 beginComputePackageMap(); |
395 PackageMapInfo packageMapInfo; | 395 OptimizingPubPackageMapInfo packageMapInfo; |
396 ServerPerformanceStatistics.pub.makeCurrentWhile(() { | 396 ServerPerformanceStatistics.pub.makeCurrentWhile(() { |
397 packageMapInfo = _packageMapProvider.computePackageMap(folder); | 397 packageMapInfo = |
| 398 _packageMapProvider.computePackageMap(folder, info.packageMapInfo); |
398 }); | 399 }); |
399 endComputePackageMap(); | 400 endComputePackageMap(); |
400 info.packageMapDependencies = packageMapInfo.dependencies; | 401 info.packageMapInfo = packageMapInfo; |
401 if (packageMapInfo.packageMap == null) { | 402 if (packageMapInfo.packageMap == null) { |
402 return null; | 403 return null; |
403 } | 404 } |
404 return new PackageMapUriResolver( | 405 return new PackageMapUriResolver( |
405 resourceProvider, packageMapInfo.packageMap); | 406 resourceProvider, packageMapInfo.packageMap); |
406 // TODO(paulberry): if any of the dependencies is outside of [folder], | 407 // TODO(paulberry): if any of the dependencies is outside of [folder], |
407 // we'll need to watch their parent folders as well. | 408 // we'll need to watch their parent folders as well. |
408 } | 409 } |
409 } | 410 } |
410 | 411 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 if (!sources.isEmpty) { | 588 if (!sources.isEmpty) { |
588 ChangeSet changeSet = new ChangeSet(); | 589 ChangeSet changeSet = new ChangeSet(); |
589 sources.forEach((Source source) { | 590 sources.forEach((Source source) { |
590 changeSet.changedSource(source); | 591 changeSet.changedSource(source); |
591 }); | 592 }); |
592 applyChangesToContext(folder, changeSet); | 593 applyChangesToContext(folder, changeSet); |
593 } | 594 } |
594 break; | 595 break; |
595 } | 596 } |
596 | 597 |
597 if (info.packageMapDependencies.contains(path)) { | 598 if (info.packageMapInfo != null && |
| 599 info.packageMapInfo.isChangedDependency(path, resourceProvider)) { |
598 _recomputePackageUriResolver(info); | 600 _recomputePackageUriResolver(info); |
599 } | 601 } |
600 } | 602 } |
601 | 603 |
602 /** | 604 /** |
603 * Returns `true` if the given [path] is excluded by [excludedPaths]. | 605 * Returns `true` if the given [path] is excluded by [excludedPaths]. |
604 */ | 606 */ |
605 bool _isExcluded(String path) { | 607 bool _isExcluded(String path) { |
606 return _isExcludedBy(excludedPaths, path); | 608 return _isExcludedBy(excludedPaths, path); |
607 } | 609 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 */ | 739 */ |
738 AnalysisContext context; | 740 AnalysisContext context; |
739 | 741 |
740 /** | 742 /** |
741 * Map from full path to the [Source] object, for each source that has been | 743 * Map from full path to the [Source] object, for each source that has been |
742 * added to the context. | 744 * added to the context. |
743 */ | 745 */ |
744 Map<String, Source> sources = new HashMap<String, Source>(); | 746 Map<String, Source> sources = new HashMap<String, Source>(); |
745 | 747 |
746 /** | 748 /** |
747 * Dependencies of the context's package map. | 749 * Info returned by the last call to |
748 * If any of these files changes, the package map needs to be recomputed. | 750 * [OptimizingPubPackageMapProvider.computePackageMap], or `null` if the |
| 751 * package map hasn't been computed for this context yet. |
749 */ | 752 */ |
750 Set<String> packageMapDependencies; | 753 OptimizingPubPackageMapInfo packageMapInfo; |
751 | 754 |
752 _ContextInfo(this.folder, File pubspecFile, this.children, this.packageRoot) { | 755 _ContextInfo(this.folder, File pubspecFile, this.children, this.packageRoot) { |
753 pubspecPath = pubspecFile.path; | 756 pubspecPath = pubspecFile.path; |
754 for (_ContextInfo child in children) { | 757 for (_ContextInfo child in children) { |
755 child.parent = this; | 758 child.parent = this; |
756 } | 759 } |
757 } | 760 } |
758 | 761 |
759 /** | 762 /** |
760 * Returns `true` if this context is root folder based. | 763 * Returns `true` if this context is root folder based. |
(...skipping 16 matching lines...) Expand all Loading... |
777 return excludes(resource.path); | 780 return excludes(resource.path); |
778 } | 781 } |
779 | 782 |
780 /** | 783 /** |
781 * Returns `true` if [path] is the pubspec file of this context. | 784 * Returns `true` if [path] is the pubspec file of this context. |
782 */ | 785 */ |
783 bool isPubspec(String path) { | 786 bool isPubspec(String path) { |
784 return path == pubspecPath; | 787 return path == pubspecPath; |
785 } | 788 } |
786 } | 789 } |
OLD | NEW |