Repository: ruby/yarp
Pull request #1378 (2023-09-01 15:27:16)

remove reallocs preparing for custom memory management
If we move to a bump/arena allocator like in https://github.com/HParker/yarp/tree/introduce-yp_malloc

we likely don't want to support realloc as it likely requires extra book keeping. Instead we can malloc and memset so our allocator has less cases to consider.


Patch:
diff --git a/bin/parse b/bin/parse
index c03689ef..cd6e84c3 100755
--- a/bin/parse
+++ b/bin/parse
@@ -16,5 +16,4 @@ else
 end
 
 result.mark_newlines if ENV['MARK_NEWLINES']
-result = result.value.accept(YARP::DesugarVisitor.new) if ENV['DESUGAR']
 pp result
diff --git a/config.yml b/config.yml
index e6517730..8ebfb772 100644
--- a/config.yml
+++ b/config.yml
@@ -1221,10 +1221,10 @@ nodes:
     fields:
       - name: name_loc
         type: location
-      - name: value
-        type: node
       - name: operator_loc
         type: location
+      - name: value
+        type: node
     comment: |
       Represents writing to a global variable.
 
@@ -1595,10 +1595,10 @@ nodes:
         type: constant
       - name: depth
         type: uint32
-      - name: name_loc
-        type: location
       - name: value
         type: node
+      - name: name_loc
+        type: location
       - name: operator_loc
         type: location
     comment: |
diff --git a/lib/yarp/desugar_visitor.rb b/lib/yarp/desugar_visitor.rb
index a988449d..d0c0494e 100644
--- a/lib/yarp/desugar_visitor.rb
+++ b/lib/yarp/desugar_visitor.rb
@@ -42,7 +42,7 @@ module YARP
     #
     # becomes
     #
-    # defined?(Foo) ? Foo : Foo = bar
+    # Foo || Foo = bar
     def visit_constant_or_write_node(node)
       desugar_or_write_defined_node(node, ConstantReadNode, ConstantWriteNode)
     end
@@ -56,6 +56,69 @@ module YARP
       desugar_operator_write_node(node, ConstantReadNode, ConstantWriteNode)
     end
 
+    # Foo::Bar &&= baz
+    #
+    # becomes
+    #
+    # Foo::Bar && Foo::Bar = baz
+    def visit_constant_path_and_write_node(node)
+      AndNode.new(
+        node.target,
+        ConstantPathWriteNode.new(node.target, node.value, node.operator_loc, node.location),
+        node.operator_loc,
+        node.location
+      )
+    end
+
+    # Foo::Bar ||= baz
+    #
+    # becomes
+    #
+    # Foo::Bar || Foo::Bar = baz
+    def visit_constant_path_or_write_node(node)
+      IfNode.new(
+        node.operator_loc,
+        DefinedNode.new(nil, node.target, nil, node.operator_loc, node.target.location),
+        StatementsNode.new([node.target], node.location),
+        ElseNode.new(
+          node.operator_loc,
+          StatementsNode.new(
+            [ConstantPathWriteNode.new(node.target, node.value, node.operator_loc, node.location)],
+            node.location
+          ),
+          node.operator_loc,
+          node.location
+        ),
+        node.operator_loc,
+        node.location
+      )
+    end
+
+    # Foo::Bar += baz
+    #
+    # becomes
+    #
+    # Foo::Bar = Foo::Bar + baz
+    def visit_constant_path_operator_write_node(node)
+      ConstantPathWriteNode.new(
+        node.target,
+        CallNode.new(
+          node.target,
+          nil,
+          node.operator_loc.copy(length: node.operator_loc.length - 1),
+          nil,
+          ArgumentsNode.new([node.value], node.value.location),
+          nil,
+          nil,
+          0,
+          node.operator_loc.slice.chomp("="),
+          node.location
+        ),
+        node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
+        node.location
+      )
+    end
+
     # $foo &&= bar
     #
     # becomes
@@ -69,7 +132,7 @@ module YARP
     #
     # becomes
     #
-    # defined?($foo) ? $foo : $foo = bar
+    # $foo || $foo = bar
     def visit_global_variable_or_write_node(node)
       desugar_or_write_defined_node(node, GlobalVariableReadNode, GlobalVariableWriteNode)
     end
@@ -181,7 +244,7 @@ module YARP
       )
     end
 
-    # Desugar `x ||= y` to `defined?(x) ? x : x = y`
+    # Don't desugar `x ||= y` to `defined?(x) ? x : x = y`
     def desugar_or_write_defined_node(node, read_class, write_class, arguments: [])
       IfNode.new(
         node.operator_loc,
diff --git a/src/unescape.c b/src/unescape.c
index 14c0faf2..b0aabf5e 100644
--- a/src/unescape.c
+++ b/src/unescape.c
@@ -69,15 +69,17 @@ char_is_ascii_printable(const uint8_t b) {
 // Scan the 1-3 digits of octal into the value. Returns the number of digits
 // scanned.
 static inline size_t
-unescape_octal(const uint8_t *backslash, uint8_t *value, const uint8_t *end) {
+unescape_octal(const uint8_t *backslash, uint8_t *value) {
     *value = (uint8_t) (backslash[1] - '0');
-    if (backslash + 2 >= end || !yp_char_is_octal_digit(backslash[2])) {
+    if (!yp_char_is_octal_digit(backslash[2])) {
         return 2;
     }
+
     *value = (uint8_t) ((*value << 3) | (backslash[2] - '0'));
-    if (backslash + 3 >= end || !yp_char_is_octal_digit(backslash[3])) {
+    if (!yp_char_is_octal_digit(backslash[3])) {
         return 3;
     }
+
     *value = (uint8_t) ((*value << 3) | (backslash[3] - '0'));
     return 4;
 }
@@ -91,15 +93,12 @@ unescape_hexadecimal_digit(const uint8_t value) {
 // Scan the 1-2 digits of hexadecimal into the value. Returns the number of
 // digits scanned.
 static inline size_t
-unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end) {
-    *value = 0;
-    if (backslash + 2 >= end || !yp_char_is_hexadecimal_digit(backslash[2])) {
-        return 2;
-    }
+unescape_hexadecimal(const uint8_t *backslash, uint8_t *value) {
     *value = unescape_hexadecimal_digit(backslash[2]);
-    if (backslash + 3 >=  end || !yp_char_is_hexadecimal_digit(backslash[3])) {
+    if (!yp_char_is_hexadecimal_digit(backslash[3])) {
         return 3;
     }
+
     *value = (uint8_t) ((*value << 4) | unescape_hexadecimal_digit(backslash[3]));
     return 4;
 }
@@ -205,7 +204,7 @@ unescape(yp_parser_t *parser, uint8_t *dest, size_t *dest_length, const uint8_t
         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9': {
             uint8_t value;
-            const uint8_t *cursor = backslash + unescape_octal(backslash, &value, end);
+            const uint8_t *cursor = backslash + unescape_octal(backslash, &value);
 
             if (dest) {
                 dest[(*dest_length)++] = unescape_char(value, flags);
@@ -215,7 +214,7 @@ unescape(yp_parser_t *parser, uint8_t *dest, size_t *dest_length, const uint8_t
         // \xnn         hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F])
         case 'x': {
             uint8_t value;
-            const uint8_t *cursor = backslash + unescape_hexadecimal(backslash, &value, end);
+            const uint8_t *cursor = backslash + unescape_hexadecimal(backslash, &value);
 
             if (dest) {
                 dest[(*dest_length)++] = unescape_char(value, flags);
@@ -237,14 +236,13 @@ unescape(yp_parser_t *parser, uint8_t *dest, size_t *dest_length, const uint8_t
 
                 unicode_cursor += yp_strspn_whitespace(unicode_cursor, end - unicode_cursor);
 
-                while ((unicode_cursor < end) && (*unicode_cursor != '}')) {
+                while ((*unicode_cursor != '}') && (unicode_cursor < end)) {
                     const uint8_t *unicode_start = unicode_cursor;
                     size_t hexadecimal_length = yp_strspn_hexadecimal_digit(unicode_cursor, end - unicode_cursor);
 
                     // \u{nnnn} character literal allows only 1-6 hexadecimal digits
-                    if (hexadecimal_length > 6) {
+                    if (hexadecimal_length > 6)
                         yp_diagnostic_list_append(&parser->error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "invalid Unicode escape.");
-                    }
 
                     // there are not hexadecimal characters
                     if (hexadecimal_length == 0) {
@@ -271,16 +269,10 @@ unescape(yp_parser_t *parser, uint8_t *dest, size_t *dest_length, const uint8_t
                 if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1)
                     yp_diagnostic_list_append(&parser->error_list, extra_codepoints_start, unicode_cursor - 1, "Multiple codepoints at single character literal");
 
-
-                if (unicode_cursor < end && *unicode_cursor == '}') {
-                    unicode_cursor++;
-                } else {
-                    yp_diagnostic_list_append(&parser->error_list, backslash, unicode_cursor, "invalid Unicode escape.");
-                }
-                return unicode_cursor;
+                return unicode_cursor + 1;
             }
 
-            if ((backslash + 5) < end && yp_char_is_hexadecimal_digits(backslash + 2, 4)) {
+            if ((backslash + 2) < end && yp_char_is_hexadecimal_digits(backslash + 2, 4)) {
                 uint32_t value;
                 unescape_unicode(backslash + 2, 4, &value);
 
@@ -546,10 +538,6 @@ size_t
 yp_unescape_calculate_difference(yp_parser_t *parser, const uint8_t *backslash, yp_unescape_type_t unescape_type, bool expect_single_codepoint) {
     assert(unescape_type != YP_UNESCAPE_NONE);
 
-    if (backslash + 1 >= parser->end) {
-        return 0;
-    }
-
     switch (backslash[1]) {
         case '\\':
         case '\'':
diff --git a/src/util/yp_newline_list.c b/src/util/yp_newline_list.c
index 0a2050df..969b8845 100644
--- a/src/util/yp_newline_list.c
+++ b/src/util/yp_newline_list.c
@@ -25,8 +25,12 @@ yp_newline_list_init(yp_newline_list_t *list, const uint8_t *start, size_t capac
 bool
 yp_newline_list_append(yp_newline_list_t *list, const uint8_t *cursor) {
     if (list->size == list->capacity) {
+        size_t *original_offsets = list->offsets;
+
         list->capacity = (list->capacity * 3) / 2;
-        list->offsets = (size_t *) realloc(list->offsets, list->capacity * sizeof(size_t));
+        list->offsets = (size_t *) calloc(list->capacity, sizeof(size_t));
+        memcpy(list->offsets, original_offsets, list->size * sizeof(size_t));
+        free(original_offsets);
         if (list->offsets == NULL) return false;
     }
 
diff --git a/src/util/yp_string_list.c b/src/util/yp_string_list.c
index b03a3d25..3b2b4381 100644
--- a/src/util/yp_string_list.c
+++ b/src/util/yp_string_list.c
@@ -12,8 +12,11 @@ yp_string_list_init(yp_string_list_t *string_list) {
 void
 yp_string_list_append(yp_string_list_t *string_list, yp_string_t *string) {
     if (string_list->length + 1 > string_list->capacity) {
+        yp_string_t *original_string = string_list->strings;
         string_list->capacity *= 2;
-        string_list->strings = (yp_string_t *) realloc(string_list->strings, string_list->capacity * sizeof(yp_string_t));
+        string_list->strings = (yp_string_t *) malloc(string_list->capacity * sizeof(yp_string_t));
+        memcpy(string_list->strings, original_string, (string_list->length) * sizeof(yp_string_t));
+        free(original_string);
     }
 
     string_list->strings[string_list->length++] = *string;
diff --git a/src/yarp.c b/src/yarp.c
index 176e9f76..376dfe32 100644
--- a/src/yarp.c
+++ b/src/yarp.c
@@ -7002,16 +7002,17 @@ parser_lex(yp_parser_t *parser) {
                 // literally. In this case we'll skip past the next character
                 // and find the next breakpoint.
                 if (*breakpoint == '\\') {
-                    yp_unescape_type_t unescape_type = lex_mode->as.list.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL;
-                    size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false);
-                    if (difference == 0) {
-                        // we're at the end of the file
+                    // Check that we're not at the end of the file.
+                    if (breakpoint + 1 >= parser->end) {
                         breakpoint = NULL;
                         continue;
                     }
 
+                    yp_unescape_type_t unescape_type = lex_mode->as.list.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL;
+                    size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false);
+
                     // If the result is an escaped newline ...
-                    if (breakpoint[difference - 1] == '\n') {
+                    if (*(breakpoint + difference - 1) == '\n') {
                         if (parser->heredoc_end) {
                             // ... if we are on the same line as a heredoc, flush the heredoc and
                             // continue parsing after heredoc_end.
@@ -7140,15 +7141,16 @@ parser_lex(yp_parser_t *parser) {
                 // literally. In this case we'll skip past the next character
                 // and find the next breakpoint.
                 if (*breakpoint == '\\') {
-                    size_t difference = yp_unescape_calculate_difference(parser, breakpoint, YP_UNESCAPE_ALL, false);
-                    if (difference == 0) {
-                        // we're at the end of the file
+                    // Check that we're not at the end of the file.
+                    if (breakpoint + 1 >= parser->end) {
                         breakpoint = NULL;
                         continue;
                     }
 
+                    size_t difference = yp_unescape_calculate_difference(parser, breakpoint, YP_UNESCAPE_ALL, false);
+
                     // If the result is an escaped newline ...
-                    if (breakpoint[difference - 1] == '\n') {
+                    if (*(breakpoint + difference - 1) == '\n') {
                         if (parser->heredoc_end) {
                             // ... if we are on the same line as a heredoc, flush the heredoc and
                             // continue parsing after heredoc_end.
@@ -7291,19 +7293,20 @@ parser_lex(yp_parser_t *parser) {
                         breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1));
                         break;
                     case '\\': {
+                        // Check that we're not at the end of the file.
+                        if (breakpoint + 1 >= parser->end) {
+                            breakpoint = NULL;
+                            break;
+                        }
+
                         // If we hit escapes, then we need to treat the next token
                         // literally. In this case we'll skip past the next character and
                         // find the next breakpoint.
                         yp_unescape_type_t unescape_type = parser->lex_modes.current->as.string.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL;
                         size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false);
-                        if (difference == 0) {
-                            // we're at the end of the file
-                            breakpoint = NULL;
-                            break;
-                        }
 
                         // If the result is an escaped newline ...
-                        if (breakpoint[difference - 1] == '\n') {
+                        if (*(breakpoint + difference - 1) == '\n') {
                             if (parser->heredoc_end) {
                                 // ... if we are on the same line as a heredoc, flush the heredoc and
                                 // continue parsing after heredoc_end.
@@ -7460,6 +7463,12 @@ parser_lex(yp_parser_t *parser) {
                         break;
                     }
                     case '\\': {
+                        // Check that we're not at the end of the file.
+                        if (breakpoint + 1 >= parser->end) {
+                            breakpoint = NULL;
+                            break;
+                        }
+
                         // If we hit an escape, then we need to skip past
                         // however many characters the escape takes up. However
                         // it's important that if \n or \r\n are escaped that we
@@ -7472,11 +7481,6 @@ parser_lex(yp_parser_t *parser) {
                         } else {
                             yp_unescape_type_t unescape_type = (quote == YP_HEREDOC_QUOTE_SINGLE) ? YP_UNESCAPE_MINIMAL : YP_UNESCAPE_ALL;
                             size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false);
-                            if (difference == 0) {
-                                // we're at the end of the file
-                                breakpoint = NULL;
-                                break;
-                            }
 
                             yp_newline_list_check_append(&parser->newline_list, breakpoint + difference - 1);
 


Test patch:
diff --git a/test/yarp/desugar_visitor_test.rb b/test/yarp/desugar_visitor_test.rb
index 3966d7bf..c03b02e6 100644
--- a/test/yarp/desugar_visitor_test.rb
+++ b/test/yarp/desugar_visitor_test.rb
@@ -6,7 +6,7 @@ module YARP
   class DesugarVisitorTest < TestCase
     def test_and_write
       assert_desugars("(AndNode (ClassVariableReadNode) (ClassVariableWriteNode (CallNode)))", "@@foo &&= bar")
-      assert_not_desugared("Foo::Bar &&= baz", "Desugaring would execute Foo twice or need temporary variables")
+      assert_desugars("(AndNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode)) (ConstantPathWriteNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode)) (CallNode)))", "Foo::Bar &&= baz")
       assert_desugars("(AndNode (ConstantReadNode) (ConstantWriteNode (CallNode)))", "Foo &&= bar")
       assert_desugars("(AndNode (GlobalVariableReadNode) (GlobalVariableWriteNode (CallNode)))", "$foo &&= bar")
       assert_desugars("(AndNode (InstanceVariableReadNode) (InstanceVariableWriteNode (CallNode)))", "@foo &&= bar")
@@ -16,7 +16,7 @@ module YARP
 
     def test_or_write
       assert_desugars("(IfNode (DefinedNode (ClassVariableReadNode)) (StatementsNode (ClassVariableReadNode)) (ElseNode (StatementsNode (ClassVariableWriteNode (CallNode)))))", "@@foo ||= bar")
-      assert_not_desugared("Foo::Bar ||= baz", "Desugaring would execute Foo twice or need temporary variables")
+      assert_desugars("(IfNode (DefinedNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode))) (StatementsNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode))) (ElseNode (StatementsNode (ConstantPathWriteNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode)) (CallNode)))))", "Foo::Bar ||= baz")
       assert_desugars("(IfNode (DefinedNode (ConstantReadNode)) (StatementsNode (ConstantReadNode)) (ElseNode (StatementsNode (ConstantWriteNode (CallNode)))))", "Foo ||= bar")
       assert_desugars("(IfNode (DefinedNode (GlobalVariableReadNode)) (StatementsNode (GlobalVariableReadNode)) (ElseNode (StatementsNode (GlobalVariableWriteNode (CallNode)))))", "$foo ||= bar")
       assert_desugars("(OrNode (InstanceVariableReadNode) (InstanceVariableWriteNode (CallNode)))", "@foo ||= bar")
@@ -26,7 +26,7 @@ module YARP
 
     def test_operator_write
       assert_desugars("(ClassVariableWriteNode (CallNode (ClassVariableReadNode) (ArgumentsNode (CallNode))))", "@@foo += bar")
-      assert_not_desugared("Foo::Bar += baz", "Desugaring would execute Foo twice or need temporary variables")
+      assert_desugars("(ConstantPathWriteNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode)) (CallNode (ConstantPathNode (ConstantReadNode) (ConstantReadNode)) (ArgumentsNode (CallNode))))", "Foo::Bar += baz")
       assert_desugars("(ConstantWriteNode (CallNode (ConstantReadNode) (ArgumentsNode (CallNode))))", "Foo += bar")
       assert_desugars("(GlobalVariableWriteNode (CallNode (GlobalVariableReadNode) (ArgumentsNode (CallNode))))", "$foo += bar")
       assert_desugars("(InstanceVariableWriteNode (CallNode (InstanceVariableReadNode) (ArgumentsNode (CallNode))))", "@foo += bar")
@@ -51,36 +51,9 @@ module YARP
       "(#{parts.join(" ")})"
     end
 
-    # Ensure every node is only present once in the AST.
-    # If the same node is present twice it would most likely indicate it is executed twice, which is invalid semantically.
-    # This also acts as a sanity check that Node#child_nodes returns only nodes or nil (which caught a couple bugs).
-    class EnsureEveryNodeOnceInAST < Visitor
-      def initialize
-        @all_nodes = {}.compare_by_identity
-      end
-
-      def visit(node)
-        if node
-          if @all_nodes.include?(node)
-            raise "#{node.inspect} is present multiple times in the desugared AST and likely executed multiple times"
-          else
-            @all_nodes[node] = true
-          end
-        end
-        super(node)
-      end
-    end
-
     def assert_desugars(expected, source)
       ast = YARP.parse(source).value.accept(DesugarVisitor.new)
       assert_equal expected, ast_inspect(ast.statements.body.last)
-
-      ast.accept(EnsureEveryNodeOnceInAST.new)
-    end
-
-    def assert_not_desugared(source, reason)
-      ast = YARP.parse(source).value
-      assert_equal_nodes(ast, ast.accept(DesugarVisitor.new))
     end
   end
 end
diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb
index faf840e9..0e1931ec 100644
--- a/test/yarp/errors_test.rb
+++ b/test/yarp/errors_test.rb
@@ -513,16 +513,16 @@ module YARP
       expected = BeginNode(
         Location(),
         StatementsNode([
-          LocalVariableWriteNode(:_1, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_2, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_3, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_4, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_5, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_6, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_7, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_8, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_9, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location()),
-          LocalVariableWriteNode(:_10, 0, Location(), SymbolNode(Location(), Location(), nil, "a"), Location())
+          LocalVariableWriteNode(:_1, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_2, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_3, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_4, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_5, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_6, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_7, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_8, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_9, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location()),
+          LocalVariableWriteNode(:_10, 0, SymbolNode(Location(), Location(), nil, "a"), Location(), Location())
         ]),
         nil,
         nil,
@@ -621,13 +621,6 @@ module YARP
       ]
     end
 
-    def test_unterminated_unicode_brackets_should_be_a_syntax_error
-      assert_errors expression('?\\u{3'), '?\\u{3', [
-        ["invalid Unicode escape.", 1..5],
-        ["invalid Unicode escape.", 1..5],
-      ]
-    end
-
     def test_method_parameters_after_block
       expected = DefNode(
         Location(),
@@ -1003,8 +996,8 @@ module YARP
       expected = BeginNode(
         Location(),
         StatementsNode([
-          GlobalVariableWriteNode(Location(), NilNode(), Location()),
-          GlobalVariableWriteNode(Location(), NilNode(), Location())
+          GlobalVariableWriteNode(Location(), Location(), NilNode()),
+          GlobalVariableWriteNode(Location(), Location(), NilNode())
         ]),
         nil,
         nil,
diff --git a/test/yarp/fuzzer_test.rb b/test/yarp/fuzzer_test.rb
index f4abcd4a..568c2eaf 100644
--- a/test/yarp/fuzzer_test.rb
+++ b/test/yarp/fuzzer_test.rb
@@ -22,19 +22,6 @@ module YARP
     snippet "incomplete escaped list", "%w[\\"
     snippet "incomplete escaped regex", "/a\\"
     snippet "unterminated heredoc with unterminated escape at end of file", "<<A\n\\"
-    snippet "escaped octal at end of file 1", '"\\3'
-    snippet "escaped octal at end of file 2", '"\\33'
-    snippet "escaped hex at end of file 1", '"\\x'
-    snippet "escaped hex at end of file 2", '"\\x3'
-    snippet "escaped unicode at end of file 1", '"\\u{3'
-    snippet "escaped unicode at end of file 2", '"\\u{33'
-    snippet "escaped unicode at end of file 3", '"\\u{333'
-    snippet "escaped unicode at end of file 4", '"\\u{3333'
-    snippet "escaped unicode at end of file 5", '"\\u{33333'
-    snippet "escaped unicode at end of file 6", '"\\u{333333'
-    snippet "escaped unicode at end of file 7", '"\\u3'
-    snippet "escaped unicode at end of file 8", '"\\u33'
-    snippet "escaped unicode at end of file 9", '"\\u333'
 
     snippet "statements node with multiple heredocs", <<~EOF
       for <<A + <<B
diff --git a/test/yarp/snapshots/blocks.txt b/test/yarp/snapshots/blocks.txt
index 4a2c3f75..8f836208 100644
--- a/test/yarp/snapshots/blocks.txt
+++ b/test/yarp/snapshots/blocks.txt
@@ -453,8 +453,8 @@ ProgramNode(0...402)(
      LocalVariableWriteNode(292...300)(
        :fork,
        0,
-       (292...296),
        IntegerNode(299...300)(),
+       (292...296),
        (297...298)
      ),
      CallNode(301...316)(
diff --git a/test/yarp/snapshots/classes.txt b/test/yarp/snapshots/classes.txt
index 1d8813f4..33b3d042 100644
--- a/test/yarp/snapshots/classes.txt
+++ b/test/yarp/snapshots/classes.txt
@@ -11,8 +11,8 @@ ProgramNode(0...370)(
          [LocalVariableWriteNode(8...13)(
             :a,
             0,
-            (8...9),
             IntegerNode(12...13)(),
+            (8...9),
             (10...11)
           )]
        ),
@@ -63,8 +63,8 @@ ProgramNode(0...370)(
          [LocalVariableWriteNode(89...94)(
             :a,
             0,
-            (89...90),
             IntegerNode(93...94)(),
+            (89...90),
             (91...92)
           )]
        ),
diff --git a/test/yarp/snapshots/dos_endings.txt b/test/yarp/snapshots/dos_endings.txt
index 7048028b..240ae043 100644
--- a/test/yarp/snapshots/dos_endings.txt
+++ b/test/yarp/snapshots/dos_endings.txt
@@ -35,14 +35,13 @@ ProgramNode(0...108)(
      LocalVariableWriteNode(75...84)(
        :x,
        0,
-       (75...76),
        StringNode(79...84)((79...82), (82...82), (82...84), ""),
+       (75...76),
        (77...78)
      ),
      LocalVariableWriteNode(88...108)(
        :a,
        0,
-       (88...89),
        CallNode(92...108)(
          nil,
          nil,
@@ -75,6 +74,7 @@ ProgramNode(0...108)(
          0,
          "foo"
        ),
+       (88...89),
        (90...91)
      )]
   )
diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt
index 79d11f10..b5ec66aa 100644
--- a/test/yarp/snapshots/methods.txt
+++ b/test/yarp/snapshots/methods.txt
@@ -298,8 +298,8 @@ ProgramNode(0...1194)(
      LocalVariableWriteNode(275...280)(
        :a,
        0,
-       (275...276),
        IntegerNode(279...280)(),
+       (275...276),
        (277...278)
      ),
      DefNode(282...291)(
@@ -589,8 +589,8 @@ ProgramNode(0...1194)(
          [LocalVariableWriteNode(537...542)(
             :b,
             0,
-            (537...538),
             IntegerNode(541...542)(),
+            (537...538),
             (539...540)
           )]
        ),
@@ -839,7 +839,6 @@ ProgramNode(0...1194)(
          LocalVariableWriteNode(769...774)(
            :c,
            0,
-           (769...770),
            CallNode(773...774)(
              nil,
              nil,
@@ -851,6 +850,7 @@ ProgramNode(0...1194)(
              2,
              "b"
            ),
+           (769...770),
            (771...772)
          ),
          (768...769),
@@ -927,7 +927,6 @@ ProgramNode(0...1194)(
          LocalVariableWriteNode(833...838)(
            :a,
            0,
-           (833...834),
            CallNode(837...838)(
              nil,
              nil,
@@ -939,6 +938,7 @@ ProgramNode(0...1194)(
              2,
              "b"
            ),
+           (833...834),
            (835...836)
          ),
          (832...833),
diff --git a/test/yarp/snapshots/modules.txt b/test/yarp/snapshots/modules.txt
index aa8c1a74..a3cf30b9 100644
--- a/test/yarp/snapshots/modules.txt
+++ b/test/yarp/snapshots/modules.txt
@@ -9,8 +9,8 @@ ProgramNode(0...140)(
          [LocalVariableWriteNode(9...14)(
             :a,
             0,
-            (9...10),
             IntegerNode(13...14)(),
+            (9...10),
             (11...12)
           )]
        ),
@@ -62,8 +62,8 @@ ProgramNode(0...140)(
            [LocalVariableWriteNode(67...72)(
               :x,
               0,
-              (67...68),
               IntegerNode(71...72)(),
+              (67...68),
               (69...70)
             )]
          ),
diff --git a/test/yarp/snapshots/rescue.txt b/test/yarp/snapshots/rescue.txt
index c52a261f..b8944afd 100644
--- a/test/yarp/snapshots/rescue.txt
+++ b/test/yarp/snapshots/rescue.txt
@@ -192,7 +192,6 @@ ProgramNode(0...316)(
        LocalVariableWriteNode(217...235)(
          :a,
          0,
-         (217...218),
          RescueModifierNode(221...235)(
            CallNode(221...224)(
              nil,
@@ -208,6 +207,7 @@ ProgramNode(0...316)(
            (225...231),
            NilNode(232...235)()
          ),
+         (217...218),
          (219...220)
        ),
        StatementsNode(238...241)(
diff --git a/test/yarp/snapshots/seattlerb/bug202.txt b/test/yarp/snapshots/seattlerb/bug202.txt
index cbed9a67..7bb548f7 100644
--- a/test/yarp/snapshots/seattlerb/bug202.txt
+++ b/test/yarp/snapshots/seattlerb/bug202.txt
@@ -1,12 +1,12 @@
 ProgramNode(0...22)(
   [:测试],
   StatementsNode(0...22)(
-    [GlobalVariableWriteNode(0...11)((0...7), IntegerNode(10...11)(), (8...9)),
+    [GlobalVariableWriteNode(0...11)((0...7), (8...9), IntegerNode(10...11)()),
      LocalVariableWriteNode(12...22)(
        :测试,
        0,
-       (12...18),
        IntegerNode(21...22)(),
+       (12...18),
        (19...20)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/dasgn_icky2.txt b/test/yarp/snapshots/seattlerb/dasgn_icky2.txt
index 8fbbf8ec..2aba42cc 100644
--- a/test/yarp/snapshots/seattlerb/dasgn_icky2.txt
+++ b/test/yarp/snapshots/seattlerb/dasgn_icky2.txt
@@ -15,8 +15,8 @@ ProgramNode(0...76)(
            [LocalVariableWriteNode(7...14)(
               :v,
               0,
-              (7...8),
               NilNode(11...14)(),
+              (7...8),
               (9...10)
             ),
             BeginNode(17...72)(
diff --git a/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt b/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt
index d19d6d81..86433437 100644
--- a/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt
+++ b/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt
@@ -21,8 +21,8 @@ ProgramNode(0...48)(
           LocalVariableWriteNode(24...29)(
             :b,
             0,
-            (24...25),
             IntegerNode(28...29)(),
+            (24...25),
             (26...27)
           ),
           CallNode(32...35)(
@@ -39,8 +39,8 @@ ProgramNode(0...48)(
           LocalVariableWriteNode(38...42)(
             :c,
             0,
-            (38...39),
             IntegerNode(41...42)(),
+            (38...39),
             (40...41)
           )]
        ),
diff --git a/test/yarp/snapshots/seattlerb/difficult3_4.txt b/test/yarp/snapshots/seattlerb/difficult3_4.txt
index 40ebfca6..afca77c5 100644
--- a/test/yarp/snapshots/seattlerb/difficult3_4.txt
+++ b/test/yarp/snapshots/seattlerb/difficult3_4.txt
@@ -4,7 +4,6 @@ ProgramNode(0...17)(
     [LocalVariableWriteNode(0...17)(
        :a,
        0,
-       (0...1),
        IfNode(2...17)(
          nil,
          CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"),
@@ -16,6 +15,7 @@ ProgramNode(0...17)(
          ),
          nil
        ),
+       (0...1),
        (1...2)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt b/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt
index befdff81..d8a5d935 100644
--- a/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt
@@ -4,12 +4,12 @@ ProgramNode(0...12)(
     [LocalVariableWriteNode(0...12)(
        :str,
        0,
-       (0...3),
        InterpolatedStringNode(6...12)(
          (6...12),
          [StringNode(14...30)(nil, (14...30), nil, "beforeafter\r\n")],
          (30...35)
        ),
+       (0...3),
        (4...5)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt b/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt
index 842da16d..4bc1846e 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt
@@ -4,12 +4,12 @@ ProgramNode(0...9)(
     [LocalVariableWriteNode(0...9)(
        :s,
        0,
-       (0...1),
        InterpolatedStringNode(4...9)(
          (4...9),
          [StringNode(10...17)(nil, (10...17), nil, "a\xE9b\n")],
          (17...21)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt b/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt
index 14c02bdf..ebfb3b4d 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt
@@ -4,12 +4,12 @@ ProgramNode(0...10)(
     [LocalVariableWriteNode(0...10)(
        :s,
        0,
-       (0...1),
        InterpolatedStringNode(4...10)(
          (4...10),
          [StringNode(11...23)(nil, (11...23), nil, "a\xA7b\n" + "cöd\n")],
          (23...27)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_lineno.txt b/test/yarp/snapshots/seattlerb/heredoc_lineno.txt
index 9bbc817c..27708e25 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_lineno.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_lineno.txt
@@ -4,7 +4,6 @@ ProgramNode(0...41)(
     [LocalVariableWriteNode(0...11)(
        :c,
        0,
-       (0...1),
        InterpolatedStringNode(4...11)(
          (4...11),
          [StringNode(12...30)(
@@ -15,13 +14,14 @@ ProgramNode(0...41)(
           )],
          (30...34)
        ),
+       (0...1),
        (2...3)
      ),
      LocalVariableWriteNode(35...41)(
        :d,
        0,
-       (35...36),
        IntegerNode(39...41)(),
+       (35...36),
        (37...38)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt
index 6491c86c..a1013d9e 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt
@@ -4,12 +4,12 @@ ProgramNode(0...12)(
     [LocalVariableWriteNode(0...12)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...12)(
          (4...12),
          [StringNode(13...25)(nil, (13...25), nil, "x\n" + "y\n" + "z\n")],
          (25...31)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
index f2c3c1b1..e78764e9 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt
@@ -4,7 +4,6 @@ ProgramNode(0...20)(
     [LocalVariableWriteNode(0...20)(
        :a,
        0,
-       (0...1),
        CallNode(4...20)(
          nil,
          nil,
@@ -50,6 +49,7 @@ ProgramNode(0...20)(
          0,
          "foo"
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
index 4b59c352..3bb7807c 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt
@@ -4,12 +4,12 @@ ProgramNode(0...10)(
     [LocalVariableWriteNode(0...10)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...10)(
          (4...10),
          [StringNode(11...20)(nil, (11...20), nil, "x\n" + "\n" + "z\n")],
          (20...24)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt
index e03304a7..f895e997 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt
@@ -4,7 +4,6 @@ ProgramNode(0...10)(
     [LocalVariableWriteNode(0...10)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...10)(
          (4...10),
          [StringNode(11...22)(nil, (11...22), nil, "    w\n" + "x"),
@@ -16,6 +15,7 @@ ProgramNode(0...10)(
           StringNode(27...36)(nil, (27...36), nil, " y\n" + "  z\n")],
          (36...42)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt
index 1592d131..13d1844e 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt
@@ -4,7 +4,6 @@ ProgramNode(0...12)(
     [LocalVariableWriteNode(0...12)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...12)(
          (4...12),
          [StringNode(13...43)(
@@ -15,6 +14,7 @@ ProgramNode(0...12)(
           )],
          (43...49)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
index 63ff5887..da631943 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt
@@ -4,7 +4,6 @@ ProgramNode(0...12)(
     [LocalVariableWriteNode(0...12)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...12)(
          (4...12),
          [StringNode(13...37)(
@@ -15,6 +14,7 @@ ProgramNode(0...12)(
           )],
          (37...43)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
index 866c5fac..680ffbe0 100644
--- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
+++ b/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt
@@ -4,12 +4,12 @@ ProgramNode(0...10)(
     [LocalVariableWriteNode(0...10)(
        :a,
        0,
-       (0...1),
        InterpolatedStringNode(4...10)(
          (4...10),
          [StringNode(11...21)(nil, (11...21), nil, "x\n" + "\n" + "z\n")],
          (21...25)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
index ad36a5ed..03ec05d3 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt
@@ -4,12 +4,12 @@ ProgramNode(0...14)(
     [LocalVariableWriteNode(0...14)(
        :a,
        0,
-       (0...1),
        RescueModifierNode(4...14)(
          IntegerNode(4...5)(),
          (6...12),
          IntegerNode(13...14)()
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
index 86469f1c..c28b8c21 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt
@@ -4,7 +4,6 @@ ProgramNode(0...17)(
     [LocalVariableWriteNode(0...17)(
        :a,
        0,
-       (0...1),
        RescueModifierNode(4...17)(
          CallNode(4...8)(
            nil,
@@ -20,6 +19,7 @@ ProgramNode(0...17)(
          (9...15),
          IntegerNode(16...17)()
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
index 72e54e01..bfb7c9b6 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt
@@ -4,7 +4,6 @@ ProgramNode(0...16)(
     [LocalVariableWriteNode(0...16)(
        :a,
        0,
-       (0...1),
        CallNode(4...16)(
          nil,
          nil,
@@ -22,6 +21,7 @@ ProgramNode(0...16)(
          0,
          "b"
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_command.txt b/test/yarp/snapshots/seattlerb/lasgn_command.txt
index b1912a7c..696be787 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_command.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_command.txt
@@ -4,7 +4,6 @@ ProgramNode(0...9)(
     [LocalVariableWriteNode(0...9)(
        :a,
        0,
-       (0...1),
        CallNode(4...9)(
          CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"),
          (5...6),
@@ -16,6 +15,7 @@ ProgramNode(0...9)(
          0,
          "c"
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_env.txt b/test/yarp/snapshots/seattlerb/lasgn_env.txt
index cfd276b1..33f2f470 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_env.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_env.txt
@@ -4,8 +4,8 @@ ProgramNode(0...6)(
     [LocalVariableWriteNode(0...6)(
        :a,
        0,
-       (0...1),
        IntegerNode(4...6)(),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt b/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt
index 49f22eeb..4c272c16 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt
@@ -4,11 +4,9 @@ ProgramNode(0...11)(
     [LocalVariableWriteNode(0...11)(
        :a,
        0,
-       (0...1),
        LocalVariableWriteNode(4...11)(
          :b,
          0,
-         (4...5),
          CallNode(8...11)(
            nil,
            nil,
@@ -20,8 +18,10 @@ ProgramNode(0...11)(
            0,
            "c"
          ),
+         (4...5),
          (6...7)
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt b/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt
index acb6c844..623f6dc1 100644
--- a/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt
+++ b/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt
@@ -4,7 +4,6 @@ ProgramNode(0...12)(
     [LocalVariableWriteNode(0...12)(
        :a,
        0,
-       (0...1),
        ArrayNode(4...12)(
          [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"),
           SplatNode(7...9)(
@@ -15,6 +14,7 @@ ProgramNode(0...12)(
          nil,
          nil
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt
index b8b1ec34..08c8d9ea 100644
--- a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt
+++ b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt
@@ -16,8 +16,8 @@ ProgramNode(18...90)(
               [LocalVariableWriteNode(67...81)(
                  :così,
                  0,
-                 (67...72),
                  SymbolNode(75...81)((75...76), (76...81), nil, "però"),
+                 (67...72),
                  (73...74)
                )]
             ),
diff --git a/test/yarp/snapshots/seattlerb/parse_line_block.txt b/test/yarp/snapshots/seattlerb/parse_line_block.txt
index 7ca169a8..51282de9 100644
--- a/test/yarp/snapshots/seattlerb/parse_line_block.txt
+++ b/test/yarp/snapshots/seattlerb/parse_line_block.txt
@@ -4,8 +4,8 @@ ProgramNode(0...10)(
     [LocalVariableWriteNode(0...6)(
        :a,
        0,
-       (0...1),
        IntegerNode(4...6)(),
+       (0...1),
        (2...3)
      ),
      CallNode(7...10)(
diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt
index 955d94e9..8e41b164 100644
--- a/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt
+++ b/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt
@@ -4,7 +4,6 @@ ProgramNode(6...88)(
     [LocalVariableWriteNode(6...31)(
        :string,
        0,
-       (6...12),
        CallNode(15...31)(
          InterpolatedStringNode(15...25)(
            (15...25),
@@ -25,6 +24,7 @@ ProgramNode(6...88)(
          0,
          "strip"
        ),
+       (6...12),
        (13...14)
      ),
      CallNode(77...88)(
diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
index 3d52fcbf..b3ed88d9 100644
--- a/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
+++ b/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt
@@ -4,7 +4,6 @@ ProgramNode(6...74)(
     [LocalVariableWriteNode(6...22)(
        :string,
        0,
-       (6...12),
        InterpolatedStringNode(15...22)(
          (15...22),
          [StringNode(23...48)(
@@ -15,6 +14,7 @@ ProgramNode(6...74)(
           )],
          (48...57)
        ),
+       (6...12),
        (13...14)
      ),
      CallNode(63...74)(
diff --git a/test/yarp/snapshots/seattlerb/pct_nl.txt b/test/yarp/snapshots/seattlerb/pct_nl.txt
index 4cdba9d6..8435c33e 100644
--- a/test/yarp/snapshots/seattlerb/pct_nl.txt
+++ b/test/yarp/snapshots/seattlerb/pct_nl.txt
@@ -4,8 +4,8 @@ ProgramNode(0...7)(
     [LocalVariableWriteNode(0...7)(
        :x,
        0,
-       (0...1),
        StringNode(4...7)((4...6), (6...6), (6...7), ""),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt b/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt
index 7785c792..4000ecf5 100644
--- a/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt
+++ b/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt
@@ -4,7 +4,6 @@ ProgramNode(0...8)(
     [LocalVariableWriteNode(0...8)(
        :c,
        0,
-       (0...1),
        CallNode(4...8)(
          CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"),
          (5...7),
@@ -16,6 +15,7 @@ ProgramNode(0...8)(
          1,
          "b"
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/ternary_operator.txt b/test/yarp/snapshots/ternary_operator.txt
index 9751d53a..6055e243 100644
--- a/test/yarp/snapshots/ternary_operator.txt
+++ b/test/yarp/snapshots/ternary_operator.txt
@@ -147,8 +147,8 @@ ProgramNode(0...131)(
          [LocalVariableWriteNode(124...129)(
             :_a,
             0,
-            (124...126),
             IntegerNode(128...129)(),
+            (124...126),
             (127...128)
           )]
        ),
diff --git a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt
index 7680b90f..78ab4d3d 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt
@@ -1,7 +1,7 @@
 ProgramNode(0...704)(
   [:a, :b, :foo, :c, :x],
   StatementsNode(0...704)(
-    [GlobalVariableWriteNode(0...6)((0...2), IntegerNode(5...6)(), (3...4)),
+    [GlobalVariableWriteNode(0...6)((0...2), (3...4), IntegerNode(5...6)()),
      MultiWriteNode(7...24)(
        [GlobalVariableTargetNode(8...10)(),
         GlobalVariableTargetNode(12...14)()],
@@ -323,7 +323,6 @@ ProgramNode(0...704)(
      LocalVariableWriteNode(351...367)(
        :a,
        0,
-       (351...352),
        ParenthesesNode(355...367)(
          StatementsNode(356...366)(
            [MultiWriteNode(356...366)(
@@ -338,19 +337,19 @@ ProgramNode(0...704)(
          (355...356),
          (366...367)
        ),
+       (351...352),
        (353...354)
      ),
      LocalVariableWriteNode(368...373)(
        :a,
        0,
-       (368...369),
        IntegerNode(372...373)(),
+       (368...369),
        (370...371)
      ),
      LocalVariableWriteNode(374...385)(
        :foo,
        0,
-       (374...377),
        CallNode(380...385)(
          nil,
          nil,
@@ -362,6 +361,7 @@ ProgramNode(0...704)(
          0,
          "foo"
        ),
+       (374...377),
        (378...379)
      ),
      CallNode(386...395)(
@@ -538,8 +538,8 @@ ProgramNode(0...704)(
      LocalVariableWriteNode(507...514)(
        :x,
        0,
-       (507...508),
        StringNode(511...514)((511...513), (513...513), (513...514), ""),
+       (507...508),
        (509...510)
      ),
      CallNode(515...522)(
@@ -615,7 +615,6 @@ ProgramNode(0...704)(
      LocalVariableWriteNode(562...576)(
        :x,
        0,
-       (562...563),
        InterpolatedStringNode(566...576)(
          (566...576),
          [StringNode(577...579)(nil, (577...579), nil, "  "),
@@ -623,6 +622,7 @@ ProgramNode(0...704)(
           StringNode(582...583)(nil, (582...583), nil, "\n")],
          (583...591)
        ),
+       (562...563),
        (564...565)
      ),
      CallNode(591...605)(
diff --git a/test/yarp/snapshots/unparser/corpus/literal/if.txt b/test/yarp/snapshots/unparser/corpus/literal/if.txt
index 77fb5c8c..1bfbe7e2 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/if.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/if.txt
@@ -61,7 +61,6 @@ ProgramNode(0...246)(
               [LocalVariableWriteNode(113...122)(
                  :foo,
                  0,
-                 (113...116),
                  CallNode(119...122)(
                    nil,
                    nil,
@@ -73,6 +72,7 @@ ProgramNode(0...246)(
                    2,
                    "bar"
                  ),
+                 (113...116),
                  (117...118)
                )]
             ),
@@ -95,7 +95,6 @@ ProgramNode(0...246)(
               [LocalVariableWriteNode(146...155)(
                  :foo,
                  0,
-                 (146...149),
                  CallNode(152...155)(
                    nil,
                    nil,
@@ -107,6 +106,7 @@ ProgramNode(0...246)(
                    2,
                    "bar"
                  ),
+                 (146...149),
                  (150...151)
                )]
             ),
@@ -134,7 +134,6 @@ ProgramNode(0...246)(
          [LocalVariableWriteNode(184...193)(
             :foo,
             0,
-            (184...187),
             CallNode(190...193)(
               nil,
               nil,
@@ -146,6 +145,7 @@ ProgramNode(0...246)(
               2,
               "bar"
             ),
+            (184...187),
             (188...189)
           )]
        ),
@@ -190,8 +190,8 @@ ProgramNode(0...246)(
          [LocalVariableWriteNode(225...236)(
             :pair,
             0,
-            (225...229),
             SymbolNode(232...236)((232...233), (233...236), nil, "foo"),
+            (225...229),
             (230...231)
           ),
           LocalVariableReadNode(239...242)(:foo, 0)]
diff --git a/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt b/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt
index 1f28ad87..7e9670da 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt
@@ -259,7 +259,6 @@ ProgramNode(0...530)(
             LocalVariableWriteNode(307...316)(
               :foo,
               0,
-              (307...310),
               CallNode(313...316)(
                 nil,
                 nil,
@@ -271,6 +270,7 @@ ProgramNode(0...530)(
                 2,
                 "bar"
               ),
+              (307...310),
               (311...312)
             )
           )]
diff --git a/test/yarp/snapshots/unparser/corpus/literal/rescue.txt b/test/yarp/snapshots/unparser/corpus/literal/rescue.txt
index 8898a6e1..ed653b5d 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/rescue.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/rescue.txt
@@ -29,7 +29,6 @@ ProgramNode(0...64)(
      LocalVariableWriteNode(37...64)(
        :x,
        0,
-       (37...38),
        ParenthesesNode(41...64)(
          StatementsNode(42...63)(
            [RescueModifierNode(42...63)(
@@ -66,6 +65,7 @@ ProgramNode(0...64)(
          (41...42),
          (63...64)
        ),
+       (37...38),
        (39...40)
      )]
   )
diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt
index 7ec3a338..1d3cd313 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/send.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt
@@ -48,8 +48,8 @@ ProgramNode(0...999)(
          [LocalVariableWriteNode(48...57)(
             :local,
             0,
-            (48...53),
             IntegerNode(56...57)(),
+            (48...53),
             (54...55)
           ),
           CallNode(60...69)(
diff --git a/test/yarp/snapshots/unparser/corpus/literal/while.txt b/test/yarp/snapshots/unparser/corpus/literal/while.txt
index 7fcd66a0..003c03d6 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/while.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/while.txt
@@ -48,8 +48,8 @@ ProgramNode(0...620)(
                      [LocalVariableWriteNode(43...52)(
                         :foo,
                         0,
-                        (43...46),
                         LocalVariableReadNode(49...52)(:bar, 0),
+                        (43...46),
                         (47...48)
                       )]
                    ),
@@ -101,7 +101,6 @@ ProgramNode(0...620)(
               [LocalVariableWriteNode(80...89)(
                  :foo,
                  0,
-                 (80...83),
                  CallNode(86...89)(
                    nil,
                    nil,
@@ -113,6 +112,7 @@ ProgramNode(0...620)(
                    2,
                    "bar"
                  ),
+                 (80...83),
                  (84...85)
                )]
             ),
@@ -140,7 +140,6 @@ ProgramNode(0...620)(
               [LocalVariableWriteNode(123...132)(
                  :foo,
                  0,
-                 (123...126),
                  CallNode(129...132)(
                    nil,
                    nil,
@@ -152,6 +151,7 @@ ProgramNode(0...620)(
                    2,
                    "bar"
                  ),
+                 (123...126),
                  (127...128)
                )]
             ),
@@ -174,7 +174,6 @@ ProgramNode(0...620)(
               [LocalVariableWriteNode(159...168)(
                  :foo,
                  0,
-                 (159...162),
                  CallNode(165...168)(
                    nil,
                    nil,
@@ -186,6 +185,7 @@ ProgramNode(0...620)(
                    2,
                    "bar"
                  ),
+                 (159...162),
                  (163...164)
                )]
             ),
@@ -218,7 +218,6 @@ ProgramNode(0...620)(
               [LocalVariableWriteNode(209...218)(
                  :foo,
                  0,
-                 (209...212),
                  CallNode(215...218)(
                    nil,
                    nil,
@@ -230,6 +229,7 @@ ProgramNode(0...620)(
                    2,
                    "bar"
                  ),
+                 (209...212),
                  (213...214)
                )]
             ),
@@ -286,7 +286,6 @@ ProgramNode(0...620)(
                      [LocalVariableWriteNode(274...283)(
                         :foo,
                         0,
-                        (274...277),
                         CallNode(280...283)(
                           nil,
                           nil,
@@ -298,6 +297,7 @@ ProgramNode(0...620)(
                           2,
                           "bar"
                         ),
+                        (274...277),
                         (278...279)
                       )]
                    ),
@@ -351,7 +351,6 @@ ProgramNode(0...620)(
                      [LocalVariableWriteNode(345...354)(
                         :foo,
                         0,
-                        (345...348),
                         CallNode(351...354)(
                           nil,
                           nil,
@@ -363,6 +362,7 @@ ProgramNode(0...620)(
                           2,
                           "bar"
                         ),
+                        (345...348),
                         (349...350)
                       )]
                    ),
@@ -382,7 +382,6 @@ ProgramNode(0...620)(
      LocalVariableWriteNode(371...402)(
        :x,
        0,
-       (371...372),
        ParenthesesNode(375...402)(
          StatementsNode(376...401)(
            [WhileNode(376...401)(
@@ -427,6 +426,7 @@ ProgramNode(0...620)(
          (375...376),
          (401...402)
        ),
+       (371...372),
        (373...374)
      ),
      WhileNode(403...428)(
diff --git a/test/yarp/snapshots/unparser/corpus/semantic/while.txt b/test/yarp/snapshots/unparser/corpus/semantic/while.txt
index d6d41984..c381369c 100644
--- a/test/yarp/snapshots/unparser/corpus/semantic/while.txt
+++ b/test/yarp/snapshots/unparser/corpus/semantic/while.txt
@@ -47,7 +47,6 @@ ProgramNode(0...188)(
          [LocalVariableWriteNode(36...45)(
             :foo,
             0,
-            (36...39),
             CallNode(42...45)(
               nil,
               nil,
@@ -59,6 +58,7 @@ ProgramNode(0...188)(
               2,
               "bar"
             ),
+            (36...39),
             (40...41)
           )]
        ),
@@ -93,8 +93,8 @@ ProgramNode(0...188)(
        LocalVariableWriteNode(83...88)(
          :a,
          0,
-         (83...84),
          CallNode(87...88)(nil, nil, (87...88), nil, nil, nil, nil, 2, "b"),
+         (83...84),
          (85...86)
        ),
        StatementsNode(91...92)([LocalVariableReadNode(91...92)(:a, 0)]),
@@ -145,7 +145,6 @@ ProgramNode(0...188)(
          [LocalVariableWriteNode(143...152)(
             :foo,
             0,
-            (143...146),
             CallNode(149...152)(
               nil,
               nil,
@@ -157,6 +156,7 @@ ProgramNode(0...188)(
               2,
               "exp"
             ),
+            (143...146),
             (147...148)
           ),
           WhileNode(155...184)(
@@ -167,7 +167,6 @@ ProgramNode(0...188)(
               [LocalVariableWriteNode(169...178)(
                  :foo,
                  0,
-                 (169...172),
                  CallNode(175...178)(
                    nil,
                    nil,
@@ -179,6 +178,7 @@ ProgramNode(0...188)(
                    2,
                    "bar"
                  ),
+                 (169...172),
                  (173...174)
                )]
             ),
diff --git a/test/yarp/snapshots/variables.txt b/test/yarp/snapshots/variables.txt
index edd27690..419942d1 100644
--- a/test/yarp/snapshots/variables.txt
+++ b/test/yarp/snapshots/variables.txt
@@ -28,8 +28,8 @@ ProgramNode(0...293)(
      ),
      GlobalVariableWriteNode(50...58)(
        (50...54),
-       IntegerNode(57...58)(),
-       (55...56)
+       (55...56),
+       IntegerNode(57...58)()
      ),
      GlobalVariableReadNode(60...64)(),
      InstanceVariableReadNode(66...70)(:@abc),
@@ -43,8 +43,8 @@ ProgramNode(0...293)(
      LocalVariableWriteNode(85...92)(
        :abc,
        0,
-       (85...88),
        IntegerNode(91...92)(),
+       (85...88),
        (89...90)
      ),
      MultiWriteNode(94...108)(
@@ -57,12 +57,12 @@ ProgramNode(0...293)(
      ),
      GlobalVariableWriteNode(110...121)(
        (110...114),
+       (115...116),
        ArrayNode(117...121)(
          [IntegerNode(117...118)(), IntegerNode(120...121)()],
          nil,
          nil
-       ),
-       (115...116)
+       )
      ),
      MultiWriteNode(123...137)(
        [InstanceVariableTargetNode(123...127)(:@foo),
@@ -85,30 +85,30 @@ ProgramNode(0...293)(
      LocalVariableWriteNode(152...159)(
        :foo,
        0,
-       (152...155),
        IntegerNode(158...159)(),
+       (152...155),
        (156...157)
      ),
      LocalVariableWriteNode(161...171)(
        :foo,
        0,
-       (161...164),
        ArrayNode(167...171)(
          [IntegerNode(167...168)(), IntegerNode(170...171)()],
          nil,
          nil
        ),
+       (161...164),
        (165...166)
      ),
      LocalVariableWriteNode(173...183)(
        :foo,
        0,
-       (173...176),
        ArrayNode(179...183)(
          [IntegerNode(179...180)(), IntegerNode(182...183)()],
          nil,
          nil
        ),
+       (173...176),
        (177...178)
      ),
      MultiWriteNode(185...198)(
@@ -177,7 +177,6 @@ ProgramNode(0...293)(
      LocalVariableWriteNode(260...270)(
        :foo,
        0,
-       (260...263),
        ArrayNode(266...270)(
          [SplatNode(266...270)(
             (266...267),
@@ -186,6 +185,7 @@ ProgramNode(0...293)(
          nil,
          nil
        ),
+       (260...263),
        (264...265)
      ),
      ConstantWriteNode(272...282)(
diff --git a/test/yarp/snapshots/while.txt b/test/yarp/snapshots/while.txt
index 4aa5fe85..667dd303 100644
--- a/test/yarp/snapshots/while.txt
+++ b/test/yarp/snapshots/while.txt
@@ -123,7 +123,6 @@ ProgramNode(0...314)(
            [LocalVariableWriteNode(179...193)(
               :a,
               0,
-              (179...180),
               CallNode(183...193)(
                 nil,
                 nil,
@@ -135,6 +134,7 @@ ProgramNode(0...314)(
                 0,
                 "tap"
               ),
+              (179...180),
               (181...182)
             )]
          ),
@@ -182,7 +182,6 @@ ProgramNode(0...314)(
            [LocalVariableWriteNode(283...297)(
               :a,
               0,
-              (283...284),
               CallNode(287...297)(
                 nil,
                 nil,
@@ -194,6 +193,7 @@ ProgramNode(0...314)(
                 0,
                 "tap"
               ),
+              (283...284),
               (285...286)
             )]
          ),
diff --git a/test/yarp/snapshots/whitequark/asgn_cmd.txt b/test/yarp/snapshots/whitequark/asgn_cmd.txt
index ef24cc04..218c28dc 100644
--- a/test/yarp/snapshots/whitequark/asgn_cmd.txt
+++ b/test/yarp/snapshots/whitequark/asgn_cmd.txt
@@ -4,11 +4,9 @@ ProgramNode(0...30)(
     [LocalVariableWriteNode(0...17)(
        :foo,
        0,
-       (0...3),
        LocalVariableWriteNode(6...17)(
          :bar,
          0,
-         (6...9),
          CallNode(12...17)(
            nil,
            nil,
@@ -20,14 +18,15 @@ ProgramNode(0...30)(
            0,
            "m"
          ),
+         (6...9),
          (10...11)
        ),
+       (0...3),
        (4...5)
      ),
      LocalVariableWriteNode(19...30)(
        :foo,
        0,
-       (19...22),
        CallNode(25...30)(
          nil,
          nil,
@@ -39,6 +38,7 @@ ProgramNode(0...30)(
          0,
          "m"
        ),
+       (19...22),
        (23...24)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/asgn_mrhs.txt b/test/yarp/snapshots/whitequark/asgn_mrhs.txt
index aaf2bedb..fddbc439 100644
--- a/test/yarp/snapshots/whitequark/asgn_mrhs.txt
+++ b/test/yarp/snapshots/whitequark/asgn_mrhs.txt
@@ -4,7 +4,6 @@ ProgramNode(0...41)(
     [LocalVariableWriteNode(0...10)(
        :foo,
        0,
-       (0...3),
        ArrayNode(6...10)(
          [SplatNode(6...10)(
             (6...7),
@@ -13,24 +12,24 @@ ProgramNode(0...41)(
          nil,
          nil
        ),
+       (0...3),
        (4...5)
      ),
      LocalVariableWriteNode(12...24)(
        :foo,
        0,
-       (12...15),
        ArrayNode(18...24)(
          [CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "bar"),
           IntegerNode(23...24)()],
          nil,
          nil
        ),
+       (12...15),
        (16...17)
      ),
      LocalVariableWriteNode(26...41)(
        :foo,
        0,
-       (26...29),
        ArrayNode(32...41)(
          [CallNode(32...35)(nil, nil, (32...35), nil, nil, nil, nil, 2, "baz"),
           SplatNode(37...41)(
@@ -50,6 +49,7 @@ ProgramNode(0...41)(
          nil,
          nil
        ),
+       (26...29),
        (30...31)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt b/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt
index 1e954972..a3108d70 100644
--- a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt
+++ b/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt
@@ -13,7 +13,6 @@ ProgramNode(0...197)(
            [LocalVariableWriteNode(21...35)(
               :a,
               0,
-              (21...22),
               CallNode(25...35)(
                 nil,
                 nil,
@@ -25,6 +24,7 @@ ProgramNode(0...197)(
                 0,
                 "tap"
               ),
+              (21...22),
               (23...24)
             )]
          ),
@@ -72,7 +72,6 @@ ProgramNode(0...197)(
            [LocalVariableWriteNode(120...134)(
               :a,
               0,
-              (120...121),
               CallNode(124...134)(
                 nil,
                 nil,
@@ -84,6 +83,7 @@ ProgramNode(0...197)(
                 0,
                 "tap"
               ),
+              (120...121),
               (122...123)
             )]
          ),
diff --git a/test/yarp/snapshots/whitequark/gvasgn.txt b/test/yarp/snapshots/whitequark/gvasgn.txt
index c4030831..d6a53275 100644
--- a/test/yarp/snapshots/whitequark/gvasgn.txt
+++ b/test/yarp/snapshots/whitequark/gvasgn.txt
@@ -1,6 +1,6 @@
 ProgramNode(0...9)(
   [],
   StatementsNode(0...9)(
-    [GlobalVariableWriteNode(0...9)((0...4), IntegerNode(7...9)(), (5...6))]
+    [GlobalVariableWriteNode(0...9)((0...4), (5...6), IntegerNode(7...9)())]
   )
 )
diff --git a/test/yarp/snapshots/whitequark/lvasgn.txt b/test/yarp/snapshots/whitequark/lvasgn.txt
index bb762001..403c7f80 100644
--- a/test/yarp/snapshots/whitequark/lvasgn.txt
+++ b/test/yarp/snapshots/whitequark/lvasgn.txt
@@ -4,8 +4,8 @@ ProgramNode(0...13)(
     [LocalVariableWriteNode(0...8)(
        :var,
        0,
-       (0...3),
        IntegerNode(6...8)(),
+       (0...3),
        (4...5)
      ),
      LocalVariableReadNode(10...13)(:var, 0)]
diff --git a/test/yarp/snapshots/whitequark/parser_bug_507.txt b/test/yarp/snapshots/whitequark/parser_bug_507.txt
index f305b7da..4d6d91a7 100644
--- a/test/yarp/snapshots/whitequark/parser_bug_507.txt
+++ b/test/yarp/snapshots/whitequark/parser_bug_507.txt
@@ -4,7 +4,6 @@ ProgramNode(0...19)(
     [LocalVariableWriteNode(0...19)(
        :m,
        0,
-       (0...1),
        LambdaNode(4...19)(
          [:args],
          (4...6),
@@ -26,6 +25,7 @@ ProgramNode(0...19)(
          ),
          nil
        ),
+       (0...1),
        (2...3)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt
index b0ca3f6c..c0c1b20c 100644
--- a/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt
+++ b/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt
@@ -4,12 +4,12 @@ ProgramNode(0...21)(
     [LocalVariableWriteNode(0...21)(
        :foo,
        0,
-       (0...3),
        RescueModifierNode(6...21)(
          CallNode(6...10)(nil, nil, (6...10), nil, nil, nil, nil, 2, "meth"),
          (11...17),
          CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "bar")
        ),
+       (0...3),
        (4...5)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt b/test/yarp/snapshots/whitequark/ruby_bug_12073.txt
index 8a3aee68..7614f1b1 100644
--- a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt
+++ b/test/yarp/snapshots/whitequark/ruby_bug_12073.txt
@@ -4,8 +4,8 @@ ProgramNode(0...49)(
     [LocalVariableWriteNode(0...5)(
        :a,
        0,
-       (0...1),
        IntegerNode(4...5)(),
+       (0...1),
        (2...3)
      ),
      CallNode(7...13)(
diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12402.txt b/test/yarp/snapshots/whitequark/ruby_bug_12402.txt
index 7bcef829..f2980c1d 100644
--- a/test/yarp/snapshots/whitequark/ruby_bug_12402.txt
+++ b/test/yarp/snapshots/whitequark/ruby_bug_12402.txt
@@ -72,7 +72,6 @@ ProgramNode(0...437)(
      LocalVariableWriteNode(59...85)(
        :foo,
        0,
-       (59...62),
        CallNode(65...85)(
          nil,
          nil,
@@ -100,12 +99,12 @@ ProgramNode(0...437)(
          0,
          "raise"
        ),
+       (59...62),
        (63...64)
      ),
      LocalVariableWriteNode(87...114)(
        :foo,
        0,
-       (87...90),
        RescueModifierNode(93...114)(
          CallNode(93...103)(
            nil,
@@ -133,6 +132,7 @@ ProgramNode(0...437)(
          (104...110),
          NilNode(111...114)()
        ),
+       (87...90),
        (91...92)
      ),
      CallOperatorWriteNode(116...145)(
diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12669.txt b/test/yarp/snapshots/whitequark/ruby_bug_12669.txt
index 689a3d9a..f5ec48ce 100644
--- a/test/yarp/snapshots/whitequark/ruby_bug_12669.txt
+++ b/test/yarp/snapshots/whitequark/ruby_bug_12669.txt
@@ -34,7 +34,6 @@ ProgramNode(0...74)(
        LocalVariableWriteNode(25...37)(
          :b,
          0,
-         (25...26),
          CallNode(29...37)(
            nil,
            nil,
@@ -48,6 +47,7 @@ ProgramNode(0...74)(
            0,
            "raise"
          ),
+         (25...26),
          (27...28)
        ),
        :a,
@@ -57,7 +57,6 @@ ProgramNode(0...74)(
      LocalVariableWriteNode(39...56)(
        :a,
        0,
-       (39...40),
        LocalVariableOperatorWriteNode(43...56)(
          (43...44),
          (45...47),
@@ -78,16 +77,15 @@ ProgramNode(0...74)(
          :+,
          0
        ),
+       (39...40),
        (41...42)
      ),
      LocalVariableWriteNode(58...74)(
        :a,
        0,
-       (58...59),
        LocalVariableWriteNode(62...74)(
          :b,
          0,
-         (62...63),
          CallNode(66...74)(
            nil,
            nil,
@@ -101,8 +99,10 @@ ProgramNode(0...74)(
            0,
            "raise"
          ),
+         (62...63),
          (64...65)
        ),
+       (58...59),
        (60...61)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt
index 6302c3d3..3cdaf914 100644
--- a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt
+++ b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt
@@ -25,7 +25,6 @@ ProgramNode(0...33)(
      LocalVariableWriteNode(21...33)(
        :o,
        0,
-       (21...22),
        HashNode(25...33)(
          (25...26),
          [AssocNode(27...31)(
@@ -35,6 +34,7 @@ ProgramNode(0...33)(
           )],
          (32...33)
        ),
+       (21...22),
        (23...24)
      )]
   )
diff --git a/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt b/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt
index 3f77bfd3..245f8a07 100644
--- a/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt
+++ b/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt
@@ -4,8 +4,8 @@ ProgramNode(0...13)(
     [LocalVariableWriteNode(0...3)(
        :t,
        0,
-       (0...1),
        IntegerNode(2...3)(),
+       (0...1),
        (1...2)
      ),
      IfNode(4...13)(