Version 2.15.0-256.0.dev
Merge commit '626c8c5f847c8cd88542b244489819be0d4e0020' into 'dev'
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 9ae5561..e798ddb 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -64,51 +64,38 @@
/// automatically called when a client listens to the stream returned by
/// [results]. Subclasses should override this method, append at least one
/// result to the [controller], and close the controller stream once complete.
- Future<CompletionResult> computeSuggestions(
- OperationPerformanceImpl perf,
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ OperationPerformanceImpl performance,
DartCompletionRequest request,
- CompletionGetSuggestionsParams params,
Set<ElementKind>? includedElementKinds,
Set<String>? includedElementNames,
List<IncludedSuggestionRelevanceTag>? includedSuggestionRelevanceTags,
) async {
- var file = params.file;
- var offset = params.offset;
//
// Allow plugins to start computing fixes.
//
- Map<PluginInfo, Future<plugin.Response>>? pluginFutures;
- plugin.CompletionGetSuggestionsParams? requestParams;
- var driver = server.getAnalysisDriver(file);
- if (driver != null) {
- requestParams = plugin.CompletionGetSuggestionsParams(file, offset);
- pluginFutures = server.pluginManager.broadcastRequest(
- requestParams,
- contextRoot: driver.analysisContext!.contextRoot,
- );
- }
+ var requestToPlugins = performance.run('askPlugins', (_) {
+ return _sendRequestToPlugins(request);
+ });
+
//
// Compute completions generated by server.
//
var suggestions = <CompletionSuggestion>[];
- const COMPUTE_SUGGESTIONS_TAG = 'computeSuggestions';
- await perf.runAsync(COMPUTE_SUGGESTIONS_TAG, (perf) async {
+ await performance.runAsync('computeSuggestions', (performance) async {
var manager = DartCompletionManager(
includedElementKinds: includedElementKinds,
includedElementNames: includedElementNames,
includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
);
- var contributorTag = 'computeSuggestions - ${manager.runtimeType}';
- await perf.runAsync(contributorTag, (performance) async {
- try {
- suggestions.addAll(
- await manager.computeSuggestions(request, performance),
- );
- } on AbortCompletion {
- suggestions.clear();
- }
- });
+ try {
+ suggestions.addAll(
+ await manager.computeSuggestions(request, performance),
+ );
+ } on AbortCompletion {
+ suggestions.clear();
+ }
});
// TODO (danrubel) if request is obsolete (processAnalysisRequest returns
// false) then send empty results
@@ -116,29 +103,13 @@
//
// Add the completions produced by plugins to the server-generated list.
//
- if (pluginFutures != null) {
- var responses = await waitForResponses(pluginFutures,
- requestParameters: requestParams, timeout: 100);
- for (var response in responses) {
- var result =
- plugin.CompletionGetSuggestionsResult.fromResponse(response);
- if (result.results.isNotEmpty) {
- if (request.replacementOffset != result.replacementOffset &&
- request.replacementLength != result.replacementLength) {
- server.instrumentationService
- .logError('Plugin completion-results dropped due to conflicting'
- ' replacement offset/length: ${result.toJson()}');
- continue;
- }
- suggestions.addAll(result.results);
- }
- }
+ if (requestToPlugins != null) {
+ await performance.runAsync('waitForPlugins', (_) async {
+ await _addPluginSuggestions(requestToPlugins, suggestions);
+ });
}
- //
- // Return the result.
- //
- return CompletionResult(
- request.replacementOffset, request.replacementLength, suggestions);
+
+ return suggestions;
}
/// Return the suggestions that should be presented in the YAML [file] at the
@@ -369,10 +340,9 @@
// Compute suggestions in the background
try {
- var result = await computeSuggestions(
+ var suggestions = await computeSuggestions(
perf,
completionRequest,
- params,
includedElementKinds,
includedElementNames,
includedSuggestionRelevanceTags,
@@ -396,9 +366,9 @@
perf.run(SEND_NOTIFICATION_TAG, (_) {
sendCompletionNotification(
completionId,
- result.replacementOffset,
- result.replacementLength,
- result.suggestions,
+ completionRequest.replacementOffset,
+ completionRequest.replacementLength,
+ suggestions,
libraryFile,
includedSuggestionSets,
includedElementKinds?.toList(),
@@ -406,7 +376,7 @@
);
});
- performance.suggestionCount = result.suggestions.length;
+ performance.suggestionCount = suggestions.length;
} finally {
ifMatchesRequestClear(completionRequest);
}
@@ -495,6 +465,55 @@
_currentRequest = null;
}
}
+
+ /// Add the completions produced by plugins to the server-generated list.
+ Future<void> _addPluginSuggestions(
+ _RequestToPlugins requestToPlugins,
+ List<CompletionSuggestion> suggestions,
+ ) async {
+ var responses = await waitForResponses(
+ requestToPlugins.futures,
+ requestParameters: requestToPlugins.parameters,
+ timeout: 100,
+ );
+ for (var response in responses) {
+ var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
+ if (result.results.isNotEmpty) {
+ var completionRequest = requestToPlugins.completionRequest;
+ if (completionRequest.replacementOffset != result.replacementOffset &&
+ completionRequest.replacementLength != result.replacementLength) {
+ server.instrumentationService
+ .logError('Plugin completion-results dropped due to conflicting'
+ ' replacement offset/length: ${result.toJson()}');
+ continue;
+ }
+ suggestions.addAll(result.results);
+ }
+ }
+ }
+
+ /// Send the completion request to plugins, so that they work in other
+ /// isolates in parallel with the server isolate.
+ _RequestToPlugins? _sendRequestToPlugins(
+ DartCompletionRequest completionRequest,
+ ) {
+ var resolvedUnit = completionRequest.result;
+ var analysisContext = resolvedUnit.session.analysisContext;
+
+ var pluginRequestParameters = plugin.CompletionGetSuggestionsParams(
+ resolvedUnit.path,
+ completionRequest.offset,
+ );
+
+ return _RequestToPlugins(
+ completionRequest: completionRequest,
+ parameters: pluginRequestParameters,
+ futures: server.pluginManager.broadcastRequest(
+ pluginRequestParameters,
+ contextRoot: analysisContext.contextRoot,
+ ),
+ );
+ }
}
/// The result of computing suggestions for code completion.
@@ -516,3 +535,15 @@
CompletionResult(
this.replacementOffset, this.replacementLength, this.suggestions);
}
+
+class _RequestToPlugins {
+ final DartCompletionRequest completionRequest;
+ final plugin.CompletionGetSuggestionsParams parameters;
+ final Map<PluginInfo, Future<plugin.Response>> futures;
+
+ _RequestToPlugins({
+ required this.completionRequest,
+ required this.parameters,
+ required this.futures,
+ });
+}
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index a0379af..7bd4630 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -331,41 +331,27 @@
required OperationPerformanceImpl performance,
}) {
var file = _pathToFile[path];
- if (file == null) {
- var fileUri = _resourceProvider.pathContext.toUri(path);
- var uri = _sourceFactory.restoreUri(
- _FakeSource(path, fileUri),
- );
- if (uri == null) {
- throw StateError('Unable to convert path to URI: $path');
- }
-
- var source = _sourceFactory.forUri2(uri);
- if (source == null) {
- throw StateError('Unable to resolve URI: $uri, path: $path');
- }
-
- var workspacePackage = _workspace.findPackageFor(path);
- var featureSet = contextFeatureSet(path, uri, workspacePackage);
- var packageLanguageVersion =
- contextLanguageVersion(path, uri, workspacePackage);
-
- var location = _FileStateLocation._(this, path, uri, source,
- workspacePackage, featureSet, packageLanguageVersion);
- file = FileState._(
- _FileStateUnlinked(
- location: location,
- partOfLibrary: null,
- performance: performance,
- ),
- );
- _pathToFile[path] = file;
- _uriToFile[uri] = file;
-
- // Recurse with recording performance.
- file.files(performance: performance);
+ if (file != null) {
+ return file;
}
- return file;
+
+ var fileUri = _resourceProvider.pathContext.toUri(path);
+ var uri = _sourceFactory.restoreUri(
+ _FakeSource(path, fileUri),
+ );
+ if (uri == null) {
+ throw StateError('Unable to convert path to URI: $path');
+ }
+
+ var source = _sourceFactory.forUri2(uri);
+ if (source == null) {
+ throw StateError('Unable to resolve URI: $uri, path: $path');
+ }
+
+ return _newFile(
+ source: source,
+ performance: performance,
+ );
}
FileState? getFileForUri({
@@ -374,35 +360,19 @@
required OperationPerformanceImpl performance,
}) {
var file = _uriToFile[uri];
- if (file == null) {
- var source = _sourceFactory.forUri2(uri);
- if (source == null) {
- return null;
- }
- var path = source.fullName;
-
- var workspacePackage = _workspace.findPackageFor(path);
- var featureSet = contextFeatureSet(path, uri, workspacePackage);
- var packageLanguageVersion =
- contextLanguageVersion(path, uri, workspacePackage);
-
- var location = _FileStateLocation._(this, path, uri, source,
- workspacePackage, featureSet, packageLanguageVersion);
- file = FileState._(
- _FileStateUnlinked(
- location: location,
- partOfLibrary: containingLibrary,
- performance: performance,
- ),
- );
-
- _pathToFile[path] = file;
- _uriToFile[uri] = file;
-
- // Recurse with recording performance.
- file.files(performance: performance);
+ if (file != null) {
+ return file;
}
- return file;
+
+ var source = _sourceFactory.forUri2(uri);
+ if (source == null) {
+ return null;
+ }
+
+ return _newFile(
+ source: source,
+ performance: performance,
+ );
}
/// Returns a list of files whose contents contains the given string.
@@ -488,6 +458,36 @@
return removedFiles;
}
+
+ FileState _newFile({
+ required Source source,
+ required OperationPerformanceImpl performance,
+ }) {
+ var path = source.fullName;
+ var uri = source.uri;
+
+ var workspacePackage = _workspace.findPackageFor(path);
+ var featureSet = contextFeatureSet(path, uri, workspacePackage);
+ var packageLanguageVersion =
+ contextLanguageVersion(path, uri, workspacePackage);
+
+ var location = _FileStateLocation._(this, path, uri, source,
+ workspacePackage, featureSet, packageLanguageVersion);
+ var file = FileState._(
+ _FileStateUnlinked(
+ location: location,
+ partOfLibrary: null,
+ performance: performance,
+ ),
+ );
+ _pathToFile[path] = file;
+ _uriToFile[uri] = file;
+
+ // Recurse with recording performance.
+ file.files(performance: performance);
+
+ return file;
+ }
}
class FileSystemStateTestView {
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 140b083..4198a79 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -316,14 +316,16 @@
addSubcommand(CompileJSCommand(verbose: verbose));
addSubcommand(CompileSnapshotCommand(
commandName: CompileSnapshotCommand.jitSnapshotCmdName,
- help: 'to a JIT snapshot.',
+ help: 'to a JIT snapshot.\n'
+ 'To run the snapshot use: dart run <JIT file>',
fileExt: 'jit',
formatName: 'app-jit',
verbose: verbose,
));
addSubcommand(CompileSnapshotCommand(
commandName: CompileSnapshotCommand.kernelCmdName,
- help: 'to a kernel snapshot.',
+ help: 'to a kernel snapshot.\n'
+ 'To run the snapshot use: dart run <kernel file>',
fileExt: 'dill',
formatName: 'kernel',
verbose: verbose,
@@ -336,7 +338,8 @@
));
addSubcommand(CompileNativeCommand(
commandName: CompileNativeCommand.aotSnapshotCmdName,
- help: 'to an AOT snapshot.',
+ help: 'to an AOT snapshot.\n'
+ 'To run the snapshot use: dartaotruntime <AOT snapshot file>',
format: 'aot',
verbose: verbose,
));
diff --git a/tools/VERSION b/tools/VERSION
index 15bdd8c..6234999 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 255
+PRERELEASE 256
PRERELEASE_PATCH 0
\ No newline at end of file