mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:56:57 +00:00
Add hook for listening to implicitly analyzed files
R=paulberry@google.com Review URL: https://codereview.chromium.org//1239863002 .
This commit is contained in:
parent
e4881c55d0
commit
503e2b68f1
|
@ -216,8 +216,10 @@ class AnalysisCache {
|
|||
|
||||
/**
|
||||
* Remove all information related to the given [target] from this cache.
|
||||
* Return the entry associated with the target, or `null` if there was cache
|
||||
* entry for the target.
|
||||
*/
|
||||
void remove(AnalysisTarget target) {
|
||||
CacheEntry remove(AnalysisTarget target) {
|
||||
int count = _partitions.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
CachePartition partition = _partitions[i];
|
||||
|
@ -226,10 +228,10 @@ class AnalysisCache {
|
|||
AnalysisEngine.instance.logger
|
||||
.logInformation('Removed the cache entry for $target.');
|
||||
}
|
||||
partition.remove(target);
|
||||
return;
|
||||
return partition.remove(target);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -896,9 +898,11 @@ abstract class CachePartition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all information related to the given [target] from this cache.
|
||||
* Remove all information related to the given [target] from this partition.
|
||||
* Return the entry associated with the target, or `null` if there was cache
|
||||
* entry for the target.
|
||||
*/
|
||||
void remove(AnalysisTarget target) {
|
||||
CacheEntry remove(AnalysisTarget target) {
|
||||
for (CacheFlushManager flushManager in _flushManagerMap.values) {
|
||||
flushManager.targetRemoved(target);
|
||||
}
|
||||
|
@ -907,6 +911,7 @@ abstract class CachePartition {
|
|||
entry._invalidateAll();
|
||||
}
|
||||
_removeIfSource(target);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -981,19 +986,17 @@ abstract class CachePartition {
|
|||
}
|
||||
|
||||
/**
|
||||
* If the given [target] is a [Source], removes it from [_sources].
|
||||
* If the given [target] is a [Source], remove it from the list of [_sources].
|
||||
*/
|
||||
void _removeIfSource(AnalysisTarget target) {
|
||||
if (target is Source) {
|
||||
_sources.remove(target);
|
||||
{
|
||||
String fullName = target.fullName;
|
||||
List<Source> sources = _pathToSources[fullName];
|
||||
if (sources != null) {
|
||||
sources.remove(target);
|
||||
if (sources.isEmpty) {
|
||||
_pathToSources.remove(fullName);
|
||||
}
|
||||
String fullName = target.fullName;
|
||||
List<Source> sources = _pathToSources[fullName];
|
||||
if (sources != null) {
|
||||
sources.remove(target);
|
||||
if (sources.isEmpty) {
|
||||
_pathToSources.remove(fullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
*/
|
||||
StreamController<SourcesChangedEvent> _onSourcesChangedController;
|
||||
|
||||
/**
|
||||
* A subscription for a stream of events indicating when files are (and are
|
||||
* not) being implicitly analyzed.
|
||||
*/
|
||||
StreamController<ImplicitAnalysisEvent> _implicitAnalysisEventsController;
|
||||
|
||||
/**
|
||||
* The listeners that are to be notified when various analysis results are
|
||||
* produced in this context.
|
||||
|
@ -220,6 +226,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
_taskManager, <WorkManager>[dartWorkManager, htmlWorkManager], this);
|
||||
_onSourcesChangedController =
|
||||
new StreamController<SourcesChangedEvent>.broadcast();
|
||||
_implicitAnalysisEventsController =
|
||||
new StreamController<ImplicitAnalysisEvent>.broadcast();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -303,6 +311,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
@override
|
||||
List<Source> get htmlSources => _getSources(SourceKind.HTML);
|
||||
|
||||
@override
|
||||
Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents =>
|
||||
_implicitAnalysisEventsController.stream;
|
||||
|
||||
@override
|
||||
bool get isDisposed => _disposed;
|
||||
|
||||
|
@ -728,6 +740,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
entry.modificationTime = getModificationStamp(target);
|
||||
}
|
||||
_cache.put(entry);
|
||||
if (target is Source) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(target, true));
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
@ -1219,7 +1235,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
for (Source source in missingSources) {
|
||||
if (getLibrariesContaining(source).isEmpty &&
|
||||
getLibrariesDependingOn(source).isEmpty) {
|
||||
_cache.remove(source);
|
||||
_removeFromCache(source);
|
||||
removalCount++;
|
||||
}
|
||||
}
|
||||
|
@ -1427,6 +1443,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
entry.modificationTime = getModificationStamp(source);
|
||||
entry.explicitlyAdded = explicitlyAdded;
|
||||
_cache.put(entry);
|
||||
if (!explicitlyAdded) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(source, true));
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -1637,6 +1657,14 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
}
|
||||
}
|
||||
|
||||
void _removeFromCache(Source source) {
|
||||
CacheEntry entry = _cache.remove(source);
|
||||
if (entry != null && entry.explicitlyAdded) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(source, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given [source] from the priority order if it is in the list.
|
||||
*/
|
||||
|
@ -1658,6 +1686,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
* that referenced the source before it existed.
|
||||
*/
|
||||
void _sourceAvailable(Source source) {
|
||||
// TODO(brianwilkerson) This method needs to check whether the source was
|
||||
// previously being implicitly analyzed. If so, the cache entry needs to be
|
||||
// update to reflect the new status and an event needs to be generated to
|
||||
// inform clients that it is no longer being implicitly analyzed.
|
||||
CacheEntry entry = _cache.get(source);
|
||||
if (entry == null) {
|
||||
_createCacheEntry(source, true);
|
||||
|
@ -1738,7 +1770,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
* Record that the give [source] has been deleted.
|
||||
*/
|
||||
void _sourceDeleted(Source source) {
|
||||
// TODO(brianwilkerson) Implement this.
|
||||
// TODO(brianwilkerson) Implement or remove this.
|
||||
// SourceEntry sourceEntry = _cache.get(source);
|
||||
// if (sourceEntry is HtmlEntry) {
|
||||
// HtmlEntry htmlEntry = sourceEntry;
|
||||
|
@ -1769,7 +1801,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
* Record that the given [source] has been removed.
|
||||
*/
|
||||
void _sourceRemoved(Source source) {
|
||||
_cache.remove(source);
|
||||
_removeFromCache(source);
|
||||
_removeFromPriorityOrder(source);
|
||||
}
|
||||
|
||||
|
|
|
@ -209,8 +209,10 @@ class AnalysisCache {
|
|||
|
||||
/**
|
||||
* Remove all information related to the given [source] from this cache.
|
||||
* Return the entry associated with the source, or `null` if there was cache
|
||||
* entry for the source.
|
||||
*/
|
||||
void remove(Source source) {
|
||||
SourceEntry remove(Source source) {
|
||||
int count = _partitions.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (_partitions[i].contains(source)) {
|
||||
|
@ -223,10 +225,10 @@ class AnalysisCache {
|
|||
JavaSystem.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
_partitions[i].remove(source);
|
||||
return;
|
||||
return _partitions[i].remove(source);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,6 +354,12 @@ abstract class AnalysisContext {
|
|||
*/
|
||||
List<Source> get htmlSources;
|
||||
|
||||
/**
|
||||
* The stream that is notified when a source either starts or stops being
|
||||
* analyzed implicitly.
|
||||
*/
|
||||
Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents;
|
||||
|
||||
/**
|
||||
* Returns `true` if this context was disposed using [dispose].
|
||||
*/
|
||||
|
@ -1033,6 +1041,12 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
*/
|
||||
StreamController<SourcesChangedEvent> _onSourcesChangedController;
|
||||
|
||||
/**
|
||||
* A subscription for a stream of events indicating when files are (and are
|
||||
* not) being implicitly analyzed.
|
||||
*/
|
||||
StreamController<ImplicitAnalysisEvent> _implicitAnalysisEventsController;
|
||||
|
||||
/**
|
||||
* The listeners that are to be notified when various analysis results are
|
||||
* produced in this context.
|
||||
|
@ -1084,6 +1098,8 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
_cache = createCacheFromSourceFactory(null);
|
||||
_onSourcesChangedController =
|
||||
new StreamController<SourcesChangedEvent>.broadcast();
|
||||
_implicitAnalysisEventsController =
|
||||
new StreamController<ImplicitAnalysisEvent>.broadcast();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1197,6 +1213,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
@override
|
||||
List<Source> get htmlSources => _getSources(SourceKind.HTML);
|
||||
|
||||
@override
|
||||
Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents =>
|
||||
_implicitAnalysisEventsController.stream;
|
||||
|
||||
@override
|
||||
bool get isDisposed => _disposed;
|
||||
|
||||
|
@ -2410,7 +2430,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
} else {
|
||||
unitEntry.recordResolutionError(thrownException);
|
||||
}
|
||||
_cache.remove(unitSource);
|
||||
_removeFromCache(unitSource);
|
||||
if (thrownException != null) {
|
||||
throw new AnalysisException('<rethrow>', thrownException);
|
||||
}
|
||||
|
@ -2483,7 +2503,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
} else {
|
||||
unitEntry.recordResolutionError(thrownException);
|
||||
}
|
||||
_cache.remove(unitSource);
|
||||
_removeFromCache(unitSource);
|
||||
if (thrownException != null) {
|
||||
throw new AnalysisException('<rethrow>', thrownException);
|
||||
}
|
||||
|
@ -2513,7 +2533,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
} else {
|
||||
dartEntry.recordResolutionErrorInLibrary(
|
||||
librarySource, thrownException);
|
||||
_cache.remove(source);
|
||||
_removeFromCache(source);
|
||||
}
|
||||
if (source != librarySource) {
|
||||
_workManager.add(source, SourcePriority.PRIORITY_PART);
|
||||
|
@ -2615,7 +2635,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
for (Source source in missingSources) {
|
||||
if (getLibrariesContaining(source).isEmpty &&
|
||||
getLibrariesDependingOn(source).isEmpty) {
|
||||
_cache.remove(source);
|
||||
_removeFromCache(source);
|
||||
removalCount++;
|
||||
}
|
||||
}
|
||||
|
@ -3385,12 +3405,20 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
htmlEntry.modificationTime = getModificationStamp(source);
|
||||
htmlEntry.explicitlyAdded = explicitlyAdded;
|
||||
_cache.put(source, htmlEntry);
|
||||
if (!explicitlyAdded) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(source, true));
|
||||
}
|
||||
return htmlEntry;
|
||||
} else {
|
||||
DartEntry dartEntry = new DartEntry();
|
||||
dartEntry.modificationTime = getModificationStamp(source);
|
||||
dartEntry.explicitlyAdded = explicitlyAdded;
|
||||
_cache.put(source, dartEntry);
|
||||
if (!explicitlyAdded) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(source, true));
|
||||
}
|
||||
return dartEntry;
|
||||
}
|
||||
}
|
||||
|
@ -4108,6 +4136,16 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
AnalysisEngine.instance.logger.logInformation(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all of the analysis listeners that a task is about to be performed.
|
||||
*/
|
||||
void _notifyAboutToPerformTask(String taskDescription) {
|
||||
int count = _listeners.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
_listeners[i].aboutToPerformTask(this, taskDescription);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Notify all of the analysis listeners that the given source is no longer included in the set of
|
||||
// * sources that are being analyzed.
|
||||
|
@ -4186,16 +4224,6 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Notify all of the analysis listeners that a task is about to be performed.
|
||||
*/
|
||||
void _notifyAboutToPerformTask(String taskDescription) {
|
||||
int count = _listeners.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
_listeners[i].aboutToPerformTask(this, taskDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all of the analysis listeners that the errors associated with the
|
||||
* given [source] has been updated to the given [errors].
|
||||
|
@ -4569,6 +4597,14 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
return dartEntry;
|
||||
}
|
||||
|
||||
void _removeFromCache(Source source) {
|
||||
SourceEntry entry = _cache.remove(source);
|
||||
if (entry != null && entry.explicitlyAdded) {
|
||||
_implicitAnalysisEventsController
|
||||
.add(new ImplicitAnalysisEvent(source, false));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given [librarySource] from the list of containing libraries for
|
||||
* all of the parts referenced by the given [dartEntry].
|
||||
|
@ -4581,7 +4617,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
if (partEntry != null && !identical(partEntry, dartEntry)) {
|
||||
partEntry.removeContainingLibrary(librarySource);
|
||||
if (partEntry.containingLibraries.length == 0 && !exists(partSource)) {
|
||||
_cache.remove(partSource);
|
||||
_removeFromCache(partSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4601,7 +4637,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
partEntry.removeContainingLibrary(librarySource);
|
||||
if (partEntry.containingLibraries.length == 0 &&
|
||||
!exists(partSource)) {
|
||||
_cache.remove(partSource);
|
||||
_removeFromCache(partSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4630,6 +4666,10 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
* that referenced the source before it existed.
|
||||
*/
|
||||
void _sourceAvailable(Source source) {
|
||||
// TODO(brianwilkerson) This method needs to check whether the source was
|
||||
// previously being implicitly analyzed. If so, the cache entry needs to be
|
||||
// update to reflect the new status and an event needs to be generated to
|
||||
// inform clients that it is no longer being implicitly analyzed.
|
||||
SourceEntry sourceEntry = _cache.get(source);
|
||||
if (sourceEntry == null) {
|
||||
sourceEntry = _createSourceEntry(source, true);
|
||||
|
@ -4718,7 +4758,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
_invalidateLibraryResolution(librarySource);
|
||||
}
|
||||
}
|
||||
_cache.remove(source);
|
||||
_removeFromCache(source);
|
||||
_workManager.remove(source);
|
||||
_removeFromPriorityOrder(source);
|
||||
}
|
||||
|
@ -6752,11 +6792,13 @@ abstract class CachePartition {
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all information related to the given [source] from this cache.
|
||||
* Remove all information related to the given [source] from this partition.
|
||||
* Return the entry associated with the source, or `null` if there was cache
|
||||
* entry for the source.
|
||||
*/
|
||||
void remove(Source source) {
|
||||
SourceEntry remove(Source source) {
|
||||
_recentlyUsed.remove(source);
|
||||
_sourceMap.remove(source);
|
||||
return _sourceMap.remove(source);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8852,6 +8894,32 @@ class HtmlEntry extends SourceEntry {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An event indicating when a source either starts or stops being implicitly
|
||||
* analyzed.
|
||||
*/
|
||||
class ImplicitAnalysisEvent {
|
||||
/**
|
||||
* The source whose status has changed.
|
||||
*/
|
||||
final Source source;
|
||||
|
||||
/**
|
||||
* A flag indicating whether the source is now being analyzed.
|
||||
*/
|
||||
final bool isAnalyzed;
|
||||
|
||||
/**
|
||||
* Initialize a newly created event to indicate that the given [source] has
|
||||
* changed it status to match the [isAnalyzed] flag.
|
||||
*/
|
||||
ImplicitAnalysisEvent(this.source, this.isAnalyzed);
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'${isAnalyzed ? '' : 'not '}analyzing ${source.fullName}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Instances of the class `IncrementalAnalysisCache` hold information used to perform
|
||||
* incremental analysis.
|
||||
|
|
|
@ -245,6 +245,21 @@ class AnalysisContextImplTest extends EngineTestCase {
|
|||
super.tearDown();
|
||||
}
|
||||
|
||||
Future test_analyzedSources_added() async {
|
||||
AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
|
||||
_context.implicitAnalysisEvents.listen(listener.onData);
|
||||
//
|
||||
// Create a file that references an file that is not explicitly being
|
||||
// analyzed and fully analyze it. Ensure that the listener is told about
|
||||
// the implicitly analyzed file.
|
||||
//
|
||||
Source sourceA = _addSource('/a.dart', "library a; import 'b.dart';");
|
||||
Source sourceB = _createSource('/b.dart', "library b;");
|
||||
_context.computeErrors(sourceA);
|
||||
await pumpEventQueue();
|
||||
listener.expectAnalyzed(sourceB);
|
||||
}
|
||||
|
||||
Future test_applyChanges_add() {
|
||||
SourcesChangedListener listener = new SourcesChangedListener();
|
||||
_context.onSourcesChanged.listen(listener.onData);
|
||||
|
@ -2151,6 +2166,12 @@ library test2;''');
|
|||
_context.applyChanges(changeSet);
|
||||
}
|
||||
|
||||
Source _createSource(String fileName, String contents) {
|
||||
Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
|
||||
_context.setContents(source, contents);
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the given compilation unit for a class with the given name. Return the class with the
|
||||
* given name, or `null` if the class cannot be found.
|
||||
|
@ -2343,6 +2364,48 @@ class AnalysisTaskTest extends EngineTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener used to gather the [ImplicitAnalysisEvent]s that are produced
|
||||
* during analysis.
|
||||
*/
|
||||
class AnalyzedSourcesListener {
|
||||
/**
|
||||
* The events that have been gathered.
|
||||
*/
|
||||
List<ImplicitAnalysisEvent> actualEvents = <ImplicitAnalysisEvent>[];
|
||||
|
||||
/**
|
||||
* The sources that are being implicitly analyzed.
|
||||
*/
|
||||
List<Source> analyzedSources = <Source>[];
|
||||
|
||||
/**
|
||||
* Assert that the given source is currently being implicitly analyzed.
|
||||
*/
|
||||
void expectAnalyzed(Source source) {
|
||||
expect(analyzedSources, contains(source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the given source is not currently being implicitly analyzed.
|
||||
*/
|
||||
void expectNotAnalyzed(Source source) {
|
||||
expect(analyzedSources, isNot(contains(source)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Record that the given event was produced.
|
||||
*/
|
||||
void onData(ImplicitAnalysisEvent event) {
|
||||
actualEvents.add(event);
|
||||
if (event.isAnalyzed) {
|
||||
analyzedSources.add(event.source);
|
||||
} else {
|
||||
analyzedSources.remove(event.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CompilationUnitMock extends TypedMock implements CompilationUnit {
|
||||
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
||||
}
|
||||
|
@ -5468,6 +5531,11 @@ class TestAnalysisContext implements InternalAnalysisContext {
|
|||
return null;
|
||||
}
|
||||
@override
|
||||
Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents {
|
||||
fail("Unexpected invocation of analyzedSources");
|
||||
return null;
|
||||
}
|
||||
@override
|
||||
bool get isDisposed {
|
||||
fail("Unexpected invocation of isDisposed");
|
||||
return false;
|
||||
|
@ -5511,6 +5579,7 @@ class TestAnalysisContext implements InternalAnalysisContext {
|
|||
fail("Unexpected invocation of getPrioritySources");
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
List<AnalysisTarget> get priorityTargets {
|
||||
fail("Unexpected invocation of visitCacheItems");
|
||||
|
@ -5528,7 +5597,6 @@ class TestAnalysisContext implements InternalAnalysisContext {
|
|||
fail("Unexpected invocation of getResolverVisitorFactory");
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
SourceFactory get sourceFactory {
|
||||
fail("Unexpected invocation of getSourceFactory");
|
||||
|
@ -5790,6 +5858,7 @@ class TestAnalysisContext implements InternalAnalysisContext {
|
|||
fail("Unexpected invocation of parseHtmlUnit");
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
AnalysisResult performAnalysisTask() {
|
||||
fail("Unexpected invocation of performAnalysisTask");
|
||||
|
@ -5832,11 +5901,11 @@ class TestAnalysisContext implements InternalAnalysisContext {
|
|||
int oldLength, int newLength) {
|
||||
fail("Unexpected invocation of setChangedContents");
|
||||
}
|
||||
|
||||
@override
|
||||
void setContents(Source source, String contents) {
|
||||
fail("Unexpected invocation of setContents");
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldErrorsBeAnalyzed(Source source, Object entry) {
|
||||
fail("Unexpected invocation of shouldErrorsBeAnalyzed");
|
||||
|
|
|
@ -176,7 +176,7 @@ class AnalysisCacheTest extends AbstractCacheTest {
|
|||
expect(entry2.getValue(result2), 222);
|
||||
expect(entry3.getValue(result3), 333);
|
||||
// remove entry1, invalidate result2 and remove empty entry2
|
||||
cache.remove(target1);
|
||||
expect(cache.remove(target1), entry1);
|
||||
expect(cache.get(target1), isNull);
|
||||
expect(cache.get(target2), isNull);
|
||||
expect(cache.get(target3), entry3);
|
||||
|
@ -197,7 +197,7 @@ class AnalysisCacheTest extends AbstractCacheTest {
|
|||
expect(entry.getValue(result1), 111);
|
||||
expect(entry.getValue(result2), 222);
|
||||
// remove target, invalidate result2
|
||||
cache.remove(target);
|
||||
expect(cache.remove(target), entry);
|
||||
expect(cache.get(target), isNull);
|
||||
expect(entry.getState(result2), CacheState.INVALID);
|
||||
}
|
||||
|
@ -945,13 +945,21 @@ abstract class CachePartitionTest extends EngineTestCase {
|
|||
expect(partition.get(target), entry);
|
||||
}
|
||||
|
||||
void test_remove() {
|
||||
void test_remove_absent() {
|
||||
CachePartition partition = createPartition();
|
||||
AnalysisTarget target = new TestSource();
|
||||
expect(partition.get(target), isNull);
|
||||
expect(partition.remove(target), isNull);
|
||||
expect(partition.get(target), isNull);
|
||||
}
|
||||
|
||||
void test_remove_present() {
|
||||
CachePartition partition = createPartition();
|
||||
AnalysisTarget target = new TestSource();
|
||||
CacheEntry entry = new CacheEntry(target);
|
||||
partition.put(entry);
|
||||
expect(partition.get(target), entry);
|
||||
partition.remove(target);
|
||||
expect(partition.remove(target), entry);
|
||||
expect(partition.get(target), isNull);
|
||||
}
|
||||
}
|
||||
|
@ -1004,6 +1012,12 @@ class UniversalCachePartitionTest extends CachePartitionTest {
|
|||
return new UniversalCachePartition(null);
|
||||
}
|
||||
|
||||
void test_contains() {
|
||||
UniversalCachePartition partition = new UniversalCachePartition(null);
|
||||
TestSource source = new TestSource();
|
||||
expect(partition.isResponsibleFor(source), isTrue);
|
||||
}
|
||||
|
||||
test_dispose() {
|
||||
InternalAnalysisContext context = new _InternalAnalysisContextMock();
|
||||
CachePartition partition1 = new UniversalCachePartition(context);
|
||||
|
@ -1034,12 +1048,6 @@ class UniversalCachePartitionTest extends CachePartitionTest {
|
|||
// result2 is removed from result1
|
||||
expect(entry1.getResultData(descriptor1).dependentResults, isEmpty);
|
||||
}
|
||||
|
||||
void test_contains() {
|
||||
UniversalCachePartition partition = new UniversalCachePartition(null);
|
||||
TestSource source = new TestSource();
|
||||
expect(partition.isResponsibleFor(source), isTrue);
|
||||
}
|
||||
}
|
||||
|
||||
class _InternalAnalysisContextMock extends TypedMock
|
||||
|
|
|
@ -55,6 +55,32 @@ main() {
|
|||
|
||||
@reflectiveTest
|
||||
class AnalysisContextImplTest extends AbstractContextTest {
|
||||
Future fail_analyzedSources_removed() async {
|
||||
AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
|
||||
context.implicitAnalysisEvents.listen(listener.onData);
|
||||
//
|
||||
// Create a file that references an file that is not explicitly being
|
||||
// analyzed and fully analyze it. Ensure that the listener is told about
|
||||
// the implicitly analyzed file.
|
||||
//
|
||||
Source sourceA = newSource('/a.dart', "library a; import 'b.dart';");
|
||||
Source sourceB = newSource('/b.dart', "library b;");
|
||||
ChangeSet changeSet = new ChangeSet();
|
||||
changeSet.addedSource(sourceA);
|
||||
context.applyChanges(changeSet);
|
||||
context.computeErrors(sourceA);
|
||||
await pumpEventQueue();
|
||||
listener.expectAnalyzed(sourceB);
|
||||
//
|
||||
// Remove the reference and ensure that the listener is told that we're no
|
||||
// longer implicitly analyzing the file.
|
||||
//
|
||||
context.setContents(sourceA, "library a;");
|
||||
context.computeErrors(sourceA);
|
||||
await pumpEventQueue();
|
||||
listener.expectNotAnalyzed(sourceB);
|
||||
}
|
||||
|
||||
void fail_performAnalysisTask_importedLibraryDelete_html() {
|
||||
// NOTE: This was failing before converting to the new task model.
|
||||
Source htmlSource = addSource("/page.html", r'''
|
||||
|
@ -90,6 +116,24 @@ class AnalysisContextImplTest extends AbstractContextTest {
|
|||
super.tearDown();
|
||||
}
|
||||
|
||||
Future test_analyzedSources_added() async {
|
||||
AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
|
||||
context.implicitAnalysisEvents.listen(listener.onData);
|
||||
//
|
||||
// Create a file that references an file that is not explicitly being
|
||||
// analyzed and fully analyze it. Ensure that the listener is told about
|
||||
// the implicitly analyzed file.
|
||||
//
|
||||
Source sourceA = newSource('/a.dart', "library a; import 'b.dart';");
|
||||
Source sourceB = newSource('/b.dart', "library b;");
|
||||
ChangeSet changeSet = new ChangeSet();
|
||||
changeSet.addedSource(sourceA);
|
||||
context.applyChanges(changeSet);
|
||||
context.computeErrors(sourceA);
|
||||
await pumpEventQueue();
|
||||
listener.expectAnalyzed(sourceB);
|
||||
}
|
||||
|
||||
Future test_applyChanges_add() {
|
||||
SourcesChangedListener listener = new SourcesChangedListener();
|
||||
context.onSourcesChanged.listen(listener.onData);
|
||||
|
|
Loading…
Reference in a new issue