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

Side by Side Diff: pkg/analyzer/bin/formatter.dart

Issue 1001403002: Remove the old formatter from analyzer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env dart
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file.
5
6 import 'dart:convert';
7 import 'dart:io';
8
9 import 'package:args/args.dart';
10 import 'package:path/path.dart' as path;
11
12 import 'package:analyzer/src/services/formatter_impl.dart';
13
14 const BINARY_NAME = 'dartfmt';
15 final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false);
16 final argParser = _initArgParser();
17 final defaultSelection = new Selection(-1, -1);
18
19 var formatterSettings;
20
21 CodeKind kind;
22 bool machineFormat;
23 bool overwriteFileContents;
24 Selection selection;
25 final List<String> paths = [];
26
27 const HELP_FLAG = 'help';
28 const KIND_FLAG = 'kind';
29 const MACHINE_FLAG = 'machine';
30 const WRITE_FLAG = 'write';
31 const SELECTION_FLAG = 'selection';
32 const TRANSFORM_FLAG = 'transform';
33 const MAX_LINE_FLAG = 'max_line_length';
34 const INDENT_FLAG = 'indent';
35
36 const FOLLOW_LINKS = false;
37
38 main(args) {
39 var options = argParser.parse(args);
40 if (options['help']) {
41 _printUsage();
42 return;
43 }
44
45 _readOptions(options);
46
47 if (options.rest.isEmpty) {
48 _formatStdin(kind);
49 } else {
50 paths.addAll(options.rest);
51 _formatPaths(paths);
52 }
53 }
54
55 _readOptions(options) {
56 kind = _parseKind(options[KIND_FLAG]);
57 machineFormat = options[MACHINE_FLAG];
58 overwriteFileContents = options[WRITE_FLAG];
59 selection = _parseSelection(options[SELECTION_FLAG]);
60 formatterSettings = new FormatterOptions(
61 codeTransforms: options[TRANSFORM_FLAG],
62 tabsForIndent: _parseTabsForIndent(options[INDENT_FLAG]),
63 spacesPerIndent: _parseSpacesPerIndent(options[INDENT_FLAG]),
64 pageWidth: _parseLineLength(options[MAX_LINE_FLAG]));
65 }
66
67 /// Translate the indent option into spaces per indent.
68 int _parseSpacesPerIndent(String indentOption) {
69 if (indentOption == 'tab') {
70 return 1;
71 }
72 int spacesPerIndent = _toInt(indentOption);
73 if (spacesPerIndent == null) {
74 throw new FormatterException(
75 'Indentation is specified as an Integer or ' 'the value "tab".');
76 }
77 return spacesPerIndent;
78 }
79
80 /// Translate the indent option into tabs for indent.
81 bool _parseTabsForIndent(String indentOption) => indentOption == 'tab';
82
83 CodeKind _parseKind(kindOption) {
84 switch (kindOption) {
85 case 'stmt':
86 return CodeKind.STATEMENT;
87 default:
88 return CodeKind.COMPILATION_UNIT;
89 }
90 }
91
92 int _parseLineLength(String lengthOption) {
93 var length = _toInt(lengthOption);
94 if (length == null) {
95 var val = lengthOption.toUpperCase();
96 if (val == 'INF' || val == 'INFINITY') {
97 length = -1;
98 } else {
99 throw new FormatterException(
100 'Line length is specified as an Integer or ' 'the value "Inf".');
101 }
102 }
103 return length;
104 }
105
106 Selection _parseSelection(String selectionOption) {
107 if (selectionOption == null) return null;
108
109 var units = selectionOption.split(',');
110 if (units.length == 2) {
111 var offset = _toInt(units[0]);
112 var length = _toInt(units[1]);
113 if (offset != null && length != null) {
114 return new Selection(offset, length);
115 }
116 }
117 throw new FormatterException(
118 'Selections are specified as integer pairs ' '(e.g., "(offset, length)".') ;
119 }
120
121 int _toInt(str) => int.parse(str, onError: (_) => null);
122
123 _formatPaths(paths) {
124 paths.forEach((path) {
125 if (FileSystemEntity.isDirectorySync(path)) {
126 _formatDirectory(new Directory(path));
127 } else {
128 _formatFile(new File(path));
129 }
130 });
131 }
132
133 _formatResource(resource) {
134 if (resource is Directory) {
135 _formatDirectory(resource);
136 } else if (resource is File) {
137 _formatFile(resource);
138 }
139 }
140
141 _formatDirectory(dir) => dir
142 .listSync(followLinks: FOLLOW_LINKS)
143 .forEach((resource) => _formatResource(resource));
144
145 _formatFile(file) {
146 if (_isDartFile(file)) {
147 if (_isPatchFile(file) && !paths.contains(file.path)) {
148 _log('Skipping patch file "${file.path}"');
149 return;
150 }
151 try {
152 var rawSource = file.readAsStringSync();
153 var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT);
154 if (overwriteFileContents) {
155 // Only touch files files whose contents will be changed
156 if (rawSource != formatted) {
157 file.writeAsStringSync(formatted);
158 }
159 } else {
160 print(formatted);
161 }
162 } catch (e) {
163 _log('Unable to format "${file.path}": $e');
164 }
165 }
166 }
167
168 _isPatchFile(file) => file.path.endsWith('_patch.dart');
169
170 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path));
171
172 _formatStdin(kind) {
173 var input = new StringBuffer();
174 stdin.transform(new Utf8Decoder()).listen((data) => input.write(data),
175 onError: (error) => _log('Error reading from stdin'),
176 onDone: () => print(_format(input.toString(), kind)));
177 }
178
179 /// Initialize the arg parser instance.
180 ArgParser _initArgParser() {
181 // NOTE: these flags are placeholders only!
182 var parser = new ArgParser();
183 parser.addFlag(WRITE_FLAG,
184 abbr: 'w',
185 negatable: false,
186 help: 'Write reformatted sources to files (overwriting contents). '
187 'Do not print reformatted sources to standard output.');
188 parser.addFlag(TRANSFORM_FLAG,
189 abbr: 't', negatable: false, help: 'Perform code transformations.');
190 parser.addOption(MAX_LINE_FLAG,
191 abbr: 'l', defaultsTo: '80', help: 'Wrap lines longer than this length. '
192 'To never wrap, specify "Infinity" or "Inf" for short.');
193 parser.addOption(INDENT_FLAG,
194 abbr: 'i',
195 defaultsTo: '2',
196 help: 'Specify number of spaces per indentation. '
197 'To indent using tabs, specify "--$INDENT_FLAG tab".' '--- [PROVISIONAL AP I].',
198 hide: true);
199 parser.addOption(KIND_FLAG,
200 abbr: 'k',
201 defaultsTo: 'cu',
202 help: 'Specify source snippet kind ("stmt" or "cu") ' '--- [PROVISIONAL AP I].',
203 hide: true);
204 parser.addOption(SELECTION_FLAG,
205 abbr: 's', help: 'Specify selection information as an offset,length pair '
206 '(e.g., -s "0,4").', hide: true);
207 parser.addFlag(MACHINE_FLAG,
208 abbr: 'm',
209 negatable: false,
210 help: 'Produce output in a format suitable for parsing.');
211 parser.addFlag(HELP_FLAG,
212 abbr: 'h', negatable: false, help: 'Print this usage information.');
213 return parser;
214 }
215
216 /// Displays usage information.
217 _printUsage() {
218 var buffer = new StringBuffer();
219 buffer
220 ..write('$BINARY_NAME formats Dart programs.')
221 ..write('\n\n')
222 ..write('Without an explicit path, $BINARY_NAME processes the standard '
223 'input. Given a file, it operates on that file; given a '
224 'directory, it operates on all .dart files in that directory, '
225 'recursively. (Files starting with a period are ignored.) By '
226 'default, $BINARY_NAME prints the reformatted sources to ' 'standard out put.')
227 ..write('\n\n')
228 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n')
229 ..write('Supported flags are:\n')
230 ..write('${argParser.usage}\n\n');
231 _log(buffer.toString());
232 }
233
234 /// Format this [src], treating it as the given snippet [kind].
235 String _format(src, kind) {
236 var formatResult = new CodeFormatter(formatterSettings).format(kind, src,
237 selection: selection);
238 if (machineFormat) {
239 if (formatResult.selection == null) {
240 formatResult.selection = defaultSelection;
241 }
242 return _toJson(formatResult);
243 }
244 return formatResult.source;
245 }
246
247 _toJson(formatResult) => // Actual JSON format TBD
248 JSON.encode({
249 'source': formatResult.source,
250 'selection': {
251 'offset': formatResult.selection.offset,
252 'length': formatResult.selection.length
253 }
254 });
255
256 /// Log the given [msg].
257 _log(String msg) {
258 //TODO(pquitslund): add proper log support
259 print(msg);
260 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/formatter.dart » ('j') | pkg/analyzer/test/services/test_utils.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698