Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: pkg/front_end/tool/_fasta/command_line.dart

Issue 3003743002: Move tools to tool folder. (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library fasta.tool.command_line;
6
7 import 'dart:io' show exit;
8
9 import 'package:front_end/compiler_options.dart' show CompilerOptions;
10
11 import 'package:front_end/src/base/processed_options.dart'
12 show ProcessedOptions;
13
14 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
15
16 import 'package:front_end/src/fasta/fasta_codes.dart'
17 show
18 Message,
19 templateFastaCLIArgumentRequired,
20 messageFastaUsageLong,
21 messageFastaUsageShort,
22 templateUnspecified;
23
24 import 'package:front_end/src/fasta/problems.dart' show unhandled;
25
26 import 'package:front_end/src/fasta/severity.dart' show Severity;
27
28 import 'package:kernel/target/targets.dart'
29 show Target, getTarget, TargetFlags, targets;
30
31 class CommandLineProblem {
32 final Message message;
33
34 CommandLineProblem(this.message);
35
36 CommandLineProblem.deprecated(String message)
37 : this(templateUnspecified.withArguments(message));
38 }
39
40 class ParsedArguments {
41 final Map<String, dynamic> options = <String, dynamic>{};
42 final List<String> arguments = <String>[];
43
44 toString() => "ParsedArguments($options, $arguments)";
45
46 /// Parses a list of command-line [arguments] into options and arguments.
47 ///
48 /// An /option/ is something that, normally, starts with `-` or `--` (one or
49 /// two dashes). However, as a special case `/?` and `/h` are also recognized
50 /// as options for increased compatibility with Windows. An option can have a
51 /// value.
52 ///
53 /// An /argument/ is something that isn't an option, for example, a file name.
54 ///
55 /// The specification is a map of options to one of the type literals `Uri`,
56 /// `int`, `bool`, or `String`, or a comma (`","`) that represents option
57 /// values of type [Uri], [int], [bool], [String], or a comma-separated list
58 /// of [String], respectively.
59 ///
60 /// If [arguments] contains `"--"`, anything before is parsed as options, and
61 /// arguments; anything following is treated as arguments (even if starting
62 /// with, for example, a `-`).
63 ///
64 /// Anything that looks like an option is assumed to be a `bool` option set
65 /// to true, unless it's mentioned in [specification] in which case the
66 /// option requires a value, either on the form `--option value` or
67 /// `--option=value`.
68 ///
69 /// This method performs only a limited amount of validation, but if an error
70 /// occurs, it will print [usage] along with a specific error message.
71 static ParsedArguments parse(
72 List<String> arguments, Map<String, dynamic> specification) {
73 specification ??= const <String, dynamic>{};
74 ParsedArguments result = new ParsedArguments();
75 int index = arguments.indexOf("--");
76 Iterable<String> nonOptions = const <String>[];
77 Iterator<String> iterator = arguments.iterator;
78 if (index != -1) {
79 nonOptions = arguments.skip(index + 1);
80 iterator = arguments.take(index).iterator;
81 }
82 while (iterator.moveNext()) {
83 String argument = iterator.current;
84 if (argument.startsWith("-")) {
85 var valueSpecification = specification[argument];
86 String value;
87 if (valueSpecification != null) {
88 if (!iterator.moveNext()) {
89 throw new CommandLineProblem(
90 templateFastaCLIArgumentRequired.withArguments(argument));
91 }
92 value = iterator.current;
93 } else {
94 index = argument.indexOf("=");
95 if (index != -1) {
96 value = argument.substring(index + 1);
97 argument = argument.substring(0, index);
98 valueSpecification = specification[argument];
99 }
100 }
101 if (valueSpecification == null) {
102 if (value != null) {
103 throw new CommandLineProblem.deprecated(
104 "Argument '$argument' doesn't take a value: '$value'.");
105 }
106 result.options[argument] = true;
107 } else {
108 if (valueSpecification is! String && valueSpecification is! Type) {
109 return throw new CommandLineProblem.deprecated(
110 "Unrecognized type of value "
111 "specification: ${valueSpecification.runtimeType}.");
112 }
113 switch ("$valueSpecification") {
114 case ",":
115 result.options
116 .putIfAbsent(argument, () => <String>[])
117 .addAll(value.split(","));
118 break;
119
120 case "int":
121 case "bool":
122 case "String":
123 case "Uri":
124 if (result.options.containsKey(argument)) {
125 return throw new CommandLineProblem.deprecated(
126 "Multiple values for '$argument': "
127 "'${result.options[argument]}' and '$value'.");
128 }
129 var parsedValue;
130 if (valueSpecification == int) {
131 parsedValue = int.parse(value, onError: (_) {
132 return throw new CommandLineProblem.deprecated(
133 "Value for '$argument', '$value', isn't an int.");
134 });
135 } else if (valueSpecification == bool) {
136 if (value == "true" || value == "yes") {
137 parsedValue = true;
138 } else if (value == "false" || value == "no") {
139 parsedValue = false;
140 } else {
141 return throw new CommandLineProblem.deprecated(
142 "Value for '$argument' is '$value', "
143 "but expected one of: 'true', 'false', 'yes', or 'no'.");
144 }
145 } else if (valueSpecification == Uri) {
146 parsedValue = Uri.base.resolve(value);
147 } else if (valueSpecification == String) {
148 parsedValue = value;
149 } else if (valueSpecification is String) {
150 return throw new CommandLineProblem.deprecated(
151 "Unrecognized value specification: "
152 "'$valueSpecification', try using a type literal instead.");
153 } else {
154 // All possible cases should have been handled above.
155 return unhandled("${valueSpecification.runtimeType}",
156 "CommandLine.parse", -1, null);
157 }
158 result.options[argument] = parsedValue;
159 break;
160
161 default:
162 return throw new CommandLineProblem.deprecated(
163 "Unrecognized value specification: '$valueSpecification'.");
164 }
165 }
166 } else if (argument == "/?" || argument == "/h") {
167 result.options[argument] = true;
168 } else {
169 result.arguments.add(argument);
170 }
171 }
172 result.arguments.addAll(nonOptions);
173 return result;
174 }
175 }
176
177 const Map<String, dynamic> optionSpecification = const <String, dynamic>{
178 "--compile-sdk": Uri,
179 "--fatal": ",",
180 "--output": Uri,
181 "-o": Uri,
182 "--packages": Uri,
183 "--platform": Uri,
184 "--sdk": Uri,
185 "--target": String,
186 "-t": String,
187 };
188
189 ProcessedOptions analyzeCommandLine(
190 String programName,
191 ParsedArguments parsedArguments,
192 bool areRestArgumentsInputs,
193 bool verbose) {
194 final Map<String, dynamic> options = parsedArguments.options;
195
196 final List<String> arguments = parsedArguments.arguments;
197
198 final bool help = options.containsKey("--help") ||
199 options.containsKey("-h") ||
200 options.containsKey("/h") ||
201 options.containsKey("/?");
202
203 if (help) {
204 print(computeUsage(programName, verbose).message);
205 exit(0);
206 }
207
208 if (options.containsKey("-o") && options.containsKey("--output")) {
209 return throw new CommandLineProblem.deprecated(
210 "Can't specify both '-o' and '--output'.");
211 }
212
213 if (options.containsKey("-t") && options.containsKey("--target")) {
214 return throw new CommandLineProblem.deprecated(
215 "Can't specify both '-t' and '--target'.");
216 }
217
218 if (options.containsKey("--compile-sdk") &&
219 options.containsKey("--platform")) {
220 return throw new CommandLineProblem.deprecated(
221 "Can't specify both '--compile-sdk' and '--platform'.");
222 }
223
224 if (programName == "compile_platform") {
225 if (arguments.length != 3) {
226 return throw new CommandLineProblem.deprecated(
227 "Expected three arguments.");
228 }
229 if (options.containsKey("--compile-sdk")) {
230 return throw new CommandLineProblem.deprecated(
231 "Cannot specify '--compile-sdk' option to compile_platform.");
232 }
233 options['--compile-sdk'] = Uri.base.resolveUri(new Uri.file(arguments[0]));
234 } else if (arguments.isEmpty) {
235 return throw new CommandLineProblem.deprecated("No Dart file specified.");
236 }
237
238 final bool strongMode = options.containsKey("--strong-mode");
239
240 final String targetName = options["-t"] ?? options["--target"] ?? "vm_fasta";
241
242 final Target target =
243 getTarget(targetName, new TargetFlags(strongMode: strongMode));
244 if (target == null) {
245 return throw new CommandLineProblem.deprecated(
246 "Target '${targetName}' not recognized. "
247 "Valid targets are:\n ${targets.keys.join("\n ")}");
248 }
249
250 final bool verify = options.containsKey("--verify");
251
252 final bool dumpIr = options.containsKey("--dump-ir");
253
254 final bool excludeSource = options.containsKey("--exclude-source");
255
256 final Uri defaultOutput = Uri.base.resolve("${arguments.first}.dill");
257
258 final Uri output = options["-o"] ?? options["--output"] ?? defaultOutput;
259
260 final Uri platform = options.containsKey("--compile-sdk")
261 ? null
262 : options["--platform"] ?? Uri.base.resolve("platform.dill");
263
264 final Uri packages = options["--packages"];
265
266 final Uri sdk = options["--sdk"] ?? options["--compile-sdk"];
267
268 final Set<String> fatal =
269 new Set<String>.from(options["--fatal"] ?? <String>[]);
270
271 final bool errorsAreFatal = fatal.contains("errors");
272
273 final bool warningsAreFatal = fatal.contains("warnings");
274
275 final bool nitsAreFatal = fatal.contains("nits");
276
277 CompilerOptions compilerOptions = new CompilerOptions()
278 ..compileSdk = options.containsKey("--compile-sdk")
279 ..sdkRoot = sdk
280 ..sdkSummary = platform
281 ..packagesFileUri = packages
282 ..strongMode = strongMode
283 ..target = target
284 ..throwOnErrors = errorsAreFatal
285 ..throwOnWarnings = warningsAreFatal
286 ..throwOnNits = nitsAreFatal
287 ..embedSourceText = !excludeSource
288 ..debugDump = dumpIr
289 ..verbose = verbose
290 ..verify = verify;
291
292 // TODO(ahe): What about chase dependencies?
293
294 var inputs = <Uri>[];
295 if (areRestArgumentsInputs) {
296 inputs = arguments.map(Uri.base.resolve).toList();
297 }
298 return new ProcessedOptions(compilerOptions, false, inputs, output);
299 }
300
301 dynamic withGlobalOptions(
302 String programName,
303 List<String> arguments,
304 bool areRestArgumentsInputs,
305 dynamic f(CompilerContext context, List<String> restArguments)) {
306 ParsedArguments parsedArguments;
307 ProcessedOptions options;
308 bool verbose = true;
309 CommandLineProblem problem;
310 try {
311 parsedArguments = ParsedArguments.parse(arguments, optionSpecification);
312 verbose = parsedArguments.options.containsKey("-v") ||
313 parsedArguments.options.containsKey("--verbose");
314 options = analyzeCommandLine(
315 programName, parsedArguments, areRestArgumentsInputs, verbose);
316 } on CommandLineProblem catch (e) {
317 options = new ProcessedOptions(new CompilerOptions());
318 problem = e;
319 }
320
321 return CompilerContext.runWithOptions(options, (c) {
322 if (problem != null) {
323 print(computeUsage(programName, verbose).message);
324 print(c.formatWithoutLocation(problem.message, Severity.error));
325 exit(1);
326 }
327
328 f(c, parsedArguments.arguments);
329 });
330 }
331
332 Message computeUsage(String programName, bool verbose) {
333 String basicUsage = "Usage: $programName [options] dartfile\n";
334 String summary;
335 String options =
336 (verbose ? messageFastaUsageLong.message : messageFastaUsageShort.message)
337 .trim();
338 switch (programName) {
339 case "outline":
340 summary =
341 "Creates an outline of a Dart program in the Dill/Kernel IR format.";
342 break;
343
344 case "compile":
345 summary = "Compiles a Dart program to the Dill/Kernel IR format.";
346 break;
347
348 case "run":
349 summary = "Runs a Dart program.";
350 break;
351
352 case "compile_platform":
353 summary = "Compiles Dart SDK platform to the Dill/Kernel IR format.";
354 basicUsage = "Usage: $programName [options] patched_sdk fullOutput "
355 "outlineOutput\n";
356 }
357 StringBuffer sb = new StringBuffer(basicUsage);
358 if (summary != null) {
359 sb.writeln();
360 sb.writeln(summary);
361 sb.writeln();
362 }
363 sb.write(options);
364 // TODO(ahe): Don't use [templateUnspecified].
365 return templateUnspecified.withArguments("$sb");
366 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698