Repository: ruby/prism
Pull request #1689 (2023-10-14 00:23:30)

Put names on back reference read nodes


Patch:
diff --git a/config.yml b/config.yml
index f299754d..6eaa6f13 100644
--- a/config.yml
+++ b/config.yml
@@ -507,6 +507,9 @@ nodes:
           { **foo }
             ^^^^^
   - name: BackReferenceReadNode
+    fields:
+      - name: name
+        type: constant
     comment: |
       Represents reading a reference to a field in the previous match.
 
diff --git a/src/prism.c b/src/prism.c
index da7611a6..b2484d6e 100644
--- a/src/prism.c
+++ b/src/prism.c
@@ -1180,7 +1180,8 @@ pm_back_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name)
         {
             .type = PM_BACK_REFERENCE_READ_NODE,
             .location = PM_LOCATION_TOKEN_VALUE(name),
-        }
+        },
+        .name = pm_parser_constant_id_token(parser, name)
     };
 
     return node;
@@ -2584,16 +2585,20 @@ pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *assoc
 
 // Retrieve the name from a node that will become a global variable write node.
 static pm_constant_id_t
-pm_global_variable_write_name(pm_parser_t *parser, pm_node_t *target) {
-    if (PM_NODE_TYPE_P(target, PM_GLOBAL_VARIABLE_READ_NODE)) {
-        return ((pm_global_variable_read_node_t *) target)->name;
+pm_global_variable_write_name(pm_parser_t *parser, const pm_node_t *target) {
+    switch (PM_NODE_TYPE(target)) {
+        case PM_GLOBAL_VARIABLE_READ_NODE:
+            return ((pm_global_variable_read_node_t *) target)->name;
+        case PM_BACK_REFERENCE_READ_NODE:
+            return ((pm_back_reference_read_node_t *) target)->name;
+        case PM_NUMBERED_REFERENCE_READ_NODE:
+            // This will only ever happen in the event of a syntax error, but we
+            // still need to provide something for the node.
+            return pm_parser_constant_id_location(parser, target->location.start, target->location.end);
+        default:
+            assert(false && "unreachable");
+            return (pm_constant_id_t) -1;
     }
-
-    assert(PM_NODE_TYPE_P(target, PM_BACK_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(target, PM_NUMBERED_REFERENCE_READ_NODE));
-
-    // This will only ever happen in the event of a syntax error, but we
-    // still need to provide something for the node.
-    return pm_parser_constant_id_location(parser, target->location.start, target->location.end);
 }
 
 // Allocate and initialize a new GlobalVariableAndWriteNode node.


Test patch:
diff --git a/test/prism/snapshots/alias.txt b/test/prism/snapshots/alias.txt
index 732c69b4..20914f3c 100644
--- a/test/prism/snapshots/alias.txt
+++ b/test/prism/snapshots/alias.txt
@@ -78,6 +78,7 @@
         │   │   └── name: :$a
         │   ├── old_name:
         │   │   @ BackReferenceReadNode (location: (9,9)-(9,11))
+        │   │   └── name: :$'
         │   └── keyword_loc: (9,0)-(9,5) = "alias"
         ├── @ AliasMethodNode (location: (11,0)-(11,13))
         │   ├── new_name:
diff --git a/test/prism/snapshots/global_variables.txt b/test/prism/snapshots/global_variables.txt
index bb2e7d53..cde964dd 100644
--- a/test/prism/snapshots/global_variables.txt
+++ b/test/prism/snapshots/global_variables.txt
@@ -24,9 +24,13 @@
         ├── @ GlobalVariableReadNode (location: (19,0)-(19,2))
         │   └── name: :$~
         ├── @ BackReferenceReadNode (location: (21,0)-(21,2))
+        │   └── name: :$&
         ├── @ BackReferenceReadNode (location: (23,0)-(23,2))
+        │   └── name: :$`
         ├── @ BackReferenceReadNode (location: (25,0)-(25,2))
+        │   └── name: :$'
         ├── @ BackReferenceReadNode (location: (27,0)-(27,2))
+        │   └── name: :$+
         ├── @ GlobalVariableReadNode (location: (29,0)-(29,2))
         │   └── name: :$:
         ├── @ GlobalVariableReadNode (location: (31,0)-(31,2))
diff --git a/test/prism/snapshots/method_calls.txt b/test/prism/snapshots/method_calls.txt
index 3cd12e52..40e10776 100644
--- a/test/prism/snapshots/method_calls.txt
+++ b/test/prism/snapshots/method_calls.txt
@@ -1342,6 +1342,7 @@
         │   │   │   @ StatementsNode (location: (95,10)-(95,12))
         │   │   │   └── body: (length: 1)
         │   │   │       └── @ BackReferenceReadNode (location: (95,10)-(95,12))
+        │   │   │           └── name: :$&
         │   │   ├── opening_loc: (95,8)-(95,9) = "{"
         │   │   └── closing_loc: (95,13)-(95,14) = "}"
         │   ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/alias_gvar_backref.txt b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
index 4ba04691..a2586423 100644
--- a/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
+++ b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt
@@ -9,4 +9,5 @@
             │   └── name: :$MATCH
             ├── old_name:
             │   @ BackReferenceReadNode (location: (1,13)-(1,15))
+            │   └── name: :$&
             └── keyword_loc: (1,0)-(1,5) = "alias"
diff --git a/test/prism/snapshots/unparser/corpus/literal/variables.txt b/test/prism/snapshots/unparser/corpus/literal/variables.txt
index a4a67f16..b86865a0 100644
--- a/test/prism/snapshots/unparser/corpus/literal/variables.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/variables.txt
@@ -22,6 +22,7 @@
         ├── @ NumberedReferenceReadNode (location: (5,0)-(5,2))
         │   └── number: 1
         ├── @ BackReferenceReadNode (location: (6,0)-(6,2))
+        │   └── name: :$`
         ├── @ ConstantReadNode (location: (7,0)-(7,5))
         │   └── name: :CONST
         ├── @ ConstantPathNode (location: (8,0)-(8,13))
diff --git a/test/prism/snapshots/whitequark/alias_gvar.txt b/test/prism/snapshots/whitequark/alias_gvar.txt
index 56357fa1..d13f8165 100644
--- a/test/prism/snapshots/whitequark/alias_gvar.txt
+++ b/test/prism/snapshots/whitequark/alias_gvar.txt
@@ -9,6 +9,7 @@
         │   │   └── name: :$a
         │   ├── old_name:
         │   │   @ BackReferenceReadNode (location: (1,9)-(1,11))
+        │   │   └── name: :$+
         │   └── keyword_loc: (1,0)-(1,5) = "alias"
         └── @ AliasGlobalVariableNode (location: (3,0)-(3,11))
             ├── new_name:
diff --git a/test/prism/snapshots/whitequark/back_ref.txt b/test/prism/snapshots/whitequark/back_ref.txt
index eafd6f14..ea6b76fa 100644
--- a/test/prism/snapshots/whitequark/back_ref.txt
+++ b/test/prism/snapshots/whitequark/back_ref.txt
@@ -4,3 +4,4 @@
     @ StatementsNode (location: (1,0)-(1,2))
     └── body: (length: 1)
         └── @ BackReferenceReadNode (location: (1,0)-(1,2))
+            └── name: :$+