Version 2.19.0-33.0.dev
Merge commit 'c8728d92e3abc5f06e8c4e744f4671611511669c' into 'dev'
diff --git a/pkg/dart2wasm/bin/dart2wasm.dart b/pkg/dart2wasm/bin/dart2wasm.dart
index 4a382a9..8e1f696 100644
--- a/pkg/dart2wasm/bin/dart2wasm.dart
+++ b/pkg/dart2wasm/bin/dart2wasm.dart
@@ -5,102 +5,109 @@
import 'dart:io';
import 'dart:typed_data';
+import 'package:args/args.dart' as args;
import 'package:front_end/src/api_unstable/vm.dart'
show printDiagnosticMessage, resolveInputUri;
import 'package:dart2wasm/compile.dart';
-import 'package:dart2wasm/translator.dart';
+import 'package:dart2wasm/compiler_options.dart';
+import 'package:dart2wasm/option.dart';
-final Map<String, void Function(TranslatorOptions, bool)> boolOptionMap = {
- "export-all": (o, value) => o.exportAll = value,
- "import-shared-memory": (o, value) => o.importSharedMemory = value,
- "inlining": (o, value) => o.inlining = value,
- "lazy-constants": (o, value) => o.lazyConstants = value,
- "local-nullability": (o, value) => o.localNullability = value,
- "name-section": (o, value) => o.nameSection = value,
- "nominal-types": (o, value) => o.nominalTypes = value,
- "parameter-nullability": (o, value) => o.parameterNullability = value,
- "polymorphic-specialization": (o, value) =>
- o.polymorphicSpecialization = value,
- "print-kernel": (o, value) => o.printKernel = value,
- "print-wasm": (o, value) => o.printWasm = value,
- "runtime-types": (o, value) => o.runtimeTypes = value,
- "string-data-segments": (o, value) => o.stringDataSegments = value,
-};
-final Map<String, void Function(TranslatorOptions, int)> intOptionMap = {
- "shared-memory-max-pages": (o, value) => o.sharedMemoryMaxPages = value,
- "watch": (o, value) => (o.watchPoints ??= []).add(value),
-};
+// Used to allow us to keep defaults on their respective option structs.
+final CompilerOptions _d = CompilerOptions.defaultOptions();
-Never usage(String message) {
- print("Usage: dart2wasm [<options>] <infile.dart> <outfile.wasm>");
- print("");
- print("*NOTE*: Wasm compilation is experimental.");
- print("The support may change, or be removed, with no advance notice.");
- print("");
- print("Options:");
- print(" --dart-sdk=<path>");
- print(" --platform=<path>");
- print("");
- for (String option in boolOptionMap.keys) {
- print(" --[no-]$option");
+final List<Option> options = [
+ Flag("help", (o, _) {}, abbr: "h", negatable: false, defaultsTo: false),
+ Flag("export-all", (o, value) => o.translatorOptions.exportAll = value,
+ defaultsTo: _d.translatorOptions.exportAll),
+ Flag("import-shared-memory",
+ (o, value) => o.translatorOptions.importSharedMemory = value,
+ defaultsTo: _d.translatorOptions.importSharedMemory),
+ Flag("inlining", (o, value) => o.translatorOptions.inlining = value,
+ defaultsTo: _d.translatorOptions.inlining),
+ Flag(
+ "lazy-constants", (o, value) => o.translatorOptions.lazyConstants = value,
+ defaultsTo: _d.translatorOptions.lazyConstants),
+ Flag("local-nullability",
+ (o, value) => o.translatorOptions.localNullability = value,
+ defaultsTo: _d.translatorOptions.localNullability),
+ Flag("name-section", (o, value) => o.translatorOptions.nameSection = value,
+ defaultsTo: _d.translatorOptions.nameSection),
+ Flag("nominal-types", (o, value) => o.translatorOptions.nominalTypes = value,
+ defaultsTo: _d.translatorOptions.nominalTypes),
+ Flag("parameter-nullability",
+ (o, value) => o.translatorOptions.parameterNullability = value,
+ defaultsTo: _d.translatorOptions.parameterNullability),
+ Flag("polymorphic-specialization",
+ (o, value) => o.translatorOptions.polymorphicSpecialization = value,
+ defaultsTo: _d.translatorOptions.polymorphicSpecialization),
+ Flag("print-kernel", (o, value) => o.translatorOptions.printKernel = value,
+ defaultsTo: _d.translatorOptions.printKernel),
+ Flag("print-wasm", (o, value) => o.translatorOptions.printWasm = value,
+ defaultsTo: _d.translatorOptions.printWasm),
+ Flag("runtime-types", (o, value) => o.translatorOptions.runtimeTypes = value,
+ defaultsTo: _d.translatorOptions.runtimeTypes),
+ Flag("string-data-segments",
+ (o, value) => o.translatorOptions.stringDataSegments = value,
+ defaultsTo: _d.translatorOptions.stringDataSegments),
+ IntOption(
+ "inlining-limit", (o, value) => o.translatorOptions.inliningLimit = value,
+ defaultsTo: "${_d.translatorOptions.inliningLimit}"),
+ IntOption("shared-memory-max-pages",
+ (o, value) => o.translatorOptions.sharedMemoryMaxPages = value),
+ UriOption("dart-sdk", (o, value) => o.sdkPath = value,
+ defaultsTo: "${_d.sdkPath}"),
+ UriOption("platform", (o, value) => o.platformPath = value),
+ IntMultiOption(
+ "watch", (o, values) => o.translatorOptions.watchPoints = values),
+];
+
+CompilerOptions parseArguments(List<String> arguments) {
+ args.ArgParser parser = args.ArgParser();
+ for (Option arg in options) {
+ arg.applyToParser(parser);
}
- print("");
- for (String option in intOptionMap.keys) {
- print(" --$option <value>");
- }
- print("");
- throw message;
+ Never usage() {
+ print("Usage: dart2wasm [<options>] <infile.dart> <outfile.wasm>");
+ print("");
+ print("*NOTE*: Wasm compilation is experimental.");
+ print("The support may change, or be removed, with no advance notice.");
+ print("");
+ print("Options:");
+ for (String line in parser.usage.split('\n')) {
+ print('\t$line');
+ }
+ exit(64);
+ }
+
+ try {
+ args.ArgResults results = parser.parse(arguments);
+ if (results['help']) {
+ usage();
+ }
+ List<String> rest = results.rest;
+ if (rest.length != 2) {
+ throw ArgumentError('Requires two positional file arguments');
+ }
+ CompilerOptions compilerOptions =
+ CompilerOptions(mainUri: resolveInputUri(rest[0]), outputFile: rest[1]);
+ for (Option arg in options) {
+ if (results.wasParsed(arg.name)) {
+ arg.applyToOptions(compilerOptions, results[arg.name]);
+ }
+ }
+ return compilerOptions;
+ } catch (e, s) {
+ print(s);
+ print('Argument Error: ' + e.toString());
+ usage();
+ }
}
Future<int> main(List<String> args) async {
- Uri sdkPath = Platform.script.resolve("../../../sdk");
- Uri? platformPath = null;
- TranslatorOptions options = TranslatorOptions();
- List<String> nonOptions = [];
- void Function(TranslatorOptions, int)? intOptionFun = null;
- for (String arg in args) {
- if (intOptionFun != null) {
- intOptionFun(options, int.parse(arg));
- intOptionFun = null;
- } else if (arg.startsWith("--dart-sdk=")) {
- String path = arg.substring("--dart-sdk=".length);
- sdkPath = Uri.file(Directory(path).absolute.path);
- } else if (arg.startsWith("--platform=")) {
- String path = arg.substring("--platform=".length);
- platformPath = Uri.file(Directory(path).absolute.path);
- } else if (arg.startsWith("--no-")) {
- var optionFun = boolOptionMap[arg.substring(5)];
- if (optionFun == null) usage("Unknown option $arg");
- optionFun(options, false);
- } else if (arg.startsWith("--")) {
- var optionFun = boolOptionMap[arg.substring(2)];
- if (optionFun != null) {
- optionFun(options, true);
- } else {
- intOptionFun = intOptionMap[arg.substring(2)];
- if (intOptionFun == null) usage("Unknown option $arg");
- }
- } else {
- nonOptions.add(arg);
- }
- }
- if (intOptionFun != null) {
- usage("Missing argument to ${args.last}");
- }
-
- if (options.importSharedMemory && options.sharedMemoryMaxPages == null) {
- usage("--shared-memory-max-pages must be "
- "specified if --import-shared-memory is used.");
- }
-
- if (nonOptions.length != 2) usage("Requires two file arguments");
- String input = nonOptions[0];
- String output = nonOptions[1];
- Uri mainUri = resolveInputUri(input);
-
- Uint8List? module = await compileToModule(mainUri, sdkPath, platformPath,
+ CompilerOptions options = parseArguments(args);
+ Uint8List? module = await compileToModule(
options, (message) => printDiagnosticMessage(message, print));
if (module == null) {
@@ -108,7 +115,7 @@
return exitCode;
}
- await File(output).writeAsBytes(module);
+ await File(options.outputFile).writeAsBytes(module);
return 0;
}
diff --git a/pkg/dart2wasm/lib/compile.dart b/pkg/dart2wasm/lib/compile.dart
index f8c4739..990f8dbd 100644
--- a/pkg/dart2wasm/lib/compile.dart
+++ b/pkg/dart2wasm/lib/compile.dart
@@ -22,6 +22,7 @@
import 'package:vm/transformations/type_flow/transformer.dart' as globalTypeFlow
show transformComponent;
+import 'package:dart2wasm/compiler_options.dart' as compiler;
import 'package:dart2wasm/target.dart';
import 'package:dart2wasm/translator.dart';
@@ -30,11 +31,7 @@
/// Returns `null` if an error occurred during compilation. The
/// [handleDiagnosticMessage] callback will have received an error message
/// describing the error.
-Future<Uint8List?> compileToModule(
- Uri mainUri,
- Uri sdkRoot,
- Uri? platformDill,
- TranslatorOptions options,
+Future<Uint8List?> compileToModule(compiler.CompilerOptions options,
void Function(DiagnosticMessage) handleDiagnosticMessage) async {
var succeeded = true;
void diagnosticMessageHandler(DiagnosticMessage message) {
@@ -47,20 +44,20 @@
Target target = WasmTarget();
CompilerOptions compilerOptions = CompilerOptions()
..target = target
- ..sdkRoot = sdkRoot
+ ..sdkRoot = options.sdkPath
..environmentDefines = {}
..verbose = false
..onDiagnostic = diagnosticMessageHandler
..nnbdMode = NnbdMode.Strong;
- if (platformDill != null) {
- compilerOptions.sdkSummary = platformDill;
+ if (options.platformPath != null) {
+ compilerOptions.sdkSummary = options.platformPath;
} else {
compilerOptions.compileSdk = true;
}
CompilerResult? compilerResult =
- await kernelForProgram(mainUri, compilerOptions);
+ await kernelForProgram(options.mainUri, compilerOptions);
if (compilerResult == null || !succeeded) {
return null;
}
@@ -78,7 +75,10 @@
return true;
}());
- var translator = Translator(component, coreTypes,
- TypeEnvironment(coreTypes, compilerResult.classHierarchy!), options);
+ var translator = Translator(
+ component,
+ coreTypes,
+ TypeEnvironment(coreTypes, compilerResult.classHierarchy!),
+ options.translatorOptions);
return translator.translate();
}
diff --git a/pkg/dart2wasm/lib/compiler_options.dart b/pkg/dart2wasm/lib/compiler_options.dart
new file mode 100644
index 0000000..b206711
--- /dev/null
+++ b/pkg/dart2wasm/lib/compiler_options.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:dart2wasm/translator.dart';
+
+class CompilerOptions {
+ final TranslatorOptions translatorOptions = TranslatorOptions();
+
+ Uri sdkPath = Platform.script.resolve("../../../sdk");
+ Uri? platformPath;
+ Uri mainUri;
+ String outputFile;
+
+ factory CompilerOptions.defaultOptions() =>
+ CompilerOptions(mainUri: Uri(), outputFile: '');
+
+ CompilerOptions({required this.mainUri, required this.outputFile});
+
+ void validate() {
+ if (translatorOptions.importSharedMemory &&
+ translatorOptions.sharedMemoryMaxPages == null) {
+ throw ArgumentError("--shared-memory-max-pages must be specified if "
+ "--import-shared-memory is used.");
+ }
+ }
+}
diff --git a/pkg/dart2wasm/lib/option.dart b/pkg/dart2wasm/lib/option.dart
new file mode 100644
index 0000000..fc45d7d
--- /dev/null
+++ b/pkg/dart2wasm/lib/option.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+
+import 'package:dart2wasm/compiler_options.dart';
+
+class Option<T> {
+ final String name;
+ final void Function(ArgParser a) applyToParser;
+ final void Function(CompilerOptions o, T v) _applyToOptions;
+ final T Function(dynamic v) converter;
+
+ void applyToOptions(CompilerOptions o, dynamic v) =>
+ _applyToOptions(o, converter(v));
+
+ Option(this.name, this.applyToParser, this._applyToOptions, this.converter);
+}
+
+class Flag extends Option<bool> {
+ Flag(String name, void applyToOptions(CompilerOptions o, bool v),
+ {String? abbr,
+ String? help,
+ bool? defaultsTo = false,
+ bool negatable = true})
+ : super(
+ name,
+ (a) => a.addFlag(name,
+ abbr: abbr,
+ help: help,
+ defaultsTo: defaultsTo,
+ negatable: negatable),
+ applyToOptions,
+ (v) => v == 'true' ? true : false);
+}
+
+class ValueOption<T> extends Option<T> {
+ ValueOption(String name, void applyToOptions(CompilerOptions o, T v),
+ T converter(dynamic v), {String? defaultsTo})
+ : super(name, (a) => a.addOption(name, defaultsTo: defaultsTo),
+ applyToOptions, converter);
+}
+
+class IntOption extends ValueOption<int> {
+ IntOption(String name, void applyToOptions(CompilerOptions o, int v),
+ {String? defaultsTo})
+ : super(name, applyToOptions, (v) => int.parse(v),
+ defaultsTo: defaultsTo);
+}
+
+class UriOption extends ValueOption<Uri> {
+ UriOption(String name, void applyToOptions(CompilerOptions o, Uri v),
+ {String? defaultsTo})
+ : super(name, applyToOptions, (v) => Uri.file(Directory(v).absolute.path),
+ defaultsTo: defaultsTo);
+}
+
+class MultiValueOption<T> extends Option<List<T>> {
+ MultiValueOption(
+ String name,
+ void Function(CompilerOptions o, List<T> v) applyToOptions,
+ T converter(dynamic v),
+ {Iterable<String>? defaultsTo})
+ : super(name, (a) => a.addMultiOption(name, defaultsTo: defaultsTo),
+ applyToOptions, (vs) => vs.map(converter).cast<T>().toList());
+}
+
+class IntMultiOption extends MultiValueOption<int> {
+ IntMultiOption(name, void applyToOptions(CompilerOptions o, List<int> v),
+ {Iterable<String>? defaultsTo})
+ : super(name, applyToOptions, (v) => int.parse(v),
+ defaultsTo: defaultsTo);
+}
diff --git a/pkg/dart2wasm/pubspec.yaml b/pkg/dart2wasm/pubspec.yaml
index a8cd88a..cc153ea 100644
--- a/pkg/dart2wasm/pubspec.yaml
+++ b/pkg/dart2wasm/pubspec.yaml
@@ -7,6 +7,7 @@
# Use 'any' constraints here; we get our versions from the DEPS file.
dependencies:
_js_interop_checks: any
+ args: any
front_end: any
kernel: any
vm: any
diff --git a/tools/VERSION b/tools/VERSION
index 725f25d..8251f4b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 19
PATCH 0
-PRERELEASE 32
+PRERELEASE 33
PRERELEASE_PATCH 0
\ No newline at end of file