Version 3.6.0-237.0.dev
Merge e06d0f3c407843ce708e8abc36d46a8a1e5edb76 into dev
diff --git a/DEPS b/DEPS
index 2e88cdf..16e9183 100644
--- a/DEPS
+++ b/DEPS
@@ -54,7 +54,7 @@
# co19 is a cipd package automatically generated for each co19 commit.
# Use tests/co19/update.sh to update this hash.
- "co19_rev": "767bb1f623a4f005072224cd7a49726a5b644296",
+ "co19_rev": "a572236bc7d760dc986fd34abe6d0b8ae56254d7",
# The internal benchmarks to use. See go/dart-benchmarks-internal
"benchmarks_internal_rev": "3bd6bc6d207dfb7cf687537e819863cf9a8f2470",
@@ -188,7 +188,7 @@
"typed_data_rev": "365468a74251c930a463daf5b8f13227e269111a",
"vector_math_rev": "2cfbe2c115a57b368ccbc3c89ebd38a06764d3d1",
"watcher_rev": "0484625589d8512b36a7ad898a6cc6351d24c556",
- "web_rev": "4996dc2acd30ff06f7e500ec76fde8a66db82c0c",
+ "web_rev": "fb3019264edbed87b40c29d7777b2f98ae562008",
"web_socket_channel_rev": "0e1d6e2eb5a0bfd62e45b772ac7107d796176cf6",
"webdev_rev": "5f30c560dc4e3df341356c43ec1a766ee6b74a7c",
"webdriver_rev": "b181c9e5eca657ea4a12621332f47d9579106fda",
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 067f441..6d4d1f7 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -12,12 +12,14 @@
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/legacy_analysis_server.dart';
-import 'package:analysis_server/src/lsp/client_capabilities.dart';
-import 'package:analysis_server/src/lsp/client_configuration.dart';
+import 'package:analysis_server/src/lsp/client_capabilities.dart' as lsp;
+import 'package:analysis_server/src/lsp/client_configuration.dart' as lsp;
import 'package:analysis_server/src/lsp/constants.dart' as lsp;
-import 'package:analysis_server/src/lsp/error_or.dart';
-import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart';
-import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
+import 'package:analysis_server/src/lsp/error_or.dart' as lsp;
+import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart'
+ as lsp;
+import 'package:analysis_server/src/lsp/handlers/handler_states.dart' as lsp;
+import 'package:analysis_server/src/lsp/handlers/handlers.dart' as lsp;
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
@@ -136,7 +138,7 @@
///
/// This allows the server to call commands itself, such as "Fix All in
/// Workspace" triggered from the [DartFixPromptManager].
- ExecuteCommandHandler? executeCommandHandler;
+ lsp.ExecuteCommandHandler? executeCommandHandler;
/// The object used to manage the execution of plugins.
late PluginManager pluginManager;
@@ -405,13 +407,13 @@
/// For the legacy server, this set may be a fixed set that is not actually
/// configured by the client, but matches what legacy protocol editors expect
/// when using LSP-over-Legacy.
- LspClientCapabilities? get editorClientCapabilities;
+ lsp.LspClientCapabilities? get editorClientCapabilities;
/// The configuration (user/workspace settings) from the LSP client.
///
/// For the legacy server, this set may be a fixed set that is not controlled
/// by the client.
- LspClientConfiguration get lspClientConfiguration;
+ lsp.LspClientConfiguration get lspClientConfiguration;
/// A [Future] that completes when the LSP server moves into the initialized
/// state and can handle normal LSP requests.
@@ -420,7 +422,7 @@
///
/// When the server leaves the initialized state, [lspUninitialized] will
/// complete.
- FutureOr<InitializedStateMessageHandler> get lspInitialized;
+ FutureOr<lsp.InitializedStateMessageHandler> get lspInitialized;
/// A [Future] that completes once the server transitions out of an
/// initialized state.
@@ -517,10 +519,10 @@
///
/// If there is already an active connection to DTD or there is an error
/// connecting, returns an error, otherwise returns `null`.
- Future<ErrorOr<Null>> connectToDtd(Uri dtdUri) async {
+ Future<lsp.ErrorOr<Null>> connectToDtd(Uri dtdUri) async {
switch (dtd?.state) {
case DtdConnectionState.Connecting || DtdConnectionState.Connected:
- return error(
+ return lsp.error(
lsp.ServerErrorCodes.StateError,
'Server is already connected to DTD',
);
@@ -528,7 +530,7 @@
var connectResult = await DtdServices.connect(this, dtdUri);
return connectResult.mapResultSync((dtd) {
this.dtd = dtd;
- return success(null);
+ return lsp.success(null);
});
}
}
@@ -795,6 +797,28 @@
}
}
+ /// Immediately handles an LSP message by delegating to the
+ /// [lsp.InitializedStateMessageHandler]. This method does not schedule the
+ /// message and is intended to be used by the scheduler (or LSP-over-Legacy
+ /// where the original legacy wrapper was already scheduled).
+ ///
+ /// If the LSP server/support is not yet initialized, will wait until it is.
+ FutureOr<lsp.ErrorOr<Object?>> immediatelyHandleLspMessage(
+ lsp.IncomingMessage message,
+ lsp.MessageInfo messageInfo, {
+ lsp.CancellationToken? cancellationToken,
+ }) async {
+ // This is FutureOr<> because for the legacy server it's never a future, so
+ // we can skip the await.
+ var initializedLspHandler = lspInitialized;
+ var handler = initializedLspHandler is lsp.InitializedStateMessageHandler
+ ? initializedLspHandler
+ : await initializedLspHandler;
+
+ return handler.handleMessage(message, messageInfo,
+ cancellationToken: cancellationToken);
+ }
+
/// Return `true` if the file or directory with the given [path] will be
/// analyzed in one of the analysis contexts.
bool isAnalyzed(String path) {
diff --git a/pkg/analysis_server/lib/src/handler/legacy/lsp_over_legacy_handler.dart b/pkg/analysis_server/lib/src/handler/legacy/lsp_over_legacy_handler.dart
index dce114c..f5f1c8b 100644
--- a/pkg/analysis_server/lib/src/handler/legacy/lsp_over_legacy_handler.dart
+++ b/pkg/analysis_server/lib/src/handler/legacy/lsp_over_legacy_handler.dart
@@ -9,7 +9,6 @@
import 'package:analysis_server/src/handler/legacy/legacy_handler.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
-import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart' as lsp;
import 'package:analyzer/dart/analysis/session.dart';
import 'package:language_server_protocol/json_parsing.dart';
@@ -43,20 +42,10 @@
})
: null;
- // Get the handler for LSP requests from the server.
- // The value is a `FutureOr<>` because for the real LSP server it can be
- // delayed (the client influences when we're in the initialized state) but
- // since it's never a `Future` for the legacy server and we want to maintain
- // request order here, skip the `await`.
- var initializedLspHandler = server.lspInitialized;
- var handler = initializedLspHandler is InitializedStateMessageHandler
- ? initializedLspHandler
- : await server.lspInitialized;
-
if (lspMessage != null) {
server.analyticsManager.startedRequestMessage(
request: lspMessage, startTime: DateTime.now());
- await handleRequest(handler, lspMessage);
+ await handleRequest(lspMessage);
} else {
var message = "The 'lspMessage' parameter was not a valid LSP request:\n"
"${reporter.errors.join('\n')}";
@@ -65,10 +54,7 @@
}
}
- Future<void> handleRequest(
- InitializedStateMessageHandler handler,
- RequestMessage message,
- ) async {
+ Future<void> handleRequest(RequestMessage message) async {
var messageInfo = lsp.MessageInfo(
performance: performance,
clientCapabilities: server.editorClientCapabilities,
@@ -77,7 +63,9 @@
ErrorOr<Object?> result;
try {
- result = await handler.handleMessage(message, messageInfo,
+ // Since this (legacy) request was already scheduled, we immediately
+ // execute the wrapped LSP request without additional scheduling.
+ result = await server.immediatelyHandleLspMessage(message, messageInfo,
cancellationToken: cancellationToken);
} on InconsistentAnalysisException {
result = error(
diff --git a/pkg/analysis_server/lib/src/server/message_scheduler.dart b/pkg/analysis_server/lib/src/server/message_scheduler.dart
index 7d9948b..7e52577 100644
--- a/pkg/analysis_server/lib/src/server/message_scheduler.dart
+++ b/pkg/analysis_server/lib/src/server/message_scheduler.dart
@@ -44,10 +44,10 @@
/// The [MessageScheduler] receives messages from all clients of the
/// [AnalysisServer]. Clients can include IDE's (LSP and Legacy protocol), DTD,
-/// and the Diagnostic server. The [MessageSchedular] acts as a hub for all
+/// and the Diagnostic server. The [MessageScheduler] acts as a hub for all
/// incoming messages and forwards the messages to the appropriate handlers.
final class MessageScheduler {
- /// The [AnalaysisServer] associated with the schedular.
+ /// The [AnalysisServer] associated with the scheduler.
late final AnalysisServer server;
/// A queue of incoming messages from all the clients of the [AnalysisServer].
@@ -61,7 +61,7 @@
_incomingMessages.addLast(message);
}
- /// Notify the [MessageSchedular] to process the messages queue.
+ /// Notify the [MessageScheduler] to process the messages queue.
void notify() async {
processMessages();
}
diff --git a/pkg/analysis_server/lib/src/services/dart_tooling_daemon/dtd_services.dart b/pkg/analysis_server/lib/src/services/dart_tooling_daemon/dtd_services.dart
index b58af9b..057e47a 100644
--- a/pkg/analysis_server/lib/src/services/dart_tooling_daemon/dtd_services.dart
+++ b/pkg/analysis_server/lib/src/services/dart_tooling_daemon/dtd_services.dart
@@ -6,6 +6,7 @@
import 'package:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/lsp/client_capabilities.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
@@ -63,52 +64,42 @@
DtdConnectionState get state => _state;
- /// Executes the LSP handler [messageHandler] with [params] and returns the
- /// results as a map to provide back to DTD.
- ///
- /// If the handler fails, throws an [RpcException] to be propagated to the
- /// client.
+ /// Executes the LSP handler for [message] and completes [completer] with the
+ /// result or an [RpcException].
void processMessage(
IncomingMessage message,
OperationPerformanceImpl performance,
Completer<Map<String, Object?>> completer) async {
- // (TODO:keertip) Lookup the right handler, execute and return results.
- // For now, complete with exception.
- completer.completeError(RpcException(
- ErrorCodes.InvalidRequest.toJson(),
- 'DTD requests are not yet supported',
- ));
+ var info = MessageInfo(
+ performance: performance,
+ // DTD clients requests are always executed with a fixed set of
+ // capabilities so that the responses don't change in format based on the
+ // owning editor.
+ clientCapabilities: fixedBasicLspClientCapabilities,
+ );
+ var token = NotCancelableToken(); // We don't currently support cancel.
- // (TODO:keertip) Uncomment when lookup has been implemented
- // var info = MessageInfo(
- // performance: performance,
- // // DTD clients requests are always executed with a fixed set of
- // // capabilities so that the responses don't change in format based on the
- // // owning editor.
- // clientCapabilities: fixedBasicLspClientCapabilities,
- // );
- // var token = NotCancelableToken(); // We don't currently support cancel.
+ // Execute the handler.
+ var result = await _server.immediatelyHandleLspMessage(message, info,
+ cancellationToken: token);
- // // Execute the handler.
- // var result = await messageHandler.handleMessage(message, info, token);
-
- // // Map the result (or error) on to what a DTD handler needs to return.
- // return result.map(
- // // Map LSP errors on to equiv JSON-RPC errors for DTD.
- // (error) => throw RpcException(
- // error.code.toJson(),
- // error.message,
- // data: error.data,
- // ),
- // // DTD requires that all results are a Map and that they contain a
- // // 'type' field. This differs slightly from LSP where we could return a
- // // boolean (for example). This means we need to put the result in a
- // // field, which we're calling 'result'.
- // (result) => {
- // 'type': result?.runtimeType.toString(),
- // 'result': result,
- // },
- // );
+ // Complete with the result or error.
+ result.map(
+ // Map LSP errors on to equiv JSON-RPC errors for DTD.
+ (error) => completer.completeError(RpcException(
+ error.code.toJson(),
+ error.message,
+ data: error.data,
+ )),
+ // DTD requires that all results are a Map and that they contain a
+ // 'type' field. This differs slightly from LSP where we could return a
+ // boolean (for example). This means we need to put the result in a
+ // field, which we're calling 'result'.
+ (result) => completer.complete({
+ 'type': result?.runtimeType.toString(),
+ 'result': result,
+ }),
+ );
}
/// Closes the connection to DTD and cleans up.
@@ -174,14 +165,14 @@
/// A completer is returned which will be completed with the result of the
/// execution of the request by the corresponding [MessageHandler].
Future<Map<String, Object?>> _executeLspHandler(
- MessageHandler<Object?, Object?, AnalysisServer> messageHandler,
+ Method method,
Parameters params,
OperationPerformanceImpl performance,
) async {
// Map the incoming request into types we use for LSP request handling.
var message = IncomingMessage(
jsonrpc: jsonRpcVersion,
- method: messageHandler.handlesMessage,
+ method: method,
params: params.asMap,
);
var scheduler = _server.messageScheduler;
@@ -227,9 +218,10 @@
DartToolingDaemon dtd,
) async {
if (messageHandler.requiresTrustedCaller) return;
+ var method = messageHandler.handlesMessage;
await dtd.registerService(
_lspServiceName,
- messageHandler.handlesMessage.toString(),
+ method.toString(),
(Parameters params) async {
var rootPerformance = OperationPerformanceImpl('<root>');
RequestPerformance? requestPerformance;
@@ -237,12 +229,12 @@
// Record request performance so DTD requests show up in the
// server diagnostic pages.
requestPerformance = RequestPerformance(
- operation: '${messageHandler.handlesMessage} (DTD)',
+ operation: '$method (DTD)',
performance: performance,
);
_server.recentPerformance.requests.add(requestPerformance!);
- return await _executeLspHandler(messageHandler, params, performance);
+ return await _executeLspHandler(method, params, performance);
});
},
);
diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart
index 8660eb0..1b4c116 100644
--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart
+++ b/pkg/analysis_server/test/services/correction/sort_members_test.dart
@@ -1317,6 +1317,33 @@
''');
}
+ Future<void> test_partFile() async {
+ newFile('$testPackageLibPath/part.dart', r'''
+part 'test.dart';
+''');
+
+ await _parseTestUnit(r'''
+part of 'part.dart';
+
+import 'dart:io';
+import 'dart:async';
+
+void f() {}
+
+Future? a;
+''');
+ _assertSort(r'''
+part of 'part.dart';
+
+import 'dart:async';
+import 'dart:io';
+
+Future? a;
+
+void f() {}
+''');
+ }
+
Future<void> test_unit_class() async {
await _parseTestUnit(r'''
class C {}
@@ -1713,6 +1740,33 @@
''');
}
+ Future<void> test_withParts() async {
+ newFile('$testPackageLibPath/part.dart', r'''
+part of 'test.dart';
+''');
+
+ await _parseTestUnit(r'''
+import 'dart:io';
+import 'dart:async';
+
+part 'part.dart';
+
+void f() {}
+
+Future? a;
+''');
+ _assertSort(r'''
+import 'dart:async';
+import 'dart:io';
+
+part 'part.dart';
+
+Future? a;
+
+void f() {}
+''');
+ }
+
void _assertSort(String expectedCode) {
var sorter = MemberSorter(testCode, testUnit, lineInfo!);
var edits = sorter.sort();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index a101d9b..bc2cbc3 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -17,6 +17,7 @@
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError;
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:analyzer_utilities/test/experiments/experiments.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
@@ -89,7 +90,7 @@
late BulkFixProcessor processor;
@override
- List<String> get experiments => const [];
+ List<String> get experiments => experimentsForTests;
/// The name of the lint code being tested.
String? get lintCode => null;
diff --git a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
index 286057a..d13772f 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/organize_imports_test.dart
@@ -12,31 +12,79 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(OrganizeImportsBulkTest);
- defineReflectiveTests(OrganizeImportsTest);
+ defineReflectiveTests(OrganizeImportsDirectivesOrderingTest);
});
}
@reflectiveTest
class OrganizeImportsBulkTest extends BulkFixProcessorTest {
+ Future<void> test_partFile() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part 'test.dart';
+''');
+
+ await resolveTestCode('''
+part of 'a.dart';
+
+import 'dart:io';
+import 'dart:async';
+
+Future? a;
+''');
+
+ await assertOrganize('''
+part of 'a.dart';
+
+import 'dart:async';
+import 'dart:io';
+
+Future? a;
+''');
+ }
+
Future<void> test_single_file() async {
await parseTestCode('''
import 'dart:io';
import 'dart:async';
-Future a;
+Future? a;
''');
await assertOrganize('''
import 'dart:async';
import 'dart:io';
-Future a;
+Future? a;
+''');
+ }
+
+ Future<void> test_withParts() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part of 'test.dart';
+''');
+
+ await parseTestCode('''
+import 'dart:io';
+import 'dart:async';
+
+part 'a.dart';
+
+Future? a;
+''');
+
+ await assertOrganize('''
+import 'dart:async';
+import 'dart:io';
+
+part 'a.dart';
+
+Future? a;
''');
}
}
@reflectiveTest
-class OrganizeImportsTest extends FixProcessorLintTest {
+class OrganizeImportsDirectivesOrderingTest extends FixProcessorLintTest {
@override
FixKind get kind => DartFixKind.ORGANIZE_IMPORTS;
diff --git a/pkg/analyzer/lib/src/dart/element/scope.dart b/pkg/analyzer/lib/src/dart/element/scope.dart
index 7ab6862..310d092 100644
--- a/pkg/analyzer/lib/src/dart/element/scope.dart
+++ b/pkg/analyzer/lib/src/dart/element/scope.dart
@@ -396,6 +396,7 @@
for (var prefixElement in _prefixElements.values) {
prefixElement.scope.importsTrackingDestroy();
}
+ _importsTracking = null;
}
ImportsTracking importsTrackingInit() {
diff --git a/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart b/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart
index 0bf93e2..87497d9 100644
--- a/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart
+++ b/pkg/compiler/test/tool/graph_isomorphizer/graph_isomorphizer_test.dart
@@ -42,7 +42,9 @@
void verifyGeneratedFile(
String filename, StringBuffer contents, Map<String, String> expectations) {
Expect.stringEquals(
- DartFormatter().format(contents.toString()), expectations[filename]!);
+ DartFormatter(languageVersion: DartFormatter.latestLanguageVersion)
+ .format(contents.toString()),
+ expectations[filename]!);
}
GraphIsomorphizer generateFiles(List<String> graphFileLines,
diff --git a/pkg/compiler/tool/graph_isomorphizer.dart b/pkg/compiler/tool/graph_isomorphizer.dart
index 7a4da5e..ff4e76c 100644
--- a/pkg/compiler/tool/graph_isomorphizer.dart
+++ b/pkg/compiler/tool/graph_isomorphizer.dart
@@ -458,7 +458,9 @@
var file = File(this.outDirectory + '/' + filename);
file.createSync(recursive: true);
var sink = file.openWrite();
- sink.write(DartFormatter().format(contents.toString()));
+ sink.write(
+ DartFormatter(languageVersion: DartFormatter.latestLanguageVersion)
+ .format(contents.toString()));
sink.close();
}
diff --git a/pkg/dart2wasm/bin/run_wasm.js b/pkg/dart2wasm/bin/run_wasm.js
index d290d84..4c20888 100644
--- a/pkg/dart2wasm/bin/run_wasm.js
+++ b/pkg/dart2wasm/bin/run_wasm.js
@@ -359,6 +359,10 @@
self.clearInterval = cancelTimer;
self.queueMicrotask = addTask;
+ // Constructor function for JS `Response` objects, allows us to test for it
+ // via `instanceof`.
+ self.Response = function() {}
+
self.location = {}
self.location.href = 'file://' + args[wasmArg];
@@ -402,7 +406,7 @@
const appInstance = await compiledApp.instantiate(importObject, {
loadDeferredWasm: async (moduleName) => {
let filename = wasmFilename.replace('.wasm', `_${moduleName}.wasm`);
- return await dart2wasm.compile(readBytes(filename));
+ return readBytes(filename);
}
});
diff --git a/pkg/dart2wasm/lib/js/runtime_blob.dart b/pkg/dart2wasm/lib/js/runtime_blob.dart
index b2cac0a..36ccfc1 100644
--- a/pkg/dart2wasm/lib/js/runtime_blob.dart
+++ b/pkg/dart2wasm/lib/js/runtime_blob.dart
@@ -14,27 +14,24 @@
new Uint8Array(bytes), {builtins: ['js-string']});
}
-// Compiles a dart2wasm-generated wasm modules from `source` which is then
+// Compiles a dart2wasm-generated main module from `source` which can then
// instantiatable via the `instantiate` method.
//
// `source` needs to be a `Response` object (or promise thereof) e.g. created
// via the `fetch()` JS API.
export async function compileStreaming(source) {
- const module = await WebAssembly.compileStreaming(
- source,
- detectJsStringBuiltins() ? {builtins: ['js-string']} : {}
- );
- return new CompiledApp(module);
+ const builtins = detectJsStringBuiltins()
+ ? {builtins: ['js-string']} : {};
+ return new CompiledApp(
+ await WebAssembly.compileStreaming(source, builtins), builtins);
}
// Compiles a dart2wasm-generated wasm modules from `bytes` which is then
// instantiatable via the `instantiate` method.
export async function compile(bytes) {
- const module = await WebAssembly.compile(
- bytes,
- detectJsStringBuiltins() ? {builtins: ['js-string']} : {}
- );
- return new CompiledApp(module);
+ const builtins = detectJsStringBuiltins()
+ ? {builtins: ['js-string']} : {};
+ return new CompiledApp(await WebAssembly.compile(bytes, builtins), builtins);
}
// DEPRECATED: Please use `compile` or `compileStreaming` to get a compiled app,
@@ -57,8 +54,9 @@
}
class CompiledApp {
- constructor(module) {
+ constructor(module, builtins) {
this.module = module;
+ this.builtins = builtins;
}
// The second argument is an options object containing:
@@ -150,8 +148,13 @@
if (!loadDeferredWasm) {
throw "No implementation of loadDeferredWasm provided.";
}
- const compiledWasm = await loadDeferredWasm(moduleName);
- return await compiledWasm.instantiate({"module0": dartInstance.exports});
+ const source = await Promise.resolve(loadDeferredWasm(moduleName));
+ const module = await ((source instanceof Response)
+ ? WebAssembly.compileStreaming(source, this.builtins)
+ : WebAssembly.compile(source, this.builtins));
+ return await WebAssembly.instantiate(module, {
+ "module0": dartInstance.exports,
+ });
},
};
diff --git a/pkg/dtd_impl/dtd_common_services_editor.md b/pkg/dtd_impl/dtd_common_services_editor.md
index f413c38..8a590d9 100644
--- a/pkg/dtd_impl/dtd_common_services_editor.md
+++ b/pkg/dtd_impl/dtd_common_services_editor.md
@@ -133,10 +133,18 @@
An event sent by an editor when a debug session is changed.
-This could be happen when a VM Service URI becomes available for a session
+This could happen when a VM Service URI becomes available for a session
launched in debug mode, for example.
+## themeChanged
+`ThemeChangedEvent`
+
+An event sent by an editor when its theme has changed.
+
+This could happen when a user changes their settings to toggle between light
+and dark mode or increase/decrease font size.
+
# Type Definitions
```dart
@@ -188,6 +196,11 @@
String? deviceId;
}
+/// An event sent by an editor when theme settings have changed.
+class ThemeChangedEvent {
+ Theme theme;
+}
+
/// A debug session running in the editor.
class EditorDebugSession {
String id;
@@ -218,6 +231,14 @@
bool supported;
}
+/// The description of an editor's theme.
+class Theme {
+ bool isDarkMode;
+ String? backgroundColor;
+ String? foregroundColor;
+ int? fontSize;
+}
+
/// Parameters for the `enablePlatformTypeParams` request.
class EnablePlatformTypeParams {
/// The `platformType` to enable.
diff --git a/pkg/test_runner/lib/src/android.dart b/pkg/test_runner/lib/src/android.dart
index 417d643..3bc3bb4 100644
--- a/pkg/test_runner/lib/src/android.dart
+++ b/pkg/test_runner/lib/src/android.dart
@@ -341,7 +341,7 @@
/// Helper to list all adb devices available.
class AdbHelper {
static final RegExp _deviceLineRegexp =
- RegExp(r'^(([a-zA-Z0-9:_-]|\.)+)[ \t]+device$', multiLine: true);
+ RegExp(r'^([a-zA-Z0-9:_.\-]+)[ \t]+device$', multiLine: true);
static Future<List<String>> listDevices() {
return Process.run('adb', ['devices']).then((ProcessResult result) {
@@ -351,7 +351,7 @@
}
return _deviceLineRegexp
.allMatches(result.stdout as String)
- .map((Match m) => m.group(1)!)
+ .map((Match m) => m[1]!)
.toList();
});
}
diff --git a/pkg/test_runner/lib/src/browser.dart b/pkg/test_runner/lib/src/browser.dart
index 32316af..c148b47 100644
--- a/pkg/test_runner/lib/src/browser.dart
+++ b/pkg/test_runner/lib/src/browser.dart
@@ -60,24 +60,26 @@
.replaceAll('-', '_'));
}
+final _digitPattern = RegExp(r'\d');
+
/// Escape [name] to make it into a valid identifier.
String _toJSIdentifier(String name) {
if (name.isEmpty) return r'$';
// Escape any invalid characters
- var result = name.replaceAllMapped(_invalidCharInIdentifier,
- (match) => '\$${match.group(0)!.codeUnits.join("")}');
+ var result = name.replaceAllMapped(
+ _invalidCharInIdentifier, (match) => '\$${match[0]!.codeUnits.join("")}');
// Ensure the identifier first character is not numeric and that the whole
// identifier is not a keyword.
- if (result.startsWith(RegExp('[0-9]')) || _invalidVariableName(result)) {
+ if (result.startsWith(_digitPattern) || _invalidVariableName(result)) {
return '\$$result';
}
return result;
}
// Invalid characters for identifiers, which would need to be escaped.
-final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_0-9]');
+final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_\d]');
bool _invalidVariableName(String keyword, {bool strictMode = true}) {
switch (keyword) {
@@ -334,7 +336,7 @@
const appInstance = await compiledApp.instantiate({}, {
loadDeferredWasm: (moduleName) => {
const moduleFile = '$wasmPath'.replace('.wasm', `_\${moduleName}.wasm`);
- return mjs.compileStreaming(fetch(moduleFile));
+ return fetch(moduleFile);
}
});
dartMainRunner(() => {
diff --git a/pkg/test_runner/lib/src/co19_test_config.dart b/pkg/test_runner/lib/src/co19_test_config.dart
index 68042956..66cc6d5 100644
--- a/pkg/test_runner/lib/src/co19_test_config.dart
+++ b/pkg/test_runner/lib/src/co19_test_config.dart
@@ -7,7 +7,7 @@
import 'test_suite.dart';
class Co19TestSuite extends StandardTestSuite {
- static final _testRegExp = RegExp(r"t[0-9]{2,3}.dart$");
+ static final _testRegExp = RegExp(r"t\d{2,3}.dart$");
Co19TestSuite(TestConfiguration configuration, String selector)
: super(configuration, selector, Path("tests/$selector/src"), [
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 7a100aa..adc4a4a 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -339,7 +339,7 @@
@override
void describe(TestCase testCase, Progress progress, OutputWriter output) {
if (_jsonResult != null) {
- _describeEvents(progress, output);
+ _describeEvents(progress, output, _jsonResult);
} else {
// We couldn't parse the events, so fallback to showing the last message.
output.section("Last message");
@@ -359,7 +359,8 @@
}
}
- void _describeEvents(Progress progress, OutputWriter output) {
+ void _describeEvents(Progress progress, OutputWriter output,
+ BrowserTestJsonResult jsonResult) {
// Always show the error events since those are most useful.
var errorShown = false;
@@ -374,19 +375,19 @@
// Skip deobfuscation if there is no indication that there is a stack
// trace in the string value.
- if (!value!.contains(RegExp('\\.js:'))) return;
+ if (!value!.contains('.js:')) return;
var stringStack = value
// Convert `http:` URIs to relative `file:` URIs.
- .replaceAll(RegExp('http://[^/]*/root_build/'), '$_buildDirectory/')
- .replaceAll(RegExp('http://[^/]*/root_dart/'), '')
+ .replaceAll(RegExp(r'http://[^/]*/root_build/'), '$_buildDirectory/')
+ .replaceAll(RegExp(r'http://[^/]*/root_dart/'), '')
// Remove query parameters (seen in .html URIs).
- .replaceAll(RegExp('\\?[^:\n]*:'), ':');
+ .replaceAll(RegExp(r'\?[^:\n]*:'), ':');
// TODO(sigmund): change internal deobfuscation code to avoid spurious
// error messages when files do not have a corresponding source-map.
_deobfuscateAndWriteStack(stringStack, output);
}
- for (var event in _jsonResult!.events) {
+ for (var event in jsonResult.events) {
if (event["type"] == "sync_exception") {
showError("Runtime error", event);
} else if (event["type"] == "window_onerror") {
@@ -401,7 +402,7 @@
}
output.subsection("Events");
- for (var event in _jsonResult!.events) {
+ for (var event in jsonResult.events) {
switch (event["type"] as String?) {
case "debug":
output.write('- debug "${event["value"]}"');
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 0278dcd..9ebb610 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -801,7 +801,7 @@
.replaceAll('/', '__')
.replaceAll('-', '_')
.replaceAll('.dart', '')
- .replaceAllMapped(RegExp(r'[^A-Za-z_$0-9]'),
+ .replaceAllMapped(RegExp(r'[^A-Za-z_$\d]'),
(Match m) => '\$${m[0]!.codeUnits.join('')}');
var testPackageLoadStatements = [
for (var package in testPackages) 'load("$pkgJsDir/$package.js");'
@@ -1421,7 +1421,7 @@
}
}
-abstract class VMKernelCompilerMixin {
+abstract mixin class VMKernelCompilerMixin {
TestConfiguration get _configuration;
bool get _useSdk;
diff --git a/pkg/test_runner/lib/src/multitest.dart b/pkg/test_runner/lib/src/multitest.dart
index cae39d3..f81bb49 100644
--- a/pkg/test_runner/lib/src/multitest.dart
+++ b/pkg/test_runner/lib/src/multitest.dart
@@ -92,7 +92,7 @@
var lineSeparator =
(firstNewline == 0 || contents[firstNewline - 1] != '\r') ? '\n' : '\r\n';
var lines = contents.split(lineSeparator);
- if (lines.last == '') lines.removeLast();
+ if (lines.last.isEmpty) lines.removeLast();
// Create the set of multitests, which will have a new test added each
// time we see a multitest line with a new key.
@@ -108,16 +108,16 @@
var annotation = Annotation.tryParse(line);
if (annotation != null) {
testsAsLines.putIfAbsent(
- annotation.key, () => List<String>.from(testsAsLines["none"]!));
+ annotation.key, () => List<String>.of(testsAsLines["none"]!));
// Add line to test with annotation.key as key, empty line to the rest.
for (var entry in testsAsLines.entries) {
entry.value.add(annotation.key == entry.key ? line : "");
}
- outcomes.putIfAbsent(annotation.key, () => <String>{});
+ var outcome = outcomes.putIfAbsent(annotation.key, () => <String>{});
if (annotation.rest != 'continued') {
for (var nextOutcome in annotation.outcomes) {
if (_multitestOutcomes.contains(nextOutcome)) {
- outcomes[annotation.key]!.add(nextOutcome);
+ outcome.add(nextOutcome);
} else {
DebugLogger.warning(
"${filePath.toNativePath()}: Invalid expectation "
@@ -277,20 +277,20 @@
Set<String> _findAllRelativeImports(Path topLibrary) {
var found = <String>{};
var libraryDir = topLibrary.directoryPath;
- var relativeImportRegExp = RegExp(
- '^(?:@.*\\s+)?' // Allow for a meta-data annotation.
- '(import|part)'
- '\\s+["\']'
- '(?!(dart:|dart-ext:|data:|package:|/))' // Look-ahead: not in package.
- '([^"\']*)' // The path to the imported file.
- '["\']');
+ var relativeImportRegExp =
+ RegExp(r'^(?:@.*\s+)?' // Allow for a meta-data annotation.
+ r'(?:import|part)\s+'
+ r'''["']'''
+ r'(?!dart:|dart-ext:|data:|package:|/)' // Look-ahead: not in package.
+ r'([^]*?)' // The path to the imported file.
+ r'''["']''');
processFile(Path filePath) {
var file = File(filePath.toNativePath());
for (var line in file.readAsLinesSync()) {
var match = relativeImportRegExp.firstMatch(line);
if (match == null) continue;
- var relativePath = match.group(3)!;
+ var relativePath = match[1]!;
// If a multitest deliberately imports a nonexistent file, don't try to
// include it.
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index 35f1034..1733112 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -509,7 +509,7 @@
// Remove the `src/` subdirectories from the co19 directories that do
// not appear in the test names.
if (selector.startsWith('co19')) {
- selector = selector.replaceFirst(RegExp('src/'), '');
+ selector = selector.replaceFirst('src/', '');
}
break;
}
@@ -858,7 +858,7 @@
var pattern = selectors[i];
var suite = pattern;
var slashLocation = pattern.indexOf('/');
- if (slashLocation != -1) {
+ if (slashLocation >= 0) {
suite = pattern.substring(0, slashLocation);
pattern = pattern.substring(slashLocation + 1);
pattern = pattern.replaceAll('*', '.*');
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index ef8b5ea..dd30e53 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -13,7 +13,7 @@
/// A front end that can report static errors.
class ErrorSource {
static const analyzer = ErrorSource._("analyzer");
- static const cfe = ErrorSource._("CFE");
+ static const cfe = ErrorSource._("CFE", marker: "cfe");
static const web = ErrorSource._("web");
/// Pseudo-front end for context messages.
@@ -41,9 +41,16 @@
final String name;
/// The string used to mark errors from this source in test files.
- String get marker => name.toLowerCase();
+ ///
+ /// Always lower-case.
+ final String marker;
- const ErrorSource._(this.name);
+ /// Creates error source.
+ ///
+ /// If [name] is not all lower-case, then a [marker] must be passed with
+ /// an all lower-case name. If `name` is lower-case, `marker` can be omitted
+ /// and then defaults to `name`.
+ const ErrorSource._(this.name, {String? marker}) : marker = marker ?? name;
}
/// Describes a single static error reported by a single front end at a specific
@@ -465,7 +472,7 @@
/// // ^^^
///
/// We look for a line that starts with a line comment followed by spaces and
- /// carets.
+ /// carets. Only used on single lines.
static final _caretLocationRegExp = RegExp(r"^\s*//\s*(\^+)\s*$");
/// Matches an explicit error location with a length, like:
@@ -475,29 +482,26 @@
/// or implicitly on the previous line
///
/// // [error column 17, length 3]
- static final _explicitLocationAndLengthRegExp = RegExp(
- r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*,\s*"
- r"length\s+(\d+)\s*\]\s*$");
-
- /// Matches an explicit error location without a length, like:
+ ///
+ /// or either without a length:
///
/// // [error line 1, column 17]
- ///
- /// or implicitly on the previous line.
- ///
/// // [error column 17]
+ ///
+ /// Only used on single lines.
static final _explicitLocationRegExp = RegExp(
- r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*\]\s*$");
+ r"^\s*//\s*\[\s*error (?:line\s+(\d+)\s*,)?\s*column\s+(\d+)\s*(?:,\s*"
+ r"length\s+(\d+)\s*)?\]\s*$");
/// Matches the beginning of an error message, like `// [analyzer]`.
///
/// May have an optional number like `// [cfe 32]`.
static final _errorMessageRegExp =
- RegExp(r"^\s*// \[(\w+)(\s+\d+)?\]\s*(.*)");
+ RegExp(r"^\s*// \[(\w+)(?:\s+(\d+))?\]\s*(.*)");
/// An analyzer error code is a dotted identifier or the magic string
/// "unspecified".
- static final _errorCodeRegExp = RegExp(r"^\w+\.\w+|unspecified$");
+ static final _errorCodeRegExp = RegExp(r"^(?:\w+\.\w+|unspecified)$");
/// Any line-comment-only lines after the first line of a CFE error message
/// are part of it.
@@ -535,40 +539,29 @@
while (_canPeek(0)) {
var sourceLine = _peek(0);
- var match = _caretLocationRegExp.firstMatch(sourceLine);
- if (match != null) {
+ if (_caretLocationRegExp.firstMatch(sourceLine) case var match?) {
if (_lastRealLine == -1) {
_fail("An error expectation must follow some code.");
}
-
+ var markerMatch = match[1]!;
_parseErrors(
path: path,
line: _lastRealLine,
column: sourceLine.indexOf("^") + 1,
- length: match[1]!.length);
+ length: markerMatch.length);
_advance();
continue;
}
- match = _explicitLocationAndLengthRegExp.firstMatch(sourceLine);
- if (match != null) {
+ if (_explicitLocationRegExp.firstMatch(sourceLine) case var match?) {
var lineCapture = match[1];
+ var columnCapture = match[2]!;
+ var lengthCapture = match[3];
_parseErrors(
path: path,
line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
- column: int.parse(match[2]!),
- length: int.parse(match[3]!));
- _advance();
- continue;
- }
-
- match = _explicitLocationRegExp.firstMatch(sourceLine);
- if (match != null) {
- var lineCapture = match[1];
- _parseErrors(
- path: path,
- line: lineCapture == null ? _lastRealLine : int.parse(lineCapture),
- column: int.parse(match[2]!));
+ column: int.parse(columnCapture),
+ length: lengthCapture == null ? 0 : int.parse(lengthCapture));
_advance();
continue;
}
@@ -604,7 +597,7 @@
_fail("Context messages must have an error number.");
}
- var message = match[3]!;
+ var message = StringBuffer(match[3]!);
_advance();
var sourceLines = {locationLine, _currentLine};
@@ -614,7 +607,6 @@
// A location line shouldn't be treated as part of the message.
if (_caretLocationRegExp.hasMatch(nextLine)) break;
- if (_explicitLocationAndLengthRegExp.hasMatch(nextLine)) break;
if (_explicitLocationRegExp.hasMatch(nextLine)) break;
// The next source should not be treated as part of the message.
@@ -623,13 +615,15 @@
var messageMatch = _errorMessageRestRegExp.firstMatch(nextLine);
if (messageMatch == null) break;
- message += "\n${messageMatch[1]!}";
+ message
+ ..write("\n")
+ ..write(messageMatch[1]!);
_advance();
sourceLines.add(_currentLine);
}
if (source == ErrorSource.analyzer &&
- !_errorCodeRegExp.hasMatch(message)) {
+ !_errorCodeRegExp.hasMatch(message.toString())) {
_fail("An analyzer error expectation should be a dotted identifier.");
}
@@ -644,7 +638,7 @@
errorLength = 0;
}
- var error = StaticError(source, message,
+ var error = StaticError(source, message.toString(),
path: path,
line: line,
column: column,
@@ -654,9 +648,9 @@
if (number != null) {
// Make sure two errors don't claim the same number.
if (source != ErrorSource.context) {
- var existingError = _errors
- .firstWhereOrNull((error) => _errorNumbers[error] == number);
- if (existingError != null) {
+ var existingError =
+ _errors.any((error) => _errorNumbers[error] == number);
+ if (existingError) {
_fail("Already have an error with number $number.");
}
}
@@ -700,9 +694,9 @@
var number = _errorNumbers[error];
if (number == null) continue;
- var context = _contextMessages
- .firstWhereOrNull((context) => _errorNumbers[context] == number);
- if (context == null) {
+ var hasContext =
+ _contextMessages.any((context) => _errorNumbers[context] == number);
+ if (!hasContext) {
throw FormatException("Missing context for numbered error $number "
"'${error.message}'.");
}
diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart
index e5706c7..f9a90e1 100644
--- a/pkg/test_runner/lib/src/test_file.dart
+++ b/pkg/test_runner/lib/src/test_file.dart
@@ -6,28 +6,33 @@
import 'feature.dart';
import 'path.dart';
import 'static_error.dart';
+import 'utils.dart';
-final _multitestRegExp = RegExp(r"//# \w+:(.*)");
+final _multitestRegExp = RegExp(r"//# \w+:");
-final _vmOptionsRegExp = RegExp(r"// VMOptions=(.*)");
-final _environmentRegExp = RegExp(r"// Environment=(.*)");
-final _packagesRegExp = RegExp(r"// Packages=(.*)");
+final _vmOptionsRegExp = RegExp(r"^[ \t]*// VMOptions=(.*)", multiLine: true);
+final _environmentRegExp =
+ RegExp(r"^[ \t]*// Environment=(.*)", multiLine: true);
+final _packagesRegExp = RegExp(r"^[ \t]*// Packages=(.*)", multiLine: true);
final _experimentRegExp = RegExp(r"^--enable-experiment=([a-z0-9,-]+)$");
final _localFileRegExp = RegExp(
- r"""^\s*(?:import(?: augment)?|part) """
- r"""['"](?!package:|dart:)(.*)['"]"""
- r"""(?: deferred as \w+)?;""",
+ r"""^[ \t]*(?:import(?: augment)?|part)\s*"""
+ r"""['"](?!package:|dart:)(.*?)['"]\s*"""
+ r"""(?:(?:deferred\s+)?as\s+\w+\s*)?"""
+ r"""(?:(?:show|hide)\s+\w+\s*(?:,\s*\w+\s*))*;""",
multiLine: true);
List<String> _splitWords(String s) =>
- s.split(' ').where((e) => e != '').toList();
+ s.split(' ')..removeWhere((s) => s.isEmpty);
List<T> _parseOption<T>(
String filePath, String contents, String name, T Function(String) convert,
{bool allowMultiple = false}) {
- var matches = RegExp('// $name=(.*)').allMatches(contents);
+ var matches = RegExp('^[ \t]*// $name=(.*)', multiLine: true)
+ .allMatches(contents)
+ .toList();
if (!allowMultiple && matches.length > 1) {
- throw Exception('More than one "// $name=" line in test $filePath');
+ throw FormatException('More than one "// $name=" line in test $filePath');
}
var options = <T>[];
@@ -99,7 +104,7 @@
return path.toString().hashCode;
}
- return originPath.relativeTo(_suiteDirectory!).toString().hashCode;
+ return originPath.relativeTo(_suiteDirectory).toString().hashCode;
}
_TestFileBase(this._suiteDirectory, this.path, this.expectedErrors) {
@@ -117,15 +122,15 @@
var directory = testNamePath.directoryPath;
var filenameWithoutExt = testNamePath.filenameWithoutExtension;
- String concat(String base, String part) {
- if (base == "") return part;
- if (part == "") return base;
+ String join(String base, String part) {
+ if (base.isEmpty) return part;
+ if (part.isEmpty) return base;
return "$base/$part";
}
var result = "$directory";
- result = concat(result, filenameWithoutExt);
- result = concat(result, multitestKey);
+ result = join(result, filenameWithoutExt);
+ result = join(result, multitestKey);
return result;
}
}
@@ -255,7 +260,7 @@
"flags. Was:\n$sharedOption");
}
- experiments.addAll(match.group(1)!.split(","));
+ experiments.addAll(match[1]!.split(","));
sharedOptions.removeAt(i);
i--;
}
@@ -266,9 +271,13 @@
matches = _environmentRegExp.allMatches(contents);
for (var match in matches) {
var envDef = match[1]!;
+ var name = envDef;
+ var value = '';
var pos = envDef.indexOf('=');
- var name = (pos < 0) ? envDef : envDef.substring(0, pos);
- var value = (pos < 0) ? '' : envDef.substring(pos + 1);
+ if (pos >= 0) {
+ name = envDef.substring(0, pos);
+ value = envDef.substring(pos + 1);
+ }
environment[name] = value;
}
@@ -278,18 +287,23 @@
matches = _packagesRegExp.allMatches(contents);
for (var match in matches) {
if (packages != null) {
- throw Exception('More than one "// Package..." line in test $filePath');
+ throw FormatException(
+ 'More than one "// Package..." line in test $filePath');
}
- packages = match[1];
+ packages = match[1]!;
if (packages != 'none') {
// Packages=none means that no packages option should be given. Any
// other value overrides packages.
packages =
- Uri.file(filePath).resolveUri(Uri.file(packages!)).toFilePath();
+ Uri.file(filePath).resolveUri(Uri.file(packages)).toFilePath();
}
}
var isMultitest = _multitestRegExp.hasMatch(contents);
+ if (isMultitest) {
+ DebugLogger.warning(
+ "${Path(filePath).toNativePath()} is a legacy multi-test file.");
+ }
var errorExpectations = <StaticError>[];
try {
@@ -323,12 +337,12 @@
{Set<String>? alreadyParsed}) {
alreadyParsed ??= {};
var file = File(path);
-
+ var pathUri = Uri.parse(path);
// Missing files set no expectations.
if (!file.existsSync()) return [];
// Catch import loops.
- if (!alreadyParsed.add(Uri.parse(path).toString())) return [];
+ if (!alreadyParsed.add(pathUri.toString())) return [];
// Parse one file.
var contents = File(path).readAsStringSync();
@@ -340,7 +354,7 @@
var localPath = Uri.tryParse(match[1]!);
// Broken import paths set no expectations.
if (localPath == null) continue;
- var uriString = Uri.parse(path).resolve(localPath.path).toString();
+ var uriString = pathUri.resolve(localPath.path).toString();
result
.addAll(_parseExpectations(uriString, alreadyParsed: alreadyParsed));
}
diff --git a/pkg/test_runner/lib/src/update_errors.dart b/pkg/test_runner/lib/src/update_errors.dart
index bcff57e..f8068c4 100644
--- a/pkg/test_runner/lib/src/update_errors.dart
+++ b/pkg/test_runner/lib/src/update_errors.dart
@@ -3,10 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
import 'static_error.dart';
-/// Matches leading indentation in a string.
-final _indentationRegExp = RegExp(r"^(\s*)");
+/// Matches end of leading indentation in a line.
+///
+/// Only used on single lines.
+final _indentationRegExp = RegExp(r"(?=\S|$)");
/// Matches a line that contains only a line comment.
+///
+/// Only used on single lines.
final _lineCommentRegExp = RegExp(r"^\s*//");
/// Removes existing static error marker comments in [source] and adds markers
@@ -190,5 +194,5 @@
/// Returns the number of characters of leading spaces in [line].
int _countIndentation(String line) {
var match = _indentationRegExp.firstMatch(line)!;
- return match.group(1)!.length;
+ return match.start;
}
diff --git a/pkg/test_runner/lib/test_runner.dart b/pkg/test_runner/lib/test_runner.dart
index 2e68d78..028a7ab 100644
--- a/pkg/test_runner/lib/test_runner.dart
+++ b/pkg/test_runner/lib/test_runner.dart
@@ -34,7 +34,7 @@
/// bar becomes 'foo
/// bar'
String shellSingleQuote(String string) {
- return "'${string.replaceAll("'", "'\\''")}'";
+ return "'${string.replaceAll("'", r"'\''")}'";
}
/// Like [shellSingleQuote], but if the string only contains safe ASCII
@@ -43,7 +43,7 @@
/// a shell keyword or a shell builtin in the first argument in a command. It
/// should be safe to use this for the second argument onwards in a command.
String simpleShellSingleQuote(String string) {
- return RegExp(r"^[a-zA-Z0-9%+,./:_-]*$").hasMatch(string)
+ return RegExp(r"^[a-zA-Z\d%+,./:_\-]*$").hasMatch(string)
? string
: shellSingleQuote(string);
}
diff --git a/pkg/test_runner/pubspec.yaml b/pkg/test_runner/pubspec.yaml
index 31396d4..3ce5bf7 100644
--- a/pkg/test_runner/pubspec.yaml
+++ b/pkg/test_runner/pubspec.yaml
@@ -7,7 +7,7 @@
publish_to: none
environment:
- sdk: '>=2.19.0 <3.0.0'
+ sdk: '>=3.4.0 <4.0.0'
# Use 'any' constraints here; we get our versions from the DEPS file.
dependencies:
diff --git a/runtime/tests/vm/dart/regress_46790_test.dart b/runtime/tests/vm/dart/regress_46790_test.dart
index ba2cfa5..8846059 100644
--- a/runtime/tests/vm/dart/regress_46790_test.dart
+++ b/runtime/tests/vm/dart/regress_46790_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--stacktrace_every=137 --deterministic
+// VMOptions=--stacktrace_every=137 --deterministic
// Reduced from
// The Dart Project Fuzz Tester (1.91).
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 504880f..e8ab786 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -1626,15 +1626,14 @@
saved_libraries_ = GrowableObjectArray::null();
}
-#ifdef DEBUG
void ProgramReloadContext::VerifyMaps() {
TIMELINE_SCOPE(VerifyMaps);
+
+ // Verify that two old classes aren't both mapped to the same new
+ // class. This could happen if the IsSameClass function is broken.
Class& cls = Class::Handle();
Class& new_cls = Class::Handle();
Class& cls2 = Class::Handle();
-
- // Verify that two old classes aren't both mapped to the same new
- // class. This could happen is the IsSameClass function is broken.
UnorderedHashMap<ClassMapTraits> class_map(class_map_storage_);
UnorderedHashMap<ClassMapTraits> reverse_class_map(
HashTables::New<UnorderedHashMap<ClassMapTraits> >(
@@ -1647,11 +1646,10 @@
cls = Class::RawCast(class_map.GetPayload(entry, 0));
cls2 ^= reverse_class_map.GetOrNull(new_cls);
if (!cls2.IsNull()) {
- OS::PrintErr(
+ FATAL(
"Classes '%s' and '%s' are distinct classes but both map "
" to class '%s'\n",
cls.ToCString(), cls2.ToCString(), new_cls.ToCString());
- UNREACHABLE();
}
bool update = reverse_class_map.UpdateOrInsert(cls, new_cls);
ASSERT(!update);
@@ -1659,15 +1657,41 @@
}
class_map.Release();
reverse_class_map.Release();
+
+ // Verify that two old libraries aren't both mapped to the same new
+ // library. This could happen if the IsSameLibrary function is broken.
+ Library& lib = Library::Handle();
+ Library& new_lib = Library::Handle();
+ Library& lib2 = Library::Handle();
+ UnorderedHashMap<LibraryMapTraits> library_map(library_map_storage_);
+ UnorderedHashMap<LibraryMapTraits> reverse_library_map(
+ HashTables::New<UnorderedHashMap<LibraryMapTraits> >(
+ library_map.NumOccupied()));
+ {
+ UnorderedHashMap<LibraryMapTraits>::Iterator it(&library_map);
+ while (it.MoveNext()) {
+ const intptr_t entry = it.Current();
+ new_lib = Library::RawCast(library_map.GetKey(entry));
+ lib = Library::RawCast(library_map.GetPayload(entry, 0));
+ lib2 ^= reverse_library_map.GetOrNull(new_lib);
+ if (!lib2.IsNull()) {
+ FATAL(
+ "Libraries '%s' and '%s' are distinct libraries but both map "
+ " to library '%s'\n",
+ lib.ToCString(), lib2.ToCString(), new_lib.ToCString());
+ }
+ bool update = reverse_library_map.UpdateOrInsert(lib, new_lib);
+ ASSERT(!update);
+ }
+ }
+ library_map.Release();
+ reverse_library_map.Release();
}
-#endif
void ProgramReloadContext::CommitBeforeInstanceMorphing() {
TIMELINE_SCOPE(Commit);
-#ifdef DEBUG
VerifyMaps();
-#endif
// Copy over certain properties of libraries, e.g. is the library
// debuggable?
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index 263b486..43e22ba 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -335,9 +335,7 @@
void RollbackLibraries();
-#ifdef DEBUG
void VerifyMaps();
-#endif
void CommitBeforeInstanceMorphing();
void CommitAfterInstanceMorphing();
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 7ab08d8..e03cf3e 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -255,7 +255,7 @@
]
source = "lib/$library"
dest = "$root_out_dir/$dart_sdk_output/lib/$library"
- exclude = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
+ exclude = "*.svn,doc,*.py,*.gypi,*.sh,.git*,*.gn,*.gni"
}
}
diff --git a/tests/language/deferred/prefix_importer_tree_shaken_test.dart b/tests/language/deferred/prefix_importer_tree_shaken_test.dart
index ccb0246..242302e 100644
--- a/tests/language/deferred/prefix_importer_tree_shaken_test.dart
+++ b/tests/language/deferred/prefix_importer_tree_shaken_test.dart
@@ -2,8 +2,8 @@
// 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.
-/// VMOptions=--dwarf_stack_traces=true
-/// VMOptions=--dwarf_stack_traces=false
+// VMOptions=--dwarf_stack_traces=true
+// VMOptions=--dwarf_stack_traces=false
import "prefix_importer_tree_shaken_immediate.dart" as i;
diff --git a/tests/language/deferred/regression_22995_test.dart b/tests/language/deferred/regression_22995_test.dart
index fdd36c1..daf72a0 100644
--- a/tests/language/deferred/regression_22995_test.dart
+++ b/tests/language/deferred/regression_22995_test.dart
@@ -4,6 +4,8 @@
// Test that closurizing a function implies a dependency on its type.
+// dart2wasmOptions=--extra-compiler-option=--enable-deferred-loading
+
import "package:expect/expect.dart";
import 'regression_22995_lib.dart' deferred as lib;
diff --git a/tests/language/vm/fuzzer_unsigned_shift_right_test.dart b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
index 01e935a..42660ed 100644
--- a/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
+++ b/tests/language/vm/fuzzer_unsigned_shift_right_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--deterministic
+// VMOptions=--deterministic
// The Dart Project Fuzz Tester (1.93).
// Program generated as:
diff --git a/tests/lib/developer/timeline_recorders_test.dart b/tests/lib/developer/timeline_recorders_test.dart
index 349cbba..2656f30 100644
--- a/tests/lib/developer/timeline_recorders_test.dart
+++ b/tests/lib/developer/timeline_recorders_test.dart
@@ -2,10 +2,10 @@
// 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.
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=endless
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=ring
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=startup
-/// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=systrace
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=endless
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=ring
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=startup
+// VMOptions=--timeline_streams=VM,Isolate,GC,Dart --timeline_recorder=systrace
import 'dart:developer';
diff --git a/tests/lib/js/static_interop_test/external_dart_reference_test.dart b/tests/lib/js/static_interop_test/external_dart_reference_test.dart
index 33108e4..98bce34 100644
--- a/tests/lib/js/static_interop_test/external_dart_reference_test.dart
+++ b/tests/lib/js/static_interop_test/external_dart_reference_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
import 'dart:js_interop';
diff --git a/tests/lib/js/static_interop_test/js_function_arity_test.dart b/tests/lib/js/static_interop_test/js_function_arity_test.dart
index a7ee811..5befc7e 100644
--- a/tests/lib/js/static_interop_test/js_function_arity_test.dart
+++ b/tests/lib/js/static_interop_test/js_function_arity_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
import 'dart:js_interop';
diff --git a/tests/lib/js/static_interop_test/js_function_conversions_test.dart b/tests/lib/js/static_interop_test/js_function_conversions_test.dart
index 9719735..f800fbe 100644
--- a/tests/lib/js/static_interop_test/js_function_conversions_test.dart
+++ b/tests/lib/js/static_interop_test/js_function_conversions_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// Requirements=checked-implicit-downcasts
+// Requirements=checked-implicit-downcasts
// Test that Function.toJS properly converts/casts arguments and return values
// when using non-JS types.
diff --git a/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart b/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
index cb155bb..da91c2e 100644
--- a/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
+++ b/tests/standalone/dwarf_stack_trace_invisible_functions_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_invisible_functions.so
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_invisible_functions.so
import 'dart:io';
diff --git a/tests/standalone/dwarf_stack_trace_obfuscate_test.dart b/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
index 01b5515..a6f09a7 100644
--- a/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
+++ b/tests/standalone/dwarf_stack_trace_obfuscate_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_obfuscate.so --obfuscate
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf_obfuscate.so --obfuscate
import 'dart:io';
diff --git a/tests/standalone/dwarf_stack_trace_test.dart b/tests/standalone/dwarf_stack_trace_test.dart
index 53f35db..f6bfad8 100644
--- a/tests/standalone/dwarf_stack_trace_test.dart
+++ b/tests/standalone/dwarf_stack_trace_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf.so
+// VMOptions=--dwarf-stack-traces --save-debugging-info=$TEST_COMPILATION_DIR/dwarf.so
import 'dart:convert';
import 'dart:io';
diff --git a/tests/standalone/regress31114_test.dart b/tests/standalone/regress31114_test.dart
index 2977a21..8f822ef 100644
--- a/tests/standalone/regress31114_test.dart
+++ b/tests/standalone/regress31114_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// VMOptions=--background-compilation=false --optimization-counter-threshold=20
+// VMOptions=--background-compilation=false --optimization-counter-threshold=20
import 'pow_test.dart' as test;
diff --git a/tests/web/consistent_subtract_error_test.dart b/tests/web/consistent_subtract_error_test.dart
index a34f50f..2a131a2 100644
--- a/tests/web/consistent_subtract_error_test.dart
+++ b/tests/web/consistent_subtract_error_test.dart
@@ -2,7 +2,7 @@
// 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.
-/// dart2jsOptions=--omit-implicit-checks
+// dart2jsOptions=--omit-implicit-checks
import "package:expect/expect.dart";
diff --git a/tools/VERSION b/tools/VERSION
index d74ebd2..286335e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 3
MINOR 6
PATCH 0
-PRERELEASE 236
+PRERELEASE 237
PRERELEASE_PATCH 0
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index ef7d845..9b0b50f 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -582,7 +582,7 @@
"use-sdk": true
}
},
- "ddc-mac-chrome": {
+ "ddc-mac-(chrome|safari)": {
"options": {
"architecture": "arm64",
"checked": true,
@@ -2022,6 +2022,49 @@
},
{
"builders": [
+ "ddc-mac-safari"
+ ],
+ "meta": {
+ "description": "DDC running in Safari on Mac."
+ },
+ "steps": [
+ {
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": [
+ "--arch=arm64",
+ "dart2js_bot",
+ "ddc_stable_test"
+ ]
+ },
+ {
+ "name": "ddc sdk tests",
+ "arguments": [
+ "-nddc-mac-safari",
+ "--arch=arm64",
+ "corelib",
+ "dartdevc",
+ "language",
+ "lib",
+ "web"
+ ],
+ "shards": 6,
+ "fileset": "js_platform"
+ },
+ {
+ "name": "ddc co19 tests",
+ "arguments": [
+ "-nddc-mac-safari",
+ "--arch=arm64",
+ "co19"
+ ],
+ "shards": 6,
+ "fileset": "js_platform"
+ }
+ ]
+ },
+ {
+ "builders": [
"ddc-linux-firefox"
],
"meta": {