| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, 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 options; | |
| 6 | |
| 7 import 'package:args/args.dart'; | |
| 8 import 'package:path/path.dart'; | |
| 9 | |
| 10 import 'dart:io'; | |
| 11 | |
| 12 | |
| 13 const _BINARY_NAME = 'dartanalyzer'; | |
| 14 | |
| 15 /** | |
| 16 * Analyzer commandline configuration options. | |
| 17 */ | |
| 18 class CommandLineOptions { | |
| 19 | |
| 20 /** Batch mode (for unit testing) */ | |
| 21 final bool shouldBatch; | |
| 22 | |
| 23 /** Whether to use machine format for error display */ | |
| 24 final bool machineFormat; | |
| 25 | |
| 26 /** Whether to display version information */ | |
| 27 final bool displayVersion; | |
| 28 | |
| 29 /** Whether to report hints */ | |
| 30 final bool disableHints; | |
| 31 | |
| 32 /** Whether to ignore unrecognized flags */ | |
| 33 final bool ignoreUnrecognizedFlags; | |
| 34 | |
| 35 /** Whether to show performance statistics */ | |
| 36 final bool perf; | |
| 37 | |
| 38 /** Whether to show package: warnings */ | |
| 39 final bool showPackageWarnings; | |
| 40 | |
| 41 /** Whether to show SDK warnings */ | |
| 42 final bool showSdkWarnings; | |
| 43 | |
| 44 /** Whether to treat warnings as fatal */ | |
| 45 final bool warningsAreFatal; | |
| 46 | |
| 47 /** The path to the dart SDK */ | |
| 48 final String dartSdkPath; | |
| 49 | |
| 50 /** The path to the package root */ | |
| 51 final String packageRootPath; | |
| 52 | |
| 53 /** The source files to analyze */ | |
| 54 final List<String> sourceFiles; | |
| 55 | |
| 56 /** | |
| 57 * Initialize options from the given parsed [args]. | |
| 58 */ | |
| 59 CommandLineOptions._fromArgs(ArgResults args) | |
| 60 : shouldBatch = args['batch'], | |
| 61 machineFormat = args['machine'] || args['format'] == 'machine', | |
| 62 displayVersion = args['version'], | |
| 63 disableHints = args['no-hints'], | |
| 64 ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'], | |
| 65 perf = args['perf'], | |
| 66 showPackageWarnings = args['show-package-warnings'] || args['package-warni
ngs'], | |
| 67 showSdkWarnings = args['show-sdk-warnings'] || args['warnings'], | |
| 68 warningsAreFatal = args['fatal-warnings'], | |
| 69 dartSdkPath = args['dart-sdk'], | |
| 70 packageRootPath = args['package-root'], | |
| 71 sourceFiles = args.rest; | |
| 72 | |
| 73 /** | |
| 74 * Parse [args] into [CommandLineOptions] describing the specified | |
| 75 * analyzer options. In case of a format error, prints error and exists. | |
| 76 */ | |
| 77 static CommandLineOptions parse(List<String> args) { | |
| 78 CommandLineOptions options = _parse(args); | |
| 79 // check SDK | |
| 80 { | |
| 81 var sdkPath = options.dartSdkPath; | |
| 82 // check that SDK is specified | |
| 83 if (sdkPath == null) { | |
| 84 print('Usage: $_BINARY_NAME: no Dart SDK found.'); | |
| 85 exit(15); | |
| 86 } | |
| 87 // check that SDK is existing directory | |
| 88 if (!(new Directory(sdkPath)).existsSync()) { | |
| 89 print('Usage: $_BINARY_NAME: invalid Dart SDK path: $sdkPath'); | |
| 90 exit(15); | |
| 91 } | |
| 92 } | |
| 93 // OK | |
| 94 return options; | |
| 95 } | |
| 96 | |
| 97 static CommandLineOptions _parse(List<String> args) { | |
| 98 args = args.expand((String arg) => arg.split('=')).toList(); | |
| 99 var parser = new _CommandLineParser() | |
| 100 ..addFlag('batch', abbr: 'b', help: 'Run in batch mode', | |
| 101 defaultsTo: false, negatable: false) | |
| 102 ..addOption('dart-sdk', help: 'The path to the Dart SDK') | |
| 103 ..addOption('package-root', abbr: 'p', | |
| 104 help: 'The path to the package root') | |
| 105 ..addOption('format', | |
| 106 help: 'Specifies the format in which errors are displayed') | |
| 107 ..addFlag('machine', | |
| 108 help: 'Print errors in a format suitable for parsing (deprecated)', | |
| 109 defaultsTo: false, negatable: false) | |
| 110 ..addFlag('version', help: 'Print the analyzer version', | |
| 111 defaultsTo: false, negatable: false) | |
| 112 ..addFlag('no-hints', help: 'Do not show hint results', | |
| 113 defaultsTo: false, negatable: false) | |
| 114 ..addFlag('ignore-unrecognized-flags', | |
| 115 help: 'Ignore unrecognized command line flags', | |
| 116 defaultsTo: false, negatable: false) | |
| 117 ..addFlag('fatal-warnings', help: 'Treat non-type warnings as fatal', | |
| 118 defaultsTo: false, negatable: false) | |
| 119 ..addFlag('package-warnings', | |
| 120 help: 'Show warnings from package: imports', | |
| 121 defaultsTo: false, negatable: false) | |
| 122 ..addFlag('show-package-warnings', | |
| 123 help: 'Show warnings from package: imports (deprecated)', | |
| 124 defaultsTo: false, negatable: false) | |
| 125 ..addFlag('perf', | |
| 126 help: 'Show performance statistics', | |
| 127 defaultsTo: false, negatable: false) | |
| 128 ..addFlag('warnings', help: 'Show warnings from SDK imports', | |
| 129 defaultsTo: false, negatable: false) | |
| 130 ..addFlag('show-sdk-warnings', help: 'Show warnings from SDK imports (depr
ecated)', | |
| 131 defaultsTo: false, negatable: false) | |
| 132 ..addFlag('help', abbr: 'h', help: 'Display this help message', | |
| 133 defaultsTo: false, negatable: false); | |
| 134 | |
| 135 try { | |
| 136 // TODO(scheglov) https://code.google.com/p/dart/issues/detail?id=11061 | |
| 137 args = args.map((String arg) => arg == '-batch' ? '--batch' : arg).toList(
); | |
| 138 var results = parser.parse(args); | |
| 139 // help requests | |
| 140 if (results['help']) { | |
| 141 _showUsage(parser); | |
| 142 exit(0); | |
| 143 } | |
| 144 // batch mode and input files | |
| 145 if (results['batch']) { | |
| 146 if (results.rest.isNotEmpty) { | |
| 147 print('No source files expected in the batch mode.'); | |
| 148 _showUsage(parser); | |
| 149 exit(15); | |
| 150 } | |
| 151 } else if (results['version']) { | |
| 152 print('$_BINARY_NAME version ${_getVersion()}'); | |
| 153 exit(0); | |
| 154 } else { | |
| 155 if (results.rest.isEmpty) { | |
| 156 _showUsage(parser); | |
| 157 exit(15); | |
| 158 } | |
| 159 } | |
| 160 return new CommandLineOptions._fromArgs(results); | |
| 161 } on FormatException catch (e) { | |
| 162 print(e.message); | |
| 163 _showUsage(parser); | |
| 164 exit(15); | |
| 165 } | |
| 166 | |
| 167 } | |
| 168 | |
| 169 static _showUsage(parser) { | |
| 170 print('Usage: $_BINARY_NAME [options...] <libraries to analyze...>'); | |
| 171 print(parser.getUsage()); | |
| 172 print(''); | |
| 173 print('For more information, see http://www.dartlang.org/tools/analyzer.'); | |
| 174 } | |
| 175 | |
| 176 static String _getVersion() { | |
| 177 try { | |
| 178 String versionPath = join(dirname(Platform.script), '..', 'version');; | |
| 179 File versionFile = new File(versionPath); | |
| 180 return versionFile.readAsStringSync().trim(); | |
| 181 } catch (_) { | |
| 182 // This happens when the script is not running in the context of an SDK. | |
| 183 return "<unknown>"; | |
| 184 } | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 /** | |
| 189 * Commandline argument parser. | |
| 190 * | |
| 191 * TODO(pquitslund): when the args package supports ignoring unrecognized | |
| 192 * options/flags, this class can be replaced with a simple [ArgParser] instance. | |
| 193 */ | |
| 194 class _CommandLineParser { | |
| 195 | |
| 196 final List<String> _knownFlags; | |
| 197 final ArgParser _parser; | |
| 198 | |
| 199 /** Creates a new command line parser */ | |
| 200 _CommandLineParser() | |
| 201 : _knownFlags = <String>[], | |
| 202 _parser = new ArgParser(); | |
| 203 | |
| 204 | |
| 205 /** | |
| 206 * Defines a flag. | |
| 207 * | |
| 208 * See [ArgParser.addFlag()]. | |
| 209 */ | |
| 210 void addFlag(String name, {String abbr, String help, bool defaultsTo: false, | |
| 211 bool negatable: true, void callback(bool value)}) { | |
| 212 _knownFlags.add(name); | |
| 213 _parser.addFlag(name, abbr: abbr, help: help, defaultsTo: defaultsTo, | |
| 214 negatable: negatable, callback: callback); | |
| 215 } | |
| 216 | |
| 217 /** | |
| 218 * Defines a value-taking option. | |
| 219 * | |
| 220 * See [ArgParser.addOption()]. | |
| 221 */ | |
| 222 void addOption(String name, {String abbr, String help, List<String> allowed, | |
| 223 Map<String, String> allowedHelp, String defaultsTo, | |
| 224 void callback(value), bool allowMultiple: false}) { | |
| 225 _knownFlags.add(name); | |
| 226 _parser.addOption(name, abbr: abbr, help: help, allowed: allowed, | |
| 227 allowedHelp: allowedHelp, defaultsTo: defaultsTo, callback: callback, | |
| 228 allowMultiple: allowMultiple); | |
| 229 } | |
| 230 | |
| 231 | |
| 232 /** | |
| 233 * Generates a string displaying usage information for the defined options. | |
| 234 * | |
| 235 * See [ArgParser.getUsage()]. | |
| 236 */ | |
| 237 String getUsage() => _parser.getUsage(); | |
| 238 | |
| 239 /** | |
| 240 * Parses [args], a list of command-line arguments, matches them against the | |
| 241 * flags and options defined by this parser, and returns the result. | |
| 242 * | |
| 243 * See [ArgParser]. | |
| 244 */ | |
| 245 ArgResults parse(List<String> args) => _parser.parse(_filterUnknowns(args)); | |
| 246 | |
| 247 List<String> _filterUnknowns(args) { | |
| 248 | |
| 249 // Only filter args if the ignore flag is specified. | |
| 250 if (!args.contains('--ignore-unrecognized-flags')) { | |
| 251 return args; | |
| 252 } | |
| 253 | |
| 254 //TODO(pquitslund): replace w/ the following once library skew issues are so
rted out | |
| 255 //return args.where((arg) => !arg.startsWith('--') || | |
| 256 // _knownFlags.contains(arg.substring(2))); | |
| 257 | |
| 258 // Filter all unrecognized flags and options. | |
| 259 var filtered = <String>[]; | |
| 260 for (var i=0; i < args.length; ++i) { | |
| 261 var arg = args[i]; | |
| 262 if (arg.startsWith('--') && arg.length > 2) { | |
| 263 if (!_knownFlags.contains(arg.substring(2))) { | |
| 264 print('remove: $arg'); | |
| 265 //"eat" params by advancing to the next flag/option | |
| 266 i = _getNextFlagIndex(args, i); | |
| 267 } else { | |
| 268 filtered.add(arg); | |
| 269 } | |
| 270 } else { | |
| 271 filtered.add(arg); | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 return filtered; | |
| 276 } | |
| 277 | |
| 278 _getNextFlagIndex(args, i) { | |
| 279 for ( ; i < args.length; ++i) { | |
| 280 if (args[i].startsWith('--')) { | |
| 281 return i; | |
| 282 } | |
| 283 } | |
| 284 return i; | |
| 285 } | |
| 286 } | |
| OLD | NEW |