| Index: pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| index c8309aa9f46ff8cd3f32ec7d5f459ee45e033334..fa3aafcd3038838f2e41ad974ea42155da72be83 100644
|
| --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
|
| @@ -238,6 +238,29 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| FileTracker _fileTracker;
|
|
|
| /**
|
| + * When this flag is set to `true`, the set of analyzed files must not change,
|
| + * and all [AnalysisResult]s are cached infinitely.
|
| + *
|
| + * The flag is intended to be used for non-interactive clients, like DDC,
|
| + * which start a new analysis session, load a set of files, resolve all of
|
| + * them, process the resolved units, and then throw away that whole session.
|
| + *
|
| + * The key problem that this flag is solving is that the driver analyzes the
|
| + * whole library when the result for a unit of the library is requested. So,
|
| + * when the client requests sequentially the defining unit, then the first
|
| + * part, then the second part, the driver has to perform analysis of the
|
| + * library three times and every time throw away all the units except the one
|
| + * which was requested. With this flag set to `true`, the driver can analyze
|
| + * once and cache all the resolved units.
|
| + */
|
| + final bool disableChangesAndCacheAllResults;
|
| +
|
| + /**
|
| + * The cache to use with [disableChangesAndCacheAllResults].
|
| + */
|
| + final Map<String, AnalysisResult> _allCachedResults = {};
|
| +
|
| + /**
|
| * Create a new instance of [AnalysisDriver].
|
| *
|
| * The given [SourceFactory] is cloned to ensure that it does not contain a
|
| @@ -252,7 +275,8 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| this.contextRoot,
|
| SourceFactory sourceFactory,
|
| this._analysisOptions,
|
| - {PackageBundle sdkBundle})
|
| + {PackageBundle sdkBundle,
|
| + this.disableChangesAndCacheAllResults: false})
|
| : _logger = logger,
|
| _sourceFactory = sourceFactory.clone(),
|
| _sdkBundle = sdkBundle {
|
| @@ -459,6 +483,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| * [changeFile] invocation.
|
| */
|
| void changeFile(String path) {
|
| + _throwIfChangesAreNotAllowed();
|
| _fileTracker.changeFile(path);
|
| _priorityResults.clear();
|
| }
|
| @@ -591,6 +616,9 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| // Return the cached result.
|
| {
|
| AnalysisResult result = _priorityResults[path];
|
| + if (disableChangesAndCacheAllResults) {
|
| + result ??= _allCachedResults[path];
|
| + }
|
| if (result != null) {
|
| return new Future.value(result);
|
| }
|
| @@ -887,6 +915,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| * but does not guarantee this.
|
| */
|
| void removeFile(String path) {
|
| + _throwIfChangesAreNotAllowed();
|
| _fileTracker.removeFile(path);
|
| _priorityResults.clear();
|
| }
|
| @@ -956,6 +985,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| try {
|
| LibraryContext libraryContext = _createLibraryContext(library);
|
| try {
|
| + _testView.numOfAnalyzedLibraries++;
|
| LibraryAnalyzer analyzer = new LibraryAnalyzer(
|
| analysisOptions,
|
| declaredVariables,
|
| @@ -978,6 +1008,12 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| bytes = unitBytes;
|
| resolvedUnit = unitResult.unit;
|
| }
|
| + if (disableChangesAndCacheAllResults) {
|
| + AnalysisResult result = _getAnalysisResultFromBytes(
|
| + unitFile, unitSignature, unitBytes,
|
| + content: unitFile.content, resolvedUnit: unitResult.unit);
|
| + _allCachedResults[unitFile.path] = result;
|
| + }
|
| }
|
|
|
| // Return the result, full or partial.
|
| @@ -1237,6 +1273,16 @@ class AnalysisDriver implements AnalysisDriverGeneric {
|
| }
|
|
|
| /**
|
| + * If the driver is used in the read-only mode with infinite cache,
|
| + * we should not allow invocations that change files.
|
| + */
|
| + void _throwIfChangesAreNotAllowed() {
|
| + if (disableChangesAndCacheAllResults) {
|
| + throw new StateError('Changing files is not allowed for this driver.');
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Given the list of [errors] for the [file], update the [file]'s
|
| * [FileState.hasErrorOrWarning] flag.
|
| */
|
| @@ -1478,6 +1524,8 @@ class AnalysisDriverScheduler {
|
| class AnalysisDriverTestView {
|
| final AnalysisDriver driver;
|
|
|
| + int numOfAnalyzedLibraries = 0;
|
| +
|
| AnalysisDriverTestView(this.driver);
|
|
|
| FileTracker get fileTracker => driver._fileTracker;
|
|
|