Skip to content

Commit

Permalink
Better debug output for piece trees. (#1324)
Browse files Browse the repository at this point in the history
* Better debug output for piece trees.

The old formatter has pretty nice debug output, but the new one is still
pretty rudimentary. This improves that situation somewhat from:

```
Sequence(Type(`class Foo` Block(`{` Sequence(Var(`static late final int` `i;`) Var(`static late int` `i;`) Var(`static late var` `i;`) Var(`covariant late var` `i;`) Var(`covariant late int` `i;`) Var(`late final int` `i;`) Var(`late int` `i;`) Var(`late var` `i;`)) `}`)))
```

To:

```
Seq(
  Type(
    `class Foo`
    Block(
      `{`
      Seq(
        Var(`static late final int` `i;`)
        Var(`static late int` `i;`)
        Var(`static late var` `i;`)
        Var(`covariant late var` `i;`)
        Var(`covariant late int` `i;`)
        Var(`late final int` `i;`)
        Var(`late int` `i;`)
        Var(`late var` `i;`)
      )
      `}`
    )
  )
)
```

It also eliminates a bunch of pointless `toString()` implementations
that are only used for debugging and can be inferred from runtimeType.

* Update doc comment.
  • Loading branch information
munificent authored Nov 16, 2023
1 parent acf0c8e commit fd6ed34
Show file tree
Hide file tree
Showing 17 changed files with 72 additions and 55 deletions.
74 changes: 61 additions & 13 deletions lib/src/debug.dart
Original file line number Diff line number Diff line change
Expand Up @@ -268,25 +268,73 @@ void dumpLines(List<Chunk> chunks, SplitSet splits) {
/// Build a string representation of the [piece] tree.
String pieceTree(Piece piece) {
var buffer = StringBuffer();
_PieceDebugTree(piece).write(buffer, 0);
return buffer.toString();
}

void traverse(Piece piece) {
buffer.write(piece);
/// A stringified representation of a tree of pieces for debug output.
class _PieceDebugTree {
final String label;
final List<_PieceDebugTree> children = [];

if (piece is! TextPiece) {
var children = <Piece>[];
piece.forEachChild(children.add);
_PieceDebugTree(Piece piece) : label = piece.toString() {
piece.forEachChild((child) {
children.add(_PieceDebugTree(child));
});
}

buffer.write('(');
for (var child in children) {
if (child != children.first) buffer.write(' ');
traverse(child);
}
buffer.write(')');
/// The approximate number of characters of output needed to print this tree
/// on a single line.
///
/// Used to determine when to show a tree's children inline or split. Note
/// that this is O(n^2), but we don't really care since it's only used for
/// debug output.
int get width {
var result = label.length;
for (var child in children) {
result += child.width;
}
return result;
}

traverse(piece);
return buffer.toString();
void write(StringBuffer buffer, int indent) {
buffer.write(label);
if (children.isEmpty) return;

buffer.write('(');

// Split the tree if it is too long.
var isSplit = indent * 2 + width > 80;
if (isSplit) {
indent++;
buffer.writeln();
buffer.write(' ' * indent);
}

var first = true;
for (var child in children) {
if (!first) {
if (isSplit) {
buffer.writeln();
buffer.write(' ' * indent);
} else {
buffer.write(' ');
}
}

child.write(buffer, indent);

first = false;
}

if (isSplit) {
indent--;
buffer.writeln();
buffer.write(' ' * indent);
}

buffer.write(')');
}
}

String _color(String ansiEscape) => useAnsiColors ? ansiEscape : '';
3 changes: 0 additions & 3 deletions lib/src/piece/adjacent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,4 @@ class AdjacentPiece extends Piece {
void forEachChild(void Function(Piece piece) callback) {
_pieces.forEach(callback);
}

@override
String toString() => 'Adjacent';
}
3 changes: 0 additions & 3 deletions lib/src/piece/assign.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,4 @@ class AssignPiece extends Piece {
callback(target);
callback(value);
}

@override
String toString() => 'Assign';
}
3 changes: 0 additions & 3 deletions lib/src/piece/block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,4 @@ class BlockPiece extends Piece {
callback(contents);
callback(rightBracket);
}

@override
String toString() => 'Block';
}
3 changes: 0 additions & 3 deletions lib/src/piece/chain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,4 @@ class ChainPiece extends Piece {
void forEachChild(void Function(Piece piece) callback) {
_operations.forEach(callback);
}

@override
String toString() => 'Chain';
}
6 changes: 0 additions & 6 deletions lib/src/piece/clause.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ class ClausesPiece extends Piece {
void forEachChild(void Function(Piece piece) callback) {
_clauses.forEach(callback);
}

@override
String toString() => 'Clauses';
}

/// A keyword followed by a comma-separated list of items described by that
Expand Down Expand Up @@ -156,7 +153,4 @@ class ClausePiece extends Piece {
callback(_keyword);
_parts.forEach(callback);
}

@override
String toString() => 'Clause';
}
3 changes: 0 additions & 3 deletions lib/src/piece/do_while.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,4 @@ class DoWhilePiece extends Piece {
callback(_body);
callback(_condition);
}

@override
String toString() => 'DoWhile';
}
3 changes: 0 additions & 3 deletions lib/src/piece/for.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,4 @@ class ForPiece extends Piece {
callback(_forParts);
callback(_body);
}

@override
String toString() => 'For';
}
2 changes: 1 addition & 1 deletion lib/src/piece/function.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ class FunctionPiece extends Piece {
}

@override
String toString() => 'Fn';
String get debugName => 'Fn';
}
3 changes: 0 additions & 3 deletions lib/src/piece/if.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ class IfPiece extends Piece {
callback(section.statement);
}
}

@override
String toString() => 'If';
}

/// A single section in a chain of if-elses.
Expand Down
3 changes: 0 additions & 3 deletions lib/src/piece/infix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,4 @@ class InfixPiece extends Piece {
void forEachChild(void Function(Piece piece) callback) {
operands.forEach(callback);
}

@override
String toString() => 'Infix';
}
3 changes: 0 additions & 3 deletions lib/src/piece/list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ class ListPiece extends Piece {

if (_after case var after?) callback(after);
}

@override
String toString() => 'List';
}

/// An element in a [ListPiece].
Expand Down
8 changes: 8 additions & 0 deletions lib/src/piece/piece.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ abstract class Piece {
void pin(State state) {
_pinnedState = state;
}

/// The name of this piece as it appears in debug output.
///
/// By default, this is the class's name with `Piece` removed.
String get debugName => runtimeType.toString().replaceAll('Piece', '');

@override
String toString() => debugName;
}

/// A simple atomic piece of code.
Expand Down
3 changes: 0 additions & 3 deletions lib/src/piece/postfix.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,4 @@ class PostfixPiece extends Piece {
void forEachChild(void Function(Piece piece) callback) {
pieces.forEach(callback);
}

@override
String toString() => 'Post';
}
2 changes: 1 addition & 1 deletion lib/src/piece/sequence.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SequencePiece extends Piece {
}

@override
String toString() => 'Sequence';
String get debugName => 'Seq';
}

/// An element inside a [SequencePiece].
Expand Down
3 changes: 0 additions & 3 deletions lib/src/piece/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,4 @@ class TypePiece extends Piece {
if (_clauses case var clauses?) callback(clauses);
callback(_body);
}

@override
String toString() => 'Type';
}
2 changes: 1 addition & 1 deletion lib/src/piece/variable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@ class VariablePiece extends Piece {
}

@override
String toString() => 'Var';
String get debugName => 'Var';
}

0 comments on commit fd6ed34

Please sign in to comment.