| OLD | NEW |
| 1 #!/usr/bin/env dart | 1 #!/usr/bin/env dart |
| 2 | |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
| 6 | 5 |
| 7 import 'dart:convert'; | 6 import 'dart:convert'; |
| 8 import 'dart:io'; | 7 import 'dart:io'; |
| 9 | 8 |
| 10 import 'package:args/args.dart'; | 9 import 'package:args/args.dart'; |
| 11 import 'package:path/path.dart' as path; | 10 import 'package:path/path.dart' as path; |
| 12 | 11 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 pageWidth: _parseLineLength(options[MAX_LINE_FLAG])); | 68 pageWidth: _parseLineLength(options[MAX_LINE_FLAG])); |
| 70 } | 69 } |
| 71 | 70 |
| 72 /// Translate the indent option into spaces per indent. | 71 /// Translate the indent option into spaces per indent. |
| 73 int _parseSpacesPerIndent(String indentOption) { | 72 int _parseSpacesPerIndent(String indentOption) { |
| 74 if (indentOption == 'tab') { | 73 if (indentOption == 'tab') { |
| 75 return 1; | 74 return 1; |
| 76 } | 75 } |
| 77 int spacesPerIndent = _toInt(indentOption); | 76 int spacesPerIndent = _toInt(indentOption); |
| 78 if (spacesPerIndent == null) { | 77 if (spacesPerIndent == null) { |
| 79 throw new FormatterException('Indentation is specified as an Integer or ' | 78 throw new FormatterException( |
| 80 'the value "tab".'); | 79 'Indentation is specified as an Integer or ' 'the value "tab".'); |
| 81 } | 80 } |
| 82 return spacesPerIndent; | 81 return spacesPerIndent; |
| 83 } | 82 } |
| 84 | 83 |
| 85 /// Translate the indent option into tabs for indent. | 84 /// Translate the indent option into tabs for indent. |
| 86 bool _parseTabsForIndent(String indentOption) => indentOption == 'tab'; | 85 bool _parseTabsForIndent(String indentOption) => indentOption == 'tab'; |
| 87 | 86 |
| 88 CodeKind _parseKind(kindOption) { | 87 CodeKind _parseKind(kindOption) { |
| 89 switch(kindOption) { | 88 switch (kindOption) { |
| 90 case 'stmt' : | 89 case 'stmt': |
| 91 return CodeKind.STATEMENT; | 90 return CodeKind.STATEMENT; |
| 92 default: | 91 default: |
| 93 return CodeKind.COMPILATION_UNIT; | 92 return CodeKind.COMPILATION_UNIT; |
| 94 } | 93 } |
| 95 } | 94 } |
| 96 | 95 |
| 97 int _parseLineLength(String lengthOption) { | 96 int _parseLineLength(String lengthOption) { |
| 98 var length = _toInt(lengthOption); | 97 var length = _toInt(lengthOption); |
| 99 if (length == null) { | 98 if (length == null) { |
| 100 var val = lengthOption.toUpperCase(); | 99 var val = lengthOption.toUpperCase(); |
| 101 if (val == 'INF' || val == 'INFINITY') { | 100 if (val == 'INF' || val == 'INFINITY') { |
| 102 length = -1; | 101 length = -1; |
| 103 } else { | 102 } else { |
| 104 throw new FormatterException('Line length is specified as an Integer or ' | 103 throw new FormatterException( |
| 105 'the value "Inf".'); | 104 'Line length is specified as an Integer or ' 'the value "Inf".'); |
| 106 } | 105 } |
| 107 } | 106 } |
| 108 return length; | 107 return length; |
| 109 } | 108 } |
| 110 | 109 |
| 111 | 110 |
| 112 Selection _parseSelection(String selectionOption) { | 111 Selection _parseSelection(String selectionOption) { |
| 113 if(selectionOption == null) return null; | 112 if (selectionOption == null) return null; |
| 114 | 113 |
| 115 var units = selectionOption.split(','); | 114 var units = selectionOption.split(','); |
| 116 if (units.length == 2) { | 115 if (units.length == 2) { |
| 117 var offset = _toInt(units[0]); | 116 var offset = _toInt(units[0]); |
| 118 var length = _toInt(units[1]); | 117 var length = _toInt(units[1]); |
| 119 if (offset != null && length != null) { | 118 if (offset != null && length != null) { |
| 120 return new Selection(offset, length); | 119 return new Selection(offset, length); |
| 121 } | 120 } |
| 122 } | 121 } |
| 123 throw new FormatterException('Selections are specified as integer pairs ' | 122 throw new FormatterException( |
| 124 '(e.g., "(offset, length)".'); | 123 'Selections are specified as integer pairs ' '(e.g., "(offset, length)".')
; |
| 125 } | 124 } |
| 126 | 125 |
| 127 int _toInt(str) => int.parse(str, onError: (_) => null); | 126 int _toInt(str) => int.parse(str, onError: (_) => null); |
| 128 | 127 |
| 129 _formatPaths(paths) { | 128 _formatPaths(paths) { |
| 130 paths.forEach((path) { | 129 paths.forEach((path) { |
| 131 if (FileSystemEntity.isDirectorySync(path)) { | 130 if (FileSystemEntity.isDirectorySync(path)) { |
| 132 _formatDirectory(new Directory(path)); | 131 _formatDirectory(new Directory(path)); |
| 133 } else { | 132 } else { |
| 134 _formatFile(new File(path)); | 133 _formatFile(new File(path)); |
| 135 } | 134 } |
| 136 }); | 135 }); |
| 137 } | 136 } |
| 138 | 137 |
| 139 _formatResource(resource) { | 138 _formatResource(resource) { |
| 140 if (resource is Directory) { | 139 if (resource is Directory) { |
| 141 _formatDirectory(resource); | 140 _formatDirectory(resource); |
| 142 } else if (resource is File) { | 141 } else if (resource is File) { |
| 143 _formatFile(resource); | 142 _formatFile(resource); |
| 144 } | 143 } |
| 145 } | 144 } |
| 146 | 145 |
| 147 _formatDirectory(dir) => dir.listSync(followLinks: FOLLOW_LINKS) | 146 _formatDirectory(dir) => |
| 148 .forEach((resource) => _formatResource(resource)); | 147 dir.listSync( |
| 148 followLinks: FOLLOW_LINKS).forEach((resource) => _formatResource(resourc
e)); |
| 149 | 149 |
| 150 _formatFile(file) { | 150 _formatFile(file) { |
| 151 if (_isDartFile(file)) { | 151 if (_isDartFile(file)) { |
| 152 if (_isPatchFile(file) && !paths.contains(file.path)) { | 152 if (_isPatchFile(file) && !paths.contains(file.path)) { |
| 153 _log('Skipping patch file "${file.path}"'); | 153 _log('Skipping patch file "${file.path}"'); |
| 154 return; | 154 return; |
| 155 } | 155 } |
| 156 try { | 156 try { |
| 157 var rawSource = file.readAsStringSync(); | 157 var rawSource = file.readAsStringSync(); |
| 158 var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT); | 158 var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 169 } | 169 } |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 | 172 |
| 173 _isPatchFile(file) => file.path.endsWith('_patch.dart'); | 173 _isPatchFile(file) => file.path.endsWith('_patch.dart'); |
| 174 | 174 |
| 175 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path)); | 175 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path)); |
| 176 | 176 |
| 177 _formatStdin(kind) { | 177 _formatStdin(kind) { |
| 178 var input = new StringBuffer(); | 178 var input = new StringBuffer(); |
| 179 stdin.transform(new Utf8Decoder()) | 179 stdin.transform( |
| 180 .listen((data) => input.write(data), | 180 new Utf8Decoder()).listen( |
| 181 onError: (error) => _log('Error reading from stdin'), | 181 (data) => input.write(data), |
| 182 onDone: () => print(_format(input.toString(), kind))); | 182 onError: (error) => _log('Error reading from stdin'), |
| 183 onDone: () => print(_format(input.toString(), kind))); |
| 183 } | 184 } |
| 184 | 185 |
| 185 /// Initialize the arg parser instance. | 186 /// Initialize the arg parser instance. |
| 186 ArgParser _initArgParser() { | 187 ArgParser _initArgParser() { |
| 187 // NOTE: these flags are placeholders only! | 188 // NOTE: these flags are placeholders only! |
| 188 var parser = new ArgParser(); | 189 var parser = new ArgParser(); |
| 189 parser.addFlag(WRITE_FLAG, abbr: 'w', negatable: false, | 190 parser.addFlag( |
| 191 WRITE_FLAG, |
| 192 abbr: 'w', |
| 193 negatable: false, |
| 190 help: 'Write reformatted sources to files (overwriting contents). ' | 194 help: 'Write reformatted sources to files (overwriting contents). ' |
| 191 'Do not print reformatted sources to standard output.'); | 195 'Do not print reformatted sources to standard output.'); |
| 192 parser.addFlag(TRANSFORM_FLAG, abbr: 't', negatable: false, | 196 parser.addFlag( |
| 197 TRANSFORM_FLAG, |
| 198 abbr: 't', |
| 199 negatable: false, |
| 193 help: 'Perform code transformations.'); | 200 help: 'Perform code transformations.'); |
| 194 parser.addOption(MAX_LINE_FLAG, abbr: 'l', defaultsTo: '80', | 201 parser.addOption( |
| 202 MAX_LINE_FLAG, |
| 203 abbr: 'l', |
| 204 defaultsTo: '80', |
| 195 help: 'Wrap lines longer than this length. ' | 205 help: 'Wrap lines longer than this length. ' |
| 196 'To never wrap, specify "Infinity" or "Inf" for short.'); | 206 'To never wrap, specify "Infinity" or "Inf" for short.'); |
| 197 parser.addOption(INDENT_FLAG, abbr: 'i', defaultsTo: '2', | 207 parser.addOption( |
| 208 INDENT_FLAG, |
| 209 abbr: 'i', |
| 210 defaultsTo: '2', |
| 198 help: 'Specify number of spaces per indentation. ' | 211 help: 'Specify number of spaces per indentation. ' |
| 199 'To indent using tabs, specify "--$INDENT_FLAG tab".' | 212 'To indent using tabs, specify "--$INDENT_FLAG tab".' '--- [PROVISIONA
L API].', |
| 200 '--- [PROVISIONAL API].', hide: true); | 213 hide: true); |
| 201 parser.addOption(KIND_FLAG, abbr: 'k', defaultsTo: 'cu', | 214 parser.addOption( |
| 202 help: 'Specify source snippet kind ("stmt" or "cu") ' | 215 KIND_FLAG, |
| 203 '--- [PROVISIONAL API].', hide: true); | 216 abbr: 'k', |
| 204 parser.addOption(SELECTION_FLAG, abbr: 's', | 217 defaultsTo: 'cu', |
| 218 help: 'Specify source snippet kind ("stmt" or "cu") ' '--- [PROVISIONAL AP
I].', |
| 219 hide: true); |
| 220 parser.addOption( |
| 221 SELECTION_FLAG, |
| 222 abbr: 's', |
| 205 help: 'Specify selection information as an offset,length pair ' | 223 help: 'Specify selection information as an offset,length pair ' |
| 206 '(e.g., -s "0,4").', hide: true); | 224 '(e.g., -s "0,4").', |
| 207 parser.addFlag(MACHINE_FLAG, abbr: 'm', negatable: false, | 225 hide: true); |
| 226 parser.addFlag( |
| 227 MACHINE_FLAG, |
| 228 abbr: 'm', |
| 229 negatable: false, |
| 208 help: 'Produce output in a format suitable for parsing.'); | 230 help: 'Produce output in a format suitable for parsing.'); |
| 209 parser.addFlag(HELP_FLAG, abbr: 'h', negatable: false, | 231 parser.addFlag( |
| 232 HELP_FLAG, |
| 233 abbr: 'h', |
| 234 negatable: false, |
| 210 help: 'Print this usage information.'); | 235 help: 'Print this usage information.'); |
| 211 return parser; | 236 return parser; |
| 212 } | 237 } |
| 213 | 238 |
| 214 | 239 |
| 215 /// Displays usage information. | 240 /// Displays usage information. |
| 216 _printUsage() { | 241 _printUsage() { |
| 217 var buffer = new StringBuffer(); | 242 var buffer = new StringBuffer(); |
| 218 buffer..write('$BINARY_NAME formats Dart programs.') | 243 buffer |
| 219 ..write('\n\n') | 244 ..write('$BINARY_NAME formats Dart programs.') |
| 220 ..write('Without an explicit path, $BINARY_NAME processes the standard ' | 245 ..write('\n\n') |
| 221 'input. Given a file, it operates on that file; given a ' | 246 ..write( |
| 222 'directory, it operates on all .dart files in that directory, ' | 247 'Without an explicit path, $BINARY_NAME processes the standard ' |
| 223 'recursively. (Files starting with a period are ignored.) By ' | 248 'input. Given a file, it operates on that file; given a ' |
| 224 'default, $BINARY_NAME prints the reformatted sources to ' | 249 'directory, it operates on all .dart files in that directory, ' |
| 225 'standard output.') | 250 'recursively. (Files starting with a period are ignored.) By ' |
| 226 ..write('\n\n') | 251 'default, $BINARY_NAME prints the reformatted sources to ' 'standa
rd output.') |
| 227 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') | 252 ..write('\n\n') |
| 228 ..write('Supported flags are:\n') | 253 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') |
| 229 ..write('${argParser.usage}\n\n'); | 254 ..write('Supported flags are:\n') |
| 255 ..write('${argParser.usage}\n\n'); |
| 230 _log(buffer.toString()); | 256 _log(buffer.toString()); |
| 231 } | 257 } |
| 232 | 258 |
| 233 /// Format this [src], treating it as the given snippet [kind]. | 259 /// Format this [src], treating it as the given snippet [kind]. |
| 234 String _format(src, kind) { | 260 String _format(src, kind) { |
| 235 var formatResult = new CodeFormatter(formatterSettings).format( | 261 var formatResult = |
| 236 kind, src, selection: selection); | 262 new CodeFormatter(formatterSettings).format(kind, src, selection: selectio
n); |
| 237 if (machineFormat) { | 263 if (machineFormat) { |
| 238 if (formatResult.selection == null) { | 264 if (formatResult.selection == null) { |
| 239 formatResult.selection = defaultSelection; | 265 formatResult.selection = defaultSelection; |
| 240 } | 266 } |
| 241 return _toJson(formatResult); | 267 return _toJson(formatResult); |
| 242 } | 268 } |
| 243 return formatResult.source; | 269 return formatResult.source; |
| 244 } | 270 } |
| 245 | 271 |
| 246 _toJson(formatResult) => | 272 _toJson(formatResult) => // Actual JSON format TBD |
| 247 // Actual JSON format TBD | 273 JSON.encode({ |
| 248 JSON.encode({'source': formatResult.source, | 274 'source': formatResult.source, |
| 249 'selection': { | 275 'selection': { |
| 250 'offset': formatResult.selection.offset, | 276 'offset': formatResult.selection.offset, |
| 251 'length': formatResult.selection.length | 277 'length': formatResult.selection.length |
| 252 } | 278 } |
| 253 }); | 279 }); |
| 254 | 280 |
| 255 /// Log the given [msg]. | 281 /// Log the given [msg]. |
| 256 _log(String msg) { | 282 _log(String msg) { |
| 257 //TODO(pquitslund): add proper log support | 283 //TODO(pquitslund): add proper log support |
| 258 print(msg); | 284 print(msg); |
| 259 } | 285 } |
| OLD | NEW |