| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer_cli.src.options; | 5 library analyzer_cli.src.options; |
| 6 | 6 |
| 7 import 'dart:io'; | 7 import 'dart:io'; |
| 8 | 8 |
| 9 import 'package:analyzer/file_system/physical_file_system.dart'; | 9 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 10 import 'package:analyzer/src/command_line/arguments.dart'; | 10 import 'package:analyzer/src/command_line/arguments.dart'; |
| 11 import 'package:analyzer/src/context/builder.dart'; |
| 11 import 'package:analyzer_cli/src/driver.dart'; | 12 import 'package:analyzer_cli/src/driver.dart'; |
| 12 import 'package:args/args.dart'; | 13 import 'package:args/args.dart'; |
| 13 import 'package:cli_util/cli_util.dart' show getSdkDir; | 14 import 'package:cli_util/cli_util.dart' show getSdkDir; |
| 14 | 15 |
| 15 const _binaryName = 'dartanalyzer'; | 16 const _binaryName = 'dartanalyzer'; |
| 16 | 17 |
| 17 /// Shared exit handler. | 18 /// Shared exit handler. |
| 18 /// | 19 /// |
| 19 /// *Visible for testing.* | 20 /// *Visible for testing.* |
| 20 ExitHandler exitHandler = exit; | 21 ExitHandler exitHandler = exit; |
| 21 | 22 |
| 22 /// Print the given [message] to stderr and exit with the given [exitCode]. | 23 /// Print the given [message] to stderr and exit with the given [exitCode]. |
| 23 void printAndFail(String message, {int exitCode: 15}) { | 24 void printAndFail(String message, {int exitCode: 15}) { |
| 24 errorSink.writeln(message); | 25 errorSink.writeln(message); |
| 25 exitHandler(exitCode); | 26 exitHandler(exitCode); |
| 26 } | 27 } |
| 27 | 28 |
| 28 /// Exit handler. | 29 /// Exit handler. |
| 29 /// | 30 /// |
| 30 /// *Visible for testing.* | 31 /// *Visible for testing.* |
| 31 typedef void ExitHandler(int code); | 32 typedef void ExitHandler(int code); |
| 32 | 33 |
| 33 /// Analyzer commandline configuration options. | 34 /// Analyzer commandline configuration options. |
| 34 class CommandLineOptions { | 35 class CommandLineOptions { |
| 35 /// The path to an analysis options file | |
| 36 final String analysisOptionsFile; | |
| 37 | |
| 38 /// The path to output analysis results when in build mode. | 36 /// The path to output analysis results when in build mode. |
| 39 final String buildAnalysisOutput; | 37 final String buildAnalysisOutput; |
| 40 | 38 |
| 41 /// Whether to use build mode. | 39 /// Whether to use build mode. |
| 42 final bool buildMode; | 40 final bool buildMode; |
| 43 | 41 |
| 44 /// Whether to use build mode as a Bazel persistent worker. | 42 /// Whether to use build mode as a Bazel persistent worker. |
| 45 final bool buildModePersistentWorker; | 43 final bool buildModePersistentWorker; |
| 46 | 44 |
| 47 /// List of summary file paths to use in build mode. | 45 /// List of summary file paths to use in build mode. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 60 /// The path to output the summary when creating summaries in build mode. | 58 /// The path to output the summary when creating summaries in build mode. |
| 61 final String buildSummaryOutput; | 59 final String buildSummaryOutput; |
| 62 | 60 |
| 63 /// The path to output the semantic-only summary when creating summaries in | 61 /// The path to output the semantic-only summary when creating summaries in |
| 64 /// build mode. | 62 /// build mode. |
| 65 final String buildSummaryOutputSemantic; | 63 final String buildSummaryOutputSemantic; |
| 66 | 64 |
| 67 /// Whether to suppress a nonzero exit code in build mode. | 65 /// Whether to suppress a nonzero exit code in build mode. |
| 68 final bool buildSuppressExitCode; | 66 final bool buildSuppressExitCode; |
| 69 | 67 |
| 68 /// The options defining the context in which analysis is performed. |
| 69 final ContextBuilderOptions contextBuilderOptions; |
| 70 |
| 70 /// The path to the dart SDK. | 71 /// The path to the dart SDK. |
| 71 String dartSdkPath; | 72 String dartSdkPath; |
| 72 | 73 |
| 73 /// The path to the dart SDK summary file. | 74 /// The path to the dart SDK summary file. |
| 74 String dartSdkSummaryPath; | 75 String dartSdkSummaryPath; |
| 75 | 76 |
| 76 /// A table mapping the names of defined variables to their values. | |
| 77 final Map<String, String> definedVariables; | |
| 78 | |
| 79 /// Whether to disable cache flushing. This option can improve analysis | 77 /// Whether to disable cache flushing. This option can improve analysis |
| 80 /// speed at the expense of memory usage. It may also be useful for working | 78 /// speed at the expense of memory usage. It may also be useful for working |
| 81 /// around bugs. | 79 /// around bugs. |
| 82 final bool disableCacheFlushing; | 80 final bool disableCacheFlushing; |
| 83 | 81 |
| 84 /// Whether to report hints | 82 /// Whether to report hints |
| 85 final bool disableHints; | 83 final bool disableHints; |
| 86 | 84 |
| 87 /// Whether to display version information | 85 /// Whether to display version information |
| 88 final bool displayVersion; | 86 final bool displayVersion; |
| 89 | 87 |
| 90 /// Whether to enable null-aware operators (DEP 9). | 88 /// Whether to enable null-aware operators (DEP 9). |
| 91 final bool enableNullAwareOperators; | 89 final bool enableNullAwareOperators; |
| 92 | 90 |
| 93 /// Whether to strictly follow the specification when generating warnings on | |
| 94 /// "call" methods (fixes dartbug.com/21938). | |
| 95 final bool enableStrictCallChecks; | |
| 96 | |
| 97 /// Whether to relax restrictions on mixins (DEP 34). | |
| 98 final bool enableSuperMixins; | |
| 99 | |
| 100 /// Whether to treat type mismatches found during constant evaluation as | 91 /// Whether to treat type mismatches found during constant evaluation as |
| 101 /// errors. | 92 /// errors. |
| 102 final bool enableTypeChecks; | 93 final bool enableTypeChecks; |
| 103 | 94 |
| 104 /// Whether to treat hints as fatal | 95 /// Whether to treat hints as fatal |
| 105 final bool hintsAreFatal; | 96 final bool hintsAreFatal; |
| 106 | 97 |
| 107 /// Whether to ignore unrecognized flags | 98 /// Whether to ignore unrecognized flags |
| 108 final bool ignoreUnrecognizedFlags; | 99 final bool ignoreUnrecognizedFlags; |
| 109 | 100 |
| 110 /// Whether to report lints | 101 /// Whether to report lints |
| 111 final bool lints; | 102 final bool lints; |
| 112 | 103 |
| 113 /// Whether to log additional analysis messages and exceptions | 104 /// Whether to log additional analysis messages and exceptions |
| 114 final bool log; | 105 final bool log; |
| 115 | 106 |
| 116 /// Whether to use machine format for error display | 107 /// Whether to use machine format for error display |
| 117 final bool machineFormat; | 108 final bool machineFormat; |
| 118 | 109 |
| 119 /// The path to the package root | |
| 120 final String packageRootPath; | |
| 121 | |
| 122 /// The path to a `.packages` configuration file | |
| 123 final String packageConfigPath; | |
| 124 | |
| 125 /// The path to a file to write a performance log. | 110 /// The path to a file to write a performance log. |
| 126 /// (Or null if not enabled.) | 111 /// (Or null if not enabled.) |
| 127 final String perfReport; | 112 final String perfReport; |
| 128 | 113 |
| 129 /// Batch mode (for unit testing) | 114 /// Batch mode (for unit testing) |
| 130 final bool shouldBatch; | 115 final bool shouldBatch; |
| 131 | 116 |
| 132 /// Whether to show package: warnings | 117 /// Whether to show package: warnings |
| 133 final bool showPackageWarnings; | 118 final bool showPackageWarnings; |
| 134 | 119 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 150 /// Whether implicit casts are enabled (in strong mode) | 135 /// Whether implicit casts are enabled (in strong mode) |
| 151 final bool implicitCasts; | 136 final bool implicitCasts; |
| 152 | 137 |
| 153 /// Whether implicit dynamic is enabled (mainly for strong mode users) | 138 /// Whether implicit dynamic is enabled (mainly for strong mode users) |
| 154 final bool implicitDynamic; | 139 final bool implicitDynamic; |
| 155 | 140 |
| 156 /// Whether to treat lints as fatal | 141 /// Whether to treat lints as fatal |
| 157 final bool lintsAreFatal; | 142 final bool lintsAreFatal; |
| 158 | 143 |
| 159 /// Initialize options from the given parsed [args]. | 144 /// Initialize options from the given parsed [args]. |
| 160 CommandLineOptions._fromArgs( | 145 CommandLineOptions._fromArgs(ArgResults args) |
| 161 ArgResults args, Map<String, String> definedVariables) | |
| 162 : buildAnalysisOutput = args['build-analysis-output'], | 146 : buildAnalysisOutput = args['build-analysis-output'], |
| 163 buildMode = args['build-mode'], | 147 buildMode = args['build-mode'], |
| 164 buildModePersistentWorker = args['persistent_worker'], | 148 buildModePersistentWorker = args['persistent_worker'], |
| 165 buildSummaryInputs = args['build-summary-input'] as List<String>, | 149 buildSummaryInputs = args['build-summary-input'] as List<String>, |
| 166 buildSummaryOnly = args['build-summary-only'], | 150 buildSummaryOnly = args['build-summary-only'], |
| 167 buildSummaryOnlyDiet = args['build-summary-only-diet'], | 151 buildSummaryOnlyDiet = args['build-summary-only-diet'], |
| 168 buildSummaryExcludeInformative = | 152 buildSummaryExcludeInformative = |
| 169 args['build-summary-exclude-informative'], | 153 args['build-summary-exclude-informative'], |
| 170 buildSummaryOutput = args['build-summary-output'], | 154 buildSummaryOutput = args['build-summary-output'], |
| 171 buildSummaryOutputSemantic = args['build-summary-output-semantic'], | 155 buildSummaryOutputSemantic = args['build-summary-output-semantic'], |
| 172 buildSuppressExitCode = args['build-suppress-exit-code'], | 156 buildSuppressExitCode = args['build-suppress-exit-code'], |
| 157 contextBuilderOptions = createContextBuilderOptions(args), |
| 173 dartSdkPath = args['dart-sdk'], | 158 dartSdkPath = args['dart-sdk'], |
| 174 dartSdkSummaryPath = args['dart-sdk-summary'], | 159 dartSdkSummaryPath = args['dart-sdk-summary'], |
| 175 definedVariables = definedVariables, | |
| 176 analysisOptionsFile = args['options'], | |
| 177 disableCacheFlushing = args['disable-cache-flushing'], | 160 disableCacheFlushing = args['disable-cache-flushing'], |
| 178 disableHints = args['no-hints'], | 161 disableHints = args['no-hints'], |
| 179 displayVersion = args['version'], | 162 displayVersion = args['version'], |
| 180 enableNullAwareOperators = args['enable-null-aware-operators'], | 163 enableNullAwareOperators = args['enable-null-aware-operators'], |
| 181 enableStrictCallChecks = args['enable-strict-call-checks'], | |
| 182 enableSuperMixins = args['supermixin'], | |
| 183 enableTypeChecks = args['enable_type_checks'], | 164 enableTypeChecks = args['enable_type_checks'], |
| 184 hintsAreFatal = args['fatal-hints'], | 165 hintsAreFatal = args['fatal-hints'], |
| 185 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], | 166 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], |
| 186 lints = args['lints'], | 167 lints = args['lints'], |
| 187 log = args['log'], | 168 log = args['log'], |
| 188 machineFormat = args['machine'] || args['format'] == 'machine', | 169 machineFormat = args['machine'] || args['format'] == 'machine', |
| 189 packageConfigPath = args['packages'], | |
| 190 packageRootPath = args['package-root'], | |
| 191 perfReport = args['x-perf-report'], | 170 perfReport = args['x-perf-report'], |
| 192 shouldBatch = args['batch'], | 171 shouldBatch = args['batch'], |
| 193 showPackageWarnings = args['show-package-warnings'] || | 172 showPackageWarnings = args['show-package-warnings'] || |
| 194 args['package-warnings'] || | 173 args['package-warnings'] || |
| 195 args['x-package-warnings-prefix'] != null, | 174 args['x-package-warnings-prefix'] != null, |
| 196 showPackageWarningsPrefix = args['x-package-warnings-prefix'], | 175 showPackageWarningsPrefix = args['x-package-warnings-prefix'], |
| 197 showSdkWarnings = args['show-sdk-warnings'] || args['warnings'], | 176 showSdkWarnings = args['show-sdk-warnings'] || args['warnings'], |
| 198 sourceFiles = args.rest, | 177 sourceFiles = args.rest, |
| 199 warningsAreFatal = args['fatal-warnings'], | 178 warningsAreFatal = args['fatal-warnings'], |
| 200 strongMode = args['strong'], | 179 strongMode = args['strong'], |
| 201 implicitCasts = !args['no-implicit-casts'], | 180 implicitCasts = !args['no-implicit-casts'], |
| 202 implicitDynamic = !args['no-implicit-dynamic'], | 181 implicitDynamic = !args['no-implicit-dynamic'], |
| 203 lintsAreFatal = args['fatal-lints']; | 182 lintsAreFatal = args['fatal-lints']; |
| 204 | 183 |
| 184 /// The path to an analysis options file |
| 185 String get analysisOptionsFile => |
| 186 contextBuilderOptions.defaultAnalysisOptionsFilePath; |
| 187 |
| 188 /// A table mapping the names of defined variables to their values. |
| 189 Map<String, String> get definedVariables => |
| 190 contextBuilderOptions.declaredVariables; |
| 191 |
| 192 /// Whether to strictly follow the specification when generating warnings on |
| 193 /// "call" methods (fixes dartbug.com/21938). |
| 194 bool get enableStrictCallChecks => |
| 195 contextBuilderOptions.defaultOptions.enableStrictCallChecks; |
| 196 |
| 197 /// Whether to relax restrictions on mixins (DEP 34). |
| 198 bool get enableSuperMixins => |
| 199 contextBuilderOptions.defaultOptions.enableSuperMixins; |
| 200 |
| 201 /// The path to the package root |
| 202 String get packageRootPath => |
| 203 contextBuilderOptions.defaultPackagesDirectoryPath; |
| 204 |
| 205 /// The path to a `.packages` configuration file |
| 206 String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath; |
| 207 |
| 205 /// Parse [args] into [CommandLineOptions] describing the specified | 208 /// Parse [args] into [CommandLineOptions] describing the specified |
| 206 /// analyzer options. In case of a format error, calls [printAndFail], which | 209 /// analyzer options. In case of a format error, calls [printAndFail], which |
| 207 /// by default prints an error message to stderr and exits. | 210 /// by default prints an error message to stderr and exits. |
| 208 static CommandLineOptions parse(List<String> args, | 211 static CommandLineOptions parse(List<String> args, |
| 209 [printAndFail(String msg) = printAndFail]) { | 212 [printAndFail(String msg) = printAndFail]) { |
| 210 CommandLineOptions options = _parse(args); | 213 CommandLineOptions options = _parse(args); |
| 211 // Check SDK. | 214 // Check SDK. |
| 212 if (!options.buildModePersistentWorker) { | 215 if (!options.buildModePersistentWorker) { |
| 213 // Infer if unspecified. | 216 // Infer if unspecified. |
| 214 if (options.dartSdkPath == null) { | 217 if (options.dartSdkPath == null) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 ..addFlag('enable_type_checks', | 450 ..addFlag('enable_type_checks', |
| 448 help: 'Check types in constant evaluation.', | 451 help: 'Check types in constant evaluation.', |
| 449 defaultsTo: false, | 452 defaultsTo: false, |
| 450 negatable: false, | 453 negatable: false, |
| 451 hide: hide); | 454 hide: hide); |
| 452 | 455 |
| 453 try { | 456 try { |
| 454 // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061 | 457 // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061 |
| 455 args = | 458 args = |
| 456 args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList(); | 459 args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList(); |
| 457 Map<String, String> definedVariables = <String, String>{}; | |
| 458 args = extractDefinedVariables(args, definedVariables); | |
| 459 if (args.contains('--$ignoreUnrecognizedFlagsFlag')) { | 460 if (args.contains('--$ignoreUnrecognizedFlagsFlag')) { |
| 460 args = filterUnknownArguments(args, parser); | 461 args = filterUnknownArguments(args, parser); |
| 461 } | 462 } |
| 462 var results = parser.parse(args); | 463 var results = parser.parse(args); |
| 463 | 464 |
| 464 // Persistent worker. | 465 // Persistent worker. |
| 465 if (args.contains('--persistent_worker')) { | 466 if (args.contains('--persistent_worker')) { |
| 466 bool validArgs; | 467 bool validArgs; |
| 467 if (!args.contains('--build-mode')) { | 468 if (!args.contains('--build-mode')) { |
| 468 validArgs = false; | 469 validArgs = false; |
| 469 } else if (args.length == 2) { | 470 } else if (args.length == 2) { |
| 470 validArgs = true; | 471 validArgs = true; |
| 471 } else if (args.length == 4 && args.contains('--dart-sdk')) { | 472 } else if (args.length == 4 && args.contains('--dart-sdk')) { |
| 472 validArgs = true; | 473 validArgs = true; |
| 473 } else { | 474 } else { |
| 474 validArgs = false; | 475 validArgs = false; |
| 475 } | 476 } |
| 476 if (!validArgs) { | 477 if (!validArgs) { |
| 477 printAndFail('The --persistent_worker flag should be used with and ' | 478 printAndFail('The --persistent_worker flag should be used with and ' |
| 478 'only with the --build-mode flag, and possibly the --dart-sdk ' | 479 'only with the --build-mode flag, and possibly the --dart-sdk ' |
| 479 'option. Got: $args'); | 480 'option. Got: $args'); |
| 480 return null; // Only reachable in testing. | 481 return null; // Only reachable in testing. |
| 481 } | 482 } |
| 482 return new CommandLineOptions._fromArgs(results, definedVariables); | 483 return new CommandLineOptions._fromArgs(results); |
| 483 } | 484 } |
| 484 | 485 |
| 485 // Help requests. | 486 // Help requests. |
| 486 if (results['help']) { | 487 if (results['help']) { |
| 487 _showUsage(parser); | 488 _showUsage(parser); |
| 488 exitHandler(0); | 489 exitHandler(0); |
| 489 return null; // Only reachable in testing. | 490 return null; // Only reachable in testing. |
| 490 } | 491 } |
| 491 // Batch mode and input files. | 492 // Batch mode and input files. |
| 492 if (results['batch']) { | 493 if (results['batch']) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 508 outSink.write('$_binaryName version ${_getVersion()}'); | 509 outSink.write('$_binaryName version ${_getVersion()}'); |
| 509 exitHandler(0); | 510 exitHandler(0); |
| 510 return null; // Only reachable in testing. | 511 return null; // Only reachable in testing. |
| 511 } else { | 512 } else { |
| 512 if (results.rest.isEmpty && !results['build-mode']) { | 513 if (results.rest.isEmpty && !results['build-mode']) { |
| 513 _showUsage(parser); | 514 _showUsage(parser); |
| 514 exitHandler(15); | 515 exitHandler(15); |
| 515 return null; // Only reachable in testing. | 516 return null; // Only reachable in testing. |
| 516 } | 517 } |
| 517 } | 518 } |
| 518 return new CommandLineOptions._fromArgs(results, definedVariables); | 519 return new CommandLineOptions._fromArgs(results); |
| 519 } on FormatException catch (e) { | 520 } on FormatException catch (e) { |
| 520 errorSink.writeln(e.message); | 521 errorSink.writeln(e.message); |
| 521 _showUsage(parser); | 522 _showUsage(parser); |
| 522 exitHandler(15); | 523 exitHandler(15); |
| 523 return null; // Only reachable in testing. | 524 return null; // Only reachable in testing. |
| 524 } | 525 } |
| 525 } | 526 } |
| 526 | 527 |
| 527 static _showUsage(parser) { | 528 static _showUsage(parser) { |
| 528 errorSink | 529 errorSink |
| 529 .writeln('Usage: $_binaryName [options...] <libraries to analyze...>'); | 530 .writeln('Usage: $_binaryName [options...] <libraries to analyze...>'); |
| 530 errorSink.writeln(parser.getUsage()); | 531 errorSink.writeln(parser.getUsage()); |
| 531 errorSink.writeln(''); | 532 errorSink.writeln(''); |
| 532 errorSink.writeln( | 533 errorSink.writeln( |
| 533 'For more information, see http://www.dartlang.org/tools/analyzer.'); | 534 'For more information, see http://www.dartlang.org/tools/analyzer.'); |
| 534 } | 535 } |
| 535 } | 536 } |
| OLD | NEW |