macro_rules! assert_parse_tree {
($src:expr, $($tree:tt)+) => { ... };
(@seq $parser:ident, Warn ( $code:expr ) $($rest:tt)*) => { ... };
(@seq $parser:ident, Error ( $code:expr ) $($rest:tt)*) => { ... };
(@seq $parser:ident, $kind:ident [ $($children:tt)+ ] $($rest:tt)*) => { ... };
(@seq $parser:ident, $kind:ident ( $text:expr ) $($rest:tt)*) => { ... };
(@seq $parser:ident, $kind:ident $($rest:tt)*) => { ... };
(@seq $parser:ident, ...) => { ... };
(@seq $parser:ident,) => { ... };
}Expand description
Macro to assert the structure and content of the parsed syntax tree from source code.
§Purpose
assert_parse_tree! allows you to declaratively specify the expected abstract syntax tree (AST)
shape and tokens produced by your parser for a given source code snippet. It recursively
matches nodes by their kinds (SyntaxKind) and token text, verifying both the hierarchical
structure and token lexemes precisely.
This macro is primarily useful in parser/unit tests where you want to:
- Assert nodes and their nested children are present in expected order.
- Assert leaf tokens have expected text content.
- Assert presence of parser errors and warnings at specific nodes.
§Syntax Overview
ⓘ
assert_parse_tree!(
"source code string",
RootNodeKind [ // Node with children
ChildNodeKind1 ( "token_text" ) // Leaf node with exact text
ChildNodeKind2 [ // Nested node with children
...
]
Warn(WARNING_CODE) // Warning node with an error code enum or const
Error(ERROR_CODE) // Error node with an error code enum or const
... // Ellipsis to skip remaining children in this subtree
]
);- Root node: The first argument is the source code string to parse.
- Nodes with children: Use
KindName [ ... ]whereKindNameis a variant of yourSyntaxKindenum. - Leaf tokens: Use
KindName("token_text")where the string is the exact matched source token text. - Warnings and errors: Use
Warn(WARNING_CODE)andError(ERROR_CODE)where the code is a known error/warning enum or constant. - Ellipsis (
...): Use to ignore remaining children in a node subtree (useful to reduce test verbosity).
§Notes
KindNamemust be a variant of yourSyntaxKindenum (without theSyntaxKind::prefix).- Leaf nodes must specify the exact token text as a string literal.
WarnandErrorare reserved special nodes recognized by the macro for diagnostics.- The macro performs strict ordering checks: children must appear in exact order as specified.
§Example: Simple function call
compose_syntax::test_utils::assert_parse_tree!(
"f(a, b: c)",
FuncCall [
Ident("f")
Args [
LeftParen("(")
Ident("a")
Comma(",")
Named [ Ident("b") Colon(":") Ident("c") ]
RightParen(")")
]
]
);§Example: Error recovery with warnings and errors
compose_syntax::test_utils::assert_parse_tree!(
r#"
f(a, b, c
1 + 2
"#,
FuncCall [
Ident("f")
Args [
Error(compose_error_codes::E0001_UNCLOSED_DELIMITER)
Ident("a")
Comma(",")
Ident("b")
Comma(",")
Ident("c")
Error(compose_error_codes::E0009_ARGS_MISSING_COMMAS)
Binary [
Int("1")
Plus("+")
Int("2")
]
]
]
);§Example: Skipping subtree content
compose_syntax::test_utils::assert_parse_tree!(
"{ ref mut a => a }",
Lambda [
LeftBrace("{")
Params [
Param [
Ref("ref")
Mut("mut")
Ident("a")
]
]
...
]
);§Common mistakes
- Forgetting to provide the exact token text string for leaf nodes results in a compile error.
- Using
WarnorErrorasSyntaxKindvariants inside children nodes causes errors; they must use the special macro arms.
§See also
SyntaxKindenum variants — the node/kind names used in this macro.- Parser error codes for
WarnandErrornodes. NodesTesterstruct for underlying test traversal and assertions.