Index: pkg/analyzer_cli/lib/src/driver.dart |
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart |
index 0654a4372d5cda82098f5cdf25c93e1793c66580..5c8ba617e6b2a2086b01b614072bd58f359634b2 100644 |
--- a/pkg/analyzer_cli/lib/src/driver.dart |
+++ b/pkg/analyzer_cli/lib/src/driver.dart |
@@ -71,6 +71,11 @@ class Driver implements CommandLineStarter { |
static final PerformanceTag _analyzeAllTag = |
new PerformanceTag("Driver._analyzeAll"); |
+ /// Cache of [AnalysisOptionsImpl] objects that correspond to directories |
+ /// with analyzed files, used to reduce searching for `analysis_options.yaml` |
+ /// files. |
+ static Map<String, AnalysisOptionsImpl> _directoryToAnalysisOptions = {}; |
+ |
static ByteStore analysisDriverMemoryByteStore = new MemoryByteStore(); |
/// The plugins that are defined outside the `analyzer_cli` package. |
@@ -311,88 +316,6 @@ class Driver implements CommandLineStarter { |
}); |
} |
- /// Determine whether the context created during a previous call to |
- /// [_analyzeAll] can be re-used in order to analyze using [options]. |
- bool _canContextBeReused( |
- CommandLineOptions options, AnalysisOptionsImpl other) { |
- // TODO(paulberry): add a command-line option that disables context re-use. |
- if (_context == null) { |
- return false; |
- } |
- |
- // Check command line options. |
- if (options.packageRootPath != _previousOptions.packageRootPath) { |
- return false; |
- } |
- if (options.packageConfigPath != _previousOptions.packageConfigPath) { |
- return false; |
- } |
- if (!_equalMaps( |
- options.definedVariables, _previousOptions.definedVariables)) { |
- return false; |
- } |
- if (options.log != _previousOptions.log) { |
- return false; |
- } |
- if (options.disableHints != _previousOptions.disableHints) { |
- return false; |
- } |
- if (options.enableStrictCallChecks != |
- _previousOptions.enableStrictCallChecks) { |
- return false; |
- } |
- if (options.enableAssertInitializer != |
- _previousOptions.enableAssertInitializer) { |
- return false; |
- } |
- if (options.showPackageWarnings != _previousOptions.showPackageWarnings) { |
- return false; |
- } |
- if (options.showPackageWarningsPrefix != |
- _previousOptions.showPackageWarningsPrefix) { |
- return false; |
- } |
- if (options.showSdkWarnings != _previousOptions.showSdkWarnings) { |
- return false; |
- } |
- if (options.lints != _previousOptions.lints) { |
- return false; |
- } |
- if (options.strongMode != _previousOptions.strongMode) { |
- return false; |
- } |
- if (options.enableSuperMixins != _previousOptions.enableSuperMixins) { |
- return false; |
- } |
- if (!_equalLists( |
- options.buildSummaryInputs, _previousOptions.buildSummaryInputs)) { |
- return false; |
- } |
- if (options.disableCacheFlushing != _previousOptions.disableCacheFlushing) { |
- return false; |
- } |
- |
- // Check analysis options. |
- var c = _context.analysisOptions; |
- if (!(other.enableAssertInitializer == c.enableAssertInitializer && |
- other.enableStrictCallChecks == c.enableStrictCallChecks && |
- other.enableLazyAssignmentOperators == |
- c.enableLazyAssignmentOperators && |
- other.enableSuperMixins == c.enableSuperMixins && |
- other.enableTiming == c.enableTiming && |
- other.generateImplicitErrors == c.generateImplicitErrors && |
- other.generateSdkErrors == c.generateSdkErrors && |
- other.hint == c.hint && |
- other.lint == c.lint && |
- AnalysisOptionsImpl.compareLints(other.lintRules, c.lintRules) && |
- other.preserveComments == c.preserveComments && |
- other.strongMode == c.strongMode)) { |
- return false; |
- } |
- |
- return true; |
- } |
- |
/// Decide on the appropriate policy for which files need to be fully parsed |
/// and which files need to be diet parsed, based on [options], and return an |
/// [AnalyzeFunctionBodiesPredicate] that implements this policy. |
@@ -521,8 +444,6 @@ class Driver implements CommandLineStarter { |
return new SourceFactory(resolvers, packageInfo.packages); |
} |
- // TODO(devoncarew): This needs to respect analysis_options excludes. |
- |
/// Collect all analyzable files at [filePath], recursively if it's a |
/// directory, ignoring links. |
Iterable<io.File> _collectFiles(String filePath) { |
@@ -546,6 +467,8 @@ class Driver implements CommandLineStarter { |
return files; |
} |
+ // TODO(devoncarew): This needs to respect analysis_options excludes. |
Brian Wilkerson
2017/06/27 19:11:02
The comment moved. I'm not sure what it was suppos
|
+ |
/// Convert the given [sourcePath] (which may be relative to the current |
/// working directory) to a [Source] object that can be fed to the analysis |
/// context. |
@@ -567,17 +490,26 @@ class Driver implements CommandLineStarter { |
/// Create an analysis context that is prepared to analyze sources according |
/// to the given [options], and store it in [_context]. |
void _createAnalysisContext(CommandLineOptions options) { |
+ // If not the same command-line options, clear cached information. |
+ if (!_equalCommandLineOptions(_previousOptions, options)) { |
+ _previousOptions = options; |
+ _directoryToAnalysisOptions.clear(); |
+ _context = null; |
+ analysisDriver = null; |
+ } |
+ |
AnalysisOptionsImpl analysisOptions = |
createAnalysisOptionsForCommandLineOptions(resourceProvider, options); |
analysisOptions.analyzeFunctionBodiesPredicate = |
_chooseDietParsingPolicy(options); |
- if (_canContextBeReused(options, analysisOptions)) { |
+ // If we have the analysis driver, and the new analysis options are the |
+ // same, we can reuse this analysis driver. |
+ if (_context != null && |
+ _equalAnalysisOptions(_context.analysisOptions, analysisOptions)) { |
return; |
} |
- _previousOptions = options; |
- |
// Save stats from previous context before clobbering it. |
if (_context != null) { |
_analyzedFileCount += _context.sources.length; |
@@ -660,6 +592,23 @@ class Driver implements CommandLineStarter { |
return null; |
} |
+ /// Return whether [a] and [b] options are equal for the purpose of |
+ /// command line analysis. |
+ bool _equalAnalysisOptions(AnalysisOptionsImpl a, AnalysisOptions b) { |
+ return a.enableAssertInitializer == b.enableAssertInitializer && |
+ a.enableStrictCallChecks == b.enableStrictCallChecks && |
+ a.enableLazyAssignmentOperators == b.enableLazyAssignmentOperators && |
+ a.enableSuperMixins == b.enableSuperMixins && |
+ a.enableTiming == b.enableTiming && |
+ a.generateImplicitErrors == b.generateImplicitErrors && |
+ a.generateSdkErrors == b.generateSdkErrors && |
+ a.hint == b.hint && |
+ a.lint == b.lint && |
+ AnalysisOptionsImpl.compareLints(a.lintRules, b.lintRules) && |
+ a.preserveComments == b.preserveComments && |
+ a.strongMode == b.strongMode; |
+ } |
+ |
_PackageInfo _findPackages(CommandLineOptions options) { |
if (packageResolverProvider != null) { |
// The resolver provider will do all the work later. |
@@ -805,8 +754,22 @@ class Driver implements CommandLineStarter { |
outSink.writeln(text); |
} |
- AnalysisOptionsImpl contextOptions = new ContextBuilder( |
- resourceProvider, null, null, |
+ // Prepare the directory which is, or contains, the context root. |
+ String contextRootDirectory; |
+ if (resourceProvider.getFolder(contextRoot).exists) { |
+ contextRootDirectory = contextRoot; |
+ } else { |
+ contextRootDirectory = resourceProvider.pathContext.dirname(contextRoot); |
+ } |
+ |
+ // Check if there is the options object for the content directory. |
+ AnalysisOptionsImpl contextOptions = |
+ _directoryToAnalysisOptions[contextRootDirectory]; |
+ if (contextOptions != null) { |
+ return contextOptions; |
+ } |
+ |
+ contextOptions = new ContextBuilder(resourceProvider, null, null, |
options: options.contextBuilderOptions) |
.getAnalysisOptions(contextRoot, |
verbosePrint: options.verbose ? verbosePrint : null); |
@@ -820,6 +783,7 @@ class Driver implements CommandLineStarter { |
contextOptions.enableAssertInitializer = options.enableAssertInitializer; |
} |
+ _directoryToAnalysisOptions[contextRootDirectory] = contextOptions; |
return contextOptions; |
} |
@@ -852,6 +816,63 @@ class Driver implements CommandLineStarter { |
context.analysisOptions = analysisOptions; |
} |
+ /// Return whether the [newOptions] are equal to the [previous]. |
+ static bool _equalCommandLineOptions( |
+ CommandLineOptions previous, CommandLineOptions newOptions) { |
+ if (previous == null || newOptions == null) { |
+ return false; |
+ } |
+ if (newOptions.packageRootPath != previous.packageRootPath) { |
+ return false; |
+ } |
+ if (newOptions.packageConfigPath != previous.packageConfigPath) { |
+ return false; |
+ } |
+ if (!_equalMaps(newOptions.definedVariables, previous.definedVariables)) { |
+ return false; |
+ } |
+ if (newOptions.log != previous.log) { |
+ return false; |
+ } |
+ if (newOptions.disableHints != previous.disableHints) { |
+ return false; |
+ } |
+ if (newOptions.enableStrictCallChecks != previous.enableStrictCallChecks) { |
+ return false; |
+ } |
+ if (newOptions.enableAssertInitializer != |
+ previous.enableAssertInitializer) { |
+ return false; |
+ } |
+ if (newOptions.showPackageWarnings != previous.showPackageWarnings) { |
+ return false; |
+ } |
+ if (newOptions.showPackageWarningsPrefix != |
+ previous.showPackageWarningsPrefix) { |
+ return false; |
+ } |
+ if (newOptions.showSdkWarnings != previous.showSdkWarnings) { |
+ return false; |
+ } |
+ if (newOptions.lints != previous.lints) { |
+ return false; |
+ } |
+ if (newOptions.strongMode != previous.strongMode) { |
+ return false; |
+ } |
+ if (newOptions.enableSuperMixins != previous.enableSuperMixins) { |
+ return false; |
+ } |
+ if (!_equalLists( |
+ newOptions.buildSummaryInputs, previous.buildSummaryInputs)) { |
+ return false; |
+ } |
+ if (newOptions.disableCacheFlushing != previous.disableCacheFlushing) { |
+ return false; |
+ } |
+ return true; |
+ } |
+ |
/// Perform a deep comparison of two string lists. |
static bool _equalLists(List<String> l1, List<String> l2) { |
if (l1.length != l2.length) { |