| OLD | NEW |
| (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/file_system/physical_file_system.dart'; | |
| 10 import 'package:analyzer/src/command_line/arguments.dart'; | |
| 11 import 'package:analyzer/src/context/builder.dart'; | |
| 12 import 'package:analyzer_cli/src/ansi.dart' as ansi; | |
| 13 import 'package:analyzer_cli/src/driver.dart'; | |
| 14 import 'package:args/args.dart'; | |
| 15 import 'package:cli_util/cli_util.dart' show getSdkDir; | |
| 16 | |
| 17 const _binaryName = 'dartanalyzer'; | |
| 18 | |
| 19 /// Shared exit handler. | |
| 20 /// | |
| 21 /// *Visible for testing.* | |
| 22 ExitHandler exitHandler = exit; | |
| 23 | |
| 24 /// Print the given [message] to stderr and exit with the given [exitCode]. | |
| 25 void printAndFail(String message, {int exitCode: 15}) { | |
| 26 errorSink.writeln(message); | |
| 27 exitHandler(exitCode); | |
| 28 } | |
| 29 | |
| 30 /// Exit handler. | |
| 31 /// | |
| 32 /// *Visible for testing.* | |
| 33 typedef void ExitHandler(int code); | |
| 34 | |
| 35 /// Analyzer commandline configuration options. | |
| 36 class CommandLineOptions { | |
| 37 final bool enableNewAnalysisDriver = true; | |
| 38 | |
| 39 /// Return `true` if the parser is to parse asserts in the initializer list of | |
| 40 /// a constructor. | |
| 41 final bool enableAssertInitializer; | |
| 42 | |
| 43 /// The path to output analysis results when in build mode. | |
| 44 final String buildAnalysisOutput; | |
| 45 | |
| 46 /// Whether to use build mode. | |
| 47 final bool buildMode; | |
| 48 | |
| 49 /// Whether to use build mode as a Bazel persistent worker. | |
| 50 final bool buildModePersistentWorker; | |
| 51 | |
| 52 /// List of summary file paths to use in build mode. | |
| 53 final List<String> buildSummaryInputs; | |
| 54 | |
| 55 /// Whether to skip analysis when creating summaries in build mode. | |
| 56 final bool buildSummaryOnly; | |
| 57 | |
| 58 /// Whether to use diet parsing, i.e. skip function bodies. We don't need to | |
| 59 /// analyze function bodies to use summaries during future compilation steps. | |
| 60 final bool buildSummaryOnlyDiet; | |
| 61 | |
| 62 /// Whether to only produce unlinked summaries instead of linked summaries. | |
| 63 /// Must be used in combination with `buildSummaryOnly`. | |
| 64 final bool buildSummaryOnlyUnlinked; | |
| 65 | |
| 66 /// The path to output the summary when creating summaries in build mode. | |
| 67 final String buildSummaryOutput; | |
| 68 | |
| 69 /// The path to output the semantic-only summary when creating summaries in | |
| 70 /// build mode. | |
| 71 final String buildSummaryOutputSemantic; | |
| 72 | |
| 73 /// Whether to suppress a nonzero exit code in build mode. | |
| 74 final bool buildSuppressExitCode; | |
| 75 | |
| 76 /// The options defining the context in which analysis is performed. | |
| 77 final ContextBuilderOptions contextBuilderOptions; | |
| 78 | |
| 79 /// The path to the dart SDK. | |
| 80 String dartSdkPath; | |
| 81 | |
| 82 /// The path to the dart SDK summary file. | |
| 83 String dartSdkSummaryPath; | |
| 84 | |
| 85 /// Whether to disable cache flushing. This option can improve analysis | |
| 86 /// speed at the expense of memory usage. It may also be useful for working | |
| 87 /// around bugs. | |
| 88 final bool disableCacheFlushing; | |
| 89 | |
| 90 /// Whether to report hints | |
| 91 final bool disableHints; | |
| 92 | |
| 93 /// Whether to display version information | |
| 94 final bool displayVersion; | |
| 95 | |
| 96 /// Whether to treat type mismatches found during constant evaluation as | |
| 97 /// errors. | |
| 98 final bool enableTypeChecks; | |
| 99 | |
| 100 /// Whether to treat hints as fatal | |
| 101 final bool hintsAreFatal; | |
| 102 | |
| 103 /// Whether to ignore unrecognized flags | |
| 104 final bool ignoreUnrecognizedFlags; | |
| 105 | |
| 106 /// Whether to report lints | |
| 107 final bool lints; | |
| 108 | |
| 109 /// Whether to log additional analysis messages and exceptions | |
| 110 final bool log; | |
| 111 | |
| 112 /// Whether to use machine format for error display | |
| 113 final bool machineFormat; | |
| 114 | |
| 115 /// The path to a file to write a performance log. | |
| 116 /// (Or null if not enabled.) | |
| 117 final String perfReport; | |
| 118 | |
| 119 /// Batch mode (for unit testing) | |
| 120 final bool shouldBatch; | |
| 121 | |
| 122 /// Whether to show package: warnings | |
| 123 final bool showPackageWarnings; | |
| 124 | |
| 125 /// If not null, show package: warnings only for matching packages. | |
| 126 final String showPackageWarningsPrefix; | |
| 127 | |
| 128 /// Whether to show SDK warnings | |
| 129 final bool showSdkWarnings; | |
| 130 | |
| 131 /// The source files to analyze | |
| 132 List<String> _sourceFiles; | |
| 133 | |
| 134 /// Whether to treat warnings as fatal | |
| 135 final bool warningsAreFatal; | |
| 136 | |
| 137 /// Whether to use strong static checking. | |
| 138 final bool strongMode; | |
| 139 | |
| 140 /// Whether implicit casts are enabled (in strong mode) | |
| 141 final bool implicitCasts; | |
| 142 | |
| 143 /// Whether implicit dynamic is enabled (mainly for strong mode users) | |
| 144 final bool implicitDynamic; | |
| 145 | |
| 146 /// Whether to treat lints as fatal | |
| 147 final bool lintsAreFatal; | |
| 148 | |
| 149 /// Whether to use memory byte store for analysis driver. | |
| 150 final bool useAnalysisDriverMemoryByteStore; | |
| 151 | |
| 152 /// Emit output in a verbose mode. | |
| 153 final bool verbose; | |
| 154 | |
| 155 /// Use ANSI color codes for output. | |
| 156 final bool color; | |
| 157 | |
| 158 /// Initialize options from the given parsed [args]. | |
| 159 CommandLineOptions._fromArgs(ArgResults args) | |
| 160 : buildAnalysisOutput = args['build-analysis-output'], | |
| 161 buildMode = args['build-mode'], | |
| 162 buildModePersistentWorker = args['persistent_worker'], | |
| 163 buildSummaryInputs = args['build-summary-input'] as List<String>, | |
| 164 buildSummaryOnly = args['build-summary-only'], | |
| 165 buildSummaryOnlyDiet = args['build-summary-only-diet'], | |
| 166 buildSummaryOnlyUnlinked = args['build-summary-only-unlinked'], | |
| 167 buildSummaryOutput = args['build-summary-output'], | |
| 168 buildSummaryOutputSemantic = args['build-summary-output-semantic'], | |
| 169 buildSuppressExitCode = args['build-suppress-exit-code'], | |
| 170 contextBuilderOptions = createContextBuilderOptions(args), | |
| 171 dartSdkPath = args['dart-sdk'], | |
| 172 dartSdkSummaryPath = args['dart-sdk-summary'], | |
| 173 disableCacheFlushing = args['disable-cache-flushing'], | |
| 174 disableHints = args['no-hints'], | |
| 175 displayVersion = args['version'], | |
| 176 enableTypeChecks = args['enable_type_checks'], | |
| 177 enableAssertInitializer = args['enable-assert-initializers'], | |
| 178 hintsAreFatal = args['fatal-hints'], | |
| 179 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], | |
| 180 lints = args[lintsFlag], | |
| 181 log = args['log'], | |
| 182 machineFormat = args['format'] == 'machine', | |
| 183 perfReport = args['x-perf-report'], | |
| 184 shouldBatch = args['batch'], | |
| 185 showPackageWarnings = args['show-package-warnings'] || | |
| 186 args['package-warnings'] || | |
| 187 args['x-package-warnings-prefix'] != null, | |
| 188 showPackageWarningsPrefix = args['x-package-warnings-prefix'], | |
| 189 showSdkWarnings = args['sdk-warnings'], | |
| 190 _sourceFiles = args.rest, | |
| 191 warningsAreFatal = args['fatal-warnings'], | |
| 192 strongMode = args['strong'], | |
| 193 implicitCasts = !args['no-implicit-casts'], | |
| 194 implicitDynamic = !args['no-implicit-dynamic'], | |
| 195 lintsAreFatal = args['fatal-lints'], | |
| 196 useAnalysisDriverMemoryByteStore = | |
| 197 args['use-analysis-driver-memory-byte-store'], | |
| 198 verbose = args['verbose'], | |
| 199 color = args['color']; | |
| 200 | |
| 201 /// The path to an analysis options file | |
| 202 String get analysisOptionsFile => | |
| 203 contextBuilderOptions.defaultAnalysisOptionsFilePath; | |
| 204 | |
| 205 /// A table mapping the names of defined variables to their values. | |
| 206 Map<String, String> get definedVariables => | |
| 207 contextBuilderOptions.declaredVariables; | |
| 208 | |
| 209 /// Whether to strictly follow the specification when generating warnings on | |
| 210 /// "call" methods (fixes dartbug.com/21938). | |
| 211 bool get enableStrictCallChecks => | |
| 212 contextBuilderOptions.defaultOptions.enableStrictCallChecks; | |
| 213 | |
| 214 /// Whether to relax restrictions on mixins (DEP 34). | |
| 215 bool get enableSuperMixins => | |
| 216 contextBuilderOptions.defaultOptions.enableSuperMixins; | |
| 217 | |
| 218 /// The path to a `.packages` configuration file | |
| 219 String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath; | |
| 220 | |
| 221 /// The path to the package root | |
| 222 String get packageRootPath => | |
| 223 contextBuilderOptions.defaultPackagesDirectoryPath; | |
| 224 | |
| 225 /// Parse [args] into [CommandLineOptions] describing the specified | |
| 226 /// analyzer options. In case of a format error, calls [printAndFail], which | |
| 227 /// by default prints an error message to stderr and exits. | |
| 228 static CommandLineOptions parse(List<String> args, | |
| 229 [printAndFail(String msg) = printAndFail]) { | |
| 230 CommandLineOptions options = _parse(args); | |
| 231 // Check SDK. | |
| 232 if (!options.buildModePersistentWorker) { | |
| 233 // Infer if unspecified. | |
| 234 if (options.dartSdkPath == null) { | |
| 235 Directory sdkDir = getSdkDir(args); | |
| 236 if (sdkDir != null) { | |
| 237 options.dartSdkPath = sdkDir.path; | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 String sdkPath = options.dartSdkPath; | |
| 242 | |
| 243 // Check that SDK is specified. | |
| 244 if (sdkPath == null) { | |
| 245 printAndFail('No Dart SDK found.'); | |
| 246 return null; // Only reachable in testing. | |
| 247 } | |
| 248 // Check that SDK is existing directory. | |
| 249 if (!(new Directory(sdkPath)).existsSync()) { | |
| 250 printAndFail('Invalid Dart SDK path: $sdkPath'); | |
| 251 return null; // Only reachable in testing. | |
| 252 } | |
| 253 } | |
| 254 | |
| 255 // Check package config. | |
| 256 { | |
| 257 if (options.packageRootPath != null && | |
| 258 options.packageConfigPath != null) { | |
| 259 printAndFail("Cannot specify both '--package-root' and '--packages."); | |
| 260 return null; // Only reachable in testing. | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 // Build mode. | |
| 265 if (options.buildModePersistentWorker && !options.buildMode) { | |
| 266 printAndFail('The option --persisten_worker can be used only ' | |
| 267 'together with --build-mode.'); | |
| 268 return null; // Only reachable in testing. | |
| 269 } | |
| 270 if (options.buildSummaryOnlyDiet && !options.buildSummaryOnly) { | |
| 271 printAndFail('The option --build-summary-only-diet can be used only ' | |
| 272 'together with --build-summary-only.'); | |
| 273 return null; // Only reachable in testing. | |
| 274 } | |
| 275 | |
| 276 if (options.buildSummaryOnlyUnlinked) { | |
| 277 if (!options.buildSummaryOnly) { | |
| 278 printAndFail( | |
| 279 'The option --build-summary-only-unlinked can be used only ' | |
| 280 'together with --build-summary-only.'); | |
| 281 return null; // Only reachable in testing. | |
| 282 } | |
| 283 if (options.buildSummaryInputs.isNotEmpty) { | |
| 284 printAndFail('No summaries should be provided in combination with ' | |
| 285 '--build-summary-only-unlinked, they aren\'t needed.'); | |
| 286 return null; // Only reachable in testing. | |
| 287 } | |
| 288 } | |
| 289 | |
| 290 return options; | |
| 291 } | |
| 292 | |
| 293 /// The source files to analyze | |
| 294 List<String> get sourceFiles => _sourceFiles; | |
| 295 | |
| 296 /// Replace the sourceFiles parsed from the command line. | |
| 297 void rewriteSourceFiles(List<String> newSourceFiles) { | |
| 298 _sourceFiles = newSourceFiles; | |
| 299 } | |
| 300 | |
| 301 static String _getVersion() { | |
| 302 try { | |
| 303 // This is relative to bin/snapshot, so ../.. | |
| 304 String versionPath = | |
| 305 Platform.script.resolve('../../version').toFilePath(); | |
| 306 File versionFile = new File(versionPath); | |
| 307 return versionFile.readAsStringSync().trim(); | |
| 308 } catch (_) { | |
| 309 // This happens when the script is not running in the context of an SDK. | |
| 310 return "<unknown>"; | |
| 311 } | |
| 312 } | |
| 313 | |
| 314 static CommandLineOptions _parse(List<String> args) { | |
| 315 args = preprocessArgs(PhysicalResourceProvider.INSTANCE, args); | |
| 316 | |
| 317 bool verbose = args.contains('-v') || args.contains('--verbose'); | |
| 318 bool hide = !verbose; | |
| 319 | |
| 320 ArgParser parser = new ArgParser(allowTrailingOptions: true); | |
| 321 | |
| 322 if (!hide) { | |
| 323 parser.addSeparator('General options:'); | |
| 324 } | |
| 325 | |
| 326 // TODO(devoncarew): This defines some hidden flags, which would be better | |
| 327 // defined with the rest of the hidden flags below (to group well with the | |
| 328 // other flags). | |
| 329 defineAnalysisArguments(parser, hide: hide); | |
| 330 | |
| 331 parser | |
| 332 ..addOption('format', | |
| 333 help: 'Specifies the format in which errors are displayed; the only ' | |
| 334 'currently allowed value is \'machine\'.') | |
| 335 ..addFlag('version', | |
| 336 help: 'Print the analyzer version.', | |
| 337 defaultsTo: false, | |
| 338 negatable: false) | |
| 339 ..addFlag('no-hints', | |
| 340 help: 'Do not show hint results.', | |
| 341 defaultsTo: false, | |
| 342 negatable: false) | |
| 343 ..addFlag('fatal-hints', | |
| 344 help: 'Treat hints as fatal.', defaultsTo: false, negatable: false) | |
| 345 ..addFlag('fatal-warnings', | |
| 346 help: 'Treat non-type warnings as fatal.', | |
| 347 defaultsTo: false, | |
| 348 negatable: false) | |
| 349 ..addFlag('fatal-lints', | |
| 350 help: 'Treat lints as fatal.', defaultsTo: false, negatable: false) | |
| 351 ..addFlag('package-warnings', | |
| 352 help: 'Show warnings from package: imports.', | |
| 353 defaultsTo: false, | |
| 354 negatable: false) | |
| 355 ..addFlag('help', | |
| 356 abbr: 'h', | |
| 357 help: | |
| 358 'Display this help message. Add --verbose to show hidden options.'
, | |
| 359 defaultsTo: false, | |
| 360 negatable: false) | |
| 361 ..addFlag('verbose', | |
| 362 abbr: 'v', | |
| 363 defaultsTo: false, | |
| 364 help: 'Verbose output.', | |
| 365 negatable: false); | |
| 366 | |
| 367 // Build mode options. | |
| 368 if (!hide) { | |
| 369 parser.addSeparator('Build mode flags:'); | |
| 370 } | |
| 371 | |
| 372 parser | |
| 373 ..addFlag('persistent_worker', | |
| 374 help: 'Enable Bazel persistent worker mode.', | |
| 375 defaultsTo: false, | |
| 376 negatable: false, | |
| 377 hide: hide) | |
| 378 ..addOption('build-analysis-output', | |
| 379 help: | |
| 380 'Specifies the path to the file where analysis results should be w
ritten.', | |
| 381 hide: hide) | |
| 382 ..addFlag('build-mode', | |
| 383 // TODO(paulberry): add more documentation. | |
| 384 help: 'Enable build mode.', | |
| 385 defaultsTo: false, | |
| 386 negatable: false, | |
| 387 hide: hide) | |
| 388 ..addOption('build-summary-input', | |
| 389 help: 'Path to a summary file that contains information from a ' | |
| 390 'previous analysis run; may be specified multiple times.', | |
| 391 allowMultiple: true, | |
| 392 hide: hide) | |
| 393 ..addOption('build-summary-output', | |
| 394 help: 'Specifies the path to the file where the full summary ' | |
| 395 'information should be written.', | |
| 396 hide: hide) | |
| 397 ..addOption('build-summary-output-semantic', | |
| 398 help: 'Specifies the path to the file where the semantic summary ' | |
| 399 'information should be written.', | |
| 400 hide: hide) | |
| 401 ..addFlag('build-summary-only', | |
| 402 help: 'Disable analysis (only generate summaries).', | |
| 403 defaultsTo: false, | |
| 404 negatable: false, | |
| 405 hide: hide) | |
| 406 ..addFlag('build-summary-only-diet', | |
| 407 help: 'Diet parse function bodies.', | |
| 408 defaultsTo: false, | |
| 409 negatable: false, | |
| 410 hide: hide) | |
| 411 ..addFlag('build-summary-only-unlinked', | |
| 412 help: 'Only output the unlinked summary.', | |
| 413 defaultsTo: false, | |
| 414 negatable: false, | |
| 415 hide: hide) | |
| 416 ..addFlag('build-suppress-exit-code', | |
| 417 help: 'Exit with code 0 even if errors are found.', | |
| 418 defaultsTo: false, | |
| 419 negatable: false, | |
| 420 hide: hide) | |
| 421 ..addFlag('color', | |
| 422 help: 'Use ansi colors when printing messages.', | |
| 423 defaultsTo: ansi.terminalSupportsAnsi(), | |
| 424 hide: hide); | |
| 425 | |
| 426 // Hidden flags. | |
| 427 if (!hide) { | |
| 428 parser.addSeparator('Less frequently used flags:'); | |
| 429 } | |
| 430 | |
| 431 parser | |
| 432 ..addFlag('batch', | |
| 433 help: 'Read commands from standard input (for testing).', | |
| 434 defaultsTo: false, | |
| 435 negatable: false, | |
| 436 hide: hide) | |
| 437 ..addFlag(ignoreUnrecognizedFlagsFlag, | |
| 438 help: 'Ignore unrecognized command line flags.', | |
| 439 defaultsTo: false, | |
| 440 negatable: false, | |
| 441 hide: hide) | |
| 442 ..addFlag('disable-cache-flushing', defaultsTo: false, hide: hide) | |
| 443 ..addOption('x-perf-report', | |
| 444 help: 'Writes a performance report to the given file (experimental).', | |
| 445 hide: hide) | |
| 446 ..addOption('x-package-warnings-prefix', | |
| 447 help: | |
| 448 'Show warnings from package: imports that match the given prefix.'
, | |
| 449 hide: hide) | |
| 450 ..addFlag('enable-conditional-directives', | |
| 451 help: | |
| 452 'deprecated -- Enable support for conditional directives (DEP 40).
', | |
| 453 defaultsTo: false, | |
| 454 negatable: false, | |
| 455 hide: hide) | |
| 456 ..addFlag('show-package-warnings', | |
| 457 help: 'Show warnings from package: imports (deprecated).', | |
| 458 defaultsTo: false, | |
| 459 negatable: false, | |
| 460 hide: hide) | |
| 461 ..addFlag('sdk-warnings', | |
| 462 help: 'Show warnings from SDK imports.', | |
| 463 defaultsTo: false, | |
| 464 negatable: false, | |
| 465 hide: hide) | |
| 466 ..addFlag('log', | |
| 467 help: 'Log additional messages and exceptions.', | |
| 468 defaultsTo: false, | |
| 469 negatable: false, | |
| 470 hide: hide) | |
| 471 ..addFlag('enable_type_checks', | |
| 472 help: 'Check types in constant evaluation.', | |
| 473 defaultsTo: false, | |
| 474 negatable: false, | |
| 475 hide: hide) | |
| 476 ..addFlag('enable-assert-initializers', | |
| 477 help: 'Enable parsing of asserts in constructor initializers.', | |
| 478 defaultsTo: false, | |
| 479 negatable: false, | |
| 480 hide: hide) | |
| 481 ..addFlag('use-analysis-driver-memory-byte-store', | |
| 482 help: 'Use memory byte store, not the file system cache.', | |
| 483 defaultsTo: false, | |
| 484 negatable: false, | |
| 485 hide: hide) | |
| 486 ..addOption('url-mapping', | |
| 487 help: '--url-mapping=libraryUri,/path/to/library.dart directs the ' | |
| 488 'analyzer to use "library.dart" as the source for an import ' | |
| 489 'of "libraryUri".', | |
| 490 allowMultiple: true, | |
| 491 splitCommas: false, | |
| 492 hide: hide); | |
| 493 | |
| 494 try { | |
| 495 if (args.contains('--$ignoreUnrecognizedFlagsFlag')) { | |
| 496 args = filterUnknownArguments(args, parser); | |
| 497 } | |
| 498 ArgResults results = parser.parse(args); | |
| 499 | |
| 500 // Persistent worker. | |
| 501 if (args.contains('--persistent_worker')) { | |
| 502 bool hasBuildMode = args.contains('--build-mode'); | |
| 503 bool onlyDartSdkArg = args.length == 2 || | |
| 504 (args.length == 3 && args.any((a) => a.startsWith('--dart-sdk'))) || | |
| 505 (args.length == 4 && args.contains('--dart-sdk')); | |
| 506 if (!(hasBuildMode && onlyDartSdkArg)) { | |
| 507 printAndFail('The --persistent_worker flag should be used with and ' | |
| 508 'only with the --build-mode flag, and possibly the --dart-sdk ' | |
| 509 'option. Got: $args'); | |
| 510 return null; // Only reachable in testing. | |
| 511 } | |
| 512 return new CommandLineOptions._fromArgs(results); | |
| 513 } | |
| 514 | |
| 515 // Help requests. | |
| 516 if (results['help']) { | |
| 517 _showUsage(parser); | |
| 518 exitHandler(0); | |
| 519 return null; // Only reachable in testing. | |
| 520 } | |
| 521 // Batch mode and input files. | |
| 522 if (results['batch']) { | |
| 523 if (results.rest.isNotEmpty) { | |
| 524 errorSink.writeln('No source files expected in the batch mode.'); | |
| 525 _showUsage(parser); | |
| 526 exitHandler(15); | |
| 527 return null; // Only reachable in testing. | |
| 528 } | |
| 529 } else if (results['persistent_worker']) { | |
| 530 if (results.rest.isNotEmpty) { | |
| 531 errorSink.writeln( | |
| 532 'No source files expected in the persistent worker mode.'); | |
| 533 _showUsage(parser); | |
| 534 exitHandler(15); | |
| 535 return null; // Only reachable in testing. | |
| 536 } | |
| 537 } else if (results['version']) { | |
| 538 outSink.writeln('$_binaryName version ${_getVersion()}'); | |
| 539 exitHandler(0); | |
| 540 return null; // Only reachable in testing. | |
| 541 } else { | |
| 542 if (results.rest.isEmpty && !results['build-mode']) { | |
| 543 _showUsage(parser); | |
| 544 exitHandler(15); | |
| 545 return null; // Only reachable in testing. | |
| 546 } | |
| 547 } | |
| 548 return new CommandLineOptions._fromArgs(results); | |
| 549 } on FormatException catch (e) { | |
| 550 errorSink.writeln(e.message); | |
| 551 _showUsage(parser); | |
| 552 exitHandler(15); | |
| 553 return null; // Only reachable in testing. | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 static _showUsage(ArgParser parser) { | |
| 558 errorSink.writeln( | |
| 559 'Usage: $_binaryName [options...] <directory or list of files>'); | |
| 560 errorSink.writeln(''); | |
| 561 errorSink.writeln(parser.usage); | |
| 562 errorSink.writeln(''); | |
| 563 errorSink.writeln(''' | |
| 564 Run "dartanalyzer -h -v" for verbose help output, including less commonly used o
ptions. | |
| 565 For more information, see http://www.dartlang.org/tools/analyzer. | |
| 566 '''); | |
| 567 } | |
| 568 } | |
| OLD | NEW |