| 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:core'; | 8 import 'dart:core'; |
| 9 | 9 |
| 10 import 'package:analyzer/context/context_root.dart'; | 10 import 'package:analyzer/context/context_root.dart'; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 * is no longer relevant. | 83 * is no longer relevant. |
| 84 */ | 84 */ |
| 85 Set<String> _dependencies = new Set<String>(); | 85 Set<String> _dependencies = new Set<String>(); |
| 86 | 86 |
| 87 /** | 87 /** |
| 88 * The analysis driver that was created for the [folder]. | 88 * The analysis driver that was created for the [folder]. |
| 89 */ | 89 */ |
| 90 AnalysisDriver analysisDriver; | 90 AnalysisDriver analysisDriver; |
| 91 | 91 |
| 92 /** | 92 /** |
| 93 * The analysis context that was created for the [folder]. | |
| 94 */ | |
| 95 AnalysisContext context; | |
| 96 | |
| 97 /** | |
| 98 * Map from full path to the [Source] object, for each source that has been | 93 * Map from full path to the [Source] object, for each source that has been |
| 99 * added to the context. | 94 * added to the context. |
| 100 */ | 95 */ |
| 101 Map<String, Source> sources = new HashMap<String, Source>(); | 96 Map<String, Source> sources = new HashMap<String, Source>(); |
| 102 | 97 |
| 103 ContextInfo(ContextManagerImpl contextManager, this.parent, Folder folder, | 98 ContextInfo(ContextManagerImpl contextManager, this.parent, Folder folder, |
| 104 File packagespecFile, this.packageRoot, this.disposition) | 99 File packagespecFile, this.packageRoot, this.disposition) |
| 105 : folder = folder, | 100 : folder = folder, |
| 106 pathFilter = new PathFilter( | 101 pathFilter = new PathFilter( |
| 107 folder.path, null, contextManager.resourceProvider.pathContext) { | 102 folder.path, null, contextManager.resourceProvider.pathContext) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 | 209 |
| 215 /** | 210 /** |
| 216 * Class that maintains a mapping from included/excluded paths to a set of | 211 * Class that maintains a mapping from included/excluded paths to a set of |
| 217 * folders that should correspond to analysis contexts. | 212 * folders that should correspond to analysis contexts. |
| 218 */ | 213 */ |
| 219 abstract class ContextManager { | 214 abstract class ContextManager { |
| 220 // TODO(brianwilkerson) Support: | 215 // TODO(brianwilkerson) Support: |
| 221 // setting the default analysis options | 216 // setting the default analysis options |
| 222 // setting the default content cache | 217 // setting the default content cache |
| 223 // setting the default SDK | 218 // setting the default SDK |
| 224 // maintaining AnalysisContext.folderMap (or remove it) | |
| 225 // telling server when a context has been added or removed (see onContextsCh
anged) | 219 // telling server when a context has been added or removed (see onContextsCh
anged) |
| 226 // telling server when a context needs to be re-analyzed | 220 // telling server when a context needs to be re-analyzed |
| 227 // notifying the client when results should be flushed | 221 // notifying the client when results should be flushed |
| 228 // using analyzeFileFunctions to determine which files to analyze | 222 // using analyzeFileFunctions to determine which files to analyze |
| 229 // | 223 // |
| 230 // TODO(brianwilkerson) Move this class to a public library. | 224 // TODO(brianwilkerson) Move this class to a public library. |
| 231 | 225 |
| 232 /** | 226 /** |
| 233 * Return the [AnalysisContext]s that are being used to analyze the analysis | |
| 234 * roots. | |
| 235 */ | |
| 236 Iterable<AnalysisContext> get analysisContexts; | |
| 237 | |
| 238 /** | |
| 239 * Get the callback interface used to create, destroy, and update contexts. | 227 * Get the callback interface used to create, destroy, and update contexts. |
| 240 */ | 228 */ |
| 241 ContextManagerCallbacks get callbacks; | 229 ContextManagerCallbacks get callbacks; |
| 242 | 230 |
| 243 /** | 231 /** |
| 244 * Set the callback interface used to create, destroy, and update contexts. | 232 * Set the callback interface used to create, destroy, and update contexts. |
| 245 */ | 233 */ |
| 246 void set callbacks(ContextManagerCallbacks value); | 234 void set callbacks(ContextManagerCallbacks value); |
| 247 | 235 |
| 248 /** | 236 /** |
| 249 * A table mapping [Folder]s to the [AnalysisDriver]s associated with them. | 237 * A table mapping [Folder]s to the [AnalysisDriver]s associated with them. |
| 250 */ | 238 */ |
| 251 Map<Folder, AnalysisDriver> get driverMap; | 239 Map<Folder, AnalysisDriver> get driverMap; |
| 252 | 240 |
| 253 /** | 241 /** |
| 254 * Return the list of excluded paths (folders and files) most recently passed | 242 * Return the list of excluded paths (folders and files) most recently passed |
| 255 * to [setRoots]. | 243 * to [setRoots]. |
| 256 */ | 244 */ |
| 257 List<String> get excludedPaths; | 245 List<String> get excludedPaths; |
| 258 | 246 |
| 259 /** | 247 /** |
| 260 * Return a table mapping [Folder]s to the [AnalysisContext]s associated with | |
| 261 * them. | |
| 262 */ | |
| 263 Map<Folder, AnalysisContext> get folderMap; | |
| 264 | |
| 265 /** | |
| 266 * Return the list of included paths (folders and files) most recently passed | 248 * Return the list of included paths (folders and files) most recently passed |
| 267 * to [setRoots]. | 249 * to [setRoots]. |
| 268 */ | 250 */ |
| 269 List<String> get includedPaths; | 251 List<String> get includedPaths; |
| 270 | 252 |
| 271 /** | 253 /** |
| 272 * Return a list of all of the contexts reachable from the given | 254 * Like [getDriverFor], but returns the [Folder] which allows plugins to |
| 273 * [analysisRoot] (the context associated with [analysisRoot] and all of its | 255 * create & manage their own tree of drivers just like using [getDriverFor]. |
| 274 * descendants). | |
| 275 */ | |
| 276 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot); | |
| 277 | |
| 278 /** | |
| 279 * Like [getDriverFor] and [getContextFor], but returns the [Folder] which | |
| 280 * allows plugins to create & manage their own tree of drivers just like using | |
| 281 * [getDriverFor]. | |
| 282 * | 256 * |
| 283 * This folder should be the root of analysis context, not just the containing | 257 * This folder should be the root of analysis context, not just the containing |
| 284 * folder of the path (like basename), as this is NOT just a file API. | 258 * folder of the path (like basename), as this is NOT just a file API. |
| 285 * | 259 * |
| 286 * This exists at least temporarily, for plugin support until the new API is | 260 * This exists at least temporarily, for plugin support until the new API is |
| 287 * ready. | 261 * ready. |
| 288 */ | 262 */ |
| 289 Folder getContextFolderFor(String path); | 263 Folder getContextFolderFor(String path); |
| 290 | 264 |
| 291 /** | 265 /** |
| 292 * Return the [AnalysisContext] for the "innermost" context whose associated | |
| 293 * folder is or contains the given path. ("innermost" refers to the nesting | |
| 294 * of contexts, so if there is a context for path /foo and a context for | |
| 295 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is | |
| 296 * the context for /foo/bar.) | |
| 297 * | |
| 298 * If no context contains the given path, `null` is returned. | |
| 299 */ | |
| 300 AnalysisContext getContextFor(String path); | |
| 301 | |
| 302 /** | |
| 303 * Return the [AnalysisDriver] for the "innermost" context whose associated | 266 * Return the [AnalysisDriver] for the "innermost" context whose associated |
| 304 * folder is or contains the given path. ("innermost" refers to the nesting | 267 * folder is or contains the given path. ("innermost" refers to the nesting |
| 305 * of contexts, so if there is a context for path /foo and a context for | 268 * of contexts, so if there is a context for path /foo and a context for |
| 306 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is | 269 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is |
| 307 * the context for /foo/bar.) | 270 * the context for /foo/bar.) |
| 308 * | 271 * |
| 309 * If no driver contains the given path, `null` is returned. | 272 * If no driver contains the given path, `null` is returned. |
| 310 */ | 273 */ |
| 311 AnalysisDriver getDriverFor(String path); | 274 AnalysisDriver getDriverFor(String path); |
| 312 | 275 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 323 */ | 286 */ |
| 324 bool isIgnored(String path); | 287 bool isIgnored(String path); |
| 325 | 288 |
| 326 /** | 289 /** |
| 327 * Return `true` if the given absolute [path] is in one of the current | 290 * Return `true` if the given absolute [path] is in one of the current |
| 328 * root folders and is not excluded. | 291 * root folders and is not excluded. |
| 329 */ | 292 */ |
| 330 bool isInAnalysisRoot(String path); | 293 bool isInAnalysisRoot(String path); |
| 331 | 294 |
| 332 /** | 295 /** |
| 296 * Return the number of contexts reachable from the given [analysisRoot] (the |
| 297 * context associated with [analysisRoot] and all of its descendants). |
| 298 */ |
| 299 int numberOfContextsInAnalysisRoot(Folder analysisRoot); |
| 300 |
| 301 /** |
| 333 * Rebuild the set of contexts from scratch based on the data last sent to | 302 * Rebuild the set of contexts from scratch based on the data last sent to |
| 334 * [setRoots]. Only contexts contained in the given list of analysis [roots] | 303 * [setRoots]. Only contexts contained in the given list of analysis [roots] |
| 335 * will be rebuilt, unless the list is `null`, in which case every context | 304 * will be rebuilt, unless the list is `null`, in which case every context |
| 336 * will be rebuilt. | 305 * will be rebuilt. |
| 337 */ | 306 */ |
| 338 void refresh(List<Resource> roots); | 307 void refresh(List<Resource> roots); |
| 339 | 308 |
| 340 /** | 309 /** |
| 341 * Change the set of paths which should be used as starting points to | 310 * Change the set of paths which should be used as starting points to |
| 342 * determine the context directories. | 311 * determine the context directories. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 357 */ | 326 */ |
| 358 abstract class ContextManagerCallbacks { | 327 abstract class ContextManagerCallbacks { |
| 359 /** | 328 /** |
| 360 * Create and return a new analysis driver rooted at the given [folder], with | 329 * Create and return a new analysis driver rooted at the given [folder], with |
| 361 * the given analysis [options]. | 330 * the given analysis [options]. |
| 362 */ | 331 */ |
| 363 AnalysisDriver addAnalysisDriver( | 332 AnalysisDriver addAnalysisDriver( |
| 364 Folder folder, ContextRoot contextRoot, AnalysisOptions options); | 333 Folder folder, ContextRoot contextRoot, AnalysisOptions options); |
| 365 | 334 |
| 366 /** | 335 /** |
| 367 * Create and return a new analysis context rooted at the given [folder], with | |
| 368 * the given analysis [options]. | |
| 369 */ | |
| 370 AnalysisContext addContext(Folder folder, AnalysisOptions options); | |
| 371 | |
| 372 /** | |
| 373 * Called when the set of files associated with a context have changed (or | 336 * Called when the set of files associated with a context have changed (or |
| 374 * some of those files have been modified). [changeSet] is the set of | 337 * some of those files have been modified). [changeSet] is the set of |
| 375 * changes that need to be applied to the context. | 338 * changes that need to be applied to the context. |
| 376 */ | 339 */ |
| 377 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); | 340 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet); |
| 378 | 341 |
| 379 /** | 342 /** |
| 380 * The given [file] was removed from the folder analyzed in the [driver]. | 343 * The given [file] was removed from the folder analyzed in the [driver]. |
| 381 */ | 344 */ |
| 382 void applyFileRemoved(AnalysisDriver driver, String file); | 345 void applyFileRemoved(AnalysisDriver driver, String file); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 403 * associated. Currently this is mostly FYI, and used only in tests. | 366 * associated. Currently this is mostly FYI, and used only in tests. |
| 404 */ | 367 */ |
| 405 void moveContext(Folder from, Folder to); | 368 void moveContext(Folder from, Folder to); |
| 406 | 369 |
| 407 /** | 370 /** |
| 408 * Remove the context associated with the given [folder]. [flushedFiles] is | 371 * Remove the context associated with the given [folder]. [flushedFiles] is |
| 409 * a list of the files which will be "orphaned" by removing this context | 372 * a list of the files which will be "orphaned" by removing this context |
| 410 * (they will no longer be analyzed by any context). | 373 * (they will no longer be analyzed by any context). |
| 411 */ | 374 */ |
| 412 void removeContext(Folder folder, List<String> flushedFiles); | 375 void removeContext(Folder folder, List<String> flushedFiles); |
| 413 | |
| 414 /** | |
| 415 * Called when the package resolution for the given [context] has changed. | |
| 416 */ | |
| 417 void updateContextPackageUriResolver(AnalysisContext context); | |
| 418 } | 376 } |
| 419 | 377 |
| 420 /** | 378 /** |
| 421 * Class that maintains a mapping from included/excluded paths to a set of | 379 * Class that maintains a mapping from included/excluded paths to a set of |
| 422 * folders that should correspond to analysis contexts. | 380 * folders that should correspond to analysis contexts. |
| 423 */ | 381 */ |
| 424 class ContextManagerImpl implements ContextManager { | 382 class ContextManagerImpl implements ContextManager { |
| 425 /** | 383 /** |
| 426 * The name of the `doc` directory. | 384 * The name of the `doc` directory. |
| 427 */ | 385 */ |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 this.sdkManager, | 511 this.sdkManager, |
| 554 this.packageResolverProvider, | 512 this.packageResolverProvider, |
| 555 this._packageMapProvider, | 513 this._packageMapProvider, |
| 556 this.analyzedFilesGlobs, | 514 this.analyzedFilesGlobs, |
| 557 this._instrumentationService, | 515 this._instrumentationService, |
| 558 this.defaultContextOptions) { | 516 this.defaultContextOptions) { |
| 559 absolutePathContext = resourceProvider.absolutePathContext; | 517 absolutePathContext = resourceProvider.absolutePathContext; |
| 560 pathContext = resourceProvider.pathContext; | 518 pathContext = resourceProvider.pathContext; |
| 561 } | 519 } |
| 562 | 520 |
| 563 @override | |
| 564 Iterable<AnalysisContext> get analysisContexts => folderMap.values; | |
| 565 | |
| 566 Map<Folder, AnalysisContext> get folderMap { | |
| 567 throw new StateError('Should not be used with the new analysis driver'); | |
| 568 } | |
| 569 | |
| 570 @override | |
| 571 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) { | |
| 572 List<AnalysisContext> contexts = <AnalysisContext>[]; | |
| 573 ContextInfo innermostContainingInfo = | |
| 574 _getInnermostContextInfoFor(analysisRoot.path); | |
| 575 void addContextAndDescendants(ContextInfo info) { | |
| 576 contexts.add(info.context); | |
| 577 info.children.forEach(addContextAndDescendants); | |
| 578 } | |
| 579 | |
| 580 if (innermostContainingInfo != null) { | |
| 581 if (analysisRoot == innermostContainingInfo.folder) { | |
| 582 addContextAndDescendants(innermostContainingInfo); | |
| 583 } else { | |
| 584 for (ContextInfo info in innermostContainingInfo.children) { | |
| 585 if (analysisRoot.isOrContains(info.folder.path)) { | |
| 586 addContextAndDescendants(info); | |
| 587 } | |
| 588 } | |
| 589 } | |
| 590 } | |
| 591 return contexts; | |
| 592 } | |
| 593 | |
| 594 /** | 521 /** |
| 595 * Check if this map defines embedded libraries. | 522 * Check if this map defines embedded libraries. |
| 596 */ | 523 */ |
| 597 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; | 524 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; |
| 598 | 525 |
| 599 Folder getContextFolderFor(String path) { | 526 Folder getContextFolderFor(String path) { |
| 600 return _getInnermostContextInfoFor(path)?.folder; | 527 return _getInnermostContextInfoFor(path)?.folder; |
| 601 } | 528 } |
| 602 | 529 |
| 603 @override | |
| 604 AnalysisContext getContextFor(String path) { | |
| 605 return _getInnermostContextInfoFor(path)?.context; | |
| 606 } | |
| 607 | |
| 608 /** | 530 /** |
| 609 * For testing: get the [ContextInfo] object for the given [folder], if any. | 531 * For testing: get the [ContextInfo] object for the given [folder], if any. |
| 610 */ | 532 */ |
| 611 ContextInfo getContextInfoFor(Folder folder) { | 533 ContextInfo getContextInfoFor(Folder folder) { |
| 612 ContextInfo info = _getInnermostContextInfoFor(folder.path); | 534 ContextInfo info = _getInnermostContextInfoFor(folder.path); |
| 613 if (info != null && folder == info.folder) { | 535 if (info != null && folder == info.folder) { |
| 614 return info; | 536 return info; |
| 615 } | 537 } |
| 616 return null; | 538 return null; |
| 617 } | 539 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // check if in one of the roots | 590 // check if in one of the roots |
| 669 for (ContextInfo info in rootInfo.children) { | 591 for (ContextInfo info in rootInfo.children) { |
| 670 if (info.folder.contains(path)) { | 592 if (info.folder.contains(path)) { |
| 671 return true; | 593 return true; |
| 672 } | 594 } |
| 673 } | 595 } |
| 674 // no | 596 // no |
| 675 return false; | 597 return false; |
| 676 } | 598 } |
| 677 | 599 |
| 678 /** | 600 @override |
| 679 * Process [options] for the given context [info]. | 601 int numberOfContextsInAnalysisRoot(Folder analysisRoot) { |
| 680 */ | 602 int count = 0; |
| 681 void processOptionsForContext(ContextInfo info, Map<String, Object> options, | 603 void addContextAndDescendants(ContextInfo info) { |
| 682 {bool optionsRemoved: false}) { | 604 count++; |
| 683 if (options == null && !optionsRemoved) { | 605 info.children.forEach(addContextAndDescendants); |
| 684 return; | |
| 685 } | 606 } |
| 686 | 607 |
| 687 AnalysisOptionsImpl analysisOptions; | 608 ContextInfo innermostContainingInfo = |
| 688 if (optionsRemoved) { | 609 _getInnermostContextInfoFor(analysisRoot.path); |
| 689 // In case options files are removed, revert to defaults. | 610 if (innermostContainingInfo != null) { |
| 690 analysisOptions = new AnalysisOptionsImpl.from(defaultContextOptions); | 611 if (analysisRoot == innermostContainingInfo.folder) { |
| 691 // Apply inherited options. | 612 addContextAndDescendants(innermostContainingInfo); |
| 692 options = _toStringMap(_getEmbeddedOptions(info)); | 613 } else { |
| 693 } else { | 614 for (ContextInfo info in innermostContainingInfo.children) { |
| 694 analysisOptions = | 615 if (analysisRoot.isOrContains(info.folder.path)) { |
| 695 new AnalysisOptionsImpl.from(info.context.analysisOptions); | 616 addContextAndDescendants(info); |
| 696 // Check for embedded options. | 617 } |
| 697 Map embeddedOptions = _getEmbeddedOptions(info); | |
| 698 if (embeddedOptions != null) { | |
| 699 options = _toStringMap(new Merger().merge(embeddedOptions, options)); | |
| 700 } | |
| 701 } | |
| 702 if (options != null) { | |
| 703 applyToAnalysisOptions(analysisOptions, options); | |
| 704 } | |
| 705 info.context.analysisOptions = analysisOptions; | |
| 706 | |
| 707 // Nothing more to do. | |
| 708 if (options == null) { | |
| 709 return; | |
| 710 } | |
| 711 | |
| 712 var analyzer = options[AnalyzerOptions.analyzer]; | |
| 713 if (analyzer is Map) { | |
| 714 // Set ignore patterns. | |
| 715 var exclude = analyzer[AnalyzerOptions.exclude]; | |
| 716 if (exclude is YamlList) { | |
| 717 List<String> excludeList = toStringList(exclude); | |
| 718 if (excludeList != null) { | |
| 719 setIgnorePatternsForContext(info, excludeList); | |
| 720 } | 618 } |
| 721 } | 619 } |
| 722 } | 620 } |
| 621 return count; |
| 723 } | 622 } |
| 724 | 623 |
| 725 /** | 624 /** |
| 726 * Process [options] for the given context [info]. | 625 * Process [options] for the given context [info]. |
| 727 */ | 626 */ |
| 728 void processOptionsForDriver(ContextInfo info, | 627 void processOptionsForDriver(ContextInfo info, |
| 729 AnalysisOptionsImpl analysisOptions, Map<String, Object> options) { | 628 AnalysisOptionsImpl analysisOptions, Map<String, Object> options) { |
| 730 if (options == null) { | 629 if (options == null) { |
| 731 return; | 630 return; |
| 732 } | 631 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 if (!_shouldFileBeAnalyzed(child)) { | 807 if (!_shouldFileBeAnalyzed(child)) { |
| 909 continue; | 808 continue; |
| 910 } | 809 } |
| 911 // ignore if was not excluded | 810 // ignore if was not excluded |
| 912 bool wasExcluded = _isExcludedBy(oldExcludedPaths, path) && | 811 bool wasExcluded = _isExcludedBy(oldExcludedPaths, path) && |
| 913 !_isExcludedBy(excludedPaths, path); | 812 !_isExcludedBy(excludedPaths, path); |
| 914 if (!wasExcluded) { | 813 if (!wasExcluded) { |
| 915 continue; | 814 continue; |
| 916 } | 815 } |
| 917 // do add the file | 816 // do add the file |
| 918 Source source = createSourceInContext(info.context, child); | 817 Source source = createSourceInContext(info.analysisDriver, child); |
| 919 changeSet.addedSource(source); | 818 changeSet.addedSource(source); |
| 920 info.sources[path] = source; | 819 info.sources[path] = source; |
| 921 } else if (child is Folder) { | 820 } else if (child is Folder) { |
| 922 if (child.shortName == PACKAGES_NAME) { | 821 if (child.shortName == PACKAGES_NAME) { |
| 923 continue; | 822 continue; |
| 924 } | 823 } |
| 925 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); | 824 _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths); |
| 926 } | 825 } |
| 927 } | 826 } |
| 928 } | 827 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 946 } | 845 } |
| 947 for (Resource child in children) { | 846 for (Resource child in children) { |
| 948 String path = child.path; | 847 String path = child.path; |
| 949 // ignore excluded files or folders | 848 // ignore excluded files or folders |
| 950 if (_isExcluded(path) || info.excludes(path) || info.ignored(path)) { | 849 if (_isExcluded(path) || info.excludes(path) || info.ignored(path)) { |
| 951 continue; | 850 continue; |
| 952 } | 851 } |
| 953 // add files, recurse into folders | 852 // add files, recurse into folders |
| 954 if (child is File) { | 853 if (child is File) { |
| 955 if (_shouldFileBeAnalyzed(child)) { | 854 if (_shouldFileBeAnalyzed(child)) { |
| 956 Source source = createSourceInContext(info.context, child); | 855 Source source = createSourceInContext(info.analysisDriver, child); |
| 957 changeSet.addedSource(source); | 856 changeSet.addedSource(source); |
| 958 info.sources[path] = source; | 857 info.sources[path] = source; |
| 959 } | 858 } |
| 960 } else if (child is Folder) { | 859 } else if (child is Folder) { |
| 961 String shortName = child.shortName; | 860 String shortName = child.shortName; |
| 962 if (shortName == PACKAGES_NAME) { | 861 if (shortName == PACKAGES_NAME) { |
| 963 continue; | 862 continue; |
| 964 } | 863 } |
| 965 _addSourceFiles(changeSet, child, info); | 864 _addSourceFiles(changeSet, child, info); |
| 966 } | 865 } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 // Now that the child contexts have been created, add the sources that | 1107 // Now that the child contexts have been created, add the sources that |
| 1209 // don't belong to the children. | 1108 // don't belong to the children. |
| 1210 ChangeSet changeSet = new ChangeSet(); | 1109 ChangeSet changeSet = new ChangeSet(); |
| 1211 _addSourceFiles(changeSet, folder, parent); | 1110 _addSourceFiles(changeSet, folder, parent); |
| 1212 callbacks.applyChangesToContext(folder, changeSet); | 1111 callbacks.applyChangesToContext(folder, changeSet); |
| 1213 } | 1112 } |
| 1214 } | 1113 } |
| 1215 | 1114 |
| 1216 /** | 1115 /** |
| 1217 * Set up a [SourceFactory] that resolves packages as appropriate for the | 1116 * Set up a [SourceFactory] that resolves packages as appropriate for the |
| 1218 * given [disposition]. | 1117 * given [folder]. |
| 1219 */ | 1118 */ |
| 1220 SourceFactory _createSourceFactory( | 1119 SourceFactory _createSourceFactory(AnalysisOptions options, Folder folder) { |
| 1221 InternalAnalysisContext context, AnalysisOptions options, Folder folder) { | |
| 1222 ContextBuilder builder = callbacks.createContextBuilder(folder, options); | 1120 ContextBuilder builder = callbacks.createContextBuilder(folder, options); |
| 1223 return builder.createSourceFactory(folder.path, options); | 1121 return builder.createSourceFactory(folder.path, options); |
| 1224 } | 1122 } |
| 1225 | 1123 |
| 1226 /** | 1124 /** |
| 1227 * Clean up and destroy the context associated with the given folder. | 1125 * Clean up and destroy the context associated with the given folder. |
| 1228 */ | 1126 */ |
| 1229 void _destroyContext(ContextInfo info) { | 1127 void _destroyContext(ContextInfo info) { |
| 1230 changeSubscriptions.remove(info.folder)?.cancel(); | 1128 changeSubscriptions.remove(info.folder)?.cancel(); |
| 1231 callbacks.removeContext(info.folder, _computeFlushedFiles(info)); | 1129 callbacks.removeContext(info.folder, _computeFlushedFiles(info)); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1617 } | 1515 } |
| 1618 return stringMap; | 1516 return stringMap; |
| 1619 } | 1517 } |
| 1620 return null; | 1518 return null; |
| 1621 } | 1519 } |
| 1622 | 1520 |
| 1623 void _updateContextPackageUriResolver(Folder contextFolder) { | 1521 void _updateContextPackageUriResolver(Folder contextFolder) { |
| 1624 ContextInfo info = getContextInfoFor(contextFolder); | 1522 ContextInfo info = getContextInfoFor(contextFolder); |
| 1625 AnalysisDriver driver = info.analysisDriver; | 1523 AnalysisDriver driver = info.analysisDriver; |
| 1626 SourceFactory sourceFactory = | 1524 SourceFactory sourceFactory = |
| 1627 _createSourceFactory(null, driver.analysisOptions, contextFolder); | 1525 _createSourceFactory(driver.analysisOptions, contextFolder); |
| 1628 driver.configure(sourceFactory: sourceFactory); | 1526 driver.configure(sourceFactory: sourceFactory); |
| 1629 } | 1527 } |
| 1630 | 1528 |
| 1631 /** | 1529 /** |
| 1632 * Create and return a source representing the given [file] within the given | 1530 * Create and return a source representing the given [file] within the given |
| 1633 * [context]. | 1531 * [driver]. |
| 1634 */ | 1532 */ |
| 1635 static Source createSourceInContext(AnalysisContext context, File file) { | 1533 static Source createSourceInContext(AnalysisDriver driver, File file) { |
| 1636 // TODO(brianwilkerson) Optimize this, by allowing support for source | 1534 // TODO(brianwilkerson) Optimize this, by allowing support for source |
| 1637 // factories to restore URI's from a file path rather than a source. | 1535 // factories to restore URI's from a file path rather than a source. |
| 1638 Source source = file.createSource(); | 1536 Source source = file.createSource(); |
| 1639 if (context == null) { | 1537 if (driver == null) { |
| 1640 return source; | 1538 return source; |
| 1641 } | 1539 } |
| 1642 Uri uri = context.sourceFactory.restoreUri(source); | 1540 Uri uri = driver.sourceFactory.restoreUri(source); |
| 1643 return file.createSource(uri); | 1541 return file.createSource(uri); |
| 1644 } | 1542 } |
| 1645 } | 1543 } |
| 1646 | 1544 |
| 1647 /** | 1545 /** |
| 1648 * An indication that one or more contexts were added, changed, or removed. | |
| 1649 * | |
| 1650 * The lists of [added], [changed] and [removed] contexts will not contain | |
| 1651 * duplications (that is, a single context will not be in any list multiple | |
| 1652 * times), nor will there be any overlap between the lists (that is, a single | |
| 1653 * context will not be in more than one list). | |
| 1654 */ | |
| 1655 class ContextsChangedEvent { | |
| 1656 /** | |
| 1657 * The contexts that were added to the server. | |
| 1658 */ | |
| 1659 final List<AnalysisContext> added; | |
| 1660 | |
| 1661 /** | |
| 1662 * The contexts that were changed. | |
| 1663 */ | |
| 1664 final List<AnalysisContext> changed; | |
| 1665 | |
| 1666 /** | |
| 1667 * The contexts that were removed from the server. | |
| 1668 */ | |
| 1669 final List<AnalysisContext> removed; | |
| 1670 | |
| 1671 /** | |
| 1672 * Initialize a newly created event to indicate which contexts have changed. | |
| 1673 */ | |
| 1674 ContextsChangedEvent( | |
| 1675 {this.added: AnalysisContext.EMPTY_LIST, | |
| 1676 this.changed: AnalysisContext.EMPTY_LIST, | |
| 1677 this.removed: AnalysisContext.EMPTY_LIST}); | |
| 1678 } | |
| 1679 | |
| 1680 /** | |
| 1681 * Concrete [FolderDisposition] object indicating that the context for a given | 1546 * Concrete [FolderDisposition] object indicating that the context for a given |
| 1682 * folder should resolve package URIs using a custom URI resolver. | 1547 * folder should resolve package URIs using a custom URI resolver. |
| 1683 */ | 1548 */ |
| 1684 class CustomPackageResolverDisposition extends FolderDisposition { | 1549 class CustomPackageResolverDisposition extends FolderDisposition { |
| 1685 /** | 1550 /** |
| 1686 * The [UriResolver] that should be used to resolve package URIs. | 1551 * The [UriResolver] that should be used to resolve package URIs. |
| 1687 */ | 1552 */ |
| 1688 UriResolver resolver; | 1553 UriResolver resolver; |
| 1689 | 1554 |
| 1690 CustomPackageResolverDisposition(this.resolver); | 1555 CustomPackageResolverDisposition(this.resolver); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1704 EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) => | 1569 EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) => |
| 1705 new EmbedderYamlLocator(null); | 1570 new EmbedderYamlLocator(null); |
| 1706 | 1571 |
| 1707 @override | 1572 @override |
| 1708 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) => | 1573 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) => |
| 1709 new SdkExtensionFinder(null); | 1574 new SdkExtensionFinder(null); |
| 1710 } | 1575 } |
| 1711 | 1576 |
| 1712 /** | 1577 /** |
| 1713 * An instance of the class [FolderDisposition] represents the information | 1578 * An instance of the class [FolderDisposition] represents the information |
| 1714 * gathered by the [ContextManagerImpl] to determine how to create an | 1579 * gathered by the [ContextManagerImpl] to determine how to create an analysis |
| 1715 * [AnalysisContext] for a given folder. | 1580 * driver for a given folder. |
| 1716 * | 1581 * |
| 1717 * Note: [ContextManagerImpl] may use equality testing and hash codes to | 1582 * Note: [ContextManagerImpl] may use equality testing and hash codes to |
| 1718 * determine when two folders should share the same context, so derived classes | 1583 * determine when two folders should share the same context, so derived classes |
| 1719 * may need to override operator== and hashCode() if object identity is | 1584 * may need to override operator== and hashCode() if object identity is |
| 1720 * insufficient. | 1585 * insufficient. |
| 1721 * | 1586 * |
| 1722 * TODO(paulberry): consider adding a flag to indicate that it is not necessary | 1587 * TODO(paulberry): consider adding a flag to indicate that it is not necessary |
| 1723 * to recurse into the given folder looking for additional contexts to create | 1588 * to recurse into the given folder looking for additional contexts to create |
| 1724 * or files to analyze (this could help avoid unnecessarily weighing down the | 1589 * or files to analyze (this could help avoid unnecessarily weighing down the |
| 1725 * system with file watchers). | 1590 * system with file watchers). |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1883 } | 1748 } |
| 1884 return _embedderLocator; | 1749 return _embedderLocator; |
| 1885 } | 1750 } |
| 1886 | 1751 |
| 1887 @override | 1752 @override |
| 1888 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { | 1753 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { |
| 1889 return _sdkExtensionFinder ??= | 1754 return _sdkExtensionFinder ??= |
| 1890 new SdkExtensionFinder(buildPackageMap(resourceProvider)); | 1755 new SdkExtensionFinder(buildPackageMap(resourceProvider)); |
| 1891 } | 1756 } |
| 1892 } | 1757 } |
| OLD | NEW |