| 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 import 'dart:convert'; | 9 import 'dart:convert'; |
| 10 import 'dart:core'; | 10 import 'dart:core'; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 * folder is or contains the given path. ("innermost" refers to the nesting | 294 * folder is or contains the given path. ("innermost" refers to the nesting |
| 295 * of contexts, so if there is a context for path /foo and a context for | 295 * of contexts, so if there is a context for path /foo and a context for |
| 296 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is | 296 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is |
| 297 * the context for /foo/bar.) | 297 * the context for /foo/bar.) |
| 298 * | 298 * |
| 299 * If no driver contains the given path, `null` is returned. | 299 * If no driver contains the given path, `null` is returned. |
| 300 */ | 300 */ |
| 301 AnalysisDriver getDriverFor(String path); | 301 AnalysisDriver getDriverFor(String path); |
| 302 | 302 |
| 303 /** | 303 /** |
| 304 * Return the [ContextInfo] for the "innermost" context whose associated | 304 * Like [getDriverFor] and [getContextFor], but returns the [Folder] which |
| 305 * folder is or contains the given path. ("innermost" refers to the nesting | 305 * allows plugins to create & manage their own tree of drivers just like using |
| 306 * of contexts, so if there is a context for path /foo and a context for | 306 * [getDriverFor]. |
| 307 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is | |
| 308 * the context for /foo/bar.) | |
| 309 * | 307 * |
| 310 * If no context contains the given path, `null` is returned. | 308 * This folder should be the root of analysis context, not just the containing |
| 309 * folder of the path (like basename), as this is NOT just a file API. |
| 311 * | 310 * |
| 312 * This is public at least temporarily, for plugin support until the new API | 311 * This exists at least temporarily, for plugin support until the new API is |
| 313 * is ready. | 312 * ready. |
| 314 */ | 313 */ |
| 315 ContextInfo getInnermostContextInfoFor(String path); | 314 Folder getContextFolderFor(String path); |
| 316 | 315 |
| 317 /** | 316 /** |
| 318 * Return a list of all of the analysis drivers reachable from the given | 317 * Return a list of all of the analysis drivers reachable from the given |
| 319 * [analysisRoot] (the driver associated with [analysisRoot] and all of its | 318 * [analysisRoot] (the driver associated with [analysisRoot] and all of its |
| 320 * descendants). | 319 * descendants). |
| 321 */ | 320 */ |
| 322 List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot); | 321 List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot); |
| 323 | 322 |
| 324 /** | 323 /** |
| 325 * Return `true` if the given [path] is ignored by a [ContextInfo] whose | 324 * Return `true` if the given [path] is ignored by a [ContextInfo] whose |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 throw new StateError('Should not be used with the new analysis driver'); | 574 throw new StateError('Should not be used with the new analysis driver'); |
| 576 } else { | 575 } else { |
| 577 return _folderMap; | 576 return _folderMap; |
| 578 } | 577 } |
| 579 } | 578 } |
| 580 | 579 |
| 581 @override | 580 @override |
| 582 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) { | 581 List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) { |
| 583 List<AnalysisContext> contexts = <AnalysisContext>[]; | 582 List<AnalysisContext> contexts = <AnalysisContext>[]; |
| 584 ContextInfo innermostContainingInfo = | 583 ContextInfo innermostContainingInfo = |
| 585 getInnermostContextInfoFor(analysisRoot.path); | 584 _getInnermostContextInfoFor(analysisRoot.path); |
| 586 void addContextAndDescendants(ContextInfo info) { | 585 void addContextAndDescendants(ContextInfo info) { |
| 587 contexts.add(info.context); | 586 contexts.add(info.context); |
| 588 info.children.forEach(addContextAndDescendants); | 587 info.children.forEach(addContextAndDescendants); |
| 589 } | 588 } |
| 590 | 589 |
| 591 if (innermostContainingInfo != null) { | 590 if (innermostContainingInfo != null) { |
| 592 if (analysisRoot == innermostContainingInfo.folder) { | 591 if (analysisRoot == innermostContainingInfo.folder) { |
| 593 addContextAndDescendants(innermostContainingInfo); | 592 addContextAndDescendants(innermostContainingInfo); |
| 594 } else { | 593 } else { |
| 595 for (ContextInfo info in innermostContainingInfo.children) { | 594 for (ContextInfo info in innermostContainingInfo.children) { |
| 596 if (analysisRoot.isOrContains(info.folder.path)) { | 595 if (analysisRoot.isOrContains(info.folder.path)) { |
| 597 addContextAndDescendants(info); | 596 addContextAndDescendants(info); |
| 598 } | 597 } |
| 599 } | 598 } |
| 600 } | 599 } |
| 601 } | 600 } |
| 602 return contexts; | 601 return contexts; |
| 603 } | 602 } |
| 604 | 603 |
| 605 /** | 604 /** |
| 606 * Check if this map defines embedded libraries. | 605 * Check if this map defines embedded libraries. |
| 607 */ | 606 */ |
| 608 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; | 607 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null; |
| 609 | 608 |
| 610 @override | 609 @override |
| 611 AnalysisContext getContextFor(String path) { | 610 AnalysisContext getContextFor(String path) { |
| 612 return getInnermostContextInfoFor(path)?.context; | 611 return _getInnermostContextInfoFor(path)?.context; |
| 613 } | 612 } |
| 614 | 613 |
| 615 /** | 614 /** |
| 616 * For testing: get the [ContextInfo] object for the given [folder], if any. | 615 * For testing: get the [ContextInfo] object for the given [folder], if any. |
| 617 */ | 616 */ |
| 618 ContextInfo getContextInfoFor(Folder folder) { | 617 ContextInfo getContextInfoFor(Folder folder) { |
| 619 ContextInfo info = getInnermostContextInfoFor(folder.path); | 618 ContextInfo info = _getInnermostContextInfoFor(folder.path); |
| 620 if (info != null && folder == info.folder) { | 619 if (info != null && folder == info.folder) { |
| 621 return info; | 620 return info; |
| 622 } | 621 } |
| 623 return null; | 622 return null; |
| 624 } | 623 } |
| 625 | 624 |
| 626 @override | 625 @override |
| 627 AnalysisDriver getDriverFor(String path) { | 626 AnalysisDriver getDriverFor(String path) { |
| 628 return getInnermostContextInfoFor(path)?.analysisDriver; | 627 return _getInnermostContextInfoFor(path)?.analysisDriver; |
| 628 } |
| 629 |
| 630 Folder getContextFolderFor(String path) { |
| 631 return _getInnermostContextInfoFor(path)?.folder; |
| 629 } | 632 } |
| 630 | 633 |
| 631 @override | 634 @override |
| 632 List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot) { | 635 List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot) { |
| 633 List<AnalysisDriver> drivers = <AnalysisDriver>[]; | 636 List<AnalysisDriver> drivers = <AnalysisDriver>[]; |
| 634 void addContextAndDescendants(ContextInfo info) { | 637 void addContextAndDescendants(ContextInfo info) { |
| 635 drivers.add(info.analysisDriver); | 638 drivers.add(info.analysisDriver); |
| 636 info.children.forEach(addContextAndDescendants); | 639 info.children.forEach(addContextAndDescendants); |
| 637 } | 640 } |
| 638 | 641 |
| 639 ContextInfo innermostContainingInfo = | 642 ContextInfo innermostContainingInfo = |
| 640 getInnermostContextInfoFor(analysisRoot.path); | 643 _getInnermostContextInfoFor(analysisRoot.path); |
| 641 if (innermostContainingInfo != null) { | 644 if (innermostContainingInfo != null) { |
| 642 if (analysisRoot == innermostContainingInfo.folder) { | 645 if (analysisRoot == innermostContainingInfo.folder) { |
| 643 addContextAndDescendants(innermostContainingInfo); | 646 addContextAndDescendants(innermostContainingInfo); |
| 644 } else { | 647 } else { |
| 645 for (ContextInfo info in innermostContainingInfo.children) { | 648 for (ContextInfo info in innermostContainingInfo.children) { |
| 646 if (analysisRoot.isOrContains(info.folder.path)) { | 649 if (analysisRoot.isOrContains(info.folder.path)) { |
| 647 addContextAndDescendants(info); | 650 addContextAndDescendants(info); |
| 648 } | 651 } |
| 649 } | 652 } |
| 650 } | 653 } |
| (...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1345 | 1348 |
| 1346 /** | 1349 /** |
| 1347 * Return the [ContextInfo] for the "innermost" context whose associated | 1350 * Return the [ContextInfo] for the "innermost" context whose associated |
| 1348 * folder is or contains the given path. ("innermost" refers to the nesting | 1351 * folder is or contains the given path. ("innermost" refers to the nesting |
| 1349 * of contexts, so if there is a context for path /foo and a context for | 1352 * of contexts, so if there is a context for path /foo and a context for |
| 1350 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is | 1353 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is |
| 1351 * the context for /foo/bar.) | 1354 * the context for /foo/bar.) |
| 1352 * | 1355 * |
| 1353 * If no context contains the given path, `null` is returned. | 1356 * If no context contains the given path, `null` is returned. |
| 1354 */ | 1357 */ |
| 1355 ContextInfo getInnermostContextInfoFor(String path) { | 1358 ContextInfo _getInnermostContextInfoFor(String path) { |
| 1356 ContextInfo info = rootInfo.findChildInfoFor(path); | 1359 ContextInfo info = rootInfo.findChildInfoFor(path); |
| 1357 if (info == null) { | 1360 if (info == null) { |
| 1358 return null; | 1361 return null; |
| 1359 } | 1362 } |
| 1360 while (true) { | 1363 while (true) { |
| 1361 ContextInfo childInfo = info.findChildInfoFor(path); | 1364 ContextInfo childInfo = info.findChildInfoFor(path); |
| 1362 if (childInfo == null) { | 1365 if (childInfo == null) { |
| 1363 return info; | 1366 return info; |
| 1364 } | 1367 } |
| 1365 info = childInfo; | 1368 info = childInfo; |
| 1366 } | 1369 } |
| 1367 } | 1370 } |
| 1368 | 1371 |
| 1369 /** | 1372 /** |
| 1370 * Return the parent for a new [ContextInfo] with the given [path] folder. | 1373 * Return the parent for a new [ContextInfo] with the given [path] folder. |
| 1371 */ | 1374 */ |
| 1372 ContextInfo _getParentForNewContext(String path) { | 1375 ContextInfo _getParentForNewContext(String path) { |
| 1373 ContextInfo parent = getInnermostContextInfoFor(path); | 1376 ContextInfo parent = _getInnermostContextInfoFor(path); |
| 1374 if (parent != null) { | 1377 if (parent != null) { |
| 1375 return parent; | 1378 return parent; |
| 1376 } | 1379 } |
| 1377 return rootInfo; | 1380 return rootInfo; |
| 1378 } | 1381 } |
| 1379 | 1382 |
| 1380 void _handleWatchEvent(WatchEvent event) { | 1383 void _handleWatchEvent(WatchEvent event) { |
| 1381 // Figure out which context this event applies to. | 1384 // Figure out which context this event applies to. |
| 1382 // TODO(brianwilkerson) If a file is explicitly included in one context | 1385 // TODO(brianwilkerson) If a file is explicitly included in one context |
| 1383 // but implicitly referenced in another context, we will only send a | 1386 // but implicitly referenced in another context, we will only send a |
| 1384 // changeSet to the context that explicitly includes the file (because | 1387 // changeSet to the context that explicitly includes the file (because |
| 1385 // that's the only context that's watching the file). | 1388 // that's the only context that's watching the file). |
| 1386 ContextInfo info = getInnermostContextInfoFor(event.path); | 1389 ContextInfo info = _getInnermostContextInfoFor(event.path); |
| 1387 if (info == null) { | 1390 if (info == null) { |
| 1388 // This event doesn't apply to any context. This could happen due to a | 1391 // This event doesn't apply to any context. This could happen due to a |
| 1389 // race condition (e.g. a context was removed while one of its events was | 1392 // race condition (e.g. a context was removed while one of its events was |
| 1390 // in the event loop). The event is inapplicable now, so just ignore it. | 1393 // in the event loop). The event is inapplicable now, so just ignore it. |
| 1391 return; | 1394 return; |
| 1392 } | 1395 } |
| 1393 _instrumentationService.logWatchEvent( | 1396 _instrumentationService.logWatchEvent( |
| 1394 info.folder.path, event.path, event.type.toString()); | 1397 info.folder.path, event.path, event.type.toString()); |
| 1395 String path = event.path; | 1398 String path = event.path; |
| 1396 // First handle changes that affect folderDisposition (since these need to | 1399 // First handle changes that affect folderDisposition (since these need to |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1955 } | 1958 } |
| 1956 return _embedderLocator; | 1959 return _embedderLocator; |
| 1957 } | 1960 } |
| 1958 | 1961 |
| 1959 @override | 1962 @override |
| 1960 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { | 1963 SdkExtensionFinder getSdkExtensionFinder(ResourceProvider resourceProvider) { |
| 1961 return _sdkExtensionFinder ??= | 1964 return _sdkExtensionFinder ??= |
| 1962 new SdkExtensionFinder(buildPackageMap(resourceProvider)); | 1965 new SdkExtensionFinder(buildPackageMap(resourceProvider)); |
| 1963 } | 1966 } |
| 1964 } | 1967 } |
| OLD | NEW |