Skip to content

Commit

Permalink
Add withTokenPreviousNext to AST printer.
Browse files Browse the repository at this point in the history
Bug: #56355
Change-Id: I0cd58070853cfe0fa59788b3ed4586fc156e27d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388054
Reviewed-by: Brian Wilkerson <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
scheglov authored and Commit Queue committed Oct 3, 2024
1 parent a409a1c commit c87b93c
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 4 deletions.
71 changes: 71 additions & 0 deletions pkg/analyzer/test/src/dart/parser/top_level_function_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,77 @@ FunctionDeclaration
''');
}

test_recovery_body_issue56355() {
// https://github.com/dart-lang/sdk/issues/56355
var parseResult = parseStringWithErrors(r'''
void get() {
http.Response response = http
}
''');

// Note, there is a cycle that should not be there.
var node = parseResult.findNode.singleFunctionDeclaration;
assertParsedNodeText(
node,
withTokenPreviousNext: true,
withOffsets: true,
r'''
FunctionDeclaration
returnType: NamedType
name: T0 void @0
next: T1 |get|
name: T1 get @5
previous: T0 |void|
next: T2 |(|
functionExpression: FunctionExpression
parameters: FormalParameterList
leftParenthesis: T2 ( @8
previous: T1 |get|
next: T3 |)|
rightParenthesis: T3 ) @9
previous: T2 |(|
next: T4 |{|
body: BlockFunctionBody
block: Block
leftBracket: T4 { @11
previous: T3 |)|
next: T5 |http|
statements
ExpressionStatement
expression: PrefixedIdentifier
prefix: SimpleIdentifier
token: T5 http @15
previous: T4 |{|
next: T6 |.|
period: T6 . @19
previous: T5 |http|
next: T7 |Response|
identifier: SimpleIdentifier
token: T7 Response @20
previous: T6 |.|
next: T8 |response|
semicolon: T9 ; @45 <synthetic>
previousX: T10 http @40
previousX: T11 = @38
previous: T8 |response|
next: T10 |http|
next: T9 |;|
next: T8 |response|
ExpressionStatement
expression: SimpleIdentifier
token: T8 response @29
previous: T9 |;|
next: T12 |;|
semicolon: T12 ; @45 <synthetic>
previous: T8 |response|
next: T13 |}|
rightBracket: T13 } @45
previous: T12 |;|
next: T14 ||
''',
);
}

test_setter_augment() {
var parseResult = parseStringWithErrors(r'''
augment set foo(int _) {}
Expand Down
6 changes: 5 additions & 1 deletion pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ class ParserDiagnosticsTest {
String expected, {
bool withCheckingLinking = false,
bool withOffsets = false,
bool withTokenPreviousNext = false,
}) {
var actual = _parsedNodeText(
node,
withCheckingLinking: withCheckingLinking,
withOffsets: withOffsets,
withTokenPreviousNext: withTokenPreviousNext,
);
if (actual != expected) {
print(actual);
Expand Down Expand Up @@ -68,6 +70,7 @@ class ParserDiagnosticsTest {
AstNode node, {
required bool withCheckingLinking,
required bool withOffsets,
required bool withTokenPreviousNext,
}) {
var buffer = StringBuffer();
var sink = TreeStringSink(
Expand All @@ -83,7 +86,8 @@ class ParserDiagnosticsTest {
sink: sink,
elementPrinter: elementPrinter,
configuration: ResolvedNodeTextConfiguration()
..withCheckingLinking = withCheckingLinking,
..withCheckingLinking = withCheckingLinking
..withTokenPreviousNext = withTokenPreviousNext,
withResolution: false,
withOffsets: withOffsets,
),
Expand Down
51 changes: 48 additions & 3 deletions pkg/analyzer/test/src/summary/resolved_ast_printer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
/// If `true`, resolution should be printed.
final bool _withResolution;

final Map<Token, String> _tokenIdMap = Map.identity();

ResolvedAstPrinter({
required TreeStringSink sink,
required ElementPrinter elementPrinter,
Expand Down Expand Up @@ -1758,6 +1760,13 @@ Expected parent: (${parent.runtimeType}) $parent
}
}

String _getTokenId(Token? token) {
if (token == null) {
return '<null>';
}
return _tokenIdMap[token] ??= 'T${_tokenIdMap.length}';
}

void _writeDeclaredElement(Element? element) {
if (_withResolution) {
if (element is LocalVariableElement) {
Expand Down Expand Up @@ -1973,16 +1982,49 @@ Expected parent: (${parent.runtimeType}) $parent
}

void _writeToken(String name, Token? token) {
if (token != null) {
_sink.writeWithIndent('$name: ');
if (token == null) {
return;
}

_sink.writeIndentedLine(() {
_sink.write('$name: ');
if (configuration.withTokenPreviousNext) {
_sink.write(_getTokenId(token));
_sink.write(' ');
}
_sink.write(token.lexeme.ifNotEmptyOrElse('<empty>'));
if (_withOffsets) {
_sink.write(' @${token.offset}');
}
if (token.isSynthetic) {
_sink.write(' <synthetic>');
}
_sink.writeln();
});

if (configuration.withTokenPreviousNext) {
_sink.withIndent(() {
if (token.previous case var previous?) {
if (!previous.isEof) {
if (_tokenIdMap[previous] == null) {
_writeToken('previousX', previous);
} else {
_sink.writelnWithIndent(
'previous: ${_getTokenId(previous)} |${previous.lexeme}|',
);
}
}
} else {
_sink.writelnWithIndent('previous: <null>');
}

if (token.next case var next?) {
_sink.writelnWithIndent(
'next: ${_getTokenId(next)} |${next.lexeme}|',
);
} else {
_sink.writelnWithIndent('next: <null>');
}
});
}
}

Expand Down Expand Up @@ -2089,4 +2131,7 @@ class ResolvedNodeTextConfiguration {
/// If `true`, `redirectedConstructor` properties of [ConstructorElement]s
/// should be printer.
bool withRedirectedConstructors = false;

/// If `true`, print IDs of each token, `previous` and `next` tokens.
bool withTokenPreviousNext = false;
}

0 comments on commit c87b93c

Please sign in to comment.