Version 2.18.0-163.0.dev Merge commit '74d1c7ffdb86e8920cd8f78012c5097513a7eb97' into 'dev'
diff --git a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart index 95b14ff..626004f 100644 --- a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart +++ b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
@@ -61,27 +61,10 @@ if (sessionData == null) { return; } - // Send session data. - var endTime = DateTime.now().millisecondsSinceEpoch; - var duration = endTime - sessionData.startTime.millisecondsSinceEpoch; - analytics.sendEvent('language_server', 'session', parameters: { - 'flags': sessionData.commandLineArguments, - 'clientId': sessionData.clientId, - 'sdkVersion': sessionData.sdkVersion, - 'duration': duration.toString(), - 'plugins': _pluginData.usageCountData, - }); - // Send response data. - for (var data in _completedRequests.values) { - analytics.sendEvent('language_server', 'request', parameters: { - 'latency': data.latencyTimes.toAnalyticsString(), - 'name': data.method, - 'duration': data.responseTimes.toAnalyticsString(), - // TODO(brianwilkerson) Report the latencies for each of the plugins, - // probably as a map from plugin name to latency information. - 'plugins': '', - }); - } + _sendSessionData(sessionData); + _sendServerResponseTimes(); + _sendPluginResponseTimes(); + analytics.waitForLastPing(timeout: Duration(milliseconds: 200)).then((_) { analytics.close(); }); @@ -138,6 +121,44 @@ var responseTime = sendTime.millisecondsSinceEpoch - startTime; requestData.responseTimes.addValue(responseTime); } + + /// Send information about the response times of plugins. + void _sendPluginResponseTimes() { + var responseTimes = PluginManager.pluginResponseTimes; + for (var pluginEntry in responseTimes.entries) { + for (var responseEntry in pluginEntry.value.entries) { + analytics.sendEvent('language_server', 'pluginRequest', parameters: { + 'pluginId': pluginEntry.key.pluginId, + 'method': responseEntry.key, + 'duration': responseEntry.value.toAnalyticsString(), + }); + } + } + } + + /// Send information about the response times of server. + void _sendServerResponseTimes() { + for (var data in _completedRequests.values) { + analytics.sendEvent('language_server', 'request', parameters: { + 'latency': data.latencyTimes.toAnalyticsString(), + 'method': data.method, + 'duration': data.responseTimes.toAnalyticsString(), + }); + } + } + + /// Send information about the session. + void _sendSessionData(_SessionData sessionData) { + var endTime = DateTime.now().millisecondsSinceEpoch; + var duration = endTime - sessionData.startTime.millisecondsSinceEpoch; + analytics.sendEvent('language_server', 'session', parameters: { + 'flags': sessionData.commandLineArguments, + 'clientId': sessionData.clientId, + 'sdkVersion': sessionData.sdkVersion, + 'duration': duration.toString(), + 'plugins': _pluginData.usageCountData, + }); + } } /// Data about a request that was received and is being handled.
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart index 7c4e7ef..9c89392 100644 --- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart +++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -7,6 +7,7 @@ import 'dart:convert'; import 'dart:io' show Platform, Process; +import 'package:analysis_server/src/analytics/percentile_calculator.dart'; import 'package:analysis_server/src/plugin/notification_manager.dart'; import 'package:analyzer/dart/analysis/context_root.dart' as analyzer; import 'package:analyzer/exception/exception.dart'; @@ -259,8 +260,8 @@ /// A table, keyed by both a plugin and a request method, to a list of the /// times that it took the plugin to return a response to requests with the /// method. - static Map<PluginInfo, Map<String, List<int>>> pluginResponseTimes = - <PluginInfo, Map<String, List<int>>>{}; + static Map<PluginInfo, Map<String, PercentileCalculator>> + pluginResponseTimes = <PluginInfo, Map<String, PercentileCalculator>>{}; /// The console environment key used by the pub tool. static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT'; @@ -792,9 +793,9 @@ /// given [method] in the given [time]. static void recordResponseTime(PluginInfo plugin, String method, int time) { pluginResponseTimes - .putIfAbsent(plugin, () => <String, List<int>>{}) - .putIfAbsent(method, () => <int>[]) - .add(time); + .putIfAbsent(plugin, () => <String, PercentileCalculator>{}) + .putIfAbsent(method, () => PercentileCalculator()) + .addValue(time); } /// Returns the environment value that should be used when running pub.
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart index 10c6d66..cb3dc90 100644 --- a/pkg/analysis_server/lib/src/status/diagnostics.dart +++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -1134,7 +1134,7 @@ var buffer = StringBuffer(); buffer.write(requestName); buffer.write(' '); - buffer.write(data); + buffer.write(data.toAnalyticsString()); p(buffer.toString()); } }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 8b58a3c..1bdfcc2 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -166,7 +166,7 @@ /// The mapping from the files for which analysis was requested using /// [getResolvedLibrary] to the [Completer]s to report the result. final _requestedLibraries = - <String, List<Completer<ResolvedLibraryResult>>>{}; + <LibraryFileStateKind, List<Completer<ResolvedLibraryResult>>>{}; /// The queue of requests for completion. final List<_ResolveForCompletionRequest> _resolveForCompletionRequests = []; @@ -861,6 +861,12 @@ final file = _fsState.getFileForPath(path); final kind = file.kind; if (kind is LibraryFileStateKind) { + final completer = Completer<ResolvedLibraryResult>(); + _requestedLibraries + .putIfAbsent(kind, () => <Completer<ResolvedLibraryResult>>[]) + .add(completer); + _scheduler.notify(this); + return completer.future; } else if (kind is AugmentationFileStateKind) { return NotLibraryButAugmentationResult(); } else if (kind is PartFileStateKind) { @@ -868,14 +874,6 @@ } else { throw UnimplementedError('(${kind.runtimeType}) $kind'); } - - // Schedule analysis. - var completer = Completer<ResolvedLibraryResult>(); - _requestedLibraries - .putIfAbsent(path, () => <Completer<ResolvedLibraryResult>>[]) - .add(completer); - _scheduler.notify(this); - return completer.future; } /// Return a [Future] that completes with a [ResolvedLibraryResult] for the @@ -1092,14 +1090,14 @@ // Analyze a requested library. if (_requestedLibraries.isNotEmpty) { - String path = _requestedLibraries.keys.first; + final library = _requestedLibraries.keys.first; try { - var result = await _computeResolvedLibrary(path); - for (var completer in _requestedLibraries.remove(path)!) { + var result = await _computeResolvedLibrary(library); + for (var completer in _requestedLibraries.remove(library)!) { completer.complete(result); } } catch (exception, stackTrace) { - for (var completer in _requestedLibraries.remove(path)!) { + for (var completer in _requestedLibraries.remove(library)!) { completer.completeError(exception, stackTrace); } _clearLibraryContextAfterException(); @@ -1314,18 +1312,11 @@ FileState file = _fsState.getFileForPath(path); // Prepare the library - the file itself, or the known library. - final FileState library; final kind = file.kind; - if (kind is LibraryFileStateKind) { - library = kind.file; - } else if (kind is PartFileStateKind) { - library = kind.library ?? kind.asLibrary.file; - } else { - throw UnimplementedError('${kind.runtimeType}'); - } + final library = kind.library ?? kind.asLibrary; // Prepare the signature and key. - String signature = _getResolvedUnitSignature(library, file); + String signature = _getResolvedUnitSignature(library.file, file); String key = _getResolvedUnitKey(signature); // Skip reading if the signature, so errors, are the same as the last time. @@ -1364,7 +1355,7 @@ analysisOptions as AnalysisOptionsImpl, declaredVariables, sourceFactory, - libraryContext.elementFactory.libraryOfUri2(library.uriStr), + libraryContext.elementFactory.libraryOfUri2(library.file.uriStr), libraryContext.elementFactory.analysisSession.inheritanceManager, library, testingData: testingData, @@ -1376,7 +1367,7 @@ var unitBytes = _serializeResolvedUnit(unitResult.unit, unitResult.errors); String unitSignature = - _getResolvedUnitSignature(library, unitResult.file); + _getResolvedUnitSignature(library.file, unitResult.file); String unitKey = _getResolvedUnitKey(unitSignature); _byteStore.put(unitKey, unitBytes); if (unitResult.file == file) { @@ -1396,7 +1387,7 @@ return result; } catch (exception, stackTrace) { String? contextKey = - _storeExceptionContext(path, library, exception, stackTrace); + _storeExceptionContext(path, library.file, exception, stackTrace); throw _ExceptionState(exception, stackTrace, contextKey); } }); @@ -1416,9 +1407,10 @@ /// Return the newly computed resolution result of the library with the /// given [path]. - Future<ResolvedLibraryResultImpl> _computeResolvedLibrary(String path) async { - FileState library = _fsState.getFileForPath(path); - + Future<ResolvedLibraryResultImpl> _computeResolvedLibrary( + LibraryFileStateKind library, + ) async { + final path = library.file.path; return _logger.runAsync('Compute resolved library $path', () async { _testView.numOfAnalyzedLibraries++; await libraryContext.load(library); @@ -1427,7 +1419,7 @@ analysisOptions as AnalysisOptionsImpl, declaredVariables, sourceFactory, - libraryContext.elementFactory.libraryOfUri2(library.uriStr), + libraryContext.elementFactory.libraryOfUri2(library.file.uriStr), libraryContext.elementFactory.analysisSession.inheritanceManager, library, testingData: testingData) @@ -1463,15 +1455,8 @@ FileState file = _fsState.getFileForPath(path); // Prepare the library - the file itself, or the known library. - final FileState library; final kind = file.kind; - if (kind is LibraryFileStateKind) { - library = kind.file; - } else if (kind is PartFileStateKind) { - library = kind.library ?? kind.asLibrary.file; - } else { - throw UnimplementedError('${kind.runtimeType}'); - } + final library = kind.library ?? kind.asLibrary; return _logger.runAsync('Compute unit element for $path', () async { _logger.writeln('Work in $name'); @@ -1774,20 +1759,18 @@ var file = _fsState.getFileForPath(path); - var library = file.isPart ? file.library : file; - if (library == null) { - return null; - } + // Prepare the library - the file itself, or the known library. + final kind = file.kind; + final library = kind.library ?? kind.asLibrary; await libraryContext.load(library); - var unitElement = libraryContext.computeUnitElement(library, file) - as CompilationUnitElementImpl; + var unitElement = libraryContext.computeUnitElement(library, file); var analysisResult = LibraryAnalyzer( analysisOptions as AnalysisOptionsImpl, declaredVariables, sourceFactory, - libraryContext.elementFactory.libraryOfUri2(library.uriStr), + libraryContext.elementFactory.libraryOfUri2(library.file.uriStr), libraryContext.elementFactory.analysisSession.inheritanceManager, library, testingData: testingData,
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart index 66b5ac0..e5ded7e 100644 --- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart +++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -43,7 +43,7 @@ import 'package:path/path.dart' as package_path; import 'package:pub_semver/pub_semver.dart'; -/// The file has a `library augmentation` directive. +/// The file has a `library augment` directive. abstract class AugmentationFileStateKind extends LibraryOrAugmentationFileKind { final UnlinkedLibraryAugmentationDirective directive; @@ -51,6 +51,12 @@ required super.file, required this.directive, }); + + @override + LibraryFileStateKind get asLibrary { + // TODO(scheglov): implement asLibrary + throw UnimplementedError(); + } } /// The URI of the [directive] can be resolved. @@ -66,11 +72,27 @@ /// If the [uriFile] has `import augment` of this file, returns [uriFile]. /// Otherwise, this file is not a valid augmentation, returns `null`. - FileState? get augmented { + LibraryOrAugmentationFileKind? get augmented { final uriKind = uriFile.kind; if (uriKind is LibraryOrAugmentationFileKind) { if (uriKind.hasAugmentation(this)) { - return uriFile; + return uriKind; + } + } + return null; + } + + @override + LibraryFileStateKind? get library { + final visited = Set<LibraryOrAugmentationFileKind>.identity(); + var current = augmented; + while (current != null && visited.add(current)) { + if (current is LibraryFileStateKind) { + return current; + } else if (current is AugmentationKnownFileStateKind) { + current = current.augmented; + } else { + return null; } } return null; @@ -83,6 +105,9 @@ required super.file, required super.directive, }); + + @override + LibraryFileStateKind? get library => null; } /// Information about a single `import` directive. @@ -363,18 +388,6 @@ FileStateKind get kind => _kind!; - /// If the file [isPart], return a currently know library the file is a part - /// of. Return `null` if a library is not known, for example because we have - /// not processed a library file yet. - FileState? get library { - final kind = _kind; - if (kind is PartFileStateKind) { - return kind.library; - } else { - return null; - } - } - /// Return the [LibraryCycle] this file belongs to, even if it consists of /// just this file. If the library cycle is not known yet, compute it. LibraryCycle get libraryCycle { @@ -937,6 +950,18 @@ FileStateKind({ required this.file, }); + + /// When [library] returns `null`, this getter is used to look at this + /// file itself as a library. + LibraryFileStateKind get asLibrary { + return LibraryFileStateKind( + file: file, + name: null, + ); + } + + /// Returns the library in which this file should be analyzed. + LibraryFileStateKind? get library; } enum FileStateRefreshResult { @@ -1345,6 +1370,9 @@ required this.name, }); + @override + LibraryFileStateKind? get library => this; + bool hasPart(PartFileStateKind part) { return file.partedFiles.contains(part.file); } @@ -1422,18 +1450,6 @@ PartFileStateKind({ required super.file, }); - - /// When [library] returns `null`, this getter is used to look at this - /// file itself as a library. - LibraryFileStateKind get asLibrary { - return LibraryFileStateKind( - file: file, - name: null, - ); - } - - /// Returns the library in which this part should be analyzed. - FileState? get library; } /// The file has `part of name` directive. @@ -1454,7 +1470,7 @@ /// If there are libraries that include this file as a part, return the /// first one as if sorted by path. @override - FileState? get library { + LibraryFileStateKind? get library { LibraryFileStateKind? result; for (final library in libraries) { if (library.hasPart(this)) { @@ -1465,7 +1481,7 @@ } } } - return result?.file; + return result; } } @@ -1490,11 +1506,11 @@ }); @override - FileState? get library { + LibraryFileStateKind? get library { final uriKind = uriFile.kind; if (uriKind is LibraryFileStateKind) { if (uriKind.hasPart(this)) { - return uriFile; + return uriKind; } } return null; @@ -1509,7 +1525,7 @@ }); @override - FileState? get library => null; + LibraryFileStateKind? get library => null; } class _LibraryNameToFiles {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart index e695ae7..d3263b3 100644 --- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart +++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -67,7 +67,7 @@ final AnalysisOptionsImpl _analysisOptions; final DeclaredVariables _declaredVariables; final SourceFactory _sourceFactory; - final FileState _library; + final LibraryFileStateKind _library; final InheritanceManager3 _inheritance; final LibraryElementImpl _libraryElement; @@ -143,7 +143,7 @@ nameScope: _libraryElement.scope, elementWalker: ElementWalker.forCompilationUnit( unitElement, - libraryFilePath: _library.path, + libraryFilePath: _library.file.path, unitFilePath: file.path, ), ), @@ -222,7 +222,7 @@ shouldReport = true; } if (shouldReport) { - _getErrorReporter(_library).reportErrorForNode( + _getErrorReporter(_library.file).reportErrorForNode( CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE, directive.uri, ); @@ -280,11 +280,11 @@ } if (_analysisOptions.lint) { - var allUnits = _library.libraryFiles + var allUnits = _library.file.libraryFiles .map((file) => LinterContextUnit(file.content, units[file]!)) .toList(); for (int i = 0; i < allUnits.length; i++) { - _computeLints(_library.libraryFiles[i], allUnits[i], allUnits, + _computeLints(_library.file.libraryFiles[i], allUnits[i], allUnits, analysisOptions: _analysisOptions); } } @@ -295,7 +295,7 @@ // This must happen after all other diagnostics have been computed but // before the list of diagnostics has been filtered. - for (var file in _library.libraryFiles) { + for (var file in _library.file.libraryFiles) { IgnoreValidator( _getErrorReporter(file), _getErrorListener(file).errors, @@ -339,7 +339,7 @@ typeSystem: _typeSystem, inheritanceManager: _inheritance, analysisOptions: _analysisOptions, - workspacePackage: _library.workspacePackage, + workspacePackage: _library.file.workspacePackage, ), ); @@ -542,13 +542,13 @@ if (source is InSummarySource) { return true; } - for (var file in _library.directReferencedFiles) { + for (var file in _library.file.directReferencedFiles) { if (file.uri == source.uri) { return file.exists; } } // A library can refer to itself with an empty URI. - return source == _library.source; + return source == _library.file.source; } /// Return a new parsed unresolved [CompilationUnit]. @@ -568,12 +568,12 @@ var units = <FileState, CompilationUnitImpl>{}; // Parse all files. - for (FileState file in _library.libraryFiles) { + for (FileState file in _library.file.libraryFiles) { units[file] = _parse(file); } // Resolve URIs in directives to corresponding sources. - FeatureSet featureSet = units[_library]!.featureSet; + FeatureSet featureSet = units[_library.file]!.featureSet; units.forEach((file, unit) { _validateFeatureSet(unit, featureSet); _resolveUriBasedDirectives(file, unit); @@ -591,14 +591,14 @@ } void _resolveDirectives(Map<FileState, CompilationUnitImpl> units) { - var definingCompilationUnit = units[_library]!; + var definingCompilationUnit = units[_library.file]!; definingCompilationUnit.element = _libraryElement.definingCompilationUnit; bool matchNodeElement(Directive node, Element element) { return node.keyword.offset == element.nameOffset; } - ErrorReporter libraryErrorReporter = _getErrorReporter(_library); + ErrorReporter libraryErrorReporter = _getErrorReporter(_library.file); LibraryIdentifier? libraryNameNode; var seenPartSources = <Source>{}; @@ -651,7 +651,7 @@ } else if (directive is PartDirectiveImpl) { StringLiteral partUri = directive.uri; - var partFile = _library.partedFiles[partDirectiveIndex++]; + var partFile = _library.file.partedFiles[partDirectiveIndex++]; if (partFile == null) { continue; } @@ -702,11 +702,11 @@ } } else { Source source = nameOrSource.source!; - if (source != _library.source) { + if (source != _library.file.source) { libraryErrorReporter.reportErrorForNode( CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY, partUri, - [_library.uriStr, source.uri]); + [_library.file.uriStr, source.uri]); } } } @@ -739,7 +739,7 @@ nameScope: _libraryElement.scope, elementWalker: ElementWalker.forCompilationUnit( unitElement, - libraryFilePath: _library.path, + libraryFilePath: _library.file.path, unitFilePath: file.path, ), ), @@ -771,7 +771,7 @@ return null; } - var absoluteUri = resolveRelativeUri(_library.uri, relativeUri); + var absoluteUri = resolveRelativeUri(_library.file.uri, relativeUri); return rewriteToCanonicalUri(_sourceFactory, absoluteUri); }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart index ea279e3..2dc8cb3 100644 --- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart +++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -16,6 +16,7 @@ import 'package:analyzer/src/dart/analysis/library_graph.dart'; import 'package:analyzer/src/dart/analysis/performance_logger.dart'; import 'package:analyzer/src/dart/analysis/session.dart'; +import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/exception/exception.dart'; import 'package:analyzer/src/generated/engine.dart' show AnalysisContext, AnalysisOptionsImpl; @@ -81,13 +82,16 @@ } /// Computes a [CompilationUnitElement] for the given library/unit pair. - CompilationUnitElement computeUnitElement(FileState library, FileState unit) { + CompilationUnitElementImpl computeUnitElement( + LibraryFileStateKind library, + FileState unit, + ) { var reference = elementFactory.rootReference - .getChild(library.uriStr) + .getChild(library.file.uriStr) .getChild('@unit') .getChild(unit.uriStr); var element = elementFactory.elementOfReference(reference); - return element as CompilationUnitElement; + return element as CompilationUnitElementImpl; } void dispose() { @@ -106,7 +110,7 @@ } /// Load data required to access elements of the given [targetLibrary]. - Future<void> load(FileState targetLibrary) async { + Future<void> load(LibraryFileStateKind targetLibrary) async { var librariesTotal = 0; var librariesLoaded = 0; var librariesLinked = 0; @@ -265,7 +269,7 @@ } await logger.runAsync('Prepare linked bundles', () async { - var libraryCycle = targetLibrary.libraryCycle; + var libraryCycle = targetLibrary.file.libraryCycle; await loadBundle(libraryCycle); logger.writeln( '[librariesTotal: $librariesTotal]'
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart index c27bf2a..5a41567 100644 --- a/pkg/analyzer/lib/src/dart/analysis/search.dart +++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -1046,13 +1046,17 @@ return; } - var library = file.library ?? file; + var library = file.kind.library; + if (library == null) { + return; + } + for (; index.supertypes[superIndex] == superId; superIndex++) { var subtype = index.subtypes[superIndex]; var name = index.strings[subtype.name]; - var subId = '${library.uriStr};${file.uriStr};$name'; + var subId = '${library.file.uriStr};${file.uriStr};$name'; results.add(SubtypeResult( - library.uriStr, + library.file.uriStr, subId, name, subtype.members.map((m) => index.strings[m]).toList(),
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart index 8dd3040..2be300b 100644 --- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -2,7 +2,6 @@ // 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 'dart:convert'; import 'dart:typed_data'; import 'package:analyzer/dart/analysis/declared_variables.dart'; @@ -28,8 +27,6 @@ import 'package:analyzer/src/util/either.dart'; import 'package:analyzer/src/workspace/basic.dart'; import 'package:analyzer_utilities/check/check.dart'; -import 'package:convert/convert.dart'; -import 'package:crypto/crypto.dart'; import 'package:meta/meta.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -173,7 +170,7 @@ cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; expect(kind.uriFile.path, b.path); - expect(kind.augmented?.path, b.path); + expect(kind.augmented?.file.path, b.path); }); final bState = fileStateFor(b); @@ -182,22 +179,24 @@ bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; expect(kind.uriFile.path, a.path); - expect(kind.augmented?.path, a.path); - }); - // Check `c.dart` again, now using the `b.dart` state. - cState.assertKind((kind) { - kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(bState)); - expect(kind.augmented, same(bState)); + expect(kind.augmented?.file.path, a.path); }); final aState = fileStateFor(a); _assertAugmentationFiles(aState, [b]); + + // Check `c.dart` again, now using the `b.dart` state. + cState.assertKind((kind) { + kind as AugmentationKnownFileStateKind; + kind.assertAugmented(bState); + kind.assertLibrary(aState); + }); + // Check `b.dart` again, now using the `a.dart` state. bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); } @@ -218,7 +217,7 @@ cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; expect(kind.uriFile.path, b.path); - expect(kind.augmented?.path, b.path); + expect(kind.augmented?.file.path, b.path); }); final bState = fileStateFor(b); @@ -229,12 +228,13 @@ expect(kind.uriFile.path, a.path); // The file `a.dart` does not exist, so no import, so `null`. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Check `c.dart` again, now using the `b.dart` state. cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(bState)); - expect(kind.augmented, same(bState)); + kind.assertAugmented(bState); + expect(kind.library, isNull); }); // The file `a.dart` does not exist. @@ -248,6 +248,7 @@ expect(kind.uriFile, same(aState)); // The file `a.dart` does not exist, so no import, so `null`. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); } @@ -271,6 +272,7 @@ expect(kind.uriFile.path, b.path); // `b.dart` does not import `c.dart` as an augmentation. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Reading `a.dart` does not change anything. @@ -286,8 +288,8 @@ _assertAugmentationFiles(bState, []); bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Check `c.dart` again, now using the `b.dart` state. @@ -295,6 +297,7 @@ kind as AugmentationKnownFileStateKind; expect(kind.uriFile, same(bState)); expect(kind.augmented, isNull); + expect(kind.library, isNull); }); } @@ -316,8 +319,8 @@ _assertAugmentationFiles(bState, [b]); bState.assertKind((bKind) { bKind as AugmentationKnownFileStateKind; - expect(bKind.uriFile, same(bState)); - expect(bKind.augmented, same(bState)); + bKind.assertAugmented(bState); + expect(bKind.library, isNull); }); // The cycle does not prevent building of the library cycle. @@ -355,13 +358,13 @@ // We can construct a cycle using augmentations. bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(bState)); - expect(kind.augmented, same(bState)); + kind.assertAugmented(bState); + kind.assertLibrary(aState); }); // The cycle does not prevent building of the library cycle. @@ -382,6 +385,7 @@ aState.assertKind((kind) { kind as AugmentationUnknownFileStateKind; expect(kind.directive.uri, 'da:'); + expect(kind.library, isNull); }); } @@ -399,7 +403,7 @@ bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; expect(kind.uriFile.path, a.path); - expect(kind.augmented?.path, a.path); + expect(kind.augmented?.file.path, a.path); }); final aState = fileStateFor(a); @@ -407,8 +411,8 @@ // Check `b.dart` again, now using the `a.dart` state. bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); } @@ -429,6 +433,7 @@ expect(kind.uriFile, same(aState)); // But `a.dart` does not import `b.dart`. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Refreshing `a.dart` does not change anything. @@ -438,6 +443,7 @@ kind as AugmentationKnownFileStateKind; expect(kind.uriFile, same(aState)); expect(kind.augmented, isNull); + expect(kind.library, isNull); }); } @@ -455,6 +461,7 @@ expect(kind.uriFile.path, a.path); // The file `a.dart` does not exist, so no import. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // We can get `a.dart`, but it does not exist. @@ -466,6 +473,7 @@ expect(kind.uriFile, same(aState)); // The file `a.dart` does not exist, so no import. expect(kind.augmented, isNull); + expect(kind.library, isNull); }); } @@ -489,8 +497,8 @@ final cState = fileStateFor(c); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Reading `b.dart` does not update the augmentation. @@ -498,24 +506,24 @@ _assertAugmentationFiles(bState, [c]); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Refreshing `a.dart` does not update the augmentation. aState.refresh(); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Refreshing `b.dart` does not update the augmentation. bState.refresh(); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Exclude from `a.dart`, the URI still points at `a.dart`. @@ -527,6 +535,7 @@ kind as AugmentationKnownFileStateKind; expect(kind.uriFile, same(aState)); expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Exclude from `b.dart`, still point at `a.dart`, still not valid. @@ -537,6 +546,7 @@ kind as AugmentationKnownFileStateKind; expect(kind.uriFile, same(aState)); expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Include into `b.dart`, still point at `a.dart`, still not valid. @@ -549,6 +559,7 @@ kind as AugmentationKnownFileStateKind; expect(kind.uriFile, same(aState)); expect(kind.augmented, isNull); + expect(kind.library, isNull); }); // Include into `a.dart`, restore to `a.dart` as the target. @@ -559,11 +570,38 @@ _assertAugmentationFiles(aState, [c]); cState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); } + test_newFile_doesNotExist() { + final a = getFile('$testPackageLibPath/a.dart'); + + final file = fileStateFor(a); + expect(file.path, a.path); + expect(file.uri, Uri.parse('package:test/a.dart')); + expect(file.content, ''); + expect(file.exists, isFalse); + + file.assertKind((kind) { + kind as LibraryFileStateKind; + expect(kind.name, isNull); + kind.assertLibrary(file); + check(kind.imports).matches([ + (import) => import + ..isLibrary(_dartCoreState) + ..isSyntheticDartCoreImport.isTrue, + ]); + check(kind.exports).isEmpty; + }); + + expect(file.exportedFiles, isEmpty); + expect(file.partedFiles, isEmpty); + expect(file.libraryFiles, [file]); + expect(file.isPart, isFalse); + } + test_newFile_library_exports_dart() async { final a = newFile('$testPackageLibPath/a.dart', r''' export 'dart:async'; @@ -1088,6 +1126,7 @@ aState.assertKind((kind) { kind as LibraryFileStateKind; expect(kind.name, 'my'); + kind.assertLibrary(aState); }); } @@ -1134,7 +1173,7 @@ bState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState]); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); } @@ -1202,7 +1241,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Reading `b.dart` does not update the part. @@ -1215,7 +1254,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState, bState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Refreshing `b.dart` does not update the part. @@ -1223,7 +1262,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState, bState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Refreshing `a.dart` does not update the part. @@ -1231,7 +1270,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState, bState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Exclude the part from `a.dart`, switch to `b.dart` instead. @@ -1240,7 +1279,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([bState]); - expect(kind.library, bState); + kind.assertLibrary(bState); }); // Exclude the part from `b.dart`, no library. @@ -1261,7 +1300,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([bState]); - expect(kind.library, bState); + kind.assertLibrary(bState); }); // Include into `a.dart`, switch to `a.dart`. @@ -1273,7 +1312,7 @@ cState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState, bState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); } @@ -1321,7 +1360,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); // Refreshing the part file does not break the kind. @@ -1329,7 +1368,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); } @@ -1348,7 +1387,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile.path, a.path); - expect(kind.library?.path, a.path); + expect(kind.library?.file.path, a.path); }); final aState = fileStateFor(a); @@ -1359,7 +1398,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); // Refreshing the part file does not break the kind. @@ -1367,7 +1406,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); } @@ -1441,7 +1480,7 @@ final cState = fileStateFor(c); cState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Reading `b.dart` does not update the part. @@ -1449,21 +1488,21 @@ _assertPartedFiles(bState, [c]); cState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Refreshing `b.dart` does not update the part. bState.refresh(); cState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Refreshing `a.dart` does not update the part. aState.refresh(); cState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; - expect(kind.library, aState); + kind.assertLibrary(aState); }); // Exclude the part from `a.dart`, but the URI in `part of` still resolves @@ -1504,7 +1543,7 @@ cState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, aState); + kind.assertLibrary(aState); }); } @@ -1523,8 +1562,8 @@ final bState = fileStateFor(b); bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Make it a library. @@ -1561,8 +1600,8 @@ final bState = fileStateFor(b); bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Make it a part. @@ -1602,7 +1641,7 @@ bState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState]); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); } @@ -1621,8 +1660,8 @@ final bState = fileStateFor(b); bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, same(aState)); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // Make it a part. @@ -1659,7 +1698,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); } @@ -1692,12 +1731,12 @@ aState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([cState]); - expect(kind.library, same(cState)); + kind.assertLibrary(cState); }); bState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([cState]); - expect(kind.library, same(cState)); + kind.assertLibrary(cState); }); newFile(c.path, r''' @@ -1719,7 +1758,7 @@ bState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([cState]); - expect(kind.library, same(cState)); + kind.assertLibrary(cState); }); } @@ -1752,12 +1791,12 @@ aState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, cState); - expect(kind.library, cState); + kind.assertLibrary(cState); }); bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, cState); - expect(kind.library, cState); + kind.assertLibrary(cState); }); newFile(c.path, r''' @@ -1779,7 +1818,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, cState); - expect(kind.library, same(cState)); + kind.assertLibrary(cState); }); } @@ -1812,8 +1851,8 @@ bState.refresh(); bState.assertKind((kind) { kind as AugmentationKnownFileStateKind; - expect(kind.uriFile, aState); - expect(kind.augmented, same(aState)); + kind.assertAugmented(aState); + kind.assertLibrary(aState); }); // The file `b.dart` was something else, but now it is a known augmentation. @@ -1855,7 +1894,7 @@ bState.assertKind((kind) { kind as PartOfNameFileStateKind; kind.assertLibraries([aState]); - expect(kind.library, aState); + kind.assertLibrary(aState); }); // The file `b.dart` was something else, but now it is a known part. @@ -1919,7 +1958,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); // The file `b.dart` was something else, but now it is a known part. @@ -1963,7 +2002,7 @@ kind as PartOfNameFileStateKind; expect(kind.directive.name, 'my.lib'); kind.assertLibraries([bState, cState]); - expect(kind.library, same(bState)); + kind.assertLibrary(bState); }); final bCycle_1 = bState.libraryCycle; @@ -1980,7 +2019,7 @@ kind as PartOfNameFileStateKind; expect(kind.directive.name, 'my.lib'); kind.assertLibraries([bState, cState]); - expect(kind.library, same(bState)); + kind.assertLibrary(bState); }); // ...but the unlinked signature of `a.dart` is different. @@ -2016,7 +2055,7 @@ bState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(aState)); - expect(kind.library, same(aState)); + kind.assertLibrary(aState); }); // There are no directives in `b.dart`, so it is a library. @@ -2069,7 +2108,7 @@ aState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(bState)); - expect(kind.library, same(bState)); + kind.assertLibrary(bState); }); final bCycle_1 = bState.libraryCycle; @@ -2085,7 +2124,7 @@ aState.assertKind((kind) { kind as PartOfUriKnownFileStateKind; expect(kind.uriFile, same(bState)); - expect(kind.library, same(bState)); + kind.assertLibrary(bState); }); // ...but the unlinked signature of `a.dart` is different. @@ -2278,24 +2317,6 @@ unorderedEquals(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'])); } - test_getFileForPath_doesNotExist() { - String path = convertPath('/aaa/lib/a.dart'); - FileState file = fileSystemState.getFileForPath(path); - expect(file.path, path); - expect(file.uri, Uri.parse('package:aaa/a.dart')); - expect(file.content, ''); - expect(file.contentHash, _md5('')); - expect(_excludeSdk(file.importedFiles), isEmpty); - expect(file.exportedFiles, isEmpty); - expect(file.partedFiles, isEmpty); - expect(file.libraryFiles, [file]); - expect(_excludeSdk(file.directReferencedFiles), isEmpty); - expect(file.isPart, isFalse); - expect(file.library, isNull); - expect(file.unlinked2, isNotNull); - expect(file.unlinked2.exports, isEmpty); - } - test_getFileForPath_emptyUri() { String path = convertPath('/test.dart'); newFile(path, r''' @@ -2358,58 +2379,6 @@ _assertIsUnresolvedFile(file.partedFiles[1]); } - test_getFileForPath_library() { - String a1 = convertPath('/aaa/lib/a1.dart'); - String a2 = convertPath('/aaa/lib/a2.dart'); - String a3 = convertPath('/aaa/lib/a3.dart'); - String a4 = convertPath('/aaa/lib/a4.dart'); - String b1 = convertPath('/bbb/lib/b1.dart'); - String b2 = convertPath('/bbb/lib/b2.dart'); - String content_a1 = r''' -import 'package:aaa/a2.dart'; -import 'package:bbb/b1.dart'; -export 'package:bbb/b2.dart'; -export 'package:aaa/a3.dart'; -part 'a4.dart'; - -class A1 {} -'''; - newFile(a1, content_a1); - - FileState file = fileSystemState.getFileForPath(a1); - expect(file.path, a1); - expect(file.content, content_a1); - expect(file.contentHash, _md5(content_a1)); - - expect(file.isPart, isFalse); - expect(file.library, isNull); - expect(file.unlinked2, isNotNull); - - expect(_excludeSdk(file.importedFiles), hasLength(2)); - expect(file.importedFiles[0]!.path, a2); - expect(file.importedFiles[0]!.uri, Uri.parse('package:aaa/a2.dart')); - expect(file.importedFiles[0]!.source, isNotNull); - expect(file.importedFiles[1]!.path, b1); - expect(file.importedFiles[1]!.uri, Uri.parse('package:bbb/b1.dart')); - expect(file.importedFiles[1]!.source, isNotNull); - - expect(file.exportedFiles, hasLength(2)); - expect(file.exportedFiles[0]!.path, b2); - expect(file.exportedFiles[0]!.uri, Uri.parse('package:bbb/b2.dart')); - expect(file.exportedFiles[0]!.source, isNotNull); - expect(file.exportedFiles[1]!.path, a3); - expect(file.exportedFiles[1]!.uri, Uri.parse('package:aaa/a3.dart')); - expect(file.exportedFiles[1]!.source, isNotNull); - - expect(file.partedFiles, hasLength(1)); - expect(file.partedFiles[0]!.path, a4); - expect(file.partedFiles[0]!.uri, Uri.parse('package:aaa/a4.dart')); - - expect(file.libraryFiles, [file, file.partedFiles[0]]); - - expect(_excludeSdk(file.directReferencedFiles), hasLength(5)); - } - test_getFileForPath_onlyDartFiles() { String not_dart = convertPath('/test/lib/not_dart.txt'); String a = convertPath('/test/lib/a.dart'); @@ -2434,53 +2403,6 @@ unorderedEquals([a, b, c, d, not_dart])); } - test_getFileForPath_part() { - String a1 = convertPath('/aaa/lib/a1.dart'); - String a2 = convertPath('/aaa/lib/a2.dart'); - newFile(a1, r''' -library a1; -part 'a2.dart'; -'''); - newFile(a2, r''' -part of a1; -class A2 {} -'''); - - FileState file_a2 = fileSystemState.getFileForPath(a2); - expect(file_a2.path, a2); - expect(file_a2.uri, Uri.parse('package:aaa/a2.dart')); - - expect(file_a2.unlinked2, isNotNull); - - expect(_excludeSdk(file_a2.importedFiles), isEmpty); - expect(file_a2.exportedFiles, isEmpty); - expect(file_a2.partedFiles, isEmpty); - expect(_excludeSdk(file_a2.directReferencedFiles), isEmpty); - - // The library is not known yet. - expect(file_a2.isPart, isTrue); - expect(file_a2.library, isNull); - - // Ask for the library. - FileState file_a1 = fileSystemState.getFileForPath(a1); - expect(file_a1.partedFiles, hasLength(1)); - expect(file_a1.partedFiles[0], same(file_a2)); - expect( - _excludeSdk(file_a1.directReferencedFiles), unorderedEquals([file_a2])); - - // Now the part knows its library. - expect(file_a2.library, same(file_a1)); - - // Now update the library, and refresh its file. - // The library does not include this part, so no library. - newFile(a1, r''' -library a1; -part 'not-a2.dart'; -'''); - file_a1.refresh(); - expect(file_a2.library, isNull); - } - test_getFileForPath_samePath() { String path = convertPath('/aaa/lib/a.dart'); FileState file1 = fileSystemState.getFileForPath(path); @@ -2921,10 +2843,6 @@ } }).toList(); } - - static String _md5(String content) { - return hex.encode(md5.convert(utf8.encode(content)).bytes); - } } class _GeneratedUriResolverMock extends UriResolver { @@ -2973,6 +2891,26 @@ } } +extension on FileStateKind { + void assertLibrary(FileState expectedLibraryFile) { + final expectedKind = expectedLibraryFile.kind as LibraryFileStateKind; + expect(library, same(expectedKind)); + } +} + +extension on AugmentationKnownFileStateKind { + void assertAugmented(FileState expectedFile) { + // The expected file must be a valid augmentation target. + final expectedKind = expectedFile.kind as LibraryOrAugmentationFileKind; + + // Any valid augmentation target is always the URI target. + expect(uriFile, same(expectedFile)); + + // Check the augmentation target itself. + expect(augmented, same(expectedKind)); + } +} + extension on PartOfNameFileStateKind { void assertLibraries(Iterable<FileState> expectedFiles) { final expectedKinds = expectedFiles.map((e) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart index 6a25363..cb8357e 100644 --- a/pkg/analyzer_cli/lib/src/driver.dart +++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -165,8 +165,8 @@ // These are used to do part file analysis across sources. var dartFiles = <String>{}; - var libraryFiles = <FileState>{}; - var danglingParts = <FileState>{}; + final analyzedFiles = <FileState>{}; + final partFiles = <FileState>{}; // Note: This references analysisDriver via closure, so it will change over // time during the following analysis. @@ -336,20 +336,13 @@ dartFiles.add(path); var file = analysisDriver.fsState.getFileForPath(path); - if (file.isPart) { - if (!libraryFiles.contains(file.library)) { - danglingParts.add(file); - } - continue; - } - libraryFiles.add(file); - - var status = await _runAnalyzer(file, options, formatter); - allResult = allResult.max(status); - - // Mark previously dangling parts as no longer dangling. - for (var part in file.partedFiles) { - danglingParts.remove(part); + final kind = file.kind; + if (kind is LibraryFileStateKind) { + var status = await _runAnalyzer(file, options, formatter); + allResult = allResult.max(status); + analyzedFiles.addAll(file.libraryFiles); + } else if (kind is PartFileStateKind) { + partFiles.add(file); } } } @@ -363,8 +356,10 @@ } // Any dangling parts still in this list were definitely dangling. - for (var partFile in danglingParts) { - reportPartError(partFile.path); + for (var partFile in partFiles) { + if (!analyzedFiles.contains(partFile)) { + reportPartError(partFile.path); + } } formatter.flush();
diff --git a/tools/VERSION b/tools/VERSION index 02213d8..1dd679d 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 18 PATCH 0 -PRERELEASE 162 +PRERELEASE 163 PRERELEASE_PATCH 0 \ No newline at end of file