File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -259,6 +259,7 @@ fn parse_query_list(tokens: &mut Tokens) -> Result<Vec<TokenStream>> {
259259 yeast:: query:: QueryListElem :: SingleNode ( #node)
260260 } ,
261261 ) ?;
262+ let elem = maybe_wrap_list_capture ( tokens, elem) ?;
262263 elems. push ( elem) ;
263264 continue ;
264265 }
@@ -276,6 +277,7 @@ fn parse_query_list(tokens: &mut Tokens) -> Result<Vec<TokenStream>> {
276277 yeast:: query:: QueryListElem :: SingleNode ( #node)
277278 } ,
278279 ) ?;
280+ let elem = maybe_wrap_list_capture ( tokens, elem) ?;
279281 elems. push ( elem) ;
280282 continue ;
281283 }
@@ -717,8 +719,11 @@ fn extract_captures_inner(
717719 }
718720 last_mult = CaptureMultiplicity :: Single ;
719721 }
720- TokenTree :: Punct ( p) if matches ! ( p. as_char( ) , '*' | '+' | '?' ) => {
721- // Keep last_mult — the @capture follows
722+ TokenTree :: Punct ( p) if p. as_char ( ) == '*' || p. as_char ( ) == '+' => {
723+ last_mult = CaptureMultiplicity :: Repeated ;
724+ }
725+ TokenTree :: Punct ( p) if p. as_char ( ) == '?' => {
726+ last_mult = CaptureMultiplicity :: Optional ;
722727 }
723728 _ => {
724729 last_mult = CaptureMultiplicity :: Single ;
Original file line number Diff line number Diff line change @@ -825,14 +825,6 @@ fn apply_one_shot_rules_inner(
825825
826826 let node_kind = ast. get_node ( id) . map ( |n| n. kind ( ) ) . unwrap_or ( "" ) ;
827827
828- // Don't rewrite unnamed nodes (punctuation, keywords, etc.); leave them
829- // as-is. Rules target named nodes only.
830- if let Some ( node) = ast. get_node ( id) {
831- if !node. is_named ( ) {
832- return Ok ( vec ! [ id] ) ;
833- }
834- }
835-
836828 for rule in index. rules_for_kind ( node_kind) {
837829 if let Some ( mut captures) = rule. try_match ( ast, id) ? {
838830 // Recursively translate every captured node before invoking the
Original file line number Diff line number Diff line change @@ -389,6 +389,29 @@ fn test_capture_unnamed_node_parenthesized() {
389389 assert ! ( !op_node. is_named( ) ) ;
390390}
391391
392+ #[ test]
393+ fn test_capture_bare_underscore_repeated ( ) {
394+ // `_` matches named and unnamed nodes in bare-child position. On this
395+ // assignment shape, bare children correspond to unnamed tokens (the `=`).
396+ let runner = Runner :: new ( tree_sitter_ruby:: LANGUAGE . into ( ) , & [ ] ) ;
397+ let ast = runner. run ( "x = 1" ) . unwrap ( ) ;
398+
399+ let query = yeast:: query!( ( assignment _* @all) ) ;
400+
401+ let mut cursor = AstCursor :: new ( & ast) ;
402+ cursor. goto_first_child ( ) ;
403+ let assignment_id = cursor. node_id ( ) ;
404+
405+ let mut captures = yeast:: captures:: Captures :: new ( ) ;
406+ let matched = query. do_match ( & ast, assignment_id, & mut captures) . unwrap ( ) ;
407+ assert ! ( matched) ;
408+
409+ let all = captures. get_all ( "all" ) ;
410+ assert_eq ! ( all. len( ) , 1 ) ;
411+ assert_eq ! ( ast. get_node( all[ 0 ] ) . unwrap( ) . kind( ) , "=" ) ;
412+ assert ! ( !ast. get_node( all[ 0 ] ) . unwrap( ) . is_named( ) ) ;
413+ }
414+
392415#[ test]
393416fn test_capture_unnamed_node_bare_literal ( ) {
394417 // `"=" @op` (without surrounding parens) is the same as `("=") @op`.
You can’t perform that action at this time.
0 commit comments