mirror of
https://github.com/dart-lang/sdk
synced 2024-10-07 10:14:53 +00:00
Issue 47804. Recompute invlaidated libraries after processing all changed files.
The issue has the discussion. Bug: https://github.com/dart-lang/sdk/issues/47804 Change-Id: I301fe8fe44b0e8e7e3b413df0363fabc44061c7d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/221564 Reviewed-by: Samuel Rawlins <srawlins@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
44b93338d9
commit
6091533c6e
|
@ -504,6 +504,10 @@ class DeclarationsTracker {
|
|||
/// The list of changed file paths.
|
||||
final List<String> _changedPaths = [];
|
||||
|
||||
/// While processing [_changedPaths] we accumulate libraries here.
|
||||
/// Then we process all of them at once, and reset to the empty set.
|
||||
Set<_File> _invalidatedLibraries = {};
|
||||
|
||||
/// The list of files scheduled for processing. It may include parts and
|
||||
/// libraries, but parts are ignored when we detect them.
|
||||
final List<_ScheduledFile> _scheduledFiles = [];
|
||||
|
@ -529,7 +533,9 @@ class DeclarationsTracker {
|
|||
_whenKnownFilesPulled = now;
|
||||
pullKnownFiles();
|
||||
}
|
||||
return _changedPaths.isNotEmpty || _scheduledFiles.isNotEmpty;
|
||||
return _changedPaths.isNotEmpty ||
|
||||
_invalidatedLibraries.isNotEmpty ||
|
||||
_scheduledFiles.isNotEmpty;
|
||||
}
|
||||
|
||||
/// Add the [analysisContext], so that its libraries are reported via the
|
||||
|
@ -595,6 +601,13 @@ class DeclarationsTracker {
|
|||
return;
|
||||
}
|
||||
|
||||
// There are no more changes as far as we know.
|
||||
// So, recompute exported declarations for all invalidated libraries.
|
||||
if (_invalidatedLibraries.isNotEmpty) {
|
||||
_processInvalidatedLibraries(_invalidatedLibraries);
|
||||
_invalidatedLibraries = {};
|
||||
}
|
||||
|
||||
if (_scheduledFiles.isNotEmpty) {
|
||||
var scheduledFile = _scheduledFiles.removeLast();
|
||||
var file = _getFileByPath(scheduledFile.context, [], scheduledFile.path)!;
|
||||
|
@ -794,10 +807,32 @@ class DeclarationsTracker {
|
|||
_invalidateExportedDeclarations(invalidatedLibraries, newLibrary);
|
||||
}
|
||||
}
|
||||
_computeExportedDeclarations(invalidatedLibraries);
|
||||
|
||||
var changedLibraries = <Library>[];
|
||||
// Don't compute exported declarations now, there might be more changes.
|
||||
// Instead, accumulate invalidated libraries, and recompute all later.
|
||||
_invalidatedLibraries.addAll(invalidatedLibraries);
|
||||
|
||||
var removedLibraries = <int>[];
|
||||
for (var libraryFile in invalidatedLibraries) {
|
||||
if (!libraryFile.exists) {
|
||||
_idToLibrary.remove(libraryFile.id);
|
||||
removedLibraries.add(libraryFile.id);
|
||||
}
|
||||
}
|
||||
for (var file in notLibraries) {
|
||||
_idToLibrary.remove(file.id);
|
||||
removedLibraries.add(file.id);
|
||||
}
|
||||
if (removedLibraries.isNotEmpty) {
|
||||
_changesController.add(
|
||||
LibraryChange._([], removedLibraries),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _processInvalidatedLibraries(Set<_File> invalidatedLibraries) {
|
||||
_computeExportedDeclarations(invalidatedLibraries);
|
||||
var changedLibraries = <Library>[];
|
||||
for (var libraryFile in invalidatedLibraries) {
|
||||
if (libraryFile.exists) {
|
||||
var library = Library._(
|
||||
|
@ -809,17 +844,10 @@ class DeclarationsTracker {
|
|||
);
|
||||
_idToLibrary[library.id] = library;
|
||||
changedLibraries.add(library);
|
||||
} else {
|
||||
_idToLibrary.remove(libraryFile.id);
|
||||
removedLibraries.add(libraryFile.id);
|
||||
}
|
||||
}
|
||||
for (var file in notLibraries) {
|
||||
_idToLibrary.remove(file.id);
|
||||
removedLibraries.add(file.id);
|
||||
}
|
||||
_changesController.add(
|
||||
LibraryChange._(changedLibraries, removedLibraries),
|
||||
LibraryChange._(changedLibraries, []),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -914,6 +914,75 @@ class C2 {}
|
|||
]);
|
||||
}
|
||||
|
||||
/// https://github.com/dart-lang/sdk/issues/47804
|
||||
test_updated_exported2() async {
|
||||
var a = convertPath('/home/test/lib/a.dart');
|
||||
var b = convertPath('/home/test/lib/b.dart');
|
||||
var c = convertPath('/home/test/lib/c.dart');
|
||||
|
||||
newFile(a, content: r'''
|
||||
class A {}
|
||||
''');
|
||||
newFile(b, content: r'''
|
||||
class B {}
|
||||
''');
|
||||
newFile(c, content: r'''
|
||||
export 'a.dart';
|
||||
export 'b.dart';
|
||||
class C {}
|
||||
''');
|
||||
tracker.addContext(testAnalysisContext);
|
||||
|
||||
await _doAllTrackerWork();
|
||||
_assertHasLibrary('package:test/c.dart', declarations: [
|
||||
_ExpectedDeclaration.class_('A', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
_ExpectedDeclaration.class_('B', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
_ExpectedDeclaration.class_('C', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
]);
|
||||
|
||||
changes.clear();
|
||||
|
||||
newFile(a, content: r'''
|
||||
class A2 {}
|
||||
''');
|
||||
newFile(b, content: r'''
|
||||
class B2 {}
|
||||
''');
|
||||
tracker.changeFile(a);
|
||||
tracker.changeFile(b);
|
||||
await _doAllTrackerWork();
|
||||
|
||||
// In general it is OK to get duplicate libraries.
|
||||
// But here we notified about both `a.dart` and `b.dart` changes before
|
||||
// performing any work. So, there is no reason do handle `c.dart` twice.
|
||||
var uniquePathSet = <String>{};
|
||||
for (var change in changes) {
|
||||
for (var library in change.changed) {
|
||||
if (!uniquePathSet.add(library.path)) {
|
||||
fail('Not unique path: ${library.path}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_assertHasLibrary('package:test/c.dart', declarations: [
|
||||
_ExpectedDeclaration.class_('A2', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
_ExpectedDeclaration.class_('B2', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
_ExpectedDeclaration.class_('C', [
|
||||
_ExpectedDeclaration.constructor(''),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
test_updated_library() async {
|
||||
var a = convertPath('/home/test/lib/a.dart');
|
||||
var b = convertPath('/home/test/lib/b.dart');
|
||||
|
|
Loading…
Reference in a new issue