| Index: pkg/analyzer/lib/src/generated/engine.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
|
| index 7ca2b2a9ae399543259c8b379315557f51f94c75..f5b4dca154d479d05bb1d74998343c00d7c86bae 100644
|
| --- a/pkg/analyzer/lib/src/generated/engine.dart
|
| +++ b/pkg/analyzer/lib/src/generated/engine.dart
|
| @@ -15,6 +15,7 @@ import 'package:analyzer/src/cancelable_future.dart';
|
| import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
|
| import 'package:analyzer/src/services/lint.dart';
|
| import 'package:analyzer/src/task/task_dart.dart';
|
| +import 'package:analyzer/src/util/lru_map.dart';
|
|
|
| import '../../instrumentation/instrumentation.dart';
|
| import 'ast.dart';
|
| @@ -952,6 +953,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| ContentCache _contentCache = new ContentCache();
|
|
|
| /**
|
| + * A cache of content used to override the default content of a source
|
| + * before the corresponding override was removed from [_contentCache].
|
| + */
|
| + LRUMap<Source, String> _prevOverlayCache = new LRUMap<Source, String>(5);
|
| +
|
| + /**
|
| * The source factory used to create the sources that can be analyzed in this context.
|
| */
|
| SourceFactory _sourceFactory;
|
| @@ -2209,8 +2216,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| TimestampedData<String> fileContents = getContents(source);
|
| String fileContentsData = fileContents.data;
|
| if (fileContentsData == originalContents) {
|
| + _prevOverlayCache.put(source, fileContentsData);
|
| sourceEntry.modificationTime = fileContents.modificationTime;
|
| - sourceEntry.setValue(SourceEntry.CONTENT, fileContentsData);
|
| changed = false;
|
| }
|
| } catch (e) {
|
| @@ -4977,13 +4984,22 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
| */
|
| void _sourceChanged(Source source) {
|
| SourceEntry sourceEntry = _cache.get(source);
|
| - if (sourceEntry == null ||
|
| - sourceEntry.modificationTime == getModificationStamp(source)) {
|
| - // Either we have removed this source, in which case we don't care that
|
| - // it is changed, or we have already invalidated the cache and don't need
|
| - // to invalidate it again.
|
| + // If the source is removed, we don't care about it.
|
| + if (sourceEntry == null) {
|
| return;
|
| }
|
| + // Check if the content of the source is the same as it was the last time.
|
| + String sourceContent = _prevOverlayCache.get(source);
|
| + if (sourceContent != null) {
|
| + try {
|
| + TimestampedData<String> fileContents = getContents(source);
|
| + if (fileContents.data == sourceContent) {
|
| + return;
|
| + }
|
| + } catch (e) {
|
| + }
|
| + }
|
| + // We have to invalidate the cache.
|
| _propagateInvalidation(source, sourceEntry);
|
| }
|
|
|
| @@ -9703,6 +9719,9 @@ abstract class InternalAnalysisContext implements AnalysisContext {
|
| */
|
| List<Source> get prioritySources;
|
|
|
| + /** A factory to override how [ResolverVisitor] is created. */
|
| + ResolverVisitorFactory get resolverVisitorFactory;
|
| +
|
| /**
|
| * Returns a statistics about this context.
|
| */
|
| @@ -9717,9 +9736,6 @@ abstract class InternalAnalysisContext implements AnalysisContext {
|
| */
|
| TypeProvider get typeProvider;
|
|
|
| - /** A factory to override how [ResolverVisitor] is created. */
|
| - ResolverVisitorFactory get resolverVisitorFactory;
|
| -
|
| /** A factory to override how [TypeResolverVisitor] is created. */
|
| TypeResolverVisitorFactory get typeResolverVisitorFactory;
|
|
|
|
|