Permalink
Browse files

Eat some dogfood!

  • Loading branch information...
munificent committed Jun 15, 2015
1 parent d97f954 commit efd38861e3e88a1694c85094c4647018d2e71ff7
View
@@ -33,8 +33,8 @@ void main(List<String> args) {
result = formatSource();
}
var elapsed = new DateTime.now()
.difference(start).inMilliseconds / FORMATS_PER_TRIAL;
var elapsed =
new DateTime.now().difference(start).inMilliseconds / FORMATS_PER_TRIAL;
// Keep track of the best run so far.
if (elapsed >= best) continue;
View
@@ -15,23 +15,31 @@ import 'package:dart_style/src/source_code.dart';
void main(List<String> args) {
var parser = new ArgParser(allowTrailingOptions: true);
parser.addFlag("help", abbr: "h", negatable: false,
help: "Shows usage information.");
parser.addOption("line-length", abbr: "l",
help: "Wrap lines longer than this.",
defaultsTo: "80");
parser.addFlag("help",
abbr: "h", negatable: false, help: "Shows usage information.");
parser.addOption("line-length",
abbr: "l", help: "Wrap lines longer than this.", defaultsTo: "80");
parser.addOption("preserve",
help: 'Selection to preserve, formatted as "start:length".');
parser.addFlag("dry-run", abbr: "n", negatable: false,
parser.addFlag("dry-run",
abbr: "n",
negatable: false,
help: "Show which files would be modified but make no changes.");
parser.addFlag("overwrite", abbr: "w", negatable: false,
parser.addFlag("overwrite",
abbr: "w",
negatable: false,
help: "Overwrite input files with formatted output.");
parser.addFlag("machine", abbr: "m", negatable: false,
parser.addFlag("machine",
abbr: "m",
negatable: false,
help: "Produce machine-readable JSON output.");
parser.addFlag("follow-links", negatable: false,
parser.addFlag("follow-links",
negatable: false,
help: "Follow links to files and directories.\n"
"If unset, links will be ignored.");
parser.addFlag("transform", abbr: "t", negatable: false,
"If unset, links will be ignored.");
parser.addFlag("transform",
abbr: "t",
negatable: false,
help: "Unused flag for compability with the old formatter.");
var argResults;
@@ -56,21 +64,21 @@ void main(List<String> args) {
try {
selection = parseSelection(argResults["preserve"]);
} on FormatException catch (_) {
usageError(parser,
usageError(
parser,
'--preserve must be a colon-separated pair of integers, was '
'"${argResults['preserve']}".');
}
if (argResults["dry-run"] && argResults["overwrite"]) {
usageError(parser,
"Cannot use --dry-run and --overwrite at the same time.");
usageError(
parser, "Cannot use --dry-run and --overwrite at the same time.");
}
checkForReporterCollision(String chosen, String other) {
if (!argResults[other]) return;
usageError(parser,
"Cannot use --$chosen and --$other at the same time.");
usageError(parser, "Cannot use --$chosen and --$other at the same time.");
}
var reporter = OutputReporter.print;
@@ -97,8 +105,10 @@ void main(List<String> args) {
try {
pageWidth = int.parse(argResults["line-length"]);
} on FormatException catch (_) {
usageError(parser, '--line-length must be an integer, was '
'"${argResults['line-length']}".');
usageError(
parser,
'--line-length must be an integer, was '
'"${argResults['line-length']}".');
}
var followLinks = argResults["follow-links"];
@@ -47,6 +47,7 @@ class ArgumentListVisitor {
return _blockRule;
}
Rule _blockRule;
/// Returns `true` if there is only a single positional argument.
@@ -75,8 +76,8 @@ class ArgumentListVisitor {
factory ArgumentListVisitor(SourceVisitor visitor, ArgumentList node) {
// Assumes named arguments follow all positional ones.
var positional = node.arguments
.takeWhile((arg) => arg is! NamedExpression).toList();
var positional =
node.arguments.takeWhile((arg) => arg is! NamedExpression).toList();
var named = node.arguments.skip(positional.length).toList();
var blocks = node.arguments.where(_isBlockArgument).toSet();
@@ -208,8 +209,8 @@ class ArgumentListVisitor {
}
// Split before the first named argument.
namedRule.beforeArguments(
_visitor.builder.split(space: _positional.isNotEmpty));
namedRule
.beforeArguments(_visitor.builder.split(space: _positional.isNotEmpty));
for (var argument in _named) {
_writeArgument(namedRule, argument);
@@ -30,7 +30,7 @@ class CallChainVisitor {
/// The mixed method calls and property accesses in the call chain in the
/// order that they appear in the source.
final List <Expression> _calls;
final List<Expression> _calls;
/// Whether or not a [Rule] is currently active for the call chain.
bool _ruleEnabled = false;
@@ -74,9 +74,8 @@ class CallChainVisitor {
// .length;
var properties = [];
if (target is SimpleIdentifier) {
properties = calls
.takeWhile((call) => call is! MethodInvocation)
.toList();
properties =
calls.takeWhile((call) => call is! MethodInvocation).toList();
}
calls.removeRange(0, properties.length);
View
@@ -146,6 +146,7 @@ class Chunk extends Selection {
assert(_canDivide != null);
return _canDivide;
}
bool _canDivide;
/// The number of characters in this chunk when unsplit.
View
@@ -91,7 +91,7 @@ class ChunkBuilder {
/// token pair.
bool get needsToPreserveNewlines =>
_pendingWhitespace == Whitespace.oneOrTwoNewlines ||
_pendingWhitespace == Whitespace.spaceOrNewline;
_pendingWhitespace == Whitespace.spaceOrNewline;
/// The number of characters of code that can fit in a single line.
int get pageWidth => _formatter.pageWidth;
@@ -148,18 +148,17 @@ class ChunkBuilder {
///
/// If [isDouble] is passed, forces the split to either be a single or double
/// newline. Otherwise, leaves it indeterminate.
Chunk split({bool space, bool isDouble, bool flushLeft}) =>
_writeSplit(_rules.last, null,
flushLeft: flushLeft, isDouble: isDouble, spaceWhenUnsplit: space);
Chunk split({bool space, bool isDouble, bool flushLeft}) => _writeSplit(
_rules.last, null,
flushLeft: flushLeft, isDouble: isDouble, spaceWhenUnsplit: space);
/// Write a split owned by the current innermost rule.
///
/// Unlike [split()], this ignores any current expression nesting. It always
/// indents the next line at the statement level.
Chunk blockSplit({bool space, bool isDouble}) =>
_writeSplit(_rules.last, _nesting.blockNesting,
isDouble: isDouble,
spaceWhenUnsplit: space);
Chunk blockSplit({bool space, bool isDouble}) => _writeSplit(
_rules.last, _nesting.blockNesting,
isDouble: isDouble, spaceWhenUnsplit: space);
/// Outputs the series of [comments] and associated whitespace that appear
/// before [token] (which is not written by this).
@@ -169,8 +168,8 @@ class ChunkBuilder {
///
/// [linesBeforeToken] is the number of lines between the last comment (or
/// previous token if there are no comments) and the next token.
void writeComments(List<SourceComment> comments, int linesBeforeToken,
String token) {
void writeComments(
List<SourceComment> comments, int linesBeforeToken, String token) {
// Corner case: if we require a blank line, but there exists one between
// some of the comments, or after the last one, then we don't need to
// enforce one before the first comment. Example:
@@ -247,7 +246,9 @@ class ChunkBuilder {
}
} else {
// The comment starts a line, so make sure it stays on its own line.
_writeHardSplit(nest: true, flushLeft: comment.flushLeft,
_writeHardSplit(
nest: true,
flushLeft: comment.flushLeft,
double: comment.linesBefore > 1);
}
@@ -460,8 +461,8 @@ class ChunkBuilder {
///
/// Nested blocks are handled using their own independent [LineWriter].
ChunkBuilder startBlock() {
var builder = new ChunkBuilder._(this, _formatter, _source,
_chunks.last.blockChunks);
var builder =
new ChunkBuilder._(this, _formatter, _source, _chunks.last.blockChunks);
// A block always starts off indented one level.
builder.indent();
@@ -643,8 +644,12 @@ class ChunkBuilder {
// Otherwise, it gets a space if the following token is not a delimiter or
// the empty string, for EOF.
return token != ")" && token != "]" && token != "}" &&
token != "," && token != ";" && token != "";
return token != ")" &&
token != "]" &&
token != "}" &&
token != "," &&
token != ";" &&
token != "";
}
/// Appends a hard split with the current indentation and nesting (the latter
View
@@ -128,8 +128,7 @@ void dumpChunks(int start, List<Chunk> chunks) {
writeIf(chunk.nesting != null && chunk.nesting != 0,
() => "nest ${chunk.nesting}");
writeIf(chunk.flushLeft != null && chunk.flushLeft,
() => "flush");
writeIf(chunk.flushLeft != null && chunk.flushLeft, () => "flush");
rows.add(row);
View
@@ -55,7 +55,7 @@ class LinePrefix {
: this._(0, {}, indent, new NestingSplitter(), flushLeft: false);
LinePrefix._(this.length, this.ruleValues, this._indent, this._nesting,
{bool flushLeft : false})
{bool flushLeft: false})
: _flushLeft = flushLeft;
bool operator ==(other) {
@@ -80,31 +80,31 @@ class LinePrefix {
/// Create a new LinePrefix one chunk longer than this one using [ruleValues],
/// and assuming that we do not split before that chunk.
LinePrefix extend(Map<Rule, int> ruleValues) =>
new LinePrefix._(length + 1, ruleValues, _indent, _nesting,
flushLeft: _flushLeft);
LinePrefix extend(Map<Rule, int> ruleValues) => new LinePrefix._(
length + 1, ruleValues, _indent, _nesting,
flushLeft: _flushLeft);
/// Create a series of new LinePrefixes one chunk longer than this one using
/// [ruleValues], and assuming that the new [chunk] splits at an expression
/// boundary so there may be multiple possible different nesting stacks.
///
/// If this prefix is for a nested block, [blockIndentation] may be nonzero
/// to push the output to the right.
Iterable<LinePrefix> split(Chunk chunk, int blockIndentation,
Map<Rule, int> ruleValues) {
Iterable<LinePrefix> split(
Chunk chunk, int blockIndentation, Map<Rule, int> ruleValues) {
var indent = chunk.indent + blockIndentation;
return _nesting.update(chunk.nesting).map((nesting) => new LinePrefix._(
length + 1, ruleValues, indent, nesting, flushLeft: chunk.flushLeft));
length + 1, ruleValues, indent, nesting,
flushLeft: chunk.flushLeft));
}
String toString() {
var result = "prefix $length";
if (_indent != 0) result += " indent ${_indent}";
if (_nesting.indent != 0) result += " nesting ${_nesting.indent}";
if (ruleValues.isNotEmpty) {
var rules = ruleValues.keys
.map((key) => "$key:${ruleValues[key]}")
.join(" ");
var rules =
ruleValues.keys.map((key) => "$key:${ruleValues[key]}").join(" ");
result += " rules $rules";
}
@@ -207,8 +207,8 @@ class LineSplitter {
/// Updates [solution] with the solution for [prefix] assuming it uses
/// [longerPrefix] for the next chunk.
void _tryLongerPrefix(SplitSolution solution, LinePrefix prefix,
LinePrefix longerPrefix) {
void _tryLongerPrefix(
SplitSolution solution, LinePrefix prefix, LinePrefix longerPrefix) {
var remaining = _findBestSplits(longerPrefix);
// If it wasn't possible to split the suffix given this nesting stack,
@@ -233,9 +233,8 @@ class LineSplitter {
var updatedValues = {};
for (var prefixRule in prefixRules) {
var ruleValue = prefixRule == nextRule
? value
: prefix.ruleValues[prefixRule];
var ruleValue =
prefixRule == nextRule ? value : prefix.ruleValues[prefixRule];
if (suffixRules.contains(prefixRule)) {
// If the same rule appears in both the prefix and suffix, then preserve
View
@@ -81,8 +81,8 @@ class LineWriter {
var cached = _blockCache[key];
if (cached != null) return cached;
var writer = new LineWriter._(chunk.blockChunks, _lineEnding,
pageWidth, column, _blockCache);
var writer = new LineWriter._(
chunk.blockChunks, _lineEnding, pageWidth, column, _blockCache);
// TODO(rnystrom): Passing in an initial indent here is hacky. The
// LineWriter ensures all but the first chunk have a block indent, and this
@@ -96,7 +96,8 @@ class LineWriter {
///
/// Since this is linear and line splitting is worse it's good to feed the
/// line splitter smaller lists of chunks when possible.
FormatResult writeLines(int firstLineIndent, {bool isCompilationUnit: false}) {
FormatResult writeLines(int firstLineIndent,
{bool isCompilationUnit: false}) {
// Now that we know what hard splits there will be, break the chunks into
// independently splittable lines.
var newlines = 0;
View
@@ -257,7 +257,8 @@ class NestingSplitter {
for (var i = lastLengthStart; i < lastLengthEnd; i++) {
var previousSubset = subsets[i];
var start = previousSubset.isNotEmpty ? previousSubset.last + 1 : min + 1;
var start =
previousSubset.isNotEmpty ? previousSubset.last + 1 : min + 1;
// Then for each value in the remainer, make a new subset that is the
// union of the shorter subset and that value.
View
@@ -213,7 +213,8 @@ class MultiplePositionalRule extends PositionalRule {
}
for (var i = _arguments.length - _trailingBlocks;
i < _arguments.length; i++) {
i < _arguments.length;
i++) {
if (chunk == _arguments[i]) return false;
}
@@ -284,9 +285,12 @@ class NamedRule extends ArgumentRule {
bool isSplit(int value, Chunk chunk) {
switch (value) {
case 0: return false;
case 1: return chunk == _first;
case 2: return true;
case 0:
return false;
case 1:
return chunk == _first;
case 2:
return true;
}
throw "unreachable";
View
@@ -50,7 +50,9 @@ class SourceCode {
}
SourceCode(this.text,
{this.uri, this.isCompilationUnit: true, this.selectionStart,
{this.uri,
this.isCompilationUnit: true,
this.selectionStart,
this.selectionLength}) {
// Must either provide both selection bounds or neither.
if ((selectionStart == null) != (selectionLength == null)) {
Oops, something went wrong.

0 comments on commit efd3886

Please sign in to comment.