| 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:io'; | 8 import 'dart:io'; |
| 8 import 'dart:utf'; | 9 import 'dart:utf'; |
| 9 | 10 |
| 10 import 'package:args/args.dart'; | 11 import 'package:args/args.dart'; |
| 11 import 'package:path/path.dart' as path; | 12 import 'package:path/path.dart' as path; |
| 12 | 13 |
| 13 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; | 14 import 'package:analyzer_experimental/src/services/formatter_impl.dart'; |
| 14 | 15 |
| 15 | 16 |
| 16 const BINARY_NAME = 'dartfmt'; | 17 const BINARY_NAME = 'dartfmt'; |
| 17 final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false); | 18 final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false); |
| 18 final argParser = _initArgParser(); | 19 final argParser = _initArgParser(); |
| 19 | 20 |
| 21 bool machineFormat; |
| 20 bool overwriteFileContents; | 22 bool overwriteFileContents; |
| 23 Selection selection; |
| 21 const followLinks = false; | 24 const followLinks = false; |
| 22 | 25 |
| 23 main() { | 26 main() { |
| 24 var options = argParser.parse(new Options().arguments); | 27 var options = argParser.parse(new Options().arguments); |
| 25 if (options['help']) { | 28 if (options['help']) { |
| 26 _printUsage(); | 29 _printUsage(); |
| 27 return; | 30 return; |
| 28 } | 31 } |
| 29 overwriteFileContents = options['write']; | |
| 30 | 32 |
| 33 _readOptions(options); |
| 34 |
| 31 if (options.rest.isEmpty) { | 35 if (options.rest.isEmpty) { |
| 32 _formatStdin(options); | 36 _formatStdin(options); |
| 33 } else { | 37 } else { |
| 34 _formatPaths(options.rest); | 38 _formatPaths(options.rest); |
| 35 } | 39 } |
| 36 } | 40 } |
| 37 | 41 |
| 42 _readOptions(options) { |
| 43 machineFormat = options['machine']; |
| 44 overwriteFileContents = options['write']; |
| 45 selection = _parseSelection(options['selection']); |
| 46 } |
| 47 |
| 48 Selection _parseSelection(selectionOption) { |
| 49 if (selectionOption != null) { |
| 50 var units = selectionOption.split(','); |
| 51 if (units.length == 2) { |
| 52 var offset = _toInt(units[0]); |
| 53 var length = _toInt(units[1]); |
| 54 if (offset != null && length != null) { |
| 55 return new Selection(offset, length); |
| 56 } |
| 57 } |
| 58 throw new FormatterException('Selections are specified as integer pairs ' |
| 59 '(e.g., "(offset, length)".'); |
| 60 } |
| 61 } |
| 62 |
| 63 int _toInt(str) => int.parse(str, onError: (_) => null); |
| 64 |
| 38 _formatPaths(paths) { | 65 _formatPaths(paths) { |
| 39 paths.forEach((path) { | 66 paths.forEach((path) { |
| 40 if (FileSystemEntity.isDirectorySync(path)) { | 67 if (FileSystemEntity.isDirectorySync(path)) { |
| 41 _formatDirectory(new Directory(path)); | 68 _formatDirectory(new Directory(path)); |
| 42 } else { | 69 } else { |
| 43 _formatFile(new File(path)); | 70 _formatFile(new File(path)); |
| 44 } | 71 } |
| 45 }); | 72 }); |
| 46 } | 73 } |
| 47 | 74 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 onDone: () => print(_formatCU(input.toString()))); | 110 onDone: () => print(_formatCU(input.toString()))); |
| 84 } | 111 } |
| 85 | 112 |
| 86 /// Initialize the arg parser instance. | 113 /// Initialize the arg parser instance. |
| 87 ArgParser _initArgParser() { | 114 ArgParser _initArgParser() { |
| 88 // NOTE: these flags are placeholders only! | 115 // NOTE: these flags are placeholders only! |
| 89 var parser = new ArgParser(); | 116 var parser = new ArgParser(); |
| 90 parser.addFlag('write', abbr: 'w', negatable: false, | 117 parser.addFlag('write', abbr: 'w', negatable: false, |
| 91 help: 'Write reformatted sources to files (overwriting contents). ' | 118 help: 'Write reformatted sources to files (overwriting contents). ' |
| 92 'Do not print reformatted sources to standard output.'); | 119 'Do not print reformatted sources to standard output.'); |
| 120 parser.addFlag('machine', abbr: 'm', negatable: false, |
| 121 help: 'Produce output in a format suitable for parsing.'); |
| 122 parser.addOption('selection', abbr: 's', |
| 123 help: 'Specify selection information as an offset,length pair ' |
| 124 '(e.g., -s "0,4").'); |
| 93 parser.addFlag('help', abbr: 'h', negatable: false, | 125 parser.addFlag('help', abbr: 'h', negatable: false, |
| 94 help: 'Print this usage information.'); | 126 help: 'Print this usage information.'); |
| 95 return parser; | 127 return parser; |
| 96 } | 128 } |
| 97 | 129 |
| 98 | 130 |
| 99 /// Displays usage information. | 131 /// Displays usage information. |
| 100 _printUsage() { | 132 _printUsage() { |
| 101 var buffer = new StringBuffer(); | 133 var buffer = new StringBuffer(); |
| 102 buffer..write('$BINARY_NAME formats Dart programs.') | 134 buffer..write('$BINARY_NAME formats Dart programs.') |
| 103 ..write('\n\n') | 135 ..write('\n\n') |
| 104 ..write('Without an explicit path, $BINARY_NAME processes the standard ' | 136 ..write('Without an explicit path, $BINARY_NAME processes the standard ' |
| 105 'input. Given a file, it operates on that file; given a ' | 137 'input. Given a file, it operates on that file; given a ' |
| 106 'directory, it operates on all .dart files in that directory, ' | 138 'directory, it operates on all .dart files in that directory, ' |
| 107 'recursively. (Files starting with a period are ignored.) By ' | 139 'recursively. (Files starting with a period are ignored.) By ' |
| 108 'default, $BINARY_NAME prints the reformatted sources to ' | 140 'default, $BINARY_NAME prints the reformatted sources to ' |
| 109 'standard output.') | 141 'standard output.') |
| 110 ..write('\n\n') | 142 ..write('\n\n') |
| 111 ..write('Supported flags are:') | 143 ..write('Supported flags are:') |
| 112 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') | 144 ..write('Usage: $BINARY_NAME [flags] [path...]\n\n') |
| 113 ..write('${argParser.getUsage()}\n\n'); | 145 ..write('${argParser.getUsage()}\n\n'); |
| 114 _log(buffer.toString()); | 146 _log(buffer.toString()); |
| 115 } | 147 } |
| 116 | 148 |
| 117 /// Format the given [src] as a compilation unit. | 149 /// Format the given [src] as a compilation unit. |
| 118 String _formatCU(src, {options: const FormatterOptions()}) => | 150 String _formatCU(src, {options: const FormatterOptions()}) { |
| 119 new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src).source; | 151 var formatResult = new CodeFormatter(options).format( |
| 152 CodeKind.COMPILATION_UNIT, src, selection: selection); |
| 153 if (machineFormat) { |
| 154 return _toJson(formatResult); |
| 155 } |
| 156 return formatResult.source; |
| 157 } |
| 158 |
| 159 _toJson(formatResult) => |
| 160 // Actual JSON format TBD |
| 161 JSON.encode({'source': formatResult.source, |
| 162 'selection': formatResult.selection.toString()}); |
| 120 | 163 |
| 121 /// Log the given [msg]. | 164 /// Log the given [msg]. |
| 122 _log(String msg) { | 165 _log(String msg) { |
| 123 //TODO(pquitslund): add proper log support | 166 //TODO(pquitslund): add proper log support |
| 124 print(msg); | 167 print(msg); |
| 125 } | 168 } |
| OLD | NEW |