Version 2.18.0-58.0.dev
Merge commit 'eabec1c6a554a3cc13dcd41a09675ec8cf79d3e2' into 'dev'
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index c044e59..2878d4e 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -130,7 +130,6 @@
offset,
triggerCharacter,
token,
- maxResults: maxResults,
);
},
);
@@ -294,9 +293,8 @@
OperationPerformanceImpl performance,
int offset,
String? triggerCharacter,
- CancellationToken token, {
- required int maxResults,
- }) async {
+ CancellationToken token,
+ ) async {
final useSuggestionSets =
suggestFromUnimportedLibraries && capabilities.applyEdit;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 97707e5..e1c9a9c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -166,6 +166,9 @@
final _requestedLibraries =
<String, List<Completer<ResolvedLibraryResult>>>{};
+ /// The queue of requests for completion.
+ final List<_ResolveForCompletionRequest> _resolveForCompletionRequests = [];
+
/// The task that discovers available files. If this field is not `null`,
/// and the task is not completed, it should be performed and completed
/// before any name searching task.
@@ -401,6 +404,9 @@
@override
AnalysisDriverPriority get workPriority {
+ if (_resolveForCompletionRequests.isNotEmpty) {
+ return AnalysisDriverPriority.completion;
+ }
if (_requestedFiles.isNotEmpty) {
return AnalysisDriverPriority.interactive;
}
@@ -1044,6 +1050,19 @@
_discoverDartCore();
}
+ if (_resolveForCompletionRequests.isNotEmpty) {
+ final request = _resolveForCompletionRequests.removeLast();
+ try {
+ final result = _resolveForCompletion(request);
+ request.completer.complete(result);
+ } catch (exception, stackTrace) {
+ _reportException(request.path, exception, stackTrace);
+ request.completer.completeError(exception, stackTrace);
+ _clearLibraryContextAfterException();
+ }
+ return;
+ }
+
// Analyze a requested file.
if (_requestedFiles.isNotEmpty) {
String path = _requestedFiles.keys.first;
@@ -1311,54 +1330,14 @@
required int offset,
required OperationPerformanceImpl performance,
}) async {
- if (!_isAbsolutePath(path)) {
- return null;
- }
-
- if (!_fsState.hasUri(path)) {
- return null;
- }
-
- // Process pending changes.
- while (_fileTracker.verifyChangedFilesIfNeeded()) {}
-
- var file = _fsState.getFileForPath(path);
-
- var library = file.isPart ? file.library : file;
- if (library == null) {
- return null;
- }
-
- await libraryContext.load(library);
- var unitElement = libraryContext.computeUnitElement(library, file)
- as CompilationUnitElementImpl;
-
- var analysisResult = LibraryAnalyzer(
- analysisOptions as AnalysisOptionsImpl,
- declaredVariables,
- sourceFactory,
- libraryContext.elementFactory.libraryOfUri2(library.uriStr),
- libraryContext.elementFactory.analysisSession.inheritanceManager,
- library,
- testingData: testingData,
- ).analyzeForCompletion(
- file: file,
+ final request = _ResolveForCompletionRequest(
+ path: path,
offset: offset,
- unitElement: unitElement,
performance: performance,
);
-
- return ResolvedForCompletionResultImpl(
- analysisSession: currentSession,
- path: path,
- uri: file.uri,
- exists: file.exists,
- content: file.content,
- lineInfo: file.lineInfo,
- parsedUnit: analysisResult.parsedUnit,
- unitElement: unitElement,
- resolvedNodes: analysisResult.resolvedNodes,
- );
+ _resolveForCompletionRequests.add(request);
+ _scheduler.notify(this);
+ return request.completer.future;
}
void _addDeclaredVariablesToSignature(ApiSignature buffer) {
@@ -1869,6 +1848,57 @@
);
}
+ Future<ResolvedForCompletionResultImpl?> _resolveForCompletion(
+ _ResolveForCompletionRequest request,
+ ) async {
+ final path = request.path;
+ if (!_isAbsolutePath(path)) {
+ return null;
+ }
+
+ if (!_fsState.hasUri(path)) {
+ return null;
+ }
+
+ var file = _fsState.getFileForPath(path);
+
+ var library = file.isPart ? file.library : file;
+ if (library == null) {
+ return null;
+ }
+
+ await libraryContext.load(library);
+ var unitElement = libraryContext.computeUnitElement(library, file)
+ as CompilationUnitElementImpl;
+
+ var analysisResult = LibraryAnalyzer(
+ analysisOptions as AnalysisOptionsImpl,
+ declaredVariables,
+ sourceFactory,
+ libraryContext.elementFactory.libraryOfUri2(library.uriStr),
+ libraryContext.elementFactory.analysisSession.inheritanceManager,
+ library,
+ testingData: testingData,
+ ).analyzeForCompletion(
+ file: file,
+ offset: request.offset,
+ unitElement: unitElement,
+ performance: request.performance,
+ );
+
+ return ResolvedForCompletionResultImpl(
+ analysisSession: currentSession,
+ path: path,
+ uri: file.uri,
+ exists: file.exists,
+ content: file.content,
+ lineInfo: file.lineInfo,
+ parsedUnit: analysisResult.parsedUnit,
+ unitElement: unitElement,
+ resolvedNodes: analysisResult.resolvedNodes,
+ );
+ }
+
/// Serialize the given [resolvedUnit] errors and index into bytes.
Uint8List _serializeResolvedUnit(
CompilationUnit resolvedUnit, List<AnalysisError> errors) {
@@ -2002,7 +2032,8 @@
generalChanged,
changedFiles,
priority,
- interactive
+ interactive,
+ completion
}
/// Instances of this class schedule work in multiple [AnalysisDriver]s so that
@@ -2618,3 +2649,16 @@
return true;
}
}
+
+class _ResolveForCompletionRequest {
+ final String path;
+ final int offset;
+ final OperationPerformanceImpl performance;
+ final Completer<ResolvedForCompletionResultImpl?> completer = Completer();
+
+ _ResolveForCompletionRequest({
+ required this.path,
+ required this.offset,
+ required this.performance,
+ });
+}
diff --git a/pkg/analyzer/lib/src/utilities/extensions/stream.dart b/pkg/analyzer/lib/src/utilities/extensions/stream.dart
new file mode 100644
index 0000000..a310cab
--- /dev/null
+++ b/pkg/analyzer/lib/src/utilities/extensions/stream.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// 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:async';
+
+class _WhereTypeStreamSink<S, T> implements EventSink<S> {
+ final EventSink<T> _sink;
+
+ _WhereTypeStreamSink(this._sink);
+
+ @override
+ void add(S data) {
+ if (data is T) {
+ _sink.add(data);
+ }
+ }
+
+ @override
+ void addError(e, [StackTrace? stackTrace]) => _sink.addError(e, stackTrace);
+
+ @override
+ void close() => _sink.close();
+}
+
+class _WhereTypeStreamTransformer<S, T> extends StreamTransformerBase<S, T> {
+ @override
+ Stream<T> bind(Stream<S> stream) => Stream.eventTransformed(
+ stream, (sink) => _WhereTypeStreamSink<S, T>(sink));
+}
+
+extension StreamExtension<T> on Stream<T> {
+ Stream<S> whereType<S>() => transform(_WhereTypeStreamTransformer<T, S>());
+}
diff --git a/pkg/analyzer/test/src/utilities/extensions/stream_test.dart b/pkg/analyzer/test/src/utilities/extensions/stream_test.dart
new file mode 100644
index 0000000..bf63f75
--- /dev/null
+++ b/pkg/analyzer/test/src/utilities/extensions/stream_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// 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/src/utilities/extensions/stream.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StreamExtensionTest);
+ });
+}
+
+@reflectiveTest
+class StreamExtensionTest {
+ test_whereType() async {
+ var result = await Stream<Object?>.fromIterable([0, '1', 2])
+ .whereType<int>()
+ .toList();
+ expect(result, [0, 2]);
+ }
+}
diff --git a/pkg/analyzer/test/src/utilities/extensions/test_all.dart b/pkg/analyzer/test/src/utilities/extensions/test_all.dart
index e8928d7..8beb97b 100644
--- a/pkg/analyzer/test/src/utilities/extensions/test_all.dart
+++ b/pkg/analyzer/test/src/utilities/extensions/test_all.dart
@@ -5,11 +5,13 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'collection_test.dart' as collection;
+import 'stream_test.dart' as stream;
import 'string_test.dart' as string;
main() {
defineReflectiveSuite(() {
collection.main();
+ stream.main();
string.main();
}, name: 'extensions');
}
diff --git a/runtime/vm/log_test.cc b/runtime/vm/log_test.cc
index d4d2864..86c2bf8 100644
--- a/runtime/vm/log_test.cc
+++ b/runtime/vm/log_test.cc
@@ -5,6 +5,7 @@
#include "platform/globals.h"
#include "include/dart_tools_api.h"
+#include "platform/utils.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
@@ -23,7 +24,7 @@
free(const_cast<char*>(test_output_));
test_output_ = NULL;
}
- test_output_ = strdup(buffer);
+ test_output_ = Utils::StrDup(buffer);
// Also print to stdout to see the overall result.
OS::PrintErr("%s", test_output_);
diff --git a/runtime/vm/tags.cc b/runtime/vm/tags.cc
index 483eaba..d1c087d 100644
--- a/runtime/vm/tags.cc
+++ b/runtime/vm/tags.cc
@@ -4,6 +4,7 @@
#include "vm/tags.h"
+#include "platform/utils.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/native_entry.h"
@@ -159,7 +160,7 @@
return;
}
}
- subscribed_tags_.Add(strdup(tag));
+ subscribed_tags_.Add(Utils::StrDup(tag));
}
void UserTags::RemoveStreamableTagName(const char* tag) {
diff --git a/tools/VERSION b/tools/VERSION
index a15f79a..f388a5b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 57
+PRERELEASE 58
PRERELEASE_PATCH 0
\ No newline at end of file