Repository: ruby/yarp
Pull request #1325 (2023-08-25 01:23:26)

Add names to classes and modules
This should hopefully make it easier to compile these nodes, and also for static analysis tools for having a quick label.

As a bonus, this also fixed a bug we had where we weren't erroring on `class foo; end`.


Patch:
diff --git a/config.yml b/config.yml
index e4987013..3662c176 100644
--- a/config.yml
+++ b/config.yml
@@ -731,6 +731,8 @@ nodes:
         type: node?
       - name: end_keyword_loc
         type: location
+      - name: name
+        type: string
     comment: |
       Represents a class declaration involving the `class` keyword.
 
@@ -1318,6 +1320,8 @@ nodes:
         type: node?
       - name: end_keyword_loc
         type: location
+      - name: name
+        type: string
     comment: |
       Represents a module declaration involving the `module` keyword.
 
diff --git a/src/yarp.c b/src/yarp.c
index 4de3338d..f6fa4b13 100644
--- a/src/yarp.c
+++ b/src/yarp.c
@@ -1553,7 +1553,7 @@ yp_case_node_end_keyword_loc_set(yp_case_node_t *node, const yp_token_t *end_key
 
 // Allocate a new ClassNode node.
 static yp_class_node_t *
-yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *body, const yp_token_t *end_keyword) {
+yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *name, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *body, const yp_token_t *end_keyword) {
     yp_class_node_t *node = YP_ALLOC_NODE(parser, yp_class_node_t);
 
     *node = (yp_class_node_t) {
@@ -1567,9 +1567,11 @@ yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const y
         .inheritance_operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(inheritance_operator),
         .superclass = superclass,
         .body = body,
-        .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword)
+        .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword),
+        .name = YP_EMPTY_STRING
     };
 
+    yp_string_shared_init(&node->name, name->start, name->end);
     return node;
 }
 
@@ -2746,7 +2748,7 @@ yp_match_required_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t *
 
 // Allocate a new ModuleNode node.
 static yp_module_node_t *
-yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, yp_node_t *body, const yp_token_t *end_keyword) {
+yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, const yp_token_t *name, yp_node_t *body, const yp_token_t *end_keyword) {
     yp_module_node_t *node = YP_ALLOC_NODE(parser, yp_module_node_t);
 
     *node = (yp_module_node_t) {
@@ -2761,9 +2763,11 @@ yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const
         .module_keyword_loc = YP_LOCATION_TOKEN_VALUE(module_keyword),
         .constant_path = constant_path,
         .body = body,
-        .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword)
+        .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword),
+        .name = YP_EMPTY_STRING
     };
 
+    yp_string_shared_init(&node->name, name->start, name->end);
     return node;
 }
 
@@ -10851,7 +10855,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
                 return (yp_node_t *) yp_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous);
             }
 
-            yp_node_t *name = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a class name after `class`.");
+            yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a class name after `class`.");
+            yp_token_t name = parser->previous;
+            if (name.type != YP_TOKEN_CONSTANT) {
+                yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected a constant name after `class`.");
+            }
+
             yp_token_t inheritance_operator;
             yp_node_t *superclass;
 
@@ -10892,7 +10901,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
             yp_constant_id_list_t locals = parser->current_scope->locals;
             yp_parser_scope_pop(parser);
             yp_do_loop_stack_pop(parser);
-            return (yp_node_t *) yp_class_node_create(parser, &locals, &class_keyword, name, &inheritance_operator, superclass, statements, &parser->previous);
+            return (yp_node_t *) yp_class_node_create(parser, &locals, &class_keyword, constant_path, &name, &inheritance_operator, superclass, statements, &parser->previous);
         }
         case YP_TOKEN_KEYWORD_DEF: {
             yp_token_t def_keyword = parser->current;
@@ -11286,13 +11295,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
             parser_lex(parser);
 
             yp_token_t module_keyword = parser->previous;
-            yp_node_t *name = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a module name after `module`.");
+            yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a module name after `module`.");
+            yp_token_t name;
 
-            // If we can recover from a syntax error that occurred while parsing the
-            // name of the module, then we'll handle that here.
-            if (YP_NODE_TYPE_P(name, YP_NODE_MISSING_NODE)) {
-                yp_token_t end_keyword = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
-                return (yp_node_t *) yp_module_node_create(parser, NULL, &module_keyword, name, NULL, &end_keyword);
+            // If we can recover from a syntax error that occurred while parsing
+            // the name of the module, then we'll handle that here.
+            if (YP_NODE_TYPE_P(constant_path, YP_NODE_MISSING_NODE)) {
+                yp_token_t missing = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end };
+                return (yp_node_t *) yp_module_node_create(parser, NULL, &module_keyword, constant_path, &missing, NULL, &missing);
             }
 
             while (accept(parser, YP_TOKEN_COLON_COLON)) {
@@ -11301,7 +11311,15 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
                 expect(parser, YP_TOKEN_CONSTANT, "Expected to find a module name after `::`.");
                 yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous);
 
-                name = (yp_node_t *)yp_constant_path_node_create(parser, name, &double_colon, constant);
+                constant_path = (yp_node_t *) yp_constant_path_node_create(parser, constant_path, &double_colon, constant);
+            }
+
+            // Here we retrieve the name of the module. If it wasn't a constant,
+            // then it's possible that `module foo` was passed, which is a
+            // syntax error. We handle that here as well.
+            name = parser->previous;
+            if (name.type != YP_TOKEN_CONSTANT) {
+                yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected to find a module name after `module`.");
             }
 
             yp_parser_scope_push(parser, true);
@@ -11328,7 +11346,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
                 yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, "Module definition in method body");
             }
 
-            return (yp_node_t *) yp_module_node_create(parser, &locals, &module_keyword, name, statements, &parser->previous);
+            return (yp_node_t *) yp_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous);
         }
         case YP_TOKEN_KEYWORD_NIL:
             parser_lex(parser);


Test patch:
diff --git a/test/errors_test.rb b/test/errors_test.rb
index 6ac2dcbc..80b9f162 100644
--- a/test/errors_test.rb
+++ b/test/errors_test.rb
@@ -18,9 +18,10 @@ class ErrorsTest < Test::Unit::TestCase
       Location(),
       ConstantReadNode(),
       StatementsNode(
-        [ModuleNode([], Location(), MissingNode(), nil, Location())]
+        [ModuleNode([], Location(), MissingNode(), nil, Location(), "")]
       ),
-      Location()
+      Location(),
+      "Parent"
     )
 
     assert_errors expected, "module Parent module end", [
@@ -383,7 +384,7 @@ class ErrorsTest < Test::Unit::TestCase
       Location(),
       nil,
       nil,
-      StatementsNode([ModuleNode([], Location(), ConstantReadNode(), nil, Location())]),
+      StatementsNode([ModuleNode([], Location(), ConstantReadNode(), nil, Location(), "A")]),
       [],
       Location(),
       nil,
@@ -414,7 +415,7 @@ class ErrorsTest < Test::Unit::TestCase
            BlockNode(
              [],
              nil,
-             StatementsNode([ModuleNode([], Location(), ConstantReadNode(), nil, Location())]),
+             StatementsNode([ModuleNode([], Location(), ConstantReadNode(), nil, Location(), "Foo")]),
              Location(),
              Location()
            ),
@@ -455,7 +456,8 @@ class ErrorsTest < Test::Unit::TestCase
            nil,
            nil,
            nil,
-           Location()
+           Location(),
+           "A"
          )]
       ),
       [],
@@ -955,7 +957,8 @@ class ErrorsTest < Test::Unit::TestCase
       nil,
       nil,
       StatementsNode([ReturnNode(Location(), nil)]),
-      Location()
+      Location(),
+      "A"
     )
 
     assert_errors expected, "class A; return; end", [
@@ -969,7 +972,8 @@ class ErrorsTest < Test::Unit::TestCase
       Location(),
       ConstantReadNode(),
       StatementsNode([ReturnNode(Location(), nil)]),
-      Location()
+      Location(),
+      "A"
     )
 
     assert_errors expected, "module A; return; end", [
diff --git a/test/snapshots/classes.txt b/test/snapshots/classes.txt
index 60ab0ead..33b3d042 100644
--- a/test/snapshots/classes.txt
+++ b/test/snapshots/classes.txt
@@ -16,7 +16,8 @@ ProgramNode(0...370)(
             (10...11)
           )]
        ),
-       (14...17)
+       (14...17),
+       "A"
      ),
      ClassNode(19...39)(
        [],
@@ -32,7 +33,8 @@ ProgramNode(0...370)(
          EnsureNode(28...39)((28...34), nil, (36...39)),
          (36...39)
        ),
-       (36...39)
+       (36...39),
+       "A"
      ),
      ClassNode(41...75)(
        [],
@@ -48,7 +50,8 @@ ProgramNode(0...370)(
          EnsureNode(64...75)((64...70), nil, (72...75)),
          (72...75)
        ),
-       (72...75)
+       (72...75),
+       "A"
      ),
      ClassNode(77...98)(
        [:a],
@@ -65,7 +68,8 @@ ProgramNode(0...370)(
             (91...92)
           )]
        ),
-       (95...98)
+       (95...98),
+       "A"
      ),
      SingletonClassNode(100...120)(
        [],
@@ -118,7 +122,8 @@ ProgramNode(0...370)(
             (154...157)
           )]
        ),
-       (159...162)
+       (159...162),
+       "A"
      ),
      ClassNode(164...218)(
        [],
@@ -143,7 +148,8 @@ ProgramNode(0...370)(
             (210...213)
           )]
        ),
-       (215...218)
+       (215...218),
+       "A"
      ),
      SingletonClassNode(220...240)(
        [],
@@ -274,7 +280,8 @@ ProgramNode(0...370)(
          "[]"
        ),
        nil,
-       (367...370)
+       (367...370),
+       "A"
      )]
   )
 )
diff --git a/test/snapshots/method_calls.txt b/test/snapshots/method_calls.txt
index f59fb7e4..b2c84d0d 100644
--- a/test/snapshots/method_calls.txt
+++ b/test/snapshots/method_calls.txt
@@ -1191,7 +1191,8 @@ ProgramNode(0...1237)(
                  "baz"
                )]
             ),
-            (926...929)
+            (926...929),
+            "Bar"
           )]
        ),
        nil,
@@ -1222,7 +1223,8 @@ ProgramNode(0...1237)(
                  "baz"
                )]
             ),
-            (957...960)
+            (957...960),
+            "Bar"
           )]
        ),
        nil,
diff --git a/test/snapshots/modules.txt b/test/snapshots/modules.txt
index 705563a9..a3cf30b9 100644
--- a/test/snapshots/modules.txt
+++ b/test/snapshots/modules.txt
@@ -14,7 +14,8 @@ ProgramNode(0...140)(
             (11...12)
           )]
        ),
-       (15...18)
+       (15...18),
+       "A"
      ),
      InterpolatedStringNode(20...38)(
        (20...23),
@@ -48,7 +49,8 @@ ProgramNode(0...140)(
          (48...50)
        ),
        nil,
-       (52...55)
+       (52...55),
+       "M"
      ),
      ModuleNode(57...85)(
        [:x],
@@ -70,14 +72,16 @@ ProgramNode(0...140)(
          nil,
          (82...85)
        ),
-       (82...85)
+       (82...85),
+       "A"
      ),
      ModuleNode(87...101)(
        [],
        (87...93),
        ConstantPathNode(94...97)(nil, ConstantReadNode(96...97)(), (94...96)),
        nil,
-       (98...101)
+       (98...101),
+       "A"
      ),
      ModuleNode(103...120)(
        [],
@@ -98,7 +102,8 @@ ProgramNode(0...140)(
          (113...115)
        ),
        nil,
-       (117...120)
+       (117...120),
+       "B"
      ),
      ModuleNode(122...140)(
        [],
@@ -119,7 +124,8 @@ ProgramNode(0...140)(
          (133...135)
        ),
        nil,
-       (137...140)
+       (137...140),
+       "B"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/TestRubyParserShared.txt b/test/snapshots/seattlerb/TestRubyParserShared.txt
index cfad7e8a..0eee2a39 100644
--- a/test/snapshots/seattlerb/TestRubyParserShared.txt
+++ b/test/snapshots/seattlerb/TestRubyParserShared.txt
@@ -86,7 +86,8 @@ ProgramNode(0...689)(
             (243...246)
           )]
        ),
-       (266...269)
+       (266...269),
+       "X"
      ),
      ClassNode(293...376)(
        [],
@@ -108,10 +109,12 @@ ProgramNode(0...689)(
                  (339...340)
                )]
             ),
-            (355...358)
+            (355...358),
+            "Y"
           )]
        ),
-       (373...376)
+       (373...376),
+       "X"
      ),
      ClassNode(395...498)(
        [],
@@ -157,7 +160,8 @@ ProgramNode(0...689)(
             (477...480)
           )]
        ),
-       (495...498)
+       (495...498),
+       "X"
      ),
      ModuleNode(517...565)(
        [],
@@ -175,7 +179,8 @@ ProgramNode(0...689)(
             (530...531)
           )]
        ),
-       (562...565)
+       (562...565),
+       "X"
      ),
      ModuleNode(568...651)(
        [],
@@ -193,10 +198,12 @@ ProgramNode(0...689)(
                  (614...615)
                )]
             ),
-            (630...633)
+            (630...633),
+            "Y"
           )]
        ),
-       (648...651)
+       (648...651),
+       "X"
      ),
      CallNode(670...689)(
        nil,
diff --git a/test/snapshots/seattlerb/class_comments.txt b/test/snapshots/seattlerb/class_comments.txt
index 12b347ee..b96c5d63 100644
--- a/test/snapshots/seattlerb/class_comments.txt
+++ b/test/snapshots/seattlerb/class_comments.txt
@@ -22,7 +22,8 @@ ProgramNode(19...71)(
             (64...67)
           )]
        ),
-       (68...71)
+       (68...71),
+       "X"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/snapshots/seattlerb/defn_oneliner_eq2.txt
index 30aaf719..d5798209 100644
--- a/test/snapshots/seattlerb/defn_oneliner_eq2.txt
+++ b/test/snapshots/seattlerb/defn_oneliner_eq2.txt
@@ -30,7 +30,8 @@ ProgramNode(0...28)(
             nil
           )]
        ),
-       (25...28)
+       (25...28),
+       "X"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/snapshots/seattlerb/defs_oneliner_eq2.txt
index 8a4f9e90..2ec8dc86 100644
--- a/test/snapshots/seattlerb/defs_oneliner_eq2.txt
+++ b/test/snapshots/seattlerb/defs_oneliner_eq2.txt
@@ -30,7 +30,8 @@ ProgramNode(0...33)(
             nil
           )]
        ),
-       (30...33)
+       (30...33),
+       "X"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/magic_encoding_comment.txt b/test/snapshots/seattlerb/magic_encoding_comment.txt
index 2ab320ed..08c8d9ea 100644
--- a/test/snapshots/seattlerb/magic_encoding_comment.txt
+++ b/test/snapshots/seattlerb/magic_encoding_comment.txt
@@ -30,7 +30,8 @@ ProgramNode(18...90)(
             (83...86)
           )]
        ),
-       (87...90)
+       (87...90),
+       "ExampleUTF8ClassNameVarietà"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/module_comments.txt b/test/snapshots/seattlerb/module_comments.txt
index 808f4799..4f399904 100644
--- a/test/snapshots/seattlerb/module_comments.txt
+++ b/test/snapshots/seattlerb/module_comments.txt
@@ -20,7 +20,8 @@ ProgramNode(24...77)(
             (70...73)
           )]
        ),
-       (74...77)
+       (74...77),
+       "X"
      )]
   )
 )
diff --git a/test/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt b/test/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
index 4f7ae811..4445e447 100644
--- a/test/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
+++ b/test/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt
@@ -18,7 +18,8 @@ ProgramNode(0...48)(
        nil,
        nil,
        nil,
-       (45...48)
+       (45...48),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/unparser/corpus/literal/class.txt b/test/snapshots/unparser/corpus/literal/class.txt
index 96b50c7a..aa457618 100644
--- a/test/snapshots/unparser/corpus/literal/class.txt
+++ b/test/snapshots/unparser/corpus/literal/class.txt
@@ -8,7 +8,8 @@ ProgramNode(0...213)(
        nil,
        nil,
        nil,
-       (8...11)
+       (8...11),
+       "A"
      ),
      SingletonClassNode(13...27)(
        [],
@@ -39,7 +40,8 @@ ProgramNode(0...213)(
        nil,
        nil,
        nil,
-       (60...63)
+       (60...63),
+       "B"
      ),
      ClassNode(65...82)(
        [],
@@ -56,7 +58,8 @@ ProgramNode(0...213)(
        nil,
        nil,
        nil,
-       (79...82)
+       (79...82),
+       "C"
      ),
      ClassNode(84...99)(
        [],
@@ -65,7 +68,8 @@ ProgramNode(0...213)(
        (92...93),
        ConstantReadNode(94...95)(),
        nil,
-       (96...99)
+       (96...99),
+       "A"
      ),
      ClassNode(101...119)(
        [],
@@ -78,7 +82,8 @@ ProgramNode(0...213)(
          (112...114)
        ),
        nil,
-       (116...119)
+       (116...119),
+       "A"
      ),
      ClassNode(121...142)(
        [],
@@ -95,7 +100,8 @@ ProgramNode(0...213)(
          (135...137)
        ),
        nil,
-       (139...142)
+       (139...142),
+       "B"
      ),
      ClassNode(144...198)(
        [],
@@ -143,7 +149,8 @@ ProgramNode(0...213)(
             (191...194)
           )]
        ),
-       (195...198)
+       (195...198),
+       "A"
      ),
      ClassNode(200...213)(
        [],
@@ -156,7 +163,8 @@ ProgramNode(0...213)(
        nil,
        nil,
        nil,
-       (210...213)
+       (210...213),
+       "A"
      )]
   )
 )
diff --git a/test/snapshots/unparser/corpus/literal/if.txt b/test/snapshots/unparser/corpus/literal/if.txt
index 8375e9ac..1bfbe7e2 100644
--- a/test/snapshots/unparser/corpus/literal/if.txt
+++ b/test/snapshots/unparser/corpus/literal/if.txt
@@ -80,7 +80,8 @@ ProgramNode(0...246)(
             nil
           )]
        ),
-       (130...133)
+       (130...133),
+       "A"
      ),
      ModuleNode(135...170)(
        [:foo],
@@ -113,7 +114,8 @@ ProgramNode(0...246)(
             nil
           )]
        ),
-       (167...170)
+       (167...170),
+       "B"
      ),
      UnlessNode(171...197)(
        (171...177),
diff --git a/test/snapshots/unparser/corpus/literal/module.txt b/test/snapshots/unparser/corpus/literal/module.txt
index c917fedd..4c805d3d 100644
--- a/test/snapshots/unparser/corpus/literal/module.txt
+++ b/test/snapshots/unparser/corpus/literal/module.txt
@@ -1,7 +1,14 @@
 ProgramNode(0...106)(
   [],
   StatementsNode(0...106)(
-    [ModuleNode(0...12)([], (0...6), ConstantReadNode(7...8)(), nil, (9...12)),
+    [ModuleNode(0...12)(
+       [],
+       (0...6),
+       ConstantReadNode(7...8)(),
+       nil,
+       (9...12),
+       "A"
+     ),
      ModuleNode(14...29)(
        [],
        (14...20),
@@ -11,7 +18,8 @@ ProgramNode(0...106)(
          (22...24)
        ),
        nil,
-       (26...29)
+       (26...29),
+       "B"
      ),
      ModuleNode(31...49)(
        [],
@@ -26,7 +34,8 @@ ProgramNode(0...106)(
          (42...44)
        ),
        nil,
-       (46...49)
+       (46...49),
+       "C"
      ),
      ModuleNode(51...106)(
        [],
@@ -72,7 +81,8 @@ ProgramNode(0...106)(
             (99...102)
           )]
        ),
-       (103...106)
+       (103...106),
+       "A"
      )]
   )
 )
diff --git a/test/snapshots/unparser/corpus/literal/send.txt b/test/snapshots/unparser/corpus/literal/send.txt
index 2c2ce8cd..083a0140 100644
--- a/test/snapshots/unparser/corpus/literal/send.txt
+++ b/test/snapshots/unparser/corpus/literal/send.txt
@@ -47,7 +47,8 @@ ProgramNode(0...999)(
             (15...18)
           )]
        ),
-       (32...35)
+       (32...35),
+       "A"
      ),
      ModuleNode(37...73)(
        [:local],
@@ -73,7 +74,8 @@ ProgramNode(0...999)(
             "bar"
           )]
        ),
-       (70...73)
+       (70...73),
+       "A"
      ),
      CallNode(74...89)(
        ClassNode(74...85)(
@@ -83,7 +85,8 @@ ProgramNode(0...999)(
          nil,
          nil,
          nil,
-         (82...85)
+         (82...85),
+         "A"
        ),
        (85...86),
        (86...89),
@@ -100,7 +103,8 @@ ProgramNode(0...999)(
          (90...96),
          ConstantReadNode(97...98)(),
          nil,
-         (99...102)
+         (99...102),
+         "A"
        ),
        (102...103),
        (103...106),
diff --git a/test/snapshots/unparser/corpus/literal/while.txt b/test/snapshots/unparser/corpus/literal/while.txt
index 98088460..dae7e0f0 100644
--- a/test/snapshots/unparser/corpus/literal/while.txt
+++ b/test/snapshots/unparser/corpus/literal/while.txt
@@ -62,7 +62,8 @@ ProgramNode(0...620)(
             "foo"
           )]
        ),
-       (65...68)
+       (65...68),
+       "A"
      ),
      DefNode(70...110)(
        (74...77),
@@ -154,7 +155,8 @@ ProgramNode(0...620)(
             0
           )]
        ),
-       (143...146)
+       (143...146),
+       "A"
      ),
      ModuleNode(148...182)(
        [:foo],
@@ -186,7 +188,8 @@ ProgramNode(0...620)(
             0
           )]
        ),
-       (179...182)
+       (179...182),
+       "A"
      ),
      ModuleNode(184...228)(
        [:foo],
@@ -228,7 +231,8 @@ ProgramNode(0...620)(
             0
           )]
        ),
-       (225...228)
+       (225...228),
+       "A"
      ),
      ModuleNode(230...299)(
        [],
@@ -301,7 +305,8 @@ ProgramNode(0...620)(
             "each"
           )]
        ),
-       (296...299)
+       (296...299),
+       "A"
      ),
      ModuleNode(301...370)(
        [],
@@ -364,7 +369,8 @@ ProgramNode(0...620)(
             "each"
           )]
        ),
-       (367...370)
+       (367...370),
+       "A"
      ),
      LocalVariableWriteNode(371...402)(
        :x,
diff --git a/test/snapshots/unparser/corpus/semantic/while.txt b/test/snapshots/unparser/corpus/semantic/while.txt
index fd495fbd..148db33d 100644
--- a/test/snapshots/unparser/corpus/semantic/while.txt
+++ b/test/snapshots/unparser/corpus/semantic/while.txt
@@ -178,7 +178,8 @@ ProgramNode(0...188)(
             0
           )]
        ),
-       (185...188)
+       (185...188),
+       "A"
      )]
   )
 )
diff --git a/test/snapshots/while.txt b/test/snapshots/while.txt
index cc0d2fbf..484eb68b 100644
--- a/test/snapshots/while.txt
+++ b/test/snapshots/while.txt
@@ -130,7 +130,8 @@ ProgramNode(0...314)(
               (181...182)
             )]
          ),
-         (195...198)
+         (195...198),
+         "Foo"
        ),
        StatementsNode(200...205)([BreakNode(200...205)(nil, (200...205))]),
        0
diff --git a/test/snapshots/whitequark/class.txt b/test/snapshots/whitequark/class.txt
index 0061b34a..c176350d 100644
--- a/test/snapshots/whitequark/class.txt
+++ b/test/snapshots/whitequark/class.txt
@@ -8,7 +8,8 @@ ProgramNode(0...29)(
        nil,
        nil,
        nil,
-       (10...13)
+       (10...13),
+       "Foo"
      ),
      ClassNode(15...29)(
        [],
@@ -17,7 +18,8 @@ ProgramNode(0...29)(
        nil,
        nil,
        nil,
-       (26...29)
+       (26...29),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/class_definition_in_while_cond.txt b/test/snapshots/whitequark/class_definition_in_while_cond.txt
index a7bee91d..0af9f40e 100644
--- a/test/snapshots/whitequark/class_definition_in_while_cond.txt
+++ b/test/snapshots/whitequark/class_definition_in_while_cond.txt
@@ -84,7 +84,8 @@ ProgramNode(0...197)(
               (122...123)
             )]
          ),
-         (136...139)
+         (136...139),
+         "Foo"
        ),
        StatementsNode(141...146)([BreakNode(141...146)(nil, (141...146))]),
        0
@@ -110,7 +111,8 @@ ProgramNode(0...197)(
               "tap"
             )]
          ),
-         (182...185)
+         (182...185),
+         "Foo"
        ),
        StatementsNode(187...192)([BreakNode(187...192)(nil, (187...192))]),
        0
diff --git a/test/snapshots/whitequark/class_super.txt b/test/snapshots/whitequark/class_super.txt
index aa2845a1..3dda8280 100644
--- a/test/snapshots/whitequark/class_super.txt
+++ b/test/snapshots/whitequark/class_super.txt
@@ -8,7 +8,8 @@ ProgramNode(0...20)(
        (10...11),
        ConstantReadNode(12...15)(),
        nil,
-       (17...20)
+       (17...20),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/class_super_label.txt b/test/snapshots/whitequark/class_super_label.txt
index ae6759c1..17e92e16 100644
--- a/test/snapshots/whitequark/class_super_label.txt
+++ b/test/snapshots/whitequark/class_super_label.txt
@@ -20,7 +20,8 @@ ProgramNode(0...20)(
          "a"
        ),
        nil,
-       (17...20)
+       (17...20),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/cpath.txt b/test/snapshots/whitequark/cpath.txt
index 94714a1a..2f838711 100644
--- a/test/snapshots/whitequark/cpath.txt
+++ b/test/snapshots/whitequark/cpath.txt
@@ -6,7 +6,8 @@ ProgramNode(0...39)(
        (0...6),
        ConstantPathNode(7...12)(nil, ConstantReadNode(9...12)(), (7...9)),
        nil,
-       (14...17)
+       (14...17),
+       "Foo"
      ),
      ModuleNode(19...39)(
        [],
@@ -17,7 +18,8 @@ ProgramNode(0...39)(
          (29...31)
        ),
        nil,
-       (36...39)
+       (36...39),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/if_while_after_class__since_32.txt b/test/snapshots/whitequark/if_while_after_class__since_32.txt
index 77f26487..2096097f 100644
--- a/test/snapshots/whitequark/if_while_after_class__since_32.txt
+++ b/test/snapshots/whitequark/if_while_after_class__since_32.txt
@@ -18,7 +18,8 @@ ProgramNode(0...178)(
        nil,
        nil,
        nil,
-       (35...38)
+       (35...38),
+       "Kernel"
      ),
      ClassNode(40...87)(
        [],
@@ -41,7 +42,8 @@ ProgramNode(0...178)(
        nil,
        nil,
        nil,
-       (84...87)
+       (84...87),
+       "Kernel"
      ),
      ModuleNode(89...128)(
        [],
@@ -58,7 +60,8 @@ ProgramNode(0...178)(
          (115...117)
        ),
        nil,
-       (125...128)
+       (125...128),
+       "Kernel"
      ),
      ModuleNode(130...178)(
        [],
@@ -79,7 +82,8 @@ ProgramNode(0...178)(
          (165...167)
        ),
        nil,
-       (175...178)
+       (175...178),
+       "Kernel"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/module.txt b/test/snapshots/whitequark/module.txt
index 54fccb1f..1695fb8f 100644
--- a/test/snapshots/whitequark/module.txt
+++ b/test/snapshots/whitequark/module.txt
@@ -6,7 +6,8 @@ ProgramNode(0...15)(
        (0...6),
        ConstantReadNode(7...10)(),
        nil,
-       (12...15)
+       (12...15),
+       "Foo"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/numparam_outside_block.txt b/test/snapshots/whitequark/numparam_outside_block.txt
index 99cb79b9..ac120e81 100644
--- a/test/snapshots/whitequark/numparam_outside_block.txt
+++ b/test/snapshots/whitequark/numparam_outside_block.txt
@@ -21,7 +21,8 @@ ProgramNode(0...83)(
        StatementsNode(36...38)(
          [CallNode(36...38)(nil, nil, (36...38), nil, nil, nil, nil, 2, "_1")]
        ),
-       (40...43)
+       (40...43),
+       "A"
      ),
      DefNode(45...64)(
        (54...55),
@@ -45,7 +46,8 @@ ProgramNode(0...83)(
        StatementsNode(76...78)(
          [CallNode(76...78)(nil, nil, (76...78), nil, nil, nil, nil, 2, "_1")]
        ),
-       (80...83)
+       (80...83),
+       "A"
      )]
   )
 )
diff --git a/test/snapshots/whitequark/parser_bug_490.txt b/test/snapshots/whitequark/parser_bug_490.txt
index 6f4c3a84..8ea556d9 100644
--- a/test/snapshots/whitequark/parser_bug_490.txt
+++ b/test/snapshots/whitequark/parser_bug_490.txt
@@ -47,7 +47,8 @@ ProgramNode(0...132)(
                  nil,
                  nil,
                  nil,
-                 (72...75)
+                 (72...75),
+                 "C"
                )]
             ),
             (77...80)
@@ -77,7 +78,8 @@ ProgramNode(0...132)(
                  (109...115),
                  ConstantReadNode(116...117)(),
                  nil,
-                 (119...122)
+                 (119...122),
+                 "M"
                )]
             ),
             (124...127)
diff --git a/test/snapshots/whitequark/parser_bug_518.txt b/test/snapshots/whitequark/parser_bug_518.txt
index 4de48dad..bee652b2 100644
--- a/test/snapshots/whitequark/parser_bug_518.txt
+++ b/test/snapshots/whitequark/parser_bug_518.txt
@@ -8,7 +8,8 @@ ProgramNode(0...15)(
        (8...9),
        ConstantReadNode(10...11)(),
        nil,
-       (12...15)
+       (12...15),
+       "A"
      )]
   )
 )