mirror of
https://github.com/dart-lang/sdk
synced 2024-07-03 08:19:13 +00:00
[dart2wasm] Switch to package args for command line parsing.
Change-Id: I6ca7846e7dd2f41d4b04dcba1fce8ac8e7b1391f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/250481 Reviewed-by: Aske Simon Christensen <askesc@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
parent
ad004cf922
commit
c8728d92e3
|
@ -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 @@ Future<int> main(List<String> args) async {
|
|||
return exitCode;
|
||||
}
|
||||
|
||||
await File(output).writeAsBytes(module);
|
||||
await File(options.outputFile).writeAsBytes(module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import 'package:kernel/verifier.dart';
|
|||
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 @@ import 'package:dart2wasm/translator.dart';
|
|||
/// 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 @@ Future<Uint8List?> compileToModule(
|
|||
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 @@ Future<Uint8List?> compileToModule(
|
|||
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();
|
||||
}
|
||||
|
|
29
pkg/dart2wasm/lib/compiler_options.dart
Normal file
29
pkg/dart2wasm/lib/compiler_options.dart
Normal file
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
76
pkg/dart2wasm/lib/option.dart
Normal file
76
pkg/dart2wasm/lib/option.dart
Normal file
|
@ -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);
|
||||
}
|
|
@ -7,6 +7,7 @@ environment:
|
|||
# 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
|
||||
|
|
Loading…
Reference in New Issue
Block a user