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 | |
9 import 'dart:io'; | |
10 | |
11 | |
12 const _BINARY_NAME = 'analyzer'; | |
13 const _SDK_ENV = 'com.google.dart.sdk'; | |
14 final _DEFAULT_SDK_LOCATION = Platform.environment[_SDK_ENV]; | |
15 | |
16 /** | |
17 * Analyzer commandline configuration options. | |
18 */ | |
19 class CommandLineOptions { | |
20 | |
21 /** Batch mode (for unit testing) */ | |
22 final bool shouldBatch; | |
23 | |
24 /** Whether to use machine format for error display */ | |
25 final bool machineFormat; | |
26 | |
27 /** Whether to ignore unrecognized flags */ | |
28 final bool ignoreUnrecognizedFlags; | |
29 | |
30 /** Whether to print metrics */ | |
31 final bool showMetrics; | |
32 | |
33 /** Whether to treat warnings as fatal */ | |
34 final bool warningsAreFatal; | |
35 | |
36 /** The path to the dart SDK */ | |
37 final String dartSdkPath; | |
38 | |
39 /** The source files to analyze */ | |
40 final List<String> sourceFiles; | |
41 | |
42 /** | |
43 * Initialize options from the given parsed [args]. | |
44 */ | |
45 CommandLineOptions._fromArgs(ArgResults args) | |
46 : shouldBatch = args['batch'], | |
47 machineFormat = args['machine_format'], | |
48 ignoreUnrecognizedFlags = args['ignore_unrecognized_flags'], | |
49 showMetrics = args['metrics'], | |
50 warningsAreFatal = args['fatal_warnings'], | |
51 dartSdkPath = args['dart_sdk'], | |
52 sourceFiles = args.rest; | |
53 | |
54 /** | |
55 * Parse [args] into [CommandLineOptions] describing the specified | |
56 * analyzer options. In case of a format error, [null] is returned. | |
57 */ | |
58 factory CommandLineOptions.parse(List<String> args) { | |
59 | |
60 var parser = new _CommandLineParser() | |
61 ..addFlag('batch', abbr: 'b', help: 'Run in batch mode', | |
62 defaultsTo: false, negatable: false) | |
63 ..addOption('dart_sdk', help: 'Specify path to the Dart sdk', | |
64 defaultsTo: _DEFAULT_SDK_LOCATION) | |
65 ..addFlag('machine_format', help: 'Specify whether errors ' | |
66 'should be in machine format', | |
67 defaultsTo: false, negatable: false) | |
68 ..addFlag('ignore_unrecognized_flags', | |
69 help: 'Ignore unrecognized command line flags', | |
70 defaultsTo: false, negatable: false) | |
71 ..addFlag('fatal_warnings', help: 'Treat non-type warnings as fatal', | |
72 defaultsTo: false, negatable: false) | |
73 ..addFlag('metrics', help: 'Print metrics', | |
74 defaultsTo: false, negatable: false) | |
75 ..addFlag('help', abbr: 'h', help: 'Display this help message', | |
76 defaultsTo: false, negatable: false); | |
77 | |
78 try { | |
79 var results = parser.parse(args); | |
80 if (results['help'] || results.rest.length == 0) { | |
81 _showUsage(parser); | |
82 return null; | |
83 } | |
84 return new CommandLineOptions._fromArgs(results); | |
85 } on FormatException catch (e) { | |
86 print(e.message); | |
87 _showUsage(parser); | |
88 return null; | |
89 } | |
90 | |
91 } | |
92 | |
93 static _showUsage(parser) { | |
94 print('Usage: ${_BINARY_NAME} [options...] ' | |
95 '<libraries to analyze...>'); | |
96 print(parser.getUsage()); | |
97 } | |
98 | |
99 } | |
100 | |
101 /** | |
102 * Commandline argument parser. | |
103 * | |
104 * TODO(pquitslund): when the args package supports ignoring unrecognized | |
105 * options/flags, this class can be replaced with a simple [ArgParser] instance. | |
106 */ | |
107 class _CommandLineParser { | |
108 | |
109 final List<String> _knownFlags; | |
110 final ArgParser _parser; | |
111 | |
112 /** Creates a new command line parser */ | |
113 _CommandLineParser() | |
114 : _knownFlags = <String>[], | |
115 _parser = new ArgParser(); | |
116 | |
117 | |
118 /** | |
119 * Defines a flag. | |
120 * | |
121 * See [ArgParser.addFlag()]. | |
122 */ | |
123 void addFlag(String name, {String abbr, String help, bool defaultsTo: false, | |
124 bool negatable: true, void callback(bool value)}) { | |
125 _knownFlags.add(name); | |
126 _parser.addFlag(name, abbr: abbr, help: help, defaultsTo: defaultsTo, | |
127 negatable: negatable, callback: callback); | |
128 } | |
129 | |
130 /** | |
131 * Defines a value-taking option. | |
132 * | |
133 * See [ArgParser.addOption()]. | |
134 */ | |
135 void addOption(String name, {String abbr, String help, List<String> allowed, | |
136 Map<String, String> allowedHelp, String defaultsTo, | |
137 void callback(value), bool allowMultiple: false}) { | |
138 _parser.addOption(name, abbr: abbr, help: help, allowed: allowed, | |
139 allowedHelp: allowedHelp, defaultsTo: defaultsTo, callback: callback, | |
140 allowMultiple: allowMultiple); | |
141 } | |
142 | |
143 | |
144 /** | |
145 * Generates a string displaying usage information for the defined options. | |
146 * | |
147 * See [ArgParser.getUsage()]. | |
148 */ | |
149 String getUsage() => _parser.getUsage(); | |
150 | |
151 /** | |
152 * Parses [args], a list of command-line arguments, matches them against the | |
153 * flags and options defined by this parser, and returns the result. | |
154 * | |
155 * See [ArgParser]. | |
156 */ | |
157 ArgResults parse(List<String> args) => _parser.parse(_filterUnknowns(args)); | |
158 | |
159 List<String> _filterUnknowns(args) { | |
160 | |
161 // Only filter args if the ignore flag is specified. | |
162 if (!args.contains('--ignore_unrecognized_flags')) { | |
163 return args; | |
164 } | |
165 | |
166 //TODO(pquitslund): replace w/ the following once library skew issues are so
rted out | |
167 //return args.where((arg) => !arg.startsWith('--') || | |
168 // _knownFlags.contains(arg.substring(2))); | |
169 | |
170 // Filter all unrecognized flags and options. | |
171 var filtered = <String>[]; | |
172 for (var i=0; i < args.length; ++i) { | |
173 var arg = args[i]; | |
174 if (arg.startsWith('--') && arg.length > 2) { | |
175 if (!_knownFlags.contains(arg.substring(2))) { | |
176 //"eat" params by advancing to the next flag/option | |
177 i = _getNextFlagIndex(args, i); | |
178 } else { | |
179 filtered.add(arg); | |
180 } | |
181 } else { | |
182 filtered.add(arg); | |
183 } | |
184 } | |
185 | |
186 return filtered; | |
187 } | |
188 | |
189 _getNextFlagIndex(args, i) { | |
190 for ( ; i < args.length; ++i) { | |
191 if (args[i].startsWith('--')) { | |
192 return i; | |
193 } | |
194 } | |
195 return i; | |
196 } | |
197 | |
198 } | |
199 | |
OLD | NEW |