diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index a67023add2..3902973170 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -1,3 +1,10 @@ +## 27.2.0-wip + +- Add `deprecatedJsInterop` to `BuildSettings` and `CompilerOptions`. When it + is set, the expression compiler worker is started with + `--[no-]deprecated-js-interop`. This requires a Dart SDK that supports the + flag. + ## 27.1.4 - Fix duplicated browser tabs taking over the original tab's DWDS connection. diff --git a/dwds/lib/src/loaders/strategy.dart b/dwds/lib/src/loaders/strategy.dart index c4ccaa6aa9..eea2416231 100644 --- a/dwds/lib/src/loaders/strategy.dart +++ b/dwds/lib/src/loaders/strategy.dart @@ -236,10 +236,17 @@ class BuildSettings { final bool isFlutterApp; final List experiments; + /// Whether the compilers allow the deprecated JS interop libraries, such as + /// `dart:html`. + /// + /// If `null`, no flag is passed and the compiler default is used. + final bool? deprecatedJsInterop; + const BuildSettings({ this.appEntrypoint, this.canaryFeatures = false, this.isFlutterApp = true, this.experiments = const [], + this.deprecatedJsInterop, }); } diff --git a/dwds/lib/src/services/chrome/chrome_proxy_service.dart b/dwds/lib/src/services/chrome/chrome_proxy_service.dart index 1add07eece..ad785f3b01 100644 --- a/dwds/lib/src/services/chrome/chrome_proxy_service.dart +++ b/dwds/lib/src/services/chrome/chrome_proxy_service.dart @@ -186,15 +186,15 @@ final class ChromeProxyService extends ProxyService { Future _updateCompilerDependencies(String entrypoint) async { final loadStrategy = globalToolConfiguration.loadStrategy; final moduleFormat = loadStrategy.moduleFormat; - final canaryFeatures = loadStrategy.buildSettings.canaryFeatures; - final experiments = loadStrategy.buildSettings.experiments; + final buildSettings = loadStrategy.buildSettings; _logger.info('Initializing expression compiler for $entrypoint'); final compilerOptions = CompilerOptions( moduleFormat: ModuleFormat.values.byName(moduleFormat), - canaryFeatures: canaryFeatures, - experiments: experiments, + canaryFeatures: buildSettings.canaryFeatures, + experiments: buildSettings.experiments, + deprecatedJsInterop: buildSettings.deprecatedJsInterop, ); final compiler = _compiler; diff --git a/dwds/lib/src/services/expression_compiler.dart b/dwds/lib/src/services/expression_compiler.dart index 2d7803a413..15e143368a 100644 --- a/dwds/lib/src/services/expression_compiler.dart +++ b/dwds/lib/src/services/expression_compiler.dart @@ -9,10 +9,17 @@ class CompilerOptions { final bool canaryFeatures; final List experiments; + /// Whether the compiler allows the deprecated JS interop libraries, such as + /// `dart:html`. + /// + /// If `null`, no flag is passed and the compiler default is used. + final bool? deprecatedJsInterop; + CompilerOptions({ required this.moduleFormat, required this.canaryFeatures, required this.experiments, + this.deprecatedJsInterop, }); } diff --git a/dwds/lib/src/services/expression_compiler_service.dart b/dwds/lib/src/services/expression_compiler_service.dart index 4e7740de5a..cf5cc12726 100644 --- a/dwds/lib/src/services/expression_compiler_service.dart +++ b/dwds/lib/src/services/expression_compiler_service.dart @@ -9,6 +9,41 @@ import 'package:async/async.dart'; import 'package:dwds/src/services/expression_compiler.dart'; import 'package:dwds/src/utilities/sdk_configuration.dart'; import 'package:logging/logging.dart'; +import 'package:meta/meta.dart'; + +/// Returns the arguments for the DDC expression compiler worker. +@visibleForTesting +List expressionCompilerWorkerArgs({ + required Uri sdkSummaryUri, + required String address, + required int port, + required CompilerOptions compilerOptions, + required bool verbose, +}) => [ + '--experimental-expression-compiler', + '--dart-sdk-summary', + '$sdkSummaryUri', + '--asset-server-address', + address, + '--asset-server-port', + '$port', + '--module-format', + compilerOptions.moduleFormat.name, + if (verbose) '--verbose', + for (final experiment in compilerOptions.experiments) + '--enable-experiment=$experiment', + if (compilerOptions.canaryFeatures) '--canary', + ?_deprecatedJsInteropArg(compilerOptions.deprecatedJsInterop), +]; + +/// The `--[no-]deprecated-js-interop` argument, or `null` to use the compiler +/// default. +String? _deprecatedJsInteropArg(bool? deprecatedJsInterop) => + switch (deprecatedJsInterop) { + null => null, + true => '--deprecated-js-interop', + false => '--no-deprecated-js-interop', + }; class _Compiler { static final _logger = Logger('ExpressionCompilerService'); @@ -67,21 +102,13 @@ class _Compiler { final workerUri = sdkConfiguration.compilerWorkerUri!; final sdkSummaryUri = sdkConfiguration.sdkSummaryUri!; - final args = [ - '--experimental-expression-compiler', - '--dart-sdk-summary', - '$sdkSummaryUri', - '--asset-server-address', - address, - '--asset-server-port', - '$port', - '--module-format', - compilerOptions.moduleFormat.name, - if (verbose) '--verbose', - for (final experiment in compilerOptions.experiments) - '--enable-experiment=$experiment', - if (compilerOptions.canaryFeatures) '--canary', - ]; + final args = expressionCompilerWorkerArgs( + sdkSummaryUri: sdkSummaryUri, + address: address, + port: port, + compilerOptions: compilerOptions, + verbose: verbose, + ); _logger.info('Starting...'); _logger.finest('$workerUri ${args.join(' ')}'); diff --git a/dwds/lib/src/version.dart b/dwds/lib/src/version.dart index e7267f63a2..aeec9f16b7 100644 --- a/dwds/lib/src/version.dart +++ b/dwds/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '27.1.4'; +const packageVersion = '27.2.0-wip'; diff --git a/dwds/pubspec.yaml b/dwds/pubspec.yaml index 42421f8b78..04453bf114 100644 --- a/dwds/pubspec.yaml +++ b/dwds/pubspec.yaml @@ -1,13 +1,13 @@ name: dwds # Every time this changes you need to run `dart run tool/build.dart`. -version: 27.1.4 +version: 27.2.0-wip description: >- A service that proxies between the Chrome debug protocol and the Dart VM service protocol. repository: https://github.com/dart-lang/webdev/tree/main/dwds environment: - sdk: ^3.13.0-107.0.dev + sdk: ^3.14.0-286.0.dev dependencies: async: ^2.9.0 diff --git a/dwds/test/services/expression_compiler_worker_args_test.dart b/dwds/test/services/expression_compiler_worker_args_test.dart new file mode 100644 index 0000000000..79ff56595a --- /dev/null +++ b/dwds/test/services/expression_compiler_worker_args_test.dart @@ -0,0 +1,57 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:dwds/src/services/expression_compiler.dart'; +import 'package:dwds/src/services/expression_compiler_service.dart'; +import 'package:test/test.dart'; + +void main() { + group('expressionCompilerWorkerArgs', () { + List argsFor({bool? deprecatedJsInterop}) => + expressionCompilerWorkerArgs( + sdkSummaryUri: Uri.file('/sdk/ddc_outline.dill'), + address: 'localhost', + port: 1234, + compilerOptions: CompilerOptions( + moduleFormat: ModuleFormat.ddc, + canaryFeatures: true, + experiments: const ['records'], + deprecatedJsInterop: deprecatedJsInterop, + ), + verbose: false, + ); + + test('passes the compiler options', () { + expect(argsFor(), [ + '--experimental-expression-compiler', + '--dart-sdk-summary', + 'file:///sdk/ddc_outline.dill', + '--asset-server-address', + 'localhost', + '--asset-server-port', + '1234', + '--module-format', + 'ddc', + '--enable-experiment=records', + '--canary', + ]); + }); + + test('does not pass deprecated-js-interop when not configured', () { + expect(argsFor(), isNot(contains(contains('deprecated-js-interop')))); + }); + + test('passes --deprecated-js-interop', () { + final args = argsFor(deprecatedJsInterop: true); + expect(args, contains('--deprecated-js-interop')); + expect(args, isNot(contains('--no-deprecated-js-interop'))); + }); + + test('passes --no-deprecated-js-interop', () { + final args = argsFor(deprecatedJsInterop: false); + expect(args, contains('--no-deprecated-js-interop')); + expect(args, isNot(contains('--deprecated-js-interop'))); + }); + }); +}