Version 2.15.0-262.0.dev
Merge commit 'b27c191c2a0a56342f29c7008947b9d2e3367932' into 'dev'
diff --git a/pkg/analysis_server/lib/src/domain_abstract.dart b/pkg/analysis_server/lib/src/domain_abstract.dart
index e7079c1..3ff067b 100644
--- a/pkg/analysis_server/lib/src/domain_abstract.dart
+++ b/pkg/analysis_server/lib/src/domain_abstract.dart
@@ -4,7 +4,6 @@
import 'dart:async';
import 'dart:convert';
-import 'dart:math' as math;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/analysis_server_abstract.dart';
@@ -38,19 +37,18 @@
/// restarted. The [timeout] is the maximum amount of time that will be spent
/// waiting for plugins to respond.
Future<List<plugin.Response>> waitForResponses(
- Map<PluginInfo, Future<plugin.Response>> futures,
- {plugin.RequestParams? requestParameters,
- int timeout = 500}) async {
+ Map<PluginInfo, Future<plugin.Response>> futures, {
+ plugin.RequestParams? requestParameters,
+ Duration timeout = const Duration(milliseconds: 500),
+ }) async {
// TODO(brianwilkerson) requestParameters might need to be required.
- var endTime = DateTime.now().millisecondsSinceEpoch + timeout;
+ var timer = Stopwatch()..start();
var responses = <plugin.Response>[];
for (var entry in futures.entries) {
var pluginInfo = entry.key;
var future = entry.value;
try {
- var startTime = DateTime.now().millisecondsSinceEpoch;
- var response = await future
- .timeout(Duration(milliseconds: math.max(endTime - startTime, 0)));
+ var response = await future.timeout(timeout - timer.elapsed);
var error = response.error;
if (error != null) {
// TODO(brianwilkerson) Report the error to the plugin manager.
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 4434ecc..015acf4 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -571,8 +571,7 @@
var responses = await waitForResponses(
requestToPlugins.futures,
requestParameters: requestToPlugins.parameters,
- // TODO(scheglov) pass Duration
- timeout: budget.left.inMilliseconds,
+ timeout: budget.left,
);
for (var response in responses) {
var result = plugin.CompletionGetSuggestionsResult.fromResponse(response);
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 c853df6b..74ca47f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -179,8 +179,8 @@
int offset,
) async {
final requestParams = plugin.CompletionGetSuggestionsParams(path, offset);
- final pluginResponses =
- await requestFromPlugins(path, requestParams, timeout: 100);
+ final pluginResponses = await requestFromPlugins(path, requestParams,
+ timeout: const Duration(milliseconds: 100));
final pluginResults = pluginResponses
.map((e) => plugin.CompletionGetSuggestionsResult.fromResponse(e))
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
index b0e3ca3..1a3d590 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
@@ -28,7 +28,11 @@
server,
);
- if (!server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
+ if (server.initializationOptions.onlyAnalyzeProjectsWithOpenFiles) {
+ await server.fetchClientConfigurationAndPerformDynamicRegistration();
+ } else {
+ // This method internally calls
+ // fetchClientConfigurationAndPerformDynamicRegistration.
await server.updateWorkspaceFolders(openWorkspacePaths, const []);
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 7837653..6b87d05 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -97,7 +97,7 @@
Future<List<Response>> requestFromPlugins(
String path,
RequestParams params, {
- int timeout = 500,
+ Duration timeout = const Duration(milliseconds: 500),
}) {
final driver = server.getAnalysisDriver(path);
final pluginFutures = server.pluginManager.broadcastRequest(
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 05e4e82..a6ff620 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -63,8 +63,8 @@
// suppress inserting colons/commas. We check only replacing _after_ the
// caret as some replacements (before) will still want colons, for example:
// foo(mySt^'bar');
- var replacementEnd = request.replacementRange.offset +
- (replacementLength ?? request.replacementRange.length);
+ var replacementEnd = request.replacementOffset +
+ (replacementLength ?? request.replacementLength);
var willReplace =
request.completionPreference == CompletionPreference.replace &&
replacementEnd > request.offset;
@@ -106,7 +106,7 @@
// not be replaced.
var replacementLength =
request.offset == request.target.entity?.offset &&
- request.replacementRange.length != 0
+ request.replacementLength != 0
? 0
: null;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 77455f0..1b62943 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -393,7 +393,6 @@
/// (that is, the number of characters in the existing identifier).
/// This will be different than the [replacementOffset] - [offset]
/// if the [offset] is in the middle of an existing identifier.
- /// TODO(scheglov) Switch to [replacementRange].
int get replacementLength => replacementRange.length;
/// The offset of the start of the text to be replaced.
@@ -401,7 +400,6 @@
/// suggestions if there was a portion of an identifier before the original
/// [offset]. In particular, the [replacementOffset] will be the offset of the
/// beginning of said identifier.
- /// TODO(scheglov) Switch to [replacementRange].
int get replacementOffset => replacementRange.offset;
/// Return the resource provider associated with this request.
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 0a72f10..b6bbc58 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -648,6 +648,25 @@
expect(server.contextManager.includedPaths, equals([file1]));
}
+ Future<void> test_onlyAnalyzeProjectsWithOpenFiles_fullyInitializes() async {
+ // Ensure when we use onlyAnalyzeProjectsWithOpenFiles that we still
+ // fully initialize (eg. capabilities are registered).
+ projectFolderPath = convertPath('/home/empty');
+
+ await expectRequest(
+ Method.client_registerCapability,
+ () => initialize(
+ rootUri: projectFolderUri,
+ initializationOptions: {'onlyAnalyzeProjectsWithOpenFiles': true},
+ // Enable some dynamic registrations, else registerCapability will not
+ // be called.
+ textDocumentCapabilities:
+ withAllSupportedTextDocumentDynamicRegistrations(
+ emptyTextDocumentClientCapabilities),
+ ),
+ );
+ }
+
Future<void> test_onlyAnalyzeProjectsWithOpenFiles_multipleFiles() async {
final file1 = join(projectFolderPath, 'file1.dart');
final file1Uri = Uri.file(file1);
diff --git a/pkg/analysis_server/test/src/domain_abstract_test.dart b/pkg/analysis_server/test/src/domain_abstract_test.dart
index 36ca0d3..1116cbf 100644
--- a/pkg/analysis_server/test/src/domain_abstract_test.dart
+++ b/pkg/analysis_server/test/src/domain_abstract_test.dart
@@ -32,7 +32,8 @@
Future<void> test_waitForResponses_empty_timeout() async {
AbstractRequestHandler handler = TestAbstractRequestHandler(server);
var futures = <PluginInfo, Future<plugin.Response>>{};
- var responses = await handler.waitForResponses(futures, timeout: 250);
+ var responses = await handler.waitForResponses(futures,
+ timeout: const Duration(milliseconds: 250));
expect(responses, isEmpty);
}
@@ -79,7 +80,8 @@
plugin2: Future.value(response2),
plugin3: Future.delayed(Duration(milliseconds: 500), () => response3)
};
- var responses = await handler.waitForResponses(futures, timeout: 50);
+ var responses = await handler.waitForResponses(futures,
+ timeout: const Duration(milliseconds: 50));
expect(responses, unorderedEquals([response2]));
}
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 466e477..5297838 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -8,17 +8,21 @@
sdk: "^2.7.0"
dependencies:
- analyzer:
- path: ../analyzer
- args: '>=0.13.0 <2.0.0'
- linter: ^0.1.16
- meta:
- path: ../meta
+ analyzer: any
+ args: any
+ linter: ^1.0.0
+ meta: any
path: any
- pub_semver: ^1.4.2
+ pub_semver: ^2.0.0
yaml: any
dev_dependencies:
lints: any
- test_reflective_loader: ^0.1.8
+ test_reflective_loader: ^0.2.0
test: ^1.0.0
+
+dependency_overrides:
+ analyzer:
+ path: ../analyzer
+ meta:
+ path: ../meta
diff --git a/pkg/frontend_server/pubspec.yaml b/pkg/frontend_server/pubspec.yaml
index 504c493..a3c97a6 100644
--- a/pkg/frontend_server/pubspec.yaml
+++ b/pkg/frontend_server/pubspec.yaml
@@ -7,7 +7,7 @@
sdk: "^2.7.0"
dependencies:
- args: ^1.4.4
+ args: ^2.0.0
build_integration:
path: ../build_integration
compiler:
@@ -18,7 +18,7 @@
path: ../front_end
kernel:
path: ../kernel
- package_config: ^1.9.0
+ package_config: ^2.0.0
path: any
usage: any
vm:
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 72c0820..140b0ee 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -7,9 +7,9 @@
environment:
sdk: '>=2.12.0 <3.0.0'
-dependencies:
+
dev_dependencies:
- args: '>=0.13.4 <2.0.0'
+ args: ^2.0.0
expect:
path: ../expect
front_end:
diff --git a/tests/language/named_arguments_anywhere/all_kinds_test.dart b/tests/language/named_arguments_anywhere/all_kinds_test.dart
new file mode 100644
index 0000000..38ea69e
--- /dev/null
+++ b/tests/language/named_arguments_anywhere/all_kinds_test.dart
@@ -0,0 +1,422 @@
+// Copyright (c) 2021, 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.
+
+// Check that placing a named argument anywhere in the argument list works for
+// all kinds of invocations.
+
+// SharedOptions=--enable-experiment=named-arguments-anywhere
+
+import "package:expect/expect.dart";
+
+List<Object?> arguments = [];
+
+X evaluate<X>(X x) {
+ arguments.add(x);
+ return x;
+}
+
+void runAndCheckEvaluationOrder(
+ List<Object?> expectedArguments,
+ void Function() functionToRun) {
+ arguments.clear();
+ functionToRun();
+ Expect.listEquals(expectedArguments, arguments);
+}
+
+class A {
+ A(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+ }
+
+ A.redir1() : this(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+
+ A.redir2() : this(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+
+ A.redir3() : this(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+
+ A.redir4() : this(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+
+ A.redir5() : this(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+
+ A.redir6() : this(evaluate(1), w: evaluate(3.14), evaluate("2"));
+
+ factory A.foo(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+ return A(x, y, z: z, w: w);
+ }
+
+ factory A.redirFactory(int x, String y, {bool z, required double w}) = A;
+
+ void Function(int x, String y, {bool z, required double w}) get property {
+ return A.foo;
+ }
+
+ void bar(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+ }
+
+ void call(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+ }
+}
+
+typedef B = A;
+
+foo(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+}
+
+test(dynamic d, Function f, A a) {
+ void local(int x, String y, {bool z = false, required double w}) {
+ Expect.equals(1, x);
+ Expect.equals("2", y);
+ Expect.isFalse(z);
+ Expect.equals(3.14, w);
+ }
+
+ // StaticInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ foo(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ foo(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ foo(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ foo(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ foo(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ foo(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // FactoryConstructorInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ A.foo(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ A.foo(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ A.foo(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ B.foo(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ B.foo(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ B.foo(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ B.foo(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ B.foo(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ B.foo(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // ConstructorInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ A(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ A(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ A(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ B(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ B(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ B(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ B(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ B(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ B(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // DynamicInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ d(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ d(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ d(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ d(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ d(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ d(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // FunctionInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ f(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ f(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ f(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ f(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ f(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ f(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // InstanceGetterInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ a.property(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ a.property(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ a.property(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ a.property(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ a.property(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ a.property(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // InstanceInvocation.
+ runAndCheckEvaluationOrder([a, 1, "2", false, 3.14], () {
+ evaluate(a).bar(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([a, 1, false, "2", 3.14], () {
+ evaluate(a).bar(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([a, false, 1, "2", 3.14], () {
+ evaluate(a).bar(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([a, 3.14, 1, "2", false], () {
+ evaluate(a).bar(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([a, 1, 3.14, "2", false], () {
+ evaluate(a).bar(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([a, 1, 3.14, "2"], () {
+ evaluate(a).bar(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // LocalFunctionInvocation.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ local(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ local(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ local(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ local(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ local(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ local(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // Redirecting generative constructors.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ A.redir1();
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ A.redir2();
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ A.redir3();
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ A.redir4();
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ A.redir5();
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ A.redir6();
+ });
+
+ // Redirecting factory constructors.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ A.redirFactory(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ A.redirFactory(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ A.redirFactory(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ A.redirFactory(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ A.redirFactory(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ A.redirFactory(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // Constructor super initializers.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ Test.super1();
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ Test.super2();
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ Test.super3();
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ Test.super4();
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ Test.super5();
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ Test.super6();
+ });
+
+ // Implicit .call insertion.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ a(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ a(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ a(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ a(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ a(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ a(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+}
+
+class Test extends A {
+ Test() : super(1, "2", z: false, w: 3.14);
+
+ Test.super1() : super(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ Test.super2() : super(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ Test.super3() : super(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ Test.super4() : super(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ Test.super5() : super(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ Test.super6() : super(evaluate(1), w: evaluate(3.14), evaluate("2"));
+
+ test() {
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ super.bar(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ super.bar(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ super.bar(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ super.bar(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ super.bar(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ super.bar(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+
+ // Using super.call() implicitly.
+ runAndCheckEvaluationOrder([1, "2", false, 3.14], () {
+ super(evaluate(1), evaluate("2"), z: evaluate(false), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([1, false, "2", 3.14], () {
+ super(evaluate(1), z: evaluate(false), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([false, 1, "2", 3.14], () {
+ super(z: evaluate(false), evaluate(1), evaluate("2"), w: evaluate(3.14));
+ });
+ runAndCheckEvaluationOrder([3.14, 1, "2", false], () {
+ super(w: evaluate(3.14), evaluate(1), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2", false], () {
+ super(evaluate(1), w: evaluate(3.14), evaluate("2"), z: evaluate(false));
+ });
+ runAndCheckEvaluationOrder([1, 3.14, "2"], () {
+ super(evaluate(1), w: evaluate(3.14), evaluate("2"));
+ });
+ }
+}
+
+extension E on A {
+ test() {
+ runAndCheckEvaluationOrder(["1", 2], () {
+ method(foo: evaluate("1"), evaluate(2)); // This call.
+ });
+ }
+ method(int bar, {String? foo}) {
+ Expect.equals(2, bar);
+ Expect.equals("1", foo);
+ }
+}
+
+main() {
+ A a = A(1, "2", z: false, w: 3.14);
+
+ test(A.foo, A.foo, a);
+ Test().test();
+ a.test();
+}
diff --git a/tests/language/named_arguments_anywhere/order_side_effects_error_test.dart b/tests/language/named_arguments_anywhere/order_side_effects_error_test.dart
new file mode 100644
index 0000000..52adfbc
--- /dev/null
+++ b/tests/language/named_arguments_anywhere/order_side_effects_error_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, 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.
+
+// Checks that compile-time errors in the arguments are reported when the named
+// arguments are placed before the positional.
+
+// SharedOptions=--enable-experiment=named-arguments-anywhere
+
+const a42 = const A(42);
+
+class A {
+ final int value;
+
+ const A(this.value);
+}
+
+class B {
+ final A a;
+
+ const B(this.a) : assert(identical(a, a42));
+}
+
+foo(B x, {required B y}) {}
+
+test() {
+ foo(const B(const A(0)), y: const B(new A(42)));
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+ // ^
+ // [cfe] Constant evaluation error:
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+ // ^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+ // [cfe] New expression is not a constant expression.
+ // ^
+ // [cfe] New expression is not a constant expression.
+ foo(y: const B(new A(42)), const B(const A(0)));
+ // ^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+ // ^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ // [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONSTANT_ARGUMENT
+ // [cfe] New expression is not a constant expression.
+ // ^
+ // [cfe] New expression is not a constant expression.
+ // ^^^^^^^^^^^^^^^^^^^
+ // [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
+ // ^
+ // [cfe] Constant evaluation error:
+}
+
+main() {}
diff --git a/tests/language/named_arguments_anywhere/order_side_effects_ok_test.dart b/tests/language/named_arguments_anywhere/order_side_effects_ok_test.dart
new file mode 100644
index 0000000..9dd9e93
--- /dev/null
+++ b/tests/language/named_arguments_anywhere/order_side_effects_ok_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2021, 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.
+
+// Checks that typeinference on arguments continues working after their order is
+// changed.
+
+// SharedOptions=--enable-experiment=named-arguments-anywhere
+
+import "package:expect/expect.dart";
+
+Type? argument = null;
+
+void registerTypeArgument<X>() {
+ argument = X;
+}
+
+void runAndCheckForTypeArgument(Type expectedArgument, void Function() functionToRun) {
+ argument = null;
+ functionToRun();
+ Expect.equals(expectedArgument, argument);
+}
+
+class BGeneric<X> {
+ const BGeneric();
+}
+
+void fooGeneric<X>(BGeneric<X> x, {required BGeneric<List<X>> y}) {
+ registerTypeArgument<X>();
+}
+
+void fooFunction(int x, {required double Function(double) y}) {
+ y(3.14);
+}
+
+X bar<X>(X x) {
+ registerTypeArgument<X>();
+ return x;
+}
+
+void fooFunctionGeneric<X>(int x, {required void Function(X) y}) {
+ registerTypeArgument<X>();
+}
+
+void main() {
+ runAndCheckForTypeArgument(dynamic, () {
+ fooGeneric(const BGeneric(), y: const BGeneric());
+ });
+ runAndCheckForTypeArgument(dynamic, () {
+ fooGeneric(y: const BGeneric(), const BGeneric());
+ });
+ runAndCheckForTypeArgument(int, () {
+ fooGeneric(const BGeneric<int>(), y: const BGeneric<List<int>>());
+ });
+ runAndCheckForTypeArgument(String, () {
+ fooGeneric(y: const BGeneric<List<String>>(), const BGeneric<String>());
+ });
+
+ runAndCheckForTypeArgument(double, () {
+ fooFunction(42, y: bar);
+ });
+ runAndCheckForTypeArgument(double, () {
+ fooFunction(y: bar, 42);
+ });
+
+ runAndCheckForTypeArgument(String, () {
+ fooFunctionGeneric(42, y: (String x) {});
+ });
+ runAndCheckForTypeArgument(num, () {
+ fooFunctionGeneric(y: (num x) {}, 42);
+ });
+}
diff --git a/tools/VERSION b/tools/VERSION
index f8a05d9..c49f227 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 261
+PRERELEASE 262
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index ab04c56..448629c 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -3470,6 +3470,20 @@
]
},
{
+ "name": "validate SDK API doc code samples",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart",
+ "arguments": [
+ "tools/verify_docs/bin/verify_docs.dart",
+ "sdk/lib/_internal",
+ "sdk/lib/cli",
+ "sdk/lib/convert",
+ "sdk/lib/ffi",
+ "sdk/lib/js",
+ "sdk/lib/math",
+ "sdk/lib/mirrors"
+ ]
+ },
+ {
"name": "validate SDK API data-driven fixes",
"script": "out/ReleaseX64/dart-sdk/bin/dart",
"arguments": [
diff --git a/tools/verify_docs/bin/verify_docs.dart b/tools/verify_docs/bin/verify_docs.dart
index aee1176..c23b102 100644
--- a/tools/verify_docs/bin/verify_docs.dart
+++ b/tools/verify_docs/bin/verify_docs.dart
@@ -55,7 +55,7 @@
var hadErrors = false;
for (final dir in coreLibraries) {
- hadErrors |= await validateLibrary(dir);
+ hadErrors |= !(await validateLibrary(dir));
}
exitCode = hadErrors ? 1 : 0;
@@ -69,16 +69,16 @@
print('## dart:$libName');
print('');
- var hadErrors = false;
+ var validDocs = true;
for (final file in dir
.listSync(recursive: true)
.whereType<File>()
.where((file) => file.path.endsWith('.dart'))) {
- hadErrors |= await verifyFile(analysisHelper, libName, file, dir);
+ validDocs &= await verifyFile(analysisHelper, libName, file, dir);
}
- return hadErrors;
+ return validDocs;
}
Future<bool> verifyFile(
@@ -113,12 +113,7 @@
sampleAssumptions,
);
await visitor.process(parseResult);
- if (visitor.errors.isNotEmpty) {
- print('${path.relative(file.path, from: parent.parent.path)}');
- print('${visitor.errors.toString()}');
- }
-
- return visitor.errors.isEmpty;
+ return !visitor.hadErrors;
}
/// Visit a compilation unit and validate the code samples found in dartdoc
@@ -131,7 +126,7 @@
final String? sampleAssumptions;
final List<CodeSample> samples = [];
- final StringBuffer errors = StringBuffer();
+ bool hadErrors = false;
ValidateCommentCodeSamplesVisitor(
this.analysisHelper,
@@ -283,6 +278,8 @@
if (errors.isNotEmpty) {
print('$filePath:${sample.lineStartOffset}: ${errors.length} errors');
+ hadErrors = true;
+
errors = errors.toList()
..sort(
(a, b) => a.offset - b.offset,
@@ -381,18 +378,23 @@
final String libraryName;
final resourceProvider =
OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
+ final pathRoot = Platform.isWindows ? r'c:\' : '/';
late AnalysisContextCollection collection;
int index = 0;
AnalysisHelper(this.libraryName) {
+ resourceProvider.pathContext;
+
collection = AnalysisContextCollection(
- includedPaths: ['/$libraryName'],
+ includedPaths: ['$pathRoot$libraryName'],
resourceProvider: resourceProvider,
);
}
Future<SomeResolvedUnitResult> resolveFile(String contents) async {
- final samplePath = '/$libraryName/sample_${index++}.dart';
+ final samplePath =
+ '$pathRoot$libraryName${resourceProvider.pathContext.separator}'
+ 'sample_${index++}.dart';
resourceProvider.setOverlay(
samplePath,
content: contents,