Skip to content

Commit a0a0e9e

Browse files
committed
yeast: Add test for chained rules with output-only kinds
Adds a regression test verifying that desugaring rules can chain across output-only node kinds: a first rule rewrites an input kind to an output-only kind, and a second rule then rewrites that output-only kind into another output-only kind. This exercises the schema lookup for query patterns whose root kind is not present in the input tree-sitter grammar.
1 parent 60dcf88 commit a0a0e9e

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

shared/yeast/tests/node-types.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
named:
66
program:
7-
stmt*: [assignment, call, identifier, for]
7+
stmt*: [assignment, call, identifier, for, first_node, second_node]
88

99
assignment:
1010
left: [identifier, left_assignment_list]
@@ -50,6 +50,16 @@ named:
5050
identifier:
5151
integer:
5252

53+
# Output-only kinds, used by tests of chained desugaring rules.
54+
# Neither exists in the input tree-sitter-ruby grammar.
55+
first_node:
56+
left: [identifier, integer]
57+
right: [identifier, integer]
58+
59+
second_node:
60+
left: [identifier, integer]
61+
right: [identifier, integer]
62+
5363
unnamed:
5464
- "="
5565
- ","

shared/yeast/tests/test.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,41 @@ fn test_shorthand_rule() {
347347
);
348348
}
349349

350+
#[test]
351+
fn test_chained_rules_output_only_kind() {
352+
// Exercise rule chaining where an intermediate kind exists only in the
353+
// output schema (not in the input tree-sitter grammar):
354+
// assignment → first_node (input → output-only)
355+
// first_node → second_node (output-only → output-only)
356+
// The matcher must look up `first_node` against the schema, which only
357+
// knows about it via the YAML node-types file.
358+
let assignment_to_first = yeast::rule!(
359+
(assignment
360+
left: (_) @left
361+
right: (_) @right
362+
)
363+
=> first_node
364+
);
365+
let first_to_second = yeast::rule!(
366+
(first_node
367+
left: (_) @left
368+
right: (_) @right
369+
)
370+
=> second_node
371+
);
372+
373+
let dump = run_and_dump("x = 1", vec![assignment_to_first, first_to_second]);
374+
assert_dump_eq(
375+
&dump,
376+
r#"
377+
program
378+
second_node
379+
left: identifier "x"
380+
right: integer "1"
381+
"#,
382+
);
383+
}
384+
350385
// ---- Cursor tests ----
351386

352387
#[test]

0 commit comments

Comments
 (0)