Return PartWithoutLibraryResult when a part without its library.
Change-Id: I5eb384d77c263b489b10e112a79115bf028e79af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245081
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart
index 262673b..4347bad 100644
--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_outline_test.dart
@@ -96,6 +96,12 @@
}
Future<void> test_libraryName_hasPartOfDirective() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+library lib;
+
+part 'test.dart';
+''');
+
addTestFile('''
part of my.lib;
''');
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index de8f23e..8e86727 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -742,8 +742,8 @@
}
''');
await findElementReferences('fff(p) {}', false);
- expect(results, hasLength(1));
- assertHasResult(SearchResultKind.INVOCATION, 'fff(10);');
+ // A part without library, no results.
+ expect(results, isEmpty);
}
Future<void> test_parameter() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 0d839ec..f6e0668 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -2272,6 +2272,7 @@
assertSuggestKeywords([]);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_part_of() async {
addTestSource('part of foo;^');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
index 74236cce..7c1d58c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
@@ -105,6 +105,7 @@
''');
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_function_hasZero_partOfName_noLibrary() async {
await resolveTestCode('''
part of my_lib;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
index 31ee456..196a197 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
@@ -79,6 +79,7 @@
''', target: a);
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_inPart_partOfName_noLibrary() async {
await resolveTestCode('''
part of my_lib;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
index af26bc4..0cc45cd 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
@@ -383,6 +383,7 @@
});
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_inPart_self() async {
await resolveTestCode('''
part of lib;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
index 7566168..f7f443f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
@@ -326,6 +326,7 @@
});
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_qualified_instance_inPart_self() async {
await resolveTestCode('''
part of lib;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
index fea7674..db18da2 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_setter_test.dart
@@ -320,6 +320,7 @@
});
}
+ @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046')
Future<void> test_qualified_instance_inPart_self() async {
await resolveTestCode('''
part of lib;
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 97198d9..200ebaf 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -195,6 +195,22 @@
CompilationUnit get unit;
}
+/// The type of [InvalidResult] returned when the file is a part, and its
+/// containing library is not known.
+///
+/// Clients may not extend, implement or mix-in this class.
+///
+/// TODO(scheglov) Add an error that points at the `part of` location.
+abstract class PartWithoutLibraryResult
+ implements
+ InvalidResult,
+ SomeErrorsResult,
+ SomeResolvedUnitResult,
+ SomeUnitElementResult {
+ /// The absolute and normalized path of the file.
+ String get path;
+}
+
/// The result of building resolved AST(s) for the whole library.
///
/// Clients may not extend, implement or mix-in this class.
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 522a0c4..1160d53 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -159,7 +159,7 @@
/// The mapping from the files for which analysis was requested using
/// [getResult] to the [Completer]s to report the result.
- final _requestedFiles = <String, List<Completer<ResolvedUnitResult>>>{};
+ final _requestedFiles = <String, List<Completer<SomeResolvedUnitResult>>>{};
/// The mapping from the files for which analysis was requested using
/// [getResolvedLibrary] to the [Completer]s to report the result.
@@ -182,35 +182,17 @@
/// The mapping from the files for which errors were requested using
/// [getErrors] to the [Completer]s to report the result.
- final _errorsRequestedFiles = <String, List<Completer<ErrorsResult>>>{};
-
- /// The requests from [_errorsRequestedFiles] for files which were found to
- /// be parts without known libraries, so delayed.
- final _errorsRequestedParts = <String, List<Completer<ErrorsResult>>>{};
+ final _errorsRequestedFiles = <String, List<Completer<SomeErrorsResult>>>{};
/// The mapping from the files for which the index was requested using
/// [getIndex] to the [Completer]s to report the result.
final _indexRequestedFiles =
- <String, List<Completer<AnalysisDriverUnitIndex>>>{};
+ <String, List<Completer<AnalysisDriverUnitIndex?>>>{};
/// The mapping from the files for which the unit element was requested using
/// [getUnitElement] to the [Completer]s to report the result.
final _unitElementRequestedFiles =
- <String, List<Completer<UnitElementResult>>>{};
-
- /// The mapping from the files for which the unit element was requested using
- /// [getUnitElement], and which were found to be parts without known
- /// libraries, to the [Completer]s to report the result.
- final _unitElementRequestedParts =
- <String, List<Completer<UnitElementResult>>>{};
-
- /// The mapping from the files for which analysis was requested using
- /// [getResult], and which were found to be parts without known libraries,
- /// to the [Completer]s to report the result.
- final _requestedParts = <String, List<Completer<ResolvedUnitResult>>>{};
-
- /// The set of part files that are currently scheduled for analysis.
- final _partsToAnalyze = <String>{};
+ <String, List<Completer<SomeUnitElementResult>>>{};
/// The controller for the [results] stream.
final _resultController = StreamController<Object>();
@@ -249,6 +231,11 @@
/// Whether `dart:core` has been transitively discovered.
bool _hasDartCoreDiscovered = false;
+ /// This flag is reset to `false` when a new file is added, because it
+ /// might be a library, so that some files that were disconnected parts
+ /// could be analyzed now.
+ bool _hasLibrariesDiscovered = false;
+
/// If testing data is being retained, a pointer to the object that is
/// retaining the testing data. Otherwise `null`.
final TestingData? testingData;
@@ -311,9 +298,7 @@
return hasPendingFileChanges ||
_fileTracker.hasChangedFiles ||
_requestedFiles.isNotEmpty ||
- _requestedParts.isNotEmpty ||
- _fileTracker.hasPendingFiles ||
- _partsToAnalyze.isNotEmpty;
+ _fileTracker.hasPendingFiles;
}
bool get hasPendingFileChanges => _pendingFileChanges.isNotEmpty;
@@ -455,11 +440,7 @@
if (_fileTracker.hasPendingFiles) {
return AnalysisDriverPriority.general;
}
- if (_errorsRequestedParts.isNotEmpty ||
- _requestedParts.isNotEmpty ||
- _partsToAnalyze.isNotEmpty ||
- _unitElementRequestedParts.isNotEmpty ||
- _pendingFileChangesCompleters.isNotEmpty) {
+ if (_pendingFileChangesCompleters.isNotEmpty) {
return AnalysisDriverPriority.general;
}
return AnalysisDriverPriority.nothing;
@@ -627,9 +608,9 @@
);
}
- var completer = Completer<ErrorsResult>();
+ var completer = Completer<SomeErrorsResult>();
_errorsRequestedFiles
- .putIfAbsent(path, () => <Completer<ErrorsResult>>[])
+ .putIfAbsent(path, () => <Completer<SomeErrorsResult>>[])
.add(completer);
_scheduler.notify(this);
return completer.future;
@@ -699,9 +680,9 @@
if (!_fsState.hasUri(path)) {
return Future.value();
}
- var completer = Completer<AnalysisDriverUnitIndex>();
+ var completer = Completer<AnalysisDriverUnitIndex?>();
_indexRequestedFiles
- .putIfAbsent(path, () => <Completer<AnalysisDriverUnitIndex>>[])
+ .putIfAbsent(path, () => <Completer<AnalysisDriverUnitIndex?>>[])
.add(completer);
_scheduler.notify(this);
return completer.future;
@@ -918,9 +899,9 @@
}
// Schedule analysis.
- var completer = Completer<ResolvedUnitResult>();
+ var completer = Completer<SomeResolvedUnitResult>();
_requestedFiles
- .putIfAbsent(path, () => <Completer<ResolvedUnitResult>>[])
+ .putIfAbsent(path, () => <Completer<SomeResolvedUnitResult>>[])
.add(completer);
_scheduler.notify(this);
return completer.future;
@@ -964,9 +945,9 @@
);
}
- var completer = Completer<UnitElementResult>();
+ var completer = Completer<SomeUnitElementResult>();
_unitElementRequestedFiles
- .putIfAbsent(path, () => <Completer<UnitElementResult>>[])
+ .putIfAbsent(path, () => <Completer<SomeUnitElementResult>>[])
.add(completer);
_scheduler.notify(this);
return completer.future;
@@ -1041,10 +1022,8 @@
@override
Future<void> performWork() async {
- if (!_hasDartCoreDiscovered) {
- _hasDartCoreDiscovered = true;
- _discoverDartCore();
- }
+ _discoverDartCore();
+ _discoverLibraries();
if (_resolveForCompletionRequests.isNotEmpty) {
final request = _resolveForCompletionRequests.removeLast();
@@ -1061,27 +1040,26 @@
// Analyze a requested file.
if (_requestedFiles.isNotEmpty) {
- String path = _requestedFiles.keys.first;
+ final path = _requestedFiles.keys.first;
+ final completers = _requestedFiles.remove(path)!;
+ _fileTracker.fileWasAnalyzed(path);
try {
- var result = await _computeAnalysisResult(path, withUnit: true);
- // If a part without a library, delay its analysis.
- if (result == null) {
- _requestedParts
- .putIfAbsent(path, () => [])
- .addAll(_requestedFiles.remove(path)!);
- return;
+ final result = await _computeAnalysisResult(path, withUnit: true);
+ final SomeResolvedUnitResult unitResult;
+ if (result != null) {
+ unitResult = result.unitResult!;
+ } else {
+ unitResult = PartWithoutLibraryResultImpl(
+ path: path,
+ );
}
- // Notify the completers.
- for (var completer in _requestedFiles.remove(path)!) {
- completer.complete(result.unitResult!);
+ for (final completer in completers) {
+ completer.complete(unitResult);
}
- // Remove from to be analyzed and produce it now.
- _fileTracker.fileWasAnalyzed(path);
- _resultController.add(result.unitResult!);
+ _resultController.add(unitResult);
} catch (exception, stackTrace) {
_reportException(path, exception, stackTrace);
- _fileTracker.fileWasAnalyzed(path);
- for (var completer in _requestedFiles.remove(path)!) {
+ for (final completer in completers) {
completer.completeError(exception, stackTrace);
}
_clearLibraryContextAfterException();
@@ -1112,14 +1090,10 @@
var completers = _errorsRequestedFiles.remove(path)!;
var result = await _computeErrors(
path: path,
- asIsIfPartWithoutLibrary: false,
);
- if (result != null) {
- for (var completer in completers) {
- completer.complete(result);
- }
- } else {
- _errorsRequestedParts.putIfAbsent(path, () => []).addAll(completers);
+ result ??= PartWithoutLibraryResultImpl(path: path);
+ for (var completer in completers) {
+ completer.complete(result);
}
return;
}
@@ -1127,7 +1101,7 @@
// Process an index request.
if (_indexRequestedFiles.isNotEmpty) {
String path = _indexRequestedFiles.keys.first;
- AnalysisDriverUnitIndex index = await _computeIndex(path);
+ final index = await _computeIndex(path);
for (var completer in _indexRequestedFiles.remove(path)!) {
completer.complete(index);
}
@@ -1137,16 +1111,11 @@
// Process a unit element request.
if (_unitElementRequestedFiles.isNotEmpty) {
String path = _unitElementRequestedFiles.keys.first;
- UnitElementResult? result = await _computeUnitElement(path);
var completers = _unitElementRequestedFiles.remove(path)!;
- if (result != null) {
- for (var completer in completers) {
- completer.complete(result);
- }
- } else {
- _unitElementRequestedParts
- .putIfAbsent(path, () => [])
- .addAll(completers);
+ SomeUnitElementResult? result = await _computeUnitElement(path);
+ result ??= PartWithoutLibraryResultImpl(path: path);
+ for (var completer in completers) {
+ completer.complete(result);
}
return;
}
@@ -1186,7 +1155,14 @@
try {
var result = await _computeAnalysisResult(path, withUnit: true);
if (result == null) {
- _partsToAnalyze.add(path);
+ // We report an invalid result (instead of silently ignoring
+ // this disconnected part) so that the listener of the stream
+ // knows, and for example removes all errors.
+ _resultController.add(
+ PartWithoutLibraryResultImpl(
+ path: path,
+ ),
+ );
} else {
_resultController.add(result.unitResult!);
}
@@ -1208,7 +1184,11 @@
var result = await _computeAnalysisResult(path,
withUnit: false, skipIfSameSignature: true);
if (result == null) {
- _partsToAnalyze.add(path);
+ _resultController.add(
+ PartWithoutLibraryResultImpl(
+ path: path,
+ ),
+ );
} else if (result.isUnchangedErrors) {
// We found that the set of errors is the same as we produced the
// last time, so we don't need to produce it again now.
@@ -1224,79 +1204,6 @@
}
return;
}
-
- // Analyze a requested part file.
- if (_requestedParts.isNotEmpty) {
- String path = _requestedParts.keys.first;
- try {
- var result = await _computeAnalysisResult(path,
- withUnit: true, asIsIfPartWithoutLibrary: true);
- result!;
- // Notify the completers.
- for (var completer in _requestedParts.remove(path)!) {
- completer.complete(result.unitResult!);
- }
- // Remove from to be analyzed and produce it now.
- _partsToAnalyze.remove(path);
- _resultController.add(result.unitResult!);
- } catch (exception, stackTrace) {
- _reportException(path, exception, stackTrace);
- _partsToAnalyze.remove(path);
- for (var completer in _requestedParts.remove(path)!) {
- completer.completeError(exception, stackTrace);
- }
- _clearLibraryContextAfterException();
- }
- return;
- }
-
- // Analyze a general part.
- if (_partsToAnalyze.isNotEmpty) {
- String path = _partsToAnalyze.first;
- _partsToAnalyze.remove(path);
- try {
- var withUnit = _priorityFiles.contains(path);
- if (withUnit) {
- var result = await _computeAnalysisResult(path,
- withUnit: true, asIsIfPartWithoutLibrary: true);
- _resultController.add(result!.unitResult!);
- } else {
- var result = await _computeAnalysisResult(path,
- withUnit: false, asIsIfPartWithoutLibrary: true);
- _resultController.add(result!.errorsResult!);
- }
- } catch (exception, stackTrace) {
- _reportException(path, exception, stackTrace);
- _clearLibraryContextAfterException();
- }
- return;
- }
-
- // Process a unit element request for a part.
- if (_unitElementRequestedParts.isNotEmpty) {
- String path = _unitElementRequestedParts.keys.first;
- var result =
- await _computeUnitElement(path, asIsIfPartWithoutLibrary: true);
- result!;
- for (var completer in _unitElementRequestedParts.remove(path)!) {
- completer.complete(result);
- }
- return;
- }
-
- // Compute errors in a part.
- if (_errorsRequestedParts.isNotEmpty) {
- var path = _errorsRequestedParts.keys.first;
- var completers = _errorsRequestedParts.remove(path)!;
- var result = await _computeErrors(
- path: path,
- asIsIfPartWithoutLibrary: true,
- );
- for (var completer in completers) {
- completer.complete(result);
- }
- return;
- }
}
/// Remove the file with the given [path] from the list of files to analyze.
@@ -1496,24 +1403,16 @@
});
}
- Future<ErrorsResult?> _computeErrors({
+ Future<SomeErrorsResult?> _computeErrors({
required String path,
- required bool asIsIfPartWithoutLibrary,
}) async {
- var analysisResult = await _computeAnalysisResult(path,
- withUnit: false, asIsIfPartWithoutLibrary: asIsIfPartWithoutLibrary);
-
- if (analysisResult == null) {
- return null;
- }
-
- return analysisResult.errorsResult;
+ var analysisResult = await _computeAnalysisResult(path, withUnit: false);
+ return analysisResult?.errorsResult;
}
- Future<AnalysisDriverUnitIndex> _computeIndex(String path) async {
- var analysisResult = await _computeAnalysisResult(path,
- withUnit: false, asIsIfPartWithoutLibrary: true);
- return analysisResult!._index!;
+ Future<AnalysisDriverUnitIndex?> _computeIndex(String path) async {
+ var analysisResult = await _computeAnalysisResult(path, withUnit: false);
+ return analysisResult?._index;
}
/// Return the newly computed resolution result of the library with the
@@ -1646,6 +1545,11 @@
/// The current workaround for this is to discover `dart:core` before any
/// analysis.
void _discoverDartCore() {
+ if (_hasDartCoreDiscovered) {
+ return;
+ }
+ _hasDartCoreDiscovered = true;
+
_fsState.getFileForUri(Uri.parse('dart:core')).map(
(file) {
file?.transitiveFiles;
@@ -1654,6 +1558,17 @@
);
}
+ void _discoverLibraries() {
+ if (_hasLibrariesDiscovered) {
+ return;
+ }
+ _hasLibrariesDiscovered = true;
+
+ for (final path in _fileTracker.addedFiles) {
+ _fsState.getFileForPath(path);
+ }
+ }
+
void _fillSalt() {
_fillSaltForUnlinked();
_fillSaltForElements();
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index 0c957ae..cef3e18 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -139,6 +139,15 @@
LineInfo get lineInfo => unit.lineInfo;
}
+class PartWithoutLibraryResultImpl implements PartWithoutLibraryResult {
+ @override
+ final String path;
+
+ PartWithoutLibraryResultImpl({
+ required this.path,
+ });
+}
+
class ResolvedForCompletionResultImpl {
final AnalysisSession analysisSession;
final String path;
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 4d58c07..5f260ff 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -6019,6 +6019,7 @@
implicitly uses the same version as the defining compilation unit:
```dart
+ %uri="lib/part.dart"
part of 'test.dart';
```
@@ -10939,6 +10940,7 @@
by URI:
```dart
+ %uri="lib/part_file.dart"
part of 'test.dart';
```
POSITIONAL_SUPER_FORMAL_PARAMETER_WITH_POSITIONAL_ARGUMENT:
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 870d899..82158be 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -270,15 +270,20 @@
}
test_annotation_onDirective_partOf() async {
- newFile('$testPackageLibPath/a.dart', r'''
+ final a = newFile('$testPackageLibPath/a.dart', r'''
part 'test.dart';
''');
+
addTestFile(r'''
@a
part of 'a.dart';
const a = 1;
''');
+
+ // Make sure that the part knows its library.
+ contextFor(a.path).currentSession.getParsedUnit(a.path);
+
await resolveTestFile();
var directive = findNode.partOf('a.dart');
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 60fd9f7..5a963a6 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -2734,21 +2734,15 @@
}
test_part_getResult_noLibrary() async {
- var c = convertPath('/test/lib/c.dart');
- newFile(c, r'''
+ final c = newFile('/test/lib/c.dart', r'''
part of a;
class C {}
-var a = new A();
-var b = new B();
''');
- driver.addFile(c);
-
- // There is no library which c.dart is a part of, so it has unresolved
- // A and B references.
- ResolvedUnitResult result = await driver.getResultValid(c);
- expect(result.errors, isNotEmpty);
- expect(result.unit, isNotNull);
+ // There is no library which c.dart is a part of, so invalid result.
+ final result = await driver.getResult(c.path);
+ result as PartWithoutLibraryResult;
+ expect(result.path, c.path);
}
test_part_getUnitElement_afterLibrary() async {
@@ -2829,28 +2823,14 @@
}
test_part_getUnitElement_noLibrary() async {
- var c = convertPath('/test/lib/c.dart');
- newFile(c, r'''
+ final c = newFile('/test/lib/c.dart', r'''
part of a;
-var a = new A();
-var b = new B();
''');
- driver.addFile(c);
-
- // We don't know the library of c.dart, but we should get a result.
- // The types "A" and "B" are unresolved.
- {
- var result = await driver.getUnitElement(c);
- result as UnitElementResult;
- var partUnit = result.element;
-
- expect(partUnit.topLevelVariables[0].name, 'a');
- assertType(partUnit.topLevelVariables[0].type, 'dynamic');
-
- expect(partUnit.topLevelVariables[1].name, 'b');
- assertType(partUnit.topLevelVariables[1].type, 'dynamic');
- }
+ // We don't know the library of c.dart, so invalid result.
+ var result = await driver.getUnitElement(c.path);
+ result as PartWithoutLibraryResult;
+ expect(result.path, c.path);
}
test_part_results_afterLibrary() async {
@@ -2889,15 +2869,16 @@
// Update a.dart so that c.dart is not a part.
{
+ allResults.clear();
+
modifyFile(a, '// does not use c.dart anymore');
driver.changeFile(a);
await waitForIdleWithoutExceptions();
- // Now c.dart does not have a library context, so A and B cannot be
- // resolved, so there are errors.
- var result =
- allResults.whereType<ErrorsResult>().lastWhere((r) => r.path == c);
- expect(result.errors, isNotEmpty);
+ // Now c.dart does not know the library, so invalid result.
+ allResults
+ .whereType<PartWithoutLibraryResult>()
+ .lastWhere((r) => r.path == c);
}
}
@@ -2949,11 +2930,29 @@
await waitForIdleWithoutExceptions();
- // There is no library which c.dart is a part of, so it has unresolved
- // A and B references.
- var result =
- allResults.whereType<ErrorsResult>().lastWhere((r) => r.path == c);
- expect(result.errors, isNotEmpty);
+ // We don't know the library for `c.dart`, so report an invalid result.
+ allResults
+ .whereType<PartWithoutLibraryResult>()
+ .lastWhere((result) => result.path == c);
+ }
+
+ test_part_results_noLibrary_priority() async {
+ var c = newFile('/test/lib/c.dart', r'''
+part of a;
+class C {}
+var a = new A();
+var b = new B();
+''');
+
+ driver.addFile(c.path);
+ driver.priorityFiles = [c.path];
+
+ await waitForIdleWithoutExceptions();
+
+ // We don't know the library for `c.dart`, so report an invalid result.
+ allResults
+ .whereType<PartWithoutLibraryResult>()
+ .lastWhere((result) => result.path == c.path);
}
test_part_results_priority_beforeLibrary() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index ba431f2..490c069 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -2526,24 +2526,6 @@
expect(c.id, endsWith('c.dart;C'));
}
- test_subtypes_class_partWithoutLibrary() async {
- await resolveTestCode('''
-part of lib;
-
-class A {}
-class B extends A {}
-''');
- var a = findElement.class_('A');
-
- List<SubtypeResult> subtypes =
- await driver.search.subtypes(SearchedFiles(), type: a);
- expect(subtypes, hasLength(1));
-
- SubtypeResult b = subtypes.singleWhere((r) => r.name == 'B');
- expect(b.libraryUri, testUriStr);
- expect(b.id, '$testUriStr;$testUriStr;B');
- }
-
test_subtypes_enum() async {
await resolveTestCode('''
class A {}
diff --git a/pkg/analyzer/test/src/diagnostics/sdk_version_async_exported_from_core_test.dart b/pkg/analyzer/test/src/diagnostics/sdk_version_async_exported_from_core_test.dart
index 90054d2..479a695 100644
--- a/pkg/analyzer/test/src/diagnostics/sdk_version_async_exported_from_core_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/sdk_version_async_exported_from_core_test.dart
@@ -2,9 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../dart/resolution/context_collection_resolution.dart';
import 'sdk_constraint_verifier_support.dart';
main() {
@@ -49,14 +52,31 @@
}
test_equals_implicitImportOfCore_inPart() async {
- newFile('/lib.dart', '''
+ writeTestPackagePubspecYamlFile(
+ PubspecYamlFileConfig(
+ sdkVersion: '>=2.1.0',
+ ),
+ );
+
+ final lib = newFile('$testPackageLibPath/lib.dart', '''
library lib;
+
+part 'a.dart';
''');
- await verifyVersion('2.1.0', '''
+
+ final a = newFile('$testPackageLibPath/a.dart', r'''
part of lib;
Future<int> zero() async => 0;
''');
+
+ final analysisSession = contextFor(lib.path).currentSession;
+ final resolvedLibrary = await analysisSession.getResolvedLibrary(lib.path);
+ resolvedLibrary as ResolvedLibraryResult;
+
+ final resolvedPart = resolvedLibrary.units.last;
+ expect(resolvedPart.path, a.path);
+ assertErrorsInList(resolvedPart.errors, []);
}
test_lessThan_explicitImportOfAsync() async {
@@ -97,14 +117,31 @@
}
test_lessThan_implicitImportOfCore_inPart() async {
- newFile('/lib.dart', '''
+ writeTestPackagePubspecYamlFile(
+ PubspecYamlFileConfig(
+ sdkVersion: '>=2.0.0',
+ ),
+ );
+
+ final lib = newFile('$testPackageLibPath/lib.dart', '''
library lib;
+
+part 'a.dart';
''');
- await verifyVersion('2.0.0', '''
+
+ final a = newFile('$testPackageLibPath/a.dart', r'''
part of lib;
Future<int> zero() async => 0;
-''', expectedErrors: [
+''');
+
+ final analysisSession = contextFor(lib.path).currentSession;
+ final resolvedLibrary = await analysisSession.getResolvedLibrary(lib.path);
+ resolvedLibrary as ResolvedLibraryResult;
+
+ final resolvedPart = resolvedLibrary.units.last;
+ expect(resolvedPart.path, a.path);
+ assertErrorsInList(resolvedPart.errors, [
error(HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE, 14, 6),
]);
}
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 3c42768..f4b9318 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -3068,16 +3068,17 @@
int T1;
F1() { }
class X {X.c(); X._d(); z() {}}''');
- addSource('/home/test/lib/a.dart', '''
+ final a = newFile('/home/test/lib/a.dart', '''
library libA;
import 'b.dart';
- part "$testFile";
+ part 'test.dart';
class A { }
var m;''');
addTestSource('''
part of libA;
class B { B.bar(int x); }
main() {new ^}''');
+ await resolveFile(a.path);
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 8609209..e1df28b 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -5730,10 +5730,9 @@
Future<void> test_part_metadata() async {
var pathContext = resourceProvider.pathContext;
addSource(pathContext.join(pathContext.dirname(testFile), 'part.dart'), '''
-part of test;
+part of 'test.dart';
''');
await analyze('''
-library test;
@deprecated
part 'part.dart';
''');
@@ -5744,10 +5743,13 @@
Future<void> test_part_of_identifier() async {
var pathContext = resourceProvider.pathContext;
var testFileName = pathContext.basename(testFile);
- addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
+ var libPath = pathContext.join(pathContext.dirname(testFile), 'lib.dart');
+ addSource(libPath, '''
library test;
part '$testFileName';
''');
+ // Discover the library for the part.
+ session.getParsedUnit(libPath);
await analyze('''
part of test;
''');
@@ -5758,13 +5760,16 @@
Future<void> test_part_of_metadata() async {
var pathContext = resourceProvider.pathContext;
var testFileName = pathContext.basename(testFile);
- addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
-library test;
+ var libPath = pathContext.join(pathContext.dirname(testFile), 'lib.dart');
+ addSource(libPath, '''
part '$testFileName';
''');
+ // TODO(scheglov) This should not be necessary, we use URI, so can find it.
+ // Discover the library for the part.
+ session.getParsedUnit(libPath);
await analyze('''
@deprecated
-part of test;
+part of 'lib.dart';
''');
// No assertions needed; the AnnotationTracker mixin verifies that the
// metadata was visited.
@@ -5773,9 +5778,13 @@
Future<void> test_part_of_path() async {
var pathContext = resourceProvider.pathContext;
var testFileName = pathContext.basename(testFile);
- addSource(pathContext.join(pathContext.dirname(testFile), 'lib.dart'), '''
+ var libPath = pathContext.join(pathContext.dirname(testFile), 'lib.dart');
+ addSource(libPath, '''
part '$testFileName';
''');
+ // TODO(scheglov) This should not be necessary, we use URI, so can find it.
+ // Discover the library for the part.
+ session.getParsedUnit(libPath);
await analyze('''
part of 'lib.dart';
''');