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

Side by Side Diff: pkg/analyzer_cli/lib/src/options.dart

Issue 1459683003: `analyzer_cli` move to SDK. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: master merge Created 5 years, 1 month 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) 2015, 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 analyzer_cli.src.options;
6
7 import 'dart:io';
8
9 import 'package:analyzer_cli/src/driver.dart';
10 import 'package:args/args.dart';
11 import 'package:cli_util/cli_util.dart' show getSdkDir;
12
13 const _binaryName = 'dartanalyzer';
14
15 /// Shared exit handler.
16 ///
17 /// *Visible for testing.*
18 ExitHandler exitHandler = exit;
19
20 /// Print the given message to stderr and exit with the given [exitCode]
21 void printAndFail(String message, {int exitCode: 15}) {
22 errorSink.writeln(message);
23 exitHandler(exitCode);
24 }
25
26 /// Exit handler.
27 ///
28 /// *Visible for testing.*
29 typedef void ExitHandler(int code);
30
31 /// Analyzer commandline configuration options.
32 class CommandLineOptions {
33 /// The path to an analysis options file
34 final String analysisOptionsFile;
35
36 /// The path to the dart SDK
37 String dartSdkPath;
38
39 /// A table mapping the names of defined variables to their values.
40 final Map<String, String> definedVariables;
41
42 /// Whether to report hints
43 final bool disableHints;
44
45 /// Whether to display version information
46 final bool displayVersion;
47
48 /// Whether to enable null-aware operators (DEP 9).
49 final bool enableNullAwareOperators;
50
51 /// Whether to strictly follow the specification when generating warnings on
52 /// "call" methods (fixes dartbug.com/21938).
53 final bool enableStrictCallChecks;
54
55 /// Whether to relax restrictions on mixins (DEP 34).
56 final bool enableSuperMixins;
57
58 /// Whether to treat type mismatches found during constant evaluation as
59 /// errors.
60 final bool enableTypeChecks;
61
62 /// Whether to treat hints as fatal
63 final bool hintsAreFatal;
64
65 /// Whether to ignore unrecognized flags
66 final bool ignoreUnrecognizedFlags;
67
68 /// Whether to report lints
69 final bool lints;
70
71 /// Whether to log additional analysis messages and exceptions
72 final bool log;
73
74 /// Whether to use machine format for error display
75 final bool machineFormat;
76
77 /// The path to the package root
78 final String packageRootPath;
79
80 /// The path to a `.packages` configuration file
81 final String packageConfigPath;
82
83 /// Batch mode (for unit testing)
84 final bool shouldBatch;
85
86 /// Whether to show package: warnings
87 final bool showPackageWarnings;
88
89 /// Whether to show SDK warnings
90 final bool showSdkWarnings;
91
92 /// The source files to analyze
93 final List<String> sourceFiles;
94
95 /// Whether to treat warnings as fatal
96 final bool warningsAreFatal;
97
98 /// Whether to use strong static checking.
99 final bool strongMode;
100
101 /// Initialize options from the given parsed [args].
102 CommandLineOptions._fromArgs(
103 ArgResults args, Map<String, String> definedVariables)
104 : dartSdkPath = args['dart-sdk'],
105 this.definedVariables = definedVariables,
106 analysisOptionsFile = args['options'],
107 disableHints = args['no-hints'],
108 displayVersion = args['version'],
109 enableNullAwareOperators = args['enable-null-aware-operators'],
110 enableStrictCallChecks = args['enable-strict-call-checks'],
111 enableSuperMixins = args['supermixin'],
112 enableTypeChecks = args['enable_type_checks'],
113 hintsAreFatal = args['fatal-hints'],
114 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
115 lints = args['lints'],
116 log = args['log'],
117 machineFormat = args['machine'] || args['format'] == 'machine',
118 packageConfigPath = args['packages'],
119 packageRootPath = args['package-root'],
120 shouldBatch = args['batch'],
121 showPackageWarnings =
122 args['show-package-warnings'] || args['package-warnings'],
123 showSdkWarnings = args['show-sdk-warnings'] || args['warnings'],
124 sourceFiles = args.rest,
125 warningsAreFatal = args['fatal-warnings'],
126 strongMode = args['strong'];
127
128 /// Parse [args] into [CommandLineOptions] describing the specified
129 /// analyzer options. In case of a format error, calls [printAndFail], which
130 /// by default prints an error message to stderr and exits.
131 static CommandLineOptions parse(List<String> args,
132 [printAndFail = printAndFail]) {
133 CommandLineOptions options = _parse(args);
134 // Check SDK.
135 {
136 // Infer if unspecified.
137 if (options.dartSdkPath == null) {
138 Directory sdkDir = getSdkDir(args);
139 if (sdkDir != null) {
140 options.dartSdkPath = sdkDir.path;
141 }
142 }
143
144 var sdkPath = options.dartSdkPath;
145
146 // Check that SDK is specified.
147 if (sdkPath == null) {
148 printAndFail('No Dart SDK found.');
149 }
150 // Check that SDK is existing directory.
151 if (!(new Directory(sdkPath)).existsSync()) {
152 printAndFail('Invalid Dart SDK path: $sdkPath');
153 }
154 }
155
156 // Check package config.
157 {
158 if (options.packageRootPath != null &&
159 options.packageConfigPath != null) {
160 printAndFail("Cannot specify both '--package-root' and '--packages.");
161 }
162 }
163
164 // OK. Report deprecated options.
165 if (options.enableNullAwareOperators) {
166 stderr.writeln(
167 "Info: Option '--enable-null-aware-operators' is no longer needed. Nul l aware operators are supported by default.");
168 }
169
170 return options;
171 }
172
173 static String _getVersion() {
174 try {
175 // This is relative to bin/snapshot, so ../..
176 String versionPath =
177 Platform.script.resolve('../../version').toFilePath();
178 File versionFile = new File(versionPath);
179 return versionFile.readAsStringSync().trim();
180 } catch (_) {
181 // This happens when the script is not running in the context of an SDK.
182 return "<unknown>";
183 }
184 }
185
186 static CommandLineOptions _parse(List<String> args) {
187 args = args.expand((String arg) => arg.split('=')).toList();
188 var parser = new CommandLineParser()
189 ..addFlag('batch',
190 abbr: 'b',
191 help: 'Read commands from standard input (for testing).',
192 defaultsTo: false,
193 negatable: false)
194 ..addOption('dart-sdk', help: 'The path to the Dart SDK.')
195 ..addOption('packages',
196 help:
197 'Path to the package resolution configuration file, which supplies a mapping of package names to paths. This option cannot be used with --package -root.')
198 ..addOption('package-root',
199 abbr: 'p',
200 help:
201 'Path to a package root directory (deprecated). This option cannot be used with --packages.')
202 ..addOption('options', help: 'Path to an analysis options file.')
203 ..addOption('format',
204 help: 'Specifies the format in which errors are displayed.')
205 ..addFlag('machine',
206 help: 'Print errors in a format suitable for parsing (deprecated).',
207 defaultsTo: false,
208 negatable: false)
209 ..addFlag('version',
210 help: 'Print the analyzer version.',
211 defaultsTo: false,
212 negatable: false)
213 ..addFlag('lints',
214 help: 'Show lint results.', defaultsTo: false, negatable: false)
215 ..addFlag('no-hints',
216 help: 'Do not show hint results.',
217 defaultsTo: false,
218 negatable: false)
219 ..addFlag('ignore-unrecognized-flags',
220 help: 'Ignore unrecognized command line flags.',
221 defaultsTo: false,
222 negatable: false)
223 ..addFlag('fatal-hints',
224 help: 'Treat hints as fatal.', defaultsTo: false, negatable: false)
225 ..addFlag('fatal-warnings',
226 help: 'Treat non-type warnings as fatal.',
227 defaultsTo: false,
228 negatable: false)
229 ..addFlag('package-warnings',
230 help: 'Show warnings from package: imports.',
231 defaultsTo: false,
232 negatable: false)
233 ..addFlag('show-package-warnings',
234 help: 'Show warnings from package: imports (deprecated).',
235 defaultsTo: false,
236 negatable: false)
237 ..addFlag('warnings',
238 help: 'Show warnings from SDK imports.',
239 defaultsTo: false,
240 negatable: false)
241 ..addFlag('show-sdk-warnings',
242 help: 'Show warnings from SDK imports (deprecated).',
243 defaultsTo: false,
244 negatable: false)
245 ..addFlag('help',
246 abbr: 'h',
247 help: 'Display this help message.',
248 defaultsTo: false,
249 negatable: false)
250 ..addOption('url-mapping',
251 help: '--url-mapping=libraryUri,/path/to/library.dart directs the '
252 'analyzer to use "library.dart" as the source for an import '
253 'of "libraryUri".',
254 allowMultiple: true,
255 splitCommas: false)
256 //
257 // Hidden flags.
258 //
259 ..addFlag('enable-async',
260 help: 'Enable support for the proposed async feature.',
261 defaultsTo: false,
262 negatable: false,
263 hide: true)
264 ..addFlag('enable-enum',
265 help: 'Enable support for the proposed enum feature.',
266 defaultsTo: false,
267 negatable: false,
268 hide: true)
269 ..addFlag('enable-null-aware-operators',
270 help: 'Enable support for null-aware operators (DEP 9).',
271 defaultsTo: false,
272 negatable: false,
273 hide: true)
274 ..addFlag('enable-strict-call-checks',
275 help: 'Fix issue 21938.',
276 defaultsTo: false,
277 negatable: false,
278 hide: true)
279 ..addFlag('enable-new-task-model',
280 help: 'Ennable new task model.',
281 defaultsTo: false,
282 negatable: false,
283 hide: true)
284 ..addFlag('supermixin',
285 help: 'Relax restrictions on mixins (DEP 34).',
286 defaultsTo: false,
287 negatable: false,
288 hide: true)
289 ..addFlag('log',
290 help: 'Log additional messages and exceptions.',
291 defaultsTo: false,
292 negatable: false,
293 hide: true)
294 ..addFlag('enable_type_checks',
295 help: 'Check types in constant evaluation.',
296 defaultsTo: false,
297 negatable: false,
298 hide: true)
299 ..addFlag('strong',
300 help: 'Enable strong static checks (https://goo.gl/DqcBsw)');
301
302 try {
303 // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061
304 args =
305 args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList();
306 Map<String, String> definedVariables = <String, String>{};
307 var results = parser.parse(args, definedVariables);
308 // Help requests.
309 if (results['help']) {
310 _showUsage(parser);
311 exit(0);
312 }
313 // Batch mode and input files.
314 if (results['batch']) {
315 if (results.rest.isNotEmpty) {
316 stderr.writeln('No source files expected in the batch mode.');
317 _showUsage(parser);
318 exit(15);
319 }
320 } else if (results['version']) {
321 print('$_binaryName version ${_getVersion()}');
322 exit(0);
323 } else {
324 if (results.rest.isEmpty) {
325 _showUsage(parser);
326 exit(15);
327 }
328 }
329 return new CommandLineOptions._fromArgs(results, definedVariables);
330 } on FormatException catch (e) {
331 stderr.writeln(e.message);
332 _showUsage(parser);
333 exit(15);
334 }
335 }
336
337 static _showUsage(parser) {
338 stderr
339 .writeln('Usage: $_binaryName [options...] <libraries to analyze...>');
340 stderr.writeln(parser.getUsage());
341 stderr.writeln('');
342 stderr.writeln(
343 'For more information, see http://www.dartlang.org/tools/analyzer.');
344 }
345 }
346
347 /// Commandline argument parser.
348 ///
349 /// TODO(pquitslund): when the args package supports ignoring unrecognized
350 /// options/flags, this class can be replaced with a simple [ArgParser]
351 /// instance.
352 class CommandLineParser {
353 final List<String> _knownFlags;
354 final bool _alwaysIgnoreUnrecognized;
355 final ArgParser _parser;
356
357 /// Creates a new command line parser.
358 CommandLineParser({bool alwaysIgnoreUnrecognized: false})
359 : _knownFlags = <String>[],
360 _alwaysIgnoreUnrecognized = alwaysIgnoreUnrecognized,
361 _parser = new ArgParser(allowTrailingOptions: true);
362
363 ArgParser get parser => _parser;
364
365 /// Defines a flag.
366 /// See [ArgParser.addFlag()].
367 void addFlag(String name,
368 {String abbr,
369 String help,
370 bool defaultsTo: false,
371 bool negatable: true,
372 void callback(bool value),
373 bool hide: false}) {
374 _knownFlags.add(name);
375 _parser.addFlag(name,
376 abbr: abbr,
377 help: help,
378 defaultsTo: defaultsTo,
379 negatable: negatable,
380 callback: callback,
381 hide: hide);
382 }
383
384 /// Defines a value-taking option.
385 /// See [ArgParser.addOption()].
386 void addOption(String name,
387 {String abbr,
388 String help,
389 List<String> allowed,
390 Map<String, String> allowedHelp,
391 String defaultsTo,
392 void callback(value),
393 bool allowMultiple: false,
394 bool splitCommas}) {
395 _knownFlags.add(name);
396 _parser.addOption(name,
397 abbr: abbr,
398 help: help,
399 allowed: allowed,
400 allowedHelp: allowedHelp,
401 defaultsTo: defaultsTo,
402 callback: callback,
403 allowMultiple: allowMultiple,
404 splitCommas: splitCommas);
405 }
406
407 /// Generates a string displaying usage information for the defined options.
408 /// See [ArgParser.usage].
409 String getUsage() => _parser.usage;
410
411 /// Parses [args], a list of command-line arguments, matches them against the
412 /// flags and options defined by this parser, and returns the result. The
413 /// values of any defined variables are captured in the given map.
414 /// See [ArgParser].
415 ArgResults parse(List<String> args, Map<String, String> definedVariables) =>
416 _parser.parse(
417 _filterUnknowns(parseDefinedVariables(args, definedVariables)));
418
419 List<String> parseDefinedVariables(
420 List<String> args, Map<String, String> definedVariables) {
421 int count = args.length;
422 List<String> remainingArgs = <String>[];
423 for (int i = 0; i < count; i++) {
424 String arg = args[i];
425 if (arg == '--') {
426 while (i < count) {
427 remainingArgs.add(args[i++]);
428 }
429 } else if (arg.startsWith("-D")) {
430 definedVariables[arg.substring(2)] = args[++i];
431 } else {
432 remainingArgs.add(arg);
433 }
434 }
435 return remainingArgs;
436 }
437
438 List<String> _filterUnknowns(List<String> args) {
439 // Only filter args if the ignore flag is specified, or if
440 // _alwaysIgnoreUnrecognized was set to true.
441 if (_alwaysIgnoreUnrecognized ||
442 args.contains('--ignore-unrecognized-flags')) {
443 //TODO(pquitslund): replace w/ the following once library skew issues are
444 // sorted out
445 //return args.where((arg) => !arg.startsWith('--') ||
446 // _knownFlags.contains(arg.substring(2)));
447
448 // Filter all unrecognized flags and options.
449 List<String> filtered = <String>[];
450 for (int i = 0; i < args.length; ++i) {
451 String arg = args[i];
452 if (arg.startsWith('--') && arg.length > 2) {
453 String option = arg.substring(2);
454 // strip the last '=value'
455 int equalsOffset = option.lastIndexOf('=');
456 if (equalsOffset != -1) {
457 option = option.substring(0, equalsOffset);
458 }
459 // Check the option
460 if (!_knownFlags.contains(option)) {
461 //"eat" params by advancing to the next flag/option
462 i = _getNextFlagIndex(args, i);
463 } else {
464 filtered.add(arg);
465 }
466 } else {
467 filtered.add(arg);
468 }
469 }
470
471 return filtered;
472 } else {
473 return args;
474 }
475 }
476
477 int _getNextFlagIndex(args, i) {
478 for (; i < args.length; ++i) {
479 if (args[i].startsWith('--')) {
480 return i;
481 }
482 }
483 return i;
484 }
485 }
OLDNEW
« no previous file with comments | « pkg/analyzer_cli/lib/src/error_formatter.dart ('k') | pkg/analyzer_cli/lib/src/plugin/plugin_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698