-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
svn merge -c 45170 https://dart.googlecode.com/svn/branches/bleeding_edge trunk svn merge -c 45183 https://dart.googlecode.com/svn/branches/bleeding_edge trunk git-svn-id: http://dart.googlecode.com/svn/trunk@45201 260f80e4-7a28-3924-810f-c04153c831b5
- Loading branch information
Showing
11 changed files
with
500 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | ||
// for details. All rights reserved. Use of this source code is governed by a | ||
// BSD-style license that can be found in the LICENSE file. | ||
|
||
library source.optimizing_pub_package_map_provider; | ||
|
||
import 'package:analyzer/file_system/file_system.dart'; | ||
import 'package:analyzer/source/package_map_provider.dart'; | ||
import 'package:analyzer/source/pub_package_map_provider.dart'; | ||
import 'package:analyzer/src/generated/sdk_io.dart'; | ||
|
||
/** | ||
* Extension of [PackageMapInfo] that tracks the modification timestamps of | ||
* pub dependencies. This allows the analysis server to avoid making redundant | ||
* calls to "pub list" when nothing has changed. | ||
*/ | ||
class OptimizingPubPackageMapInfo extends PackageMapInfo { | ||
/** | ||
* Map from file path to the file's modification timestamp prior to running | ||
* "pub list". Since the set of dependencies is not always known prior to | ||
* running "pub list", some or all of the dependencies may be missing from | ||
* this map. | ||
*/ | ||
final Map<String, int> modificationTimes; | ||
|
||
OptimizingPubPackageMapInfo(Map<String, List<Folder>> packageMap, | ||
Set<String> dependencies, this.modificationTimes) | ||
: super(packageMap, dependencies); | ||
|
||
/** | ||
* Return `true` if the given [path] is listed as a dependency, and we cannot | ||
* prove using modification timestamps that it is unchanged. | ||
* [resourceProvider] is used (if necessary) to read the [path]'s | ||
* modification time. | ||
*/ | ||
bool isChangedDependency(String path, ResourceProvider resourceProvider) { | ||
if (!dependencies.contains(path)) { | ||
// Path is not a dependency. | ||
return false; | ||
} | ||
int lastModificationTime = modificationTimes[path]; | ||
if (lastModificationTime != null) { | ||
Resource resource = resourceProvider.getResource(path); | ||
if (resource is File) { | ||
try { | ||
if (resource.modificationStamp == lastModificationTime) { | ||
// Path is a dependency, but it hasn't changed since the last run | ||
// of "pub list". | ||
return false; | ||
} | ||
} on FileSystemException { | ||
// Path is a dependency, but we can't read its timestamp. Assume | ||
// it's changed to be safe. | ||
} | ||
} | ||
} | ||
// Path is a dependency, and we couldn't prove that it hadn't changed. | ||
// Assume it's changed to be safe. | ||
return true; | ||
} | ||
} | ||
|
||
/** | ||
* Extension of [PubPackageMapProvider] that outputs additional information to | ||
* allow the analysis server to avoid making redundant calls to "pub list" when | ||
* nothing has changed. | ||
*/ | ||
class OptimizingPubPackageMapProvider extends PubPackageMapProvider { | ||
OptimizingPubPackageMapProvider( | ||
ResourceProvider resourceProvider, DirectoryBasedDartSdk sdk, [RunPubList runPubList]) | ||
: super(resourceProvider, sdk, runPubList); | ||
|
||
/** | ||
* Compute a package map for the given folder by executing "pub list". If | ||
* [previousInfo] is provided, it is used as a guess of which files the | ||
* package map is likely to depend on; the modification times of those files | ||
* are captured prior to executing "pub list" so that they can be used to | ||
* avoid making redundant calls to "pub list" in the future. | ||
* | ||
* Also, in the case where dependencies can't be determined because of an | ||
* error, the dependencies from [previousInfo] will be preserved. | ||
*/ | ||
OptimizingPubPackageMapInfo computePackageMap(Folder folder, | ||
[OptimizingPubPackageMapInfo previousInfo]) { | ||
// Prior to running "pub list", read the modification timestamps of all of | ||
// the old dependencies (if known). | ||
Map<String, int> modificationTimes = <String, int>{}; | ||
if (previousInfo != null) { | ||
for (String path in previousInfo.dependencies) { | ||
Resource resource = resourceProvider.getResource(path); | ||
if (resource is File) { | ||
try { | ||
modificationTimes[path] = resource.modificationStamp; | ||
} on FileSystemException { | ||
// File no longer exists. Don't record a timestamp for it; this | ||
// will ensure that if the file reappears, we will re-run "pub | ||
// list" regardless of the timestamp it reappears with. | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Try running "pub list". | ||
PackageMapInfo info = super.computePackageMap(folder); | ||
if (info == null) { | ||
// Computing the package map resulted in an error. Merge the old | ||
// dependencies with the new ones, if possible. | ||
info = super.computePackageMapError(folder); | ||
if (previousInfo != null) { | ||
info.dependencies.addAll(previousInfo.dependencies); | ||
} | ||
} | ||
|
||
// Discard any elements of modificationTimes that are no longer | ||
// dependencies. | ||
if (previousInfo != null) { | ||
for (String dependency | ||
in previousInfo.dependencies.difference(info.dependencies)) { | ||
modificationTimes.remove(dependency); | ||
} | ||
} | ||
|
||
// Bundle the modificationTimes with the other info. | ||
return new OptimizingPubPackageMapInfo( | ||
info.packageMap, info.dependencies, modificationTimes); | ||
} | ||
|
||
@override | ||
PackageMapInfo computePackageMapError(Folder folder) { | ||
// Return null to indicate to our override of computePackageMap that there | ||
// was an error, so it can compute dependencies correctly. | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.