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'; |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 String shortName = child.shortName; | 380 String shortName = child.shortName; |
381 if (shortName == PACKAGES_NAME) { | 381 if (shortName == PACKAGES_NAME) { |
382 continue; | 382 continue; |
383 } | 383 } |
384 _addSourceFiles(changeSet, child, info); | 384 _addSourceFiles(changeSet, child, info); |
385 } | 385 } |
386 } | 386 } |
387 } | 387 } |
388 | 388 |
389 /** | 389 /** |
390 * Cancel all dependency subscriptions for the given context. | |
391 */ | |
392 void _cancelDependencySubscriptions(_ContextInfo info) { | |
393 for (StreamSubscription<WatchEvent> s in info.dependencySubscriptions) { | |
394 s.cancel(); | |
395 } | |
396 info.dependencySubscriptions.clear(); | |
397 } | |
398 | |
399 /** | |
390 * Compute the appropriate package URI resolver for [folder], and store | 400 * Compute the appropriate package URI resolver for [folder], and store |
391 * dependency information in [info]. Return `null` if no package map can | 401 * dependency information in [info]. Return `null` if no package map can |
392 * be computed. | 402 * be computed. |
393 */ | 403 */ |
394 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { | 404 UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) { |
405 _cancelDependencySubscriptions(info); | |
395 if (info.packageRoot != null) { | 406 if (info.packageRoot != null) { |
396 info.packageMapInfo = null; | 407 info.packageMapInfo = null; |
397 JavaFile packagesDir = new JavaFile(info.packageRoot); | 408 JavaFile packagesDir = new JavaFile(info.packageRoot); |
398 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>(); | 409 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>(); |
399 if (packagesDir.isDirectory()) { | 410 if (packagesDir.isDirectory()) { |
400 for (JavaFile file in packagesDir.listFiles()) { | 411 for (JavaFile file in packagesDir.listFiles()) { |
401 // Ensure symlinks in packages directory are canonicalized | 412 // Ensure symlinks in packages directory are canonicalized |
402 // to prevent 'type X cannot be assigned to type X' warnings | 413 // to prevent 'type X cannot be assigned to type X' warnings |
403 String path; | 414 String path; |
404 try { | 415 try { |
(...skipping 13 matching lines...) Expand all Loading... | |
418 //TODO(danrubel) remove this if it will never be called | 429 //TODO(danrubel) remove this if it will never be called |
419 return new PackageUriResolver([packagesDir]); | 430 return new PackageUriResolver([packagesDir]); |
420 } else { | 431 } else { |
421 beginComputePackageMap(); | 432 beginComputePackageMap(); |
422 OptimizingPubPackageMapInfo packageMapInfo; | 433 OptimizingPubPackageMapInfo packageMapInfo; |
423 ServerPerformanceStatistics.pub.makeCurrentWhile(() { | 434 ServerPerformanceStatistics.pub.makeCurrentWhile(() { |
424 packageMapInfo = | 435 packageMapInfo = |
425 _packageMapProvider.computePackageMap(folder, info.packageMapInfo); | 436 _packageMapProvider.computePackageMap(folder, info.packageMapInfo); |
426 }); | 437 }); |
427 endComputePackageMap(); | 438 endComputePackageMap(); |
439 for (String dependencyPath in packageMapInfo.dependencies) { | |
Paul Berry
2015/06/18 20:15:53
There's a small race condition here, which is that
| |
440 Resource resource = resourceProvider.getResource(dependencyPath); | |
441 if (resource is File) { | |
442 info.dependencySubscriptions.add(resource.changes | |
443 .listen((WatchEvent event) { | |
444 if (info.packageMapInfo != null && | |
445 info.packageMapInfo.isChangedDependency( | |
446 dependencyPath, resourceProvider)) { | |
447 _recomputePackageUriResolver(info); | |
448 } | |
449 })); | |
450 } | |
451 } | |
428 info.packageMapInfo = packageMapInfo; | 452 info.packageMapInfo = packageMapInfo; |
429 if (packageMapInfo.packageMap == null) { | 453 if (packageMapInfo.packageMap == null) { |
430 return null; | 454 return null; |
431 } | 455 } |
432 return new PackageMapUriResolver( | 456 return new PackageMapUriResolver( |
433 resourceProvider, packageMapInfo.packageMap); | 457 resourceProvider, packageMapInfo.packageMap); |
434 // TODO(paulberry): if any of the dependencies is outside of [folder], | 458 // TODO(paulberry): if any of the dependencies is outside of [folder], |
Paul Berry
2015/06/18 20:15:53
Remove this TODO.
| |
435 // we'll need to watch their parent folders as well. | 459 // we'll need to watch their parent folders as well. |
436 } | 460 } |
437 } | 461 } |
438 | 462 |
439 /** | 463 /** |
440 * Create a new empty context associated with [folder]. | 464 * Create a new empty context associated with [folder]. |
441 */ | 465 */ |
442 _ContextInfo _createContext( | 466 _ContextInfo _createContext( |
443 Folder folder, File pubspecFile, List<_ContextInfo> children) { | 467 Folder folder, File pubspecFile, List<_ContextInfo> children) { |
444 _ContextInfo info = new _ContextInfo( | 468 _ContextInfo info = new _ContextInfo( |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 ChangeSet changeSet = new ChangeSet(); | 530 ChangeSet changeSet = new ChangeSet(); |
507 _addSourceFiles(changeSet, folder, info); | 531 _addSourceFiles(changeSet, folder, info); |
508 applyChangesToContext(folder, changeSet); | 532 applyChangesToContext(folder, changeSet); |
509 return info; | 533 return info; |
510 } | 534 } |
511 | 535 |
512 /** | 536 /** |
513 * Clean up and destroy the context associated with the given folder. | 537 * Clean up and destroy the context associated with the given folder. |
514 */ | 538 */ |
515 void _destroyContext(Folder folder) { | 539 void _destroyContext(Folder folder) { |
516 _contexts[folder].changeSubscription.cancel(); | 540 _ContextInfo info = _contexts[folder]; |
541 info.changeSubscription.cancel(); | |
542 _cancelDependencySubscriptions(info); | |
517 removeContext(folder); | 543 removeContext(folder); |
518 _contexts.remove(folder); | 544 _contexts.remove(folder); |
519 } | 545 } |
520 | 546 |
521 /** | 547 /** |
522 * Extract a new [pubspecFile]-based context from [oldInfo]. | 548 * Extract a new [pubspecFile]-based context from [oldInfo]. |
523 */ | 549 */ |
524 void _extractContext(_ContextInfo oldInfo, File pubspecFile) { | 550 void _extractContext(_ContextInfo oldInfo, File pubspecFile) { |
525 Folder newFolder = pubspecFile.parent; | 551 Folder newFolder = pubspecFile.parent; |
526 _ContextInfo newInfo = _createContext(newFolder, pubspecFile, []); | 552 _ContextInfo newInfo = _createContext(newFolder, pubspecFile, []); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 */ | 768 */ |
743 String pubspecPath; | 769 String pubspecPath; |
744 | 770 |
745 /** | 771 /** |
746 * Stream subscription we are using to watch the context's directory for | 772 * Stream subscription we are using to watch the context's directory for |
747 * changes. | 773 * changes. |
748 */ | 774 */ |
749 StreamSubscription<WatchEvent> changeSubscription; | 775 StreamSubscription<WatchEvent> changeSubscription; |
750 | 776 |
751 /** | 777 /** |
778 * Stream subscriptions we are using to watch the files | |
779 * used to determine the package map. | |
780 */ | |
781 final List<StreamSubscription<WatchEvent>> dependencySubscriptions = | |
782 <StreamSubscription<WatchEvent>>[]; | |
783 | |
784 /** | |
752 * The analysis context that was created for the [folder]. | 785 * The analysis context that was created for the [folder]. |
753 */ | 786 */ |
754 AnalysisContext context; | 787 AnalysisContext context; |
755 | 788 |
756 /** | 789 /** |
757 * Map from full path to the [Source] object, for each source that has been | 790 * Map from full path to the [Source] object, for each source that has been |
758 * added to the context. | 791 * added to the context. |
759 */ | 792 */ |
760 Map<String, Source> sources = new HashMap<String, Source>(); | 793 Map<String, Source> sources = new HashMap<String, Source>(); |
761 | 794 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
794 return excludes(resource.path); | 827 return excludes(resource.path); |
795 } | 828 } |
796 | 829 |
797 /** | 830 /** |
798 * Returns `true` if [path] is the pubspec file of this context. | 831 * Returns `true` if [path] is the pubspec file of this context. |
799 */ | 832 */ |
800 bool isPubspec(String path) { | 833 bool isPubspec(String path) { |
801 return path == pubspecPath; | 834 return path == pubspecPath; |
802 } | 835 } |
803 } | 836 } |
OLD | NEW |