diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart index 262673be79f..4347bad5dcb 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 @@ library my.lib; } Future 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 de8f23e65c3..8e86727cf2e 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 @@ void f() { } '''); await findElementReferences('fff(p) {}', false); - expect(results, hasLength(1)); - assertHasResult(SearchResultKind.INVOCATION, 'fff(10);'); + // A part without library, no results. + expect(results, isEmpty); } Future 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 0d839ecb354..f6e06684da3 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 @@ void m() { assertSuggestKeywords([]); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 74236cce515..7c1d58ca817 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 @@ void f() { '''); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 31ee4566c29..196a197de0d 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 @@ class A { ''', target: a); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 af26bc4e5b5..0cc45cd40d9 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 @@ void f(A a) { }); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 7566168df10..f7f443f8116 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 @@ void f(A a) { }); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 fea7674ac23..db18da2032d 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 @@ void f(A a) { }); } + @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/49046') Future 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 97198d9b1cf..200ebaf6148 100644 --- a/pkg/analyzer/lib/dart/analysis/results.dart +++ b/pkg/analyzer/lib/dart/analysis/results.dart @@ -195,6 +195,22 @@ abstract class ParseStringResult { 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 522a0c4f0dc..1160d53865b 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart @@ -159,7 +159,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { /// The mapping from the files for which analysis was requested using /// [getResult] to the [Completer]s to report the result. - final _requestedFiles = >>{}; + final _requestedFiles = >>{}; /// The mapping from the files for which analysis was requested using /// [getResolvedLibrary] to the [Completer]s to report the result. @@ -182,35 +182,17 @@ class AnalysisDriver implements AnalysisDriverGeneric { /// The mapping from the files for which errors were requested using /// [getErrors] to the [Completer]s to report the result. - final _errorsRequestedFiles = >>{}; - - /// The requests from [_errorsRequestedFiles] for files which were found to - /// be parts without known libraries, so delayed. - final _errorsRequestedParts = >>{}; + final _errorsRequestedFiles = >>{}; /// The mapping from the files for which the index was requested using /// [getIndex] to the [Completer]s to report the result. final _indexRequestedFiles = - >>{}; + >>{}; /// The mapping from the files for which the unit element was requested using /// [getUnitElement] to the [Completer]s to report the result. final _unitElementRequestedFiles = - >>{}; - - /// 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 = - >>{}; - - /// 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 = >>{}; - - /// The set of part files that are currently scheduled for analysis. - final _partsToAnalyze = {}; + >>{}; /// The controller for the [results] stream. final _resultController = StreamController(); @@ -249,6 +231,11 @@ class AnalysisDriver implements AnalysisDriverGeneric { /// 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { return hasPendingFileChanges || _fileTracker.hasChangedFiles || _requestedFiles.isNotEmpty || - _requestedParts.isNotEmpty || - _fileTracker.hasPendingFiles || - _partsToAnalyze.isNotEmpty; + _fileTracker.hasPendingFiles; } bool get hasPendingFileChanges => _pendingFileChanges.isNotEmpty; @@ -455,11 +440,7 @@ class AnalysisDriver implements AnalysisDriverGeneric { 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { ); } - var completer = Completer(); + var completer = Completer(); _errorsRequestedFiles - .putIfAbsent(path, () => >[]) + .putIfAbsent(path, () => >[]) .add(completer); _scheduler.notify(this); return completer.future; @@ -699,9 +680,9 @@ class AnalysisDriver implements AnalysisDriverGeneric { if (!_fsState.hasUri(path)) { return Future.value(); } - var completer = Completer(); + var completer = Completer(); _indexRequestedFiles - .putIfAbsent(path, () => >[]) + .putIfAbsent(path, () => >[]) .add(completer); _scheduler.notify(this); return completer.future; @@ -918,9 +899,9 @@ class AnalysisDriver implements AnalysisDriverGeneric { } // Schedule analysis. - var completer = Completer(); + var completer = Completer(); _requestedFiles - .putIfAbsent(path, () => >[]) + .putIfAbsent(path, () => >[]) .add(completer); _scheduler.notify(this); return completer.future; @@ -964,9 +945,9 @@ class AnalysisDriver implements AnalysisDriverGeneric { ); } - var completer = Completer(); + var completer = Completer(); _unitElementRequestedFiles - .putIfAbsent(path, () => >[]) + .putIfAbsent(path, () => >[]) .add(completer); _scheduler.notify(this); return completer.future; @@ -1041,10 +1022,8 @@ class AnalysisDriver implements AnalysisDriverGeneric { @override Future performWork() async { - if (!_hasDartCoreDiscovered) { - _hasDartCoreDiscovered = true; - _discoverDartCore(); - } + _discoverDartCore(); + _discoverLibraries(); if (_resolveForCompletionRequests.isNotEmpty) { final request = _resolveForCompletionRequests.removeLast(); @@ -1061,27 +1040,26 @@ class AnalysisDriver implements AnalysisDriverGeneric { // 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { // 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { // 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { } 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { }); } - Future _computeErrors({ + Future _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 _computeIndex(String path) async { - var analysisResult = await _computeAnalysisResult(path, - withUnit: false, asIsIfPartWithoutLibrary: true); - return analysisResult!._index!; + Future _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 @@ class AnalysisDriver implements AnalysisDriverGeneric { /// 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 @@ class AnalysisDriver implements AnalysisDriverGeneric { ); } + 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 0c957aebfed..cef3e1863cd 100644 --- a/pkg/analyzer/lib/src/dart/analysis/results.dart +++ b/pkg/analyzer/lib/src/dart/analysis/results.dart @@ -139,6 +139,15 @@ class ParseStringResultImpl implements ParseStringResult { 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 4d58c072286..5f260ffa757 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -6019,6 +6019,7 @@ CompileTimeErrorCode: implicitly uses the same version as the defining compilation unit: ```dart + %uri="lib/part.dart" part of 'test.dart'; ``` @@ -10939,6 +10940,7 @@ CompileTimeErrorCode: 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 870d899b302..82158beb2c1 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 @@ const a = 1; } 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 60fd9f7ec22..5a963a69062 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 @@ Future f; } 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 @@ var b = new B(); } 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 @@ var b = new B(); // 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().lastWhere((r) => r.path == c); - expect(result.errors, isNotEmpty); + // Now c.dart does not know the library, so invalid result. + allResults + .whereType() + .lastWhere((r) => r.path == c); } } @@ -2949,11 +2930,29 @@ var b = new B(); 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().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() + .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() + .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 ba431f28313..490c06968db 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 @@ class A {} 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 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 90054d29e41..479a695ab64 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 @@ Future zero() async => 0; } 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 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 @@ Future zero() async => 0; } 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 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 3c42768db06..f4b93182eef 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 @@ void main() {C.^ print("something");}'''); 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 86092098468..e1df28b83a2 100644 --- a/pkg/nnbd_migration/test/edge_builder_test.dart +++ b/pkg/nnbd_migration/test/edge_builder_test.dart @@ -5730,10 +5730,9 @@ int f2(int i2) => (i2)/*!*/; Future 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 @@ part 'part.dart'; Future 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 @@ part of test; Future 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 @@ part of test; Future 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'; ''');