| OLD | NEW |
| 1 #!/usr/bin/env dart | 1 #!/usr/bin/env dart |
| 2 | 2 |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // 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 | 4 // 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. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 | 6 |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import 'package:args/args.dart'; | 10 import 'package:args/args.dart'; |
| 11 import 'package:path/path.dart' as path; | 11 import 'package:path/path.dart' as path; |
| 12 | 12 |
| 13 import 'package:analyzer/src/services/formatter_impl.dart'; | 13 import 'package:analyzer/src/services/formatter_impl.dart'; |
| 14 | 14 |
| 15 | 15 |
| 16 const BINARY_NAME = 'dartfmt'; | 16 const BINARY_NAME = 'dartfmt'; |
| 17 final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false); | 17 final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false); |
| 18 final argParser = _initArgParser(); | 18 final argParser = _initArgParser(); |
| 19 final defaultSelection = new Selection(-1, -1); | 19 final defaultSelection = new Selection(-1, -1); |
| 20 | 20 |
| 21 var formatterSettings; | 21 var formatterSettings; |
| 22 | 22 |
| 23 CodeKind kind; |
| 23 bool machineFormat; | 24 bool machineFormat; |
| 24 bool overwriteFileContents; | 25 bool overwriteFileContents; |
| 25 Selection selection; | 26 Selection selection; |
| 26 const followLinks = false; | 27 const followLinks = false; |
| 27 | 28 |
| 28 | 29 |
| 29 main(args) { | 30 main(args) { |
| 30 var options = argParser.parse(args); | 31 var options = argParser.parse(args); |
| 31 if (options['help']) { | 32 if (options['help']) { |
| 32 _printUsage(); | 33 _printUsage(); |
| 33 return; | 34 return; |
| 34 } | 35 } |
| 35 | 36 |
| 36 _readOptions(options); | 37 _readOptions(options); |
| 37 | 38 |
| 38 if (options.rest.isEmpty) { | 39 if (options.rest.isEmpty) { |
| 39 _formatStdin(options); | 40 _formatStdin(kind); |
| 40 } else { | 41 } else { |
| 41 _formatPaths(options.rest); | 42 _formatPaths(options.rest); |
| 42 } | 43 } |
| 43 } | 44 } |
| 44 | 45 |
| 45 _readOptions(options) { | 46 _readOptions(options) { |
| 47 kind = _parseKind(options['kind']); |
| 46 machineFormat = options['machine']; | 48 machineFormat = options['machine']; |
| 47 overwriteFileContents = options['write']; | 49 overwriteFileContents = options['write']; |
| 48 selection = _parseSelection(options['selection']); | 50 selection = _parseSelection(options['selection']); |
| 49 formatterSettings = | 51 formatterSettings = |
| 50 new FormatterOptions(codeTransforms: options['transform']); | 52 new FormatterOptions(codeTransforms: options['transform']); |
| 51 } | 53 } |
| 52 | 54 |
| 55 CodeKind _parseKind(kindOption) { |
| 56 switch(kindOption) { |
| 57 case 'stmt' : |
| 58 return CodeKind.STATEMENT; |
| 59 default: |
| 60 return CodeKind.COMPILATION_UNIT; |
| 61 } |
| 62 } |
| 63 |
| 53 Selection _parseSelection(selectionOption) { | 64 Selection _parseSelection(selectionOption) { |
| 54 if (selectionOption != null) { | 65 if (selectionOption != null) { |
| 55 var units = selectionOption.split(','); | 66 var units = selectionOption.split(','); |
| 56 if (units.length == 2) { | 67 if (units.length == 2) { |
| 57 var offset = _toInt(units[0]); | 68 var offset = _toInt(units[0]); |
| 58 var length = _toInt(units[1]); | 69 var length = _toInt(units[1]); |
| 59 if (offset != null && length != null) { | 70 if (offset != null && length != null) { |
| 60 return new Selection(offset, length); | 71 return new Selection(offset, length); |
| 61 } | 72 } |
| 62 } | 73 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 86 } | 97 } |
| 87 | 98 |
| 88 _formatDirectory(dir) => dir.listSync(followLinks: followLinks) | 99 _formatDirectory(dir) => dir.listSync(followLinks: followLinks) |
| 89 .forEach((resource) => _formatResource(resource)); | 100 .forEach((resource) => _formatResource(resource)); |
| 90 | 101 |
| 91 _formatFile(file) { | 102 _formatFile(file) { |
| 92 if (_isDartFile(file)) { | 103 if (_isDartFile(file)) { |
| 93 try { | 104 try { |
| 94 var buffer = new StringBuffer(); | 105 var buffer = new StringBuffer(); |
| 95 var rawSource = file.readAsStringSync(); | 106 var rawSource = file.readAsStringSync(); |
| 96 var formatted = _formatCU(rawSource); | 107 var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT); |
| 97 if (overwriteFileContents) { | 108 if (overwriteFileContents) { |
| 98 file.writeAsStringSync(formatted); | 109 file.writeAsStringSync(formatted); |
| 99 } else { | 110 } else { |
| 100 print(formatted); | 111 print(formatted); |
| 101 } | 112 } |
| 102 } catch (e) { | 113 } catch (e) { |
| 103 _log('Unable to format "${file.path}": $e'); | 114 _log('Unable to format "${file.path}": $e'); |
| 104 } | 115 } |
| 105 } | 116 } |
| 106 } | 117 } |
| 107 | 118 |
| 108 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path)); | 119 _isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path)); |
| 109 | 120 |
| 110 _formatStdin(options) { | 121 _formatStdin(kind) { |
| 111 var input = new StringBuffer(); | 122 var input = new StringBuffer(); |
| 112 stdin.transform(new Utf8Decoder()) | 123 stdin.transform(new Utf8Decoder()) |
| 113 .listen((data) => input.write(data), | 124 .listen((data) => input.write(data), |
| 114 onError: (error) => _log('Error reading from stdin'), | 125 onError: (error) => _log('Error reading from stdin'), |
| 115 onDone: () => print(_formatCU(input.toString()))); | 126 onDone: () => print(_format(input.toString(), kind))); |
| 116 } | 127 } |
| 117 | 128 |
| 118 /// Initialize the arg parser instance. | 129 /// Initialize the arg parser instance. |
| 119 ArgParser _initArgParser() { | 130 ArgParser _initArgParser() { |
| 120 // NOTE: these flags are placeholders only! | 131 // NOTE: these flags are placeholders only! |
| 121 var parser = new ArgParser(); | 132 var parser = new ArgParser(); |
| 122 parser.addFlag('write', abbr: 'w', negatable: false, | 133 parser.addFlag('write', abbr: 'w', negatable: false, |
| 123 help: 'Write reformatted sources to files (overwriting contents). ' | 134 help: 'Write reformatted sources to files (overwriting contents). ' |
| 124 'Do not print reformatted sources to standard output.'); | 135 'Do not print reformatted sources to standard output.'); |
| 136 parser.addOption('kind', abbr: 'k', defaultsTo: 'cu', |
| 137 help: 'Specify source snippet kind ("stmt" or "cu")' |
| 138 ' --- [PROVISIONAL API].'); |
| 125 parser.addFlag('machine', abbr: 'm', negatable: false, | 139 parser.addFlag('machine', abbr: 'm', negatable: false, |
| 126 help: 'Produce output in a format suitable for parsing.'); | 140 help: 'Produce output in a format suitable for parsing.'); |
| 127 parser.addOption('selection', abbr: 's', | 141 parser.addOption('selection', abbr: 's', |
| 128 help: 'Specify selection information as an offset,length pair ' | 142 help: 'Specify selection information as an offset,length pair ' |
| 129 '(e.g., -s "0,4").'); | 143 '(e.g., -s "0,4").'); |
| 130 parser.addFlag('transform', abbr: 't', negatable: true, | 144 parser.addFlag('transform', abbr: 't', negatable: true, |
| 131 help: 'Perform code transformations.'); | 145 help: 'Perform code transformations.'); |
| 132 parser.addFlag('help', abbr: 'h', negatable: false, | 146 parser.addFlag('help', abbr: 'h', negatable: false, |
| 133 help: 'Print this usage information.'); | 147 help: 'Print this usage information.'); |
| 134 return parser; | 148 return parser; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 146 'recursively. (Files starting with a period are ignored.) By ' | 160 'recursively. (Files starting with a period are ignored.) By ' |
| 147 'default, $BINARY_NAME prints the reformatted sources to ' | 161 'default, $BINARY_NAME prints the reformatted sources to ' |
| 148 'standard output.') | 162 'standard output.') |
| 149 ..write('\n\n') | 163 ..write('\n\n') |
| 150 ..write('Supported flags are:') | 164 ..write('Supported flags are:') |
| 151 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') | 165 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') |
| 152 ..write('${argParser.getUsage()}\n\n'); | 166 ..write('${argParser.getUsage()}\n\n'); |
| 153 _log(buffer.toString()); | 167 _log(buffer.toString()); |
| 154 } | 168 } |
| 155 | 169 |
| 156 /// Format the given [src] as a compilation unit. | 170 /// Format this [src], treating it as the given snippet [kind]. |
| 157 String _formatCU(src) { | 171 String _format(src, kind) { |
| 158 var formatResult = new CodeFormatter(formatterSettings).format( | 172 var formatResult = new CodeFormatter(formatterSettings).format( |
| 159 CodeKind.COMPILATION_UNIT, src, selection: selection); | 173 kind, src, selection: selection); |
| 160 if (machineFormat) { | 174 if (machineFormat) { |
| 161 if (formatResult.selection == null) { | 175 if (formatResult.selection == null) { |
| 162 formatResult.selection = defaultSelection; | 176 formatResult.selection = defaultSelection; |
| 163 } | 177 } |
| 164 return _toJson(formatResult); | 178 return _toJson(formatResult); |
| 165 } | 179 } |
| 166 return formatResult.source; | 180 return formatResult.source; |
| 167 } | 181 } |
| 168 | 182 |
| 169 _toJson(formatResult) => | 183 _toJson(formatResult) => |
| 170 // Actual JSON format TBD | 184 // Actual JSON format TBD |
| 171 JSON.encode({'source': formatResult.source, | 185 JSON.encode({'source': formatResult.source, |
| 172 'selection': { | 186 'selection': { |
| 173 'offset': formatResult.selection.offset, | 187 'offset': formatResult.selection.offset, |
| 174 'length': formatResult.selection.length | 188 'length': formatResult.selection.length |
| 175 } | 189 } |
| 176 }); | 190 }); |
| 177 | 191 |
| 178 /// Log the given [msg]. | 192 /// Log the given [msg]. |
| 179 _log(String msg) { | 193 _log(String msg) { |
| 180 //TODO(pquitslund): add proper log support | 194 //TODO(pquitslund): add proper log support |
| 181 print(msg); | 195 print(msg); |
| 182 } | 196 } |
| OLD | NEW |