Repository: ruby/yarp
Pull request #1552 (2023-09-19 16:31:10)

Better Node#pretty_print
Respect the current indentation


Patch:
diff --git a/config.yml b/config.yml
index 59406fed..fbaea52f 100644
--- a/config.yml
+++ b/config.yml
@@ -668,6 +668,7 @@ nodes:
         type: location?
       - name: block
         type: node?
+        kind: BlockNode
       - name: flags
         type: flags
         kind: CallNodeFlags
@@ -2314,6 +2315,7 @@ nodes:
         type: location?
       - name: block
         type: node?
+        kind: BlockNode
     comment: |
       Represents the use of the `super` keyword with parentheses or arguments.
 
diff --git a/ext/yarp/extension.c b/ext/yarp/extension.c
index b5fe43b3..f951b0c4 100644
--- a/ext/yarp/extension.c
+++ b/ext/yarp/extension.c
@@ -491,12 +491,6 @@ unescape_minimal(VALUE self, VALUE source) {
     return unescape(source, YP_UNESCAPE_MINIMAL);
 }
 
-// Escape the given string minimally plus whitespace. Returns the unescaped string.
-static VALUE
-unescape_whitespace(VALUE self, VALUE source) {
-    return unescape(source, YP_UNESCAPE_WHITESPACE);
-}
-
 // Unescape everything in the given string. Return the unescaped string.
 static VALUE
 unescape_all(VALUE self, VALUE source) {
@@ -614,7 +608,6 @@ Init_yarp(void) {
     rb_define_singleton_method(rb_cYARPDebug, "named_captures", named_captures, 1);
     rb_define_singleton_method(rb_cYARPDebug, "unescape_none", unescape_none, 1);
     rb_define_singleton_method(rb_cYARPDebug, "unescape_minimal", unescape_minimal, 1);
-    rb_define_singleton_method(rb_cYARPDebug, "unescape_whitespace", unescape_whitespace, 1);
     rb_define_singleton_method(rb_cYARPDebug, "unescape_all", unescape_all, 1);
     rb_define_singleton_method(rb_cYARPDebug, "memsize", memsize, 1);
     rb_define_singleton_method(rb_cYARPDebug, "profile_file", profile_file, 1);
diff --git a/include/yarp/unescape.h b/include/yarp/unescape.h
index bb0ef315..fb0df9fc 100644
--- a/include/yarp/unescape.h
+++ b/include/yarp/unescape.h
@@ -24,13 +24,9 @@ typedef enum {
     // single quotes and backslashes.
     YP_UNESCAPE_MINIMAL,
 
-    // When we're unescaping a string list, in addition to MINIMAL, we need to
-    // unescape whitespace.
-    YP_UNESCAPE_WHITESPACE,
-
     // When we're unescaping a double-quoted string, we need to unescape all
     // escapes.
-    YP_UNESCAPE_ALL,
+    YP_UNESCAPE_ALL
 } yp_unescape_type_t;
 
 // Unescape the contents of the given token into the given string using the given unescape mode.
diff --git a/include/yarp/util/yp_constant_pool.h b/include/yarp/util/yp_constant_pool.h
index c07cd0b7..ecd3ff61 100644
--- a/include/yarp/util/yp_constant_pool.h
+++ b/include/yarp/util/yp_constant_pool.h
@@ -44,20 +44,20 @@ typedef struct {
     bool owned: 1;
     const uint8_t *start;
     size_t length;
-    uint32_t hash;
+    size_t hash;
 } yp_constant_t;
 
 typedef struct {
     yp_constant_t *constants;
-    uint32_t size;
-    uint32_t capacity;
+    size_t size;
+    size_t capacity;
 } yp_constant_pool_t;
 
 // Define an empty constant pool.
 #define YP_CONSTANT_POOL_EMPTY ((yp_constant_pool_t) { .constants = NULL, .size = 0, .capacity = 0 })
 
 // Initialize a new constant pool with a given capacity.
-bool yp_constant_pool_init(yp_constant_pool_t *pool, uint32_t capacity);
+bool yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity);
 
 // Insert a constant into a constant pool that is a slice of a source string.
 // Returns the id of the constant, or 0 if any potential calls to resize fail.
diff --git a/lib/yarp.rb b/lib/yarp.rb
index 28f0fae0..ed1bb685 100644
--- a/lib/yarp.rb
+++ b/lib/yarp.rb
@@ -307,7 +307,10 @@ module YARP
     end
 
     def pretty_print(q)
-      q.text(inspect.chomp)
+      q.seplist(inspect.chomp.each_line, -> { q.breakable }) do |line|
+        q.text(line.chomp)
+      end
+      q.current_group.break
     end
   end
 
diff --git a/rust/yarp/build.rs b/rust/yarp/build.rs
index 2b190f1c..d51b3ce7 100644
--- a/rust/yarp/build.rs
+++ b/rust/yarp/build.rs
@@ -552,7 +552,7 @@ impl<'pr> ConstantId<'pr> {{
         unsafe {{
             let pool = &(*self.parser.as_ptr()).constant_pool;
             for i in 0..pool.capacity {{
-                let constant = &(*pool.constants.add(i.try_into().unwrap()));
+                let constant = &(*pool.constants.add(i));
                 if constant.id() == self.id {{
                     return std::slice::from_raw_parts(constant.start, constant.length);
                 }}
diff --git a/src/unescape.c b/src/unescape.c
index 6ecb8f49..9da52eae 100644
--- a/src/unescape.c
+++ b/src/unescape.c
@@ -509,17 +509,7 @@ yp_unescape_manipulate_string_or_char_literal(yp_parser_t *parser, yp_string_t *
                 cursor = backslash + 2;
                 break;
             default:
-                if (unescape_type == YP_UNESCAPE_WHITESPACE) {
-                    if (backslash[1] == '\r' && backslash[2] == '\n') {
-                        cursor = backslash + 2;
-                        break;
-                    }
-                    if (yp_strspn_whitespace(backslash + 1, 1)) {
-                        cursor = backslash + 1;
-                        break;
-                    }
-                }
-                if (unescape_type == YP_UNESCAPE_WHITESPACE || unescape_type == YP_UNESCAPE_MINIMAL) {
+                if (unescape_type == YP_UNESCAPE_MINIMAL) {
                     // In this case we're escaping something that doesn't need escaping.
                     dest[dest_length++] = '\\';
                     cursor = backslash + 1;
@@ -589,16 +579,7 @@ yp_unescape_calculate_difference(yp_parser_t *parser, const uint8_t *backslash,
         case '\'':
             return 2;
         default: {
-            if (unescape_type == YP_UNESCAPE_WHITESPACE) {
-                if (backslash[1] == '\r' && backslash[2] == '\n') {
-                    return 2;
-                }
-                size_t whitespace = yp_strspn_whitespace(backslash + 1, 1);
-                if (whitespace > 0) {
-                    return whitespace;
-                }
-            }
-            if (unescape_type == YP_UNESCAPE_WHITESPACE || unescape_type == YP_UNESCAPE_MINIMAL) {
+            if (unescape_type == YP_UNESCAPE_MINIMAL) {
                 return 1 + yp_char_width(parser, backslash + 1, parser->end);
             }
 
diff --git a/src/util/yp_constant_pool.c b/src/util/yp_constant_pool.c
index 18376dce..b8dc5772 100644
--- a/src/util/yp_constant_pool.c
+++ b/src/util/yp_constant_pool.c
@@ -47,10 +47,10 @@ yp_constant_id_list_free(yp_constant_id_list_t *list) {
 
 // A relatively simple hash function (djb2) that is used to hash strings. We are
 // optimizing here for simplicity and speed.
-static inline uint32_t
+static inline size_t
 yp_constant_pool_hash(const uint8_t *start, size_t length) {
     // This is a prime number used as the initial value for the hash function.
-    uint32_t value = 5381;
+    size_t value = 5381;
 
     for (size_t index = 0; index < length; index++) {
         value = ((value << 5) + value) + start[index];
@@ -60,8 +60,8 @@ yp_constant_pool_hash(const uint8_t *start, size_t length) {
 }
 
 // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
-static uint32_t
-next_power_of_two(uint32_t v) {
+static size_t
+next_power_of_two(size_t v) {
     // Avoid underflow in subtraction on next line.
     if (v == 0) {
         // 1 is the nearest power of 2 to 0 (2^0)
@@ -73,13 +73,16 @@ next_power_of_two(uint32_t v) {
     v |= v >> 4;
     v |= v >> 8;
     v |= v >> 16;
+#if defined(__LP64__) || defined(_WIN64)
+    v |= v >> 32;
+#endif
     v++;
     return v;
 }
 
 #ifndef NDEBUG
 static bool
-is_power_of_two(uint32_t size) {
+is_power_of_two(size_t size) {
     return (size & (size - 1)) == 0;
 }
 #endif
@@ -88,23 +91,22 @@ is_power_of_two(uint32_t size) {
 static inline bool
 yp_constant_pool_resize(yp_constant_pool_t *pool) {
     assert(is_power_of_two(pool->capacity));
-
-    uint32_t next_capacity = pool->capacity * 2;
+    size_t next_capacity = pool->capacity * 2;
     if (next_capacity < pool->capacity) return false;
 
-    const uint32_t mask = next_capacity - 1;
+    const size_t mask = next_capacity - 1;
     yp_constant_t *next_constants = calloc(next_capacity, sizeof(yp_constant_t));
     if (next_constants == NULL) return false;
 
     // For each constant in the current constant pool, rehash the content, find
     // the index in the next constant pool, and insert it.
-    for (uint32_t index = 0; index < pool->capacity; index++) {
+    for (size_t index = 0; index < pool->capacity; index++) {
         yp_constant_t *constant = &pool->constants[index];
 
         // If an id is set on this constant, then we know we have content here.
         // In this case we need to insert it into the next constant pool.
         if (constant->id != 0) {
-            uint32_t next_index = constant->hash & mask;
+            size_t next_index = constant->hash & mask;
 
             // This implements linear scanning to find the next available slot
             // in case this index is already taken. We don't need to bother
@@ -127,9 +129,9 @@ yp_constant_pool_resize(yp_constant_pool_t *pool) {
 
 // Initialize a new constant pool with a given capacity.
 bool
-yp_constant_pool_init(yp_constant_pool_t *pool, uint32_t capacity) {
-    const uint32_t maximum = (~((uint32_t) 0));
-    if (capacity >= ((maximum / 2) + 1)) return false;
+yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity) {
+    const size_t size_t_max = (~((size_t) 0));
+    if (capacity >= ((size_t_max / 2) + 1)) return false;
 
     capacity = next_power_of_two(capacity);
     pool->constants = calloc(capacity, sizeof(yp_constant_t));
@@ -148,10 +150,9 @@ yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t l
     }
 
     assert(is_power_of_two(pool->capacity));
-    const uint32_t mask = pool->capacity - 1;
-
-    uint32_t hash = yp_constant_pool_hash(start, length);
-    uint32_t index = hash & mask;
+    const size_t mask = pool->capacity - 1;
+    size_t hash = yp_constant_pool_hash(start, length);
+    size_t index = hash & mask;
     yp_constant_t *constant;
 
     while (constant = &pool->constants[index], constant->id != 0) {
@@ -184,7 +185,7 @@ yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t l
     }
 
     pool->size++;
-    assert(pool->size < ((uint32_t) (1 << 31)));
+    assert(pool->size < ((size_t) (1 << 31)));
 
     *constant = (yp_constant_t) {
         .id = (unsigned int) (pool->size & 0x7FFFFFFF),
diff --git a/src/yarp.c b/src/yarp.c
index d38871f0..6dc71413 100644
--- a/src/yarp.c
+++ b/src/yarp.c
@@ -549,7 +549,11 @@ typedef struct {
     yp_location_t opening_loc;
     yp_arguments_node_t *arguments;
     yp_location_t closing_loc;
-    yp_node_t *block;
+    yp_block_node_t *block;
+
+    // This boolean is used to tell if there is an implicit block (i.e., an
+    // argument passed with an & operator).
+    bool implicit_block;
 } yp_arguments_t;
 
 #define YP_EMPTY_ARGUMENTS ((yp_arguments_t) {              \
@@ -557,37 +561,36 @@ typedef struct {
     .arguments = NULL,                                      \
     .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, \
     .block = NULL,                                          \
+    .implicit_block = false                                 \
 })
 
-// Check that we're not about to attempt to attach a brace block to a call that
-// has arguments without parentheses.
+// Check that the set of arguments parsed for a given node is valid. This means
+// checking that we don't have both an implicit and explicit block.
 static void
-yp_arguments_validate_block(yp_parser_t *parser, yp_arguments_t *arguments, yp_block_node_t *block) {
-    // First, check that we have arguments and that we don't have a closing
-    // location for them.
-    if (arguments->arguments == NULL || arguments->closing_loc.start != NULL) {
-        return;
+yp_arguments_validate(yp_parser_t *parser, yp_arguments_t *arguments) {
+    if (arguments->block != NULL && arguments->implicit_block) {
+        yp_diagnostic_list_append(
+            &parser->error_list,
+            arguments->block->base.location.start,
+            arguments->block->base.location.end,
+            YP_ERR_ARGUMENT_BLOCK_MULTI
+        );
     }
 
-    // Next, check that we don't have a single parentheses argument. This would
-    // look like:
-    //
-    //     foo (1) {}
-    //
-    // In this case, it's actually okay for the block to be attached to the
-    // call, even though it looks like it's attached to the argument.
-    if (arguments->arguments->arguments.size == 1 && YP_NODE_TYPE_P(arguments->arguments->arguments.nodes[0], YP_PARENTHESES_NODE)) {
-        return;
+    // Brace blocks can't be attached to arguments, only to the call
+    if (arguments->block != NULL &&
+            *arguments->block->opening_loc.start == '{' &&
+            arguments->arguments != NULL &&
+            !(arguments->arguments->arguments.size == 1 &&
+                YP_NODE_TYPE_P(arguments->arguments->arguments.nodes[0], YP_PARENTHESES_NODE)) &&
+            !arguments->closing_loc.end) {
+        yp_diagnostic_list_append(
+            &parser->error_list,
+            arguments->block->base.location.start,
+            arguments->block->base.location.end,
+            YP_ERR_ARGUMENT_BLOCK_MULTI
+        );
     }
-
-    // If we didn't hit a case before this check, then at this point we need to
-    // add a syntax error.
-    yp_diagnostic_list_append(
-        &parser->error_list,
-        block->base.location.start,
-        block->base.location.end,
-        YP_ERR_ARGUMENT_UNEXPECTED_BLOCK
-    );
 }
 
 /******************************************************************************/
@@ -1337,7 +1340,7 @@ yp_call_node_aref_create(yp_parser_t *parser, yp_node_t *receiver, yp_arguments_
 
     node->base.location.start = receiver->location.start;
     if (arguments->block != NULL) {
-        node->base.location.end = arguments->block->location.end;
+        node->base.location.end = arguments->block->base.location.end;
     } else {
         node->base.location.end = arguments->closing_loc.end;
     }
@@ -1381,7 +1384,7 @@ yp_call_node_call_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *o
 
     node->base.location.start = receiver->location.start;
     if (arguments->block != NULL) {
-        node->base.location.end = arguments->block->location.end;
+        node->base.location.end = arguments->block->base.location.end;
     } else if (arguments->closing_loc.start != NULL) {
         node->base.location.end = arguments->closing_loc.end;
     } else if (arguments->arguments != NULL) {
@@ -1414,7 +1417,7 @@ yp_call_node_fcall_create(yp_parser_t *parser, yp_token_t *message, yp_arguments
 
     node->base.location.start = message->start;
     if (arguments->block != NULL) {
-        node->base.location.end = arguments->block->location.end;
+        node->base.location.end = arguments->block->base.location.end;
     } else if (arguments->closing_loc.start != NULL) {
         node->base.location.end = arguments->closing_loc.end;
     } else if (arguments->arguments != NULL) {
@@ -1462,7 +1465,7 @@ yp_call_node_shorthand_create(yp_parser_t *parser, yp_node_t *receiver, yp_token
 
     node->base.location.start = receiver->location.start;
     if (arguments->block != NULL) {
-        node->base.location.end = arguments->block->location.end;
+        node->base.location.end = arguments->block->base.location.end;
     } else {
         node->base.location.end = arguments->closing_loc.end;
     }
@@ -2411,24 +2414,18 @@ yp_forwarding_parameter_node_create(yp_parser_t *parser, const yp_token_t *token
 // Allocate and initialize a new ForwardingSuper node.
 static yp_forwarding_super_node_t *
 yp_forwarding_super_node_create(yp_parser_t *parser, const yp_token_t *token, yp_arguments_t *arguments) {
-    assert(arguments->block == NULL || YP_NODE_TYPE_P(arguments->block, YP_BLOCK_NODE));
     assert(token->type == YP_TOKEN_KEYWORD_SUPER);
     yp_forwarding_super_node_t *node = YP_ALLOC_NODE(parser, yp_forwarding_super_node_t);
 
-    yp_block_node_t *block = NULL;
-    if (arguments->block != NULL) {
-        block = (yp_block_node_t *) arguments->block;
-    }
-
     *node = (yp_forwarding_super_node_t) {
         {
             .type = YP_FORWARDING_SUPER_NODE,
             .location = {
                 .start = token->start,
-                .end = block != NULL ? block->base.location.end : token->end
+                .end = arguments->block != NULL ? arguments->block->base.location.end : token->end
             },
         },
-        .block = block
+        .block = arguments->block
     };
 
     return node;
@@ -4285,7 +4282,7 @@ yp_super_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_argument
 
     const uint8_t *end;
     if (arguments->block != NULL) {
-        end = arguments->block->location.end;
+        end = arguments->block->base.location.end;
     } else if (arguments->closing_loc.start != NULL) {
         end = arguments->closing_loc.end;
     } else if (arguments->arguments != NULL) {
@@ -8897,16 +8894,6 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) {
     }
 }
 
-// Append an argument to a list of arguments.
-static inline void
-parse_arguments_append(yp_parser_t *parser, yp_arguments_t *arguments, yp_node_t *argument) {
-    if (arguments->arguments == NULL) {
-        arguments->arguments = yp_arguments_node_create(parser);
-    }
-
-    yp_arguments_node_arguments_append(arguments->arguments, argument);
-}
-
 // Parse a list of arguments.
 static void
 parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_forwarding, yp_token_type_t terminator) {
@@ -8940,14 +8927,13 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
                 }
 
                 yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser);
-                argument = (yp_node_t *) hash;
+                argument = (yp_node_t *)hash;
 
                 if (!match7(parser, terminator, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON, YP_TOKEN_EOF, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_KEYWORD_DO, YP_TOKEN_PARENTHESIS_RIGHT)) {
                     parse_assocs(parser, (yp_node_t *) hash);
                 }
 
                 parsed_bare_hash = true;
-                parse_arguments_append(parser, arguments, argument);
                 break;
             }
             case YP_TOKEN_UAMPERSAND: {
@@ -8961,14 +8947,9 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
                     yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_AMP);
                 }
 
-                argument = (yp_node_t *) yp_block_argument_node_create(parser, &operator, expression);
-                if (parsed_block_argument) {
-                    parse_arguments_append(parser, arguments, argument);
-                } else {
-                    arguments->block = argument;
-                }
-
+                argument = (yp_node_t *)yp_block_argument_node_create(parser, &operator, expression);
                 parsed_block_argument = true;
+                arguments->implicit_block = true;
                 break;
             }
             case YP_TOKEN_USTAR: {
@@ -8991,7 +8972,6 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
                     argument = (yp_node_t *) yp_splat_node_create(parser, &operator, expression);
                 }
 
-                parse_arguments_append(parser, arguments, argument);
                 break;
             }
             case YP_TOKEN_UDOT_DOT_DOT: {
@@ -9009,8 +8989,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
                             yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES);
                         }
 
-                        argument = (yp_node_t *) yp_forwarding_arguments_node_create(parser, &parser->previous);
-                        parse_arguments_append(parser, arguments, argument);
+                        argument = (yp_node_t *)yp_forwarding_arguments_node_create(parser, &parser->previous);
                         break;
                     }
                 }
@@ -9053,11 +9032,12 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for
                     parsed_bare_hash = true;
                 }
 
-                parse_arguments_append(parser, arguments, argument);
                 break;
             }
         }
 
+        yp_arguments_node_arguments_append(arguments->arguments, argument);
+
         // If parsing the argument failed, we need to stop parsing arguments.
         if (YP_NODE_TYPE_P(argument, YP_MISSING_NODE) || parser->recovering) break;
 
@@ -9757,6 +9737,8 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept
         if (accept1(parser, YP_TOKEN_PARENTHESIS_RIGHT)) {
             arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous);
         } else {
+            arguments->arguments = yp_arguments_node_create(parser);
+
             yp_accepts_block_stack_push(parser, true);
             parse_arguments(parser, arguments, true, YP_TOKEN_PARENTHESIS_RIGHT);
             expect1(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_ARGUMENT_TERM_PAREN);
@@ -9771,6 +9753,7 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept
         // If we get here, then the subsequent token cannot be used as an infix
         // operator. In this case we assume the subsequent token is part of an
         // argument to this method call.
+        arguments->arguments = yp_arguments_node_create(parser);
         parse_arguments(parser, arguments, true, YP_TOKEN_EOF);
 
         yp_accepts_block_stack_pop(parser);
@@ -9780,28 +9763,16 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept
     // node that starts with a {. If there is, then we can parse it and add it to
     // the arguments.
     if (accepts_block) {
-        yp_block_node_t *block = NULL;
-
         if (accept1(parser, YP_TOKEN_BRACE_LEFT)) {
             found |= true;
-            block = parse_block(parser);
-            yp_arguments_validate_block(parser, arguments, block);
+            arguments->block = parse_block(parser);
         } else if (yp_accepts_block_stack_p(parser) && accept1(parser, YP_TOKEN_KEYWORD_DO)) {
             found |= true;
-            block = parse_block(parser);
-        }
-
-        if (block != NULL) {
-            if (arguments->block == NULL) {
-                arguments->block = (yp_node_t *) block;
-            } else {
-                yp_diagnostic_list_append(&parser->error_list, block->base.location.start, block->base.location.end, YP_ERR_ARGUMENT_BLOCK_MULTI);
-                yp_arguments_node_arguments_append(arguments->arguments, arguments->block);
-                arguments->block = (yp_node_t *) block;
-            }
+            arguments->block = parse_block(parser);
         }
     }
 
+    yp_arguments_validate(parser, arguments);
     return found;
 }
 
@@ -11735,7 +11706,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
                     call->block = arguments.block;
 
                     if (arguments.block != NULL) {
-                        call->base.location.end = arguments.block->location.end;
+                        call->base.location.end = arguments.block->base.location.end;
                     } else if (arguments.closing_loc.start == NULL) {
                         if (arguments.arguments != NULL) {
                             call->base.location.end = arguments.arguments->base.location.end;
@@ -12154,6 +12125,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
                 yp_binding_power_t binding_power = yp_binding_powers[parser->current.type].left;
 
                 if (binding_power == YP_BINDING_POWER_UNSET || binding_power >= YP_BINDING_POWER_RANGE) {
+                    arguments.arguments = yp_arguments_node_create(parser);
                     parse_arguments(parser, &arguments, false, YP_TOKEN_EOF);
                 }
             }
@@ -12987,7 +12959,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) {
 
                 yp_token_t opening = not_provided(parser);
                 yp_token_t closing = not_provided(parser);
-                yp_node_t *string = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_WHITESPACE);
+                yp_node_t *string = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_MINIMAL);
                 yp_array_node_elements_append(array, string);
             }
 
@@ -14111,8 +14083,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
 
             if (!accept1(parser, YP_TOKEN_BRACKET_RIGHT)) {
                 yp_accepts_block_stack_push(parser, true);
+                arguments.arguments = yp_arguments_node_create(parser);
+
                 parse_arguments(parser, &arguments, false, YP_TOKEN_BRACKET_RIGHT);
                 yp_accepts_block_stack_pop(parser);
+
                 expect1(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_EXPECT_RBRACKET);
             }
 
@@ -14128,23 +14103,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t
             // If we're at the end of the arguments, we can now check if there is a
             // block node that starts with a {. If there is, then we can parse it and
             // add it to the arguments.
-            yp_block_node_t *block = NULL;
             if (accept1(parser, YP_TOKEN_BRACE_LEFT)) {
-                block = parse_block(parser);
-                yp_arguments_validate_block(parser, &arguments, block);
+                arguments.block = parse_block(parser);
             } else if (yp_accepts_block_stack_p(parser) && accept1(parser, YP_TOKEN_KEYWORD_DO)) {
-                block = parse_block(parser);
-            }
-
-            if (block != NULL) {
-                if (arguments.block != NULL) {
-                    yp_diagnostic_list_append(&parser->error_list, block->base.location.start, block->base.location.end, YP_ERR_ARGUMENT_AFTER_BLOCK);
-                    yp_arguments_node_arguments_append(arguments.arguments, arguments.block);
-                }
-
-                arguments.block = (yp_node_t *) block;
+                arguments.block = parse_block(parser);
             }
 
+            yp_arguments_validate(parser, &arguments);
             return (yp_node_t *) yp_call_node_aref_create(parser, node, &arguments);
         }
         case YP_TOKEN_KEYWORD_IN: {
@@ -14381,7 +14346,7 @@ yp_parser_init(yp_parser_t *parser, const uint8_t *source, size_t size, const ch
     //
     // This ratio will need to change if we add more constants to the constant
     // pool for another node type.
-    uint32_t constant_size = ((uint32_t) size) / 95;
+    size_t constant_size = size / 95;
     yp_constant_pool_init(&parser->constant_pool, constant_size < 4 ? 4 : constant_size);
 
     // Initialize the newline list. Similar to the constant pool, we're going to
diff --git a/templates/ext/yarp/api_node.c.erb b/templates/ext/yarp/api_node.c.erb
index d05e0f9b..a0d52899 100644
--- a/templates/ext/yarp/api_node.c.erb
+++ b/templates/ext/yarp/api_node.c.erb
@@ -81,7 +81,7 @@ yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) {
     VALUE source = yp_source_new(parser, encoding);
     ID *constants = calloc(parser->constant_pool.size, sizeof(ID));
 
-    for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) {
+    for (size_t index = 0; index < parser->constant_pool.capacity; index++) {
         yp_constant_t constant = parser->constant_pool.constants[index];
 
         if (constant.id != 0) {
diff --git a/templates/src/node.c.erb b/templates/src/node.c.erb
index f21144f1..9f231239 100644
--- a/templates/src/node.c.erb
+++ b/templates/src/node.c.erb
@@ -102,14 +102,6 @@ yp_node_memsize_node(yp_node_t *node, yp_memsize_t *memsize) {
         case <%= node.type %>: {
             yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node;
             memsize->memsize += sizeof(*cast);
-            <%- if node.fields.any? { |f| f.is_a?(YARP::NodeListField) } -%>
-            // Node lists will add in their own sizes below.
-            memsize->memsize -= sizeof(yp_node_list_t) * <%= node.fields.count { |f| f.is_a?(YARP::NodeListField) } %>;
-            <%- end -%>
-            <%- if node.fields.any? { |f| f.is_a?(YARP::ConstantListField) } -%>
-            // Constant id lists will add in their own sizes below.
-            memsize->memsize -= sizeof(yp_constant_id_list_t) * <%= node.fields.count { |f| f.is_a?(YARP::ConstantListField) } %>;
-            <%- end -%>
             <%- node.fields.each do |field| -%>
             <%- case field -%>
             <%- when YARP::ConstantField, YARP::OptionalConstantField, YARP::UInt32Field, YARP::FlagsField, YARP::LocationField, YARP::OptionalLocationField -%>
@@ -122,7 +114,7 @@ yp_node_memsize_node(yp_node_t *node, yp_memsize_t *memsize) {
             <%- when YARP::StringField -%>
             memsize->memsize += yp_string_memsize(&cast-><%= field.name %>);
             <%- when YARP::NodeListField -%>
-            memsize->memsize += yp_node_list_memsize(&cast-><%= field.name %>, memsize);
+            yp_node_list_memsize(&cast-><%= field.name %>, memsize);
             <%- when YARP::ConstantListField -%>
             memsize->memsize += yp_constant_id_list_memsize(&cast-><%= field.name %>);
             <%- else -%>
diff --git a/templates/src/serialize.c.erb b/templates/src/serialize.c.erb
index 13efd893..b60bce21 100644
--- a/templates/src/serialize.c.erb
+++ b/templates/src/serialize.c.erb
@@ -185,7 +185,7 @@ yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer)
     yp_buffer_append_zeroes(buffer, 4);
 
     // Next, encode the length of the constant pool.
-    yp_buffer_append_u32(buffer, parser->constant_pool.size);
+    yp_buffer_append_u32(buffer, yp_sizet_to_u32(parser->constant_pool.size));
 
     // Now we're going to serialize the content of the node.
     yp_serialize_node(parser, node, buffer);
@@ -200,7 +200,7 @@ yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer)
     yp_buffer_append_zeroes(buffer, parser->constant_pool.size * 8);
 
     yp_constant_t *constant;
-    for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) {
+    for (size_t index = 0; index < parser->constant_pool.capacity; index++) {
         constant = &parser->constant_pool.constants[index];
 
         // If we find a constant at this index, serialize it at the correct


Test patch:
diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb
index 5a4d469c..9664c471 100644
--- a/test/yarp/errors_test.rb
+++ b/test/yarp/errors_test.rb
@@ -364,9 +364,12 @@ module YARP
         nil,
         Location(),
         Location(),
-        ArgumentsNode([expression("foo")]),
+        ArgumentsNode([
+          BlockArgumentNode(expression("block"), Location()),
+          expression("foo")
+        ]),
         Location(),
-        BlockArgumentNode(expression("block"), Location()),
+        nil,
         0,
         "a"
       )
diff --git a/test/yarp/location_test.rb b/test/yarp/location_test.rb
index a8e9b345..1c9aa104 100644
--- a/test/yarp/location_test.rb
+++ b/test/yarp/location_test.rb
@@ -68,7 +68,7 @@ module YARP
     end
 
     def test_BlockArgumentNode
-      assert_location(BlockArgumentNode, "foo(&bar)", 4...8, &:block)
+      assert_location(BlockArgumentNode, "foo(&bar)", 4...8) { |node| node.arguments.arguments.last }
     end
 
     def test_BlockLocalVariableNode
diff --git a/test/yarp/snapshots/constants.txt b/test/yarp/snapshots/constants.txt
index 3238f9e9..0e650050 100644
--- a/test/yarp/snapshots/constants.txt
+++ b/test/yarp/snapshots/constants.txt
@@ -135,22 +135,24 @@
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (71...74) = "Foo"
         │   ├── opening_loc: ∅
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (75...79))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (75...79))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (76...79))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (76...79) = "bar"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "bar"
+        │   │           └── operator_loc: (75...76) = "&"
         │   ├── closing_loc: ∅
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (75...79))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (76...79))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (76...79) = "bar"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "bar"
-        │   │   └── operator_loc: (75...76) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "Foo"
         ├── @ CallNode (location: (81...94))
@@ -216,22 +218,24 @@
         │   ├── call_operator_loc: (115...117) = "::"
         │   ├── message_loc: (117...120) = "Bar"
         │   ├── opening_loc: ∅
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (121...125))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (121...125))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (122...125))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (122...125) = "baz"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "baz"
+        │   │           └── operator_loc: (121...122) = "&"
         │   ├── closing_loc: ∅
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (121...125))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (122...125))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (122...125) = "baz"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "baz"
-        │   │   └── operator_loc: (121...122) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "Bar"
         ├── @ CallNode (location: (127...135))
diff --git a/test/yarp/snapshots/method_calls.txt b/test/yarp/snapshots/method_calls.txt
index 0225e1d1..55dd0cdf 100644
--- a/test/yarp/snapshots/method_calls.txt
+++ b/test/yarp/snapshots/method_calls.txt
@@ -267,27 +267,29 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "a?"
-        ├── @ CallNode (location: (108...116))
+        ├── @ CallNode (location: (108...117))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (108...109) = "a"
         │   ├── opening_loc: (109...110) = "("
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (110...116))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (110...116))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (111...116))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (111...116) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (110...111) = "&"
         │   ├── closing_loc: (116...117) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (110...116))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (111...116))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (111...116) = "block"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "block"
-        │   │   └── operator_loc: (110...111) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "a"
         ├── @ CallNode (location: (119...130))
@@ -749,68 +751,68 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
-        ├── @ CallNode (location: (300...339))
+        ├── @ CallNode (location: (300...340))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (300...303) = "foo"
         │   ├── opening_loc: (303...304) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (304...332))
-        │   │   └── arguments: (length: 2)
+        │   │   @ ArgumentsNode (location: (304...339))
+        │   │   └── arguments: (length: 3)
         │   │       ├── @ SymbolNode (location: (304...306))
         │   │       │   ├── opening_loc: (304...305) = ":"
         │   │       │   ├── value_loc: (305...306) = "a"
         │   │       │   ├── closing_loc: ∅
         │   │       │   └── unescaped: "a"
-        │   │       └── @ KeywordHashNode (location: (308...332))
-        │   │           └── elements: (length: 2)
-        │   │               ├── @ AssocNode (location: (308...322))
-        │   │               │   ├── key:
-        │   │               │   │   @ SymbolNode (location: (308...310))
-        │   │               │   │   ├── opening_loc: (308...309) = ":"
-        │   │               │   │   ├── value_loc: (309...310) = "h"
-        │   │               │   │   ├── closing_loc: ∅
-        │   │               │   │   └── unescaped: "h"
-        │   │               │   ├── value:
-        │   │               │   │   @ ArrayNode (location: (314...322))
-        │   │               │   │   ├── elements: (length: 2)
-        │   │               │   │   │   ├── @ SymbolNode (location: (315...317))
-        │   │               │   │   │   │   ├── opening_loc: (315...316) = ":"
-        │   │               │   │   │   │   ├── value_loc: (316...317) = "x"
-        │   │               │   │   │   │   ├── closing_loc: ∅
-        │   │               │   │   │   │   └── unescaped: "x"
-        │   │               │   │   │   └── @ SymbolNode (location: (319...321))
-        │   │               │   │   │       ├── opening_loc: (319...320) = ":"
-        │   │               │   │   │       ├── value_loc: (320...321) = "y"
-        │   │               │   │   │       ├── closing_loc: ∅
-        │   │               │   │   │       └── unescaped: "y"
-        │   │               │   │   ├── opening_loc: (314...315) = "["
-        │   │               │   │   └── closing_loc: (321...322) = "]"
-        │   │               │   └── operator_loc: (311...313) = "=>"
-        │   │               └── @ AssocNode (location: (324...332))
-        │   │                   ├── key:
-        │   │                   │   @ SymbolNode (location: (324...326))
-        │   │                   │   ├── opening_loc: (324...325) = ":"
-        │   │                   │   ├── value_loc: (325...326) = "a"
-        │   │                   │   ├── closing_loc: ∅
-        │   │                   │   └── unescaped: "a"
-        │   │                   ├── value:
-        │   │                   │   @ SymbolNode (location: (330...332))
-        │   │                   │   ├── opening_loc: (330...331) = ":"
-        │   │                   │   ├── value_loc: (331...332) = "b"
-        │   │                   │   ├── closing_loc: ∅
-        │   │                   │   └── unescaped: "b"
-        │   │                   └── operator_loc: (327...329) = "=>"
+        │   │       ├── @ KeywordHashNode (location: (308...332))
+        │   │       │   └── elements: (length: 2)
+        │   │       │       ├── @ AssocNode (location: (308...322))
+        │   │       │       │   ├── key:
+        │   │       │       │   │   @ SymbolNode (location: (308...310))
+        │   │       │       │   │   ├── opening_loc: (308...309) = ":"
+        │   │       │       │   │   ├── value_loc: (309...310) = "h"
+        │   │       │       │   │   ├── closing_loc: ∅
+        │   │       │       │   │   └── unescaped: "h"
+        │   │       │       │   ├── value:
+        │   │       │       │   │   @ ArrayNode (location: (314...322))
+        │   │       │       │   │   ├── elements: (length: 2)
+        │   │       │       │   │   │   ├── @ SymbolNode (location: (315...317))
+        │   │       │       │   │   │   │   ├── opening_loc: (315...316) = ":"
+        │   │       │       │   │   │   │   ├── value_loc: (316...317) = "x"
+        │   │       │       │   │   │   │   ├── closing_loc: ∅
+        │   │       │       │   │   │   │   └── unescaped: "x"
+        │   │       │       │   │   │   └── @ SymbolNode (location: (319...321))
+        │   │       │       │   │   │       ├── opening_loc: (319...320) = ":"
+        │   │       │       │   │   │       ├── value_loc: (320...321) = "y"
+        │   │       │       │   │   │       ├── closing_loc: ∅
+        │   │       │       │   │   │       └── unescaped: "y"
+        │   │       │       │   │   ├── opening_loc: (314...315) = "["
+        │   │       │       │   │   └── closing_loc: (321...322) = "]"
+        │   │       │       │   └── operator_loc: (311...313) = "=>"
+        │   │       │       └── @ AssocNode (location: (324...332))
+        │   │       │           ├── key:
+        │   │       │           │   @ SymbolNode (location: (324...326))
+        │   │       │           │   ├── opening_loc: (324...325) = ":"
+        │   │       │           │   ├── value_loc: (325...326) = "a"
+        │   │       │           │   ├── closing_loc: ∅
+        │   │       │           │   └── unescaped: "a"
+        │   │       │           ├── value:
+        │   │       │           │   @ SymbolNode (location: (330...332))
+        │   │       │           │   ├── opening_loc: (330...331) = ":"
+        │   │       │           │   ├── value_loc: (331...332) = "b"
+        │   │       │           │   ├── closing_loc: ∅
+        │   │       │           │   └── unescaped: "b"
+        │   │       │           └── operator_loc: (327...329) = "=>"
+        │   │       └── @ BlockArgumentNode (location: (334...339))
+        │   │           ├── expression:
+        │   │           │   @ SymbolNode (location: (335...339))
+        │   │           │   ├── opening_loc: (335...336) = ":"
+        │   │           │   ├── value_loc: (336...339) = "bar"
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   └── unescaped: "bar"
+        │   │           └── operator_loc: (334...335) = "&"
         │   ├── closing_loc: (339...340) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (334...339))
-        │   │   ├── expression:
-        │   │   │   @ SymbolNode (location: (335...339))
-        │   │   │   ├── opening_loc: (335...336) = ":"
-        │   │   │   ├── value_loc: (336...339) = "bar"
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "bar"
-        │   │   └── operator_loc: (334...335) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
         ├── @ CallNode (location: (342...391))
@@ -1061,48 +1063,48 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "hi"
-        ├── @ CallNode (location: (535...570))
+        ├── @ CallNode (location: (535...571))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (535...538) = "foo"
         │   ├── opening_loc: (538...539) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (539...561))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ HashNode (location: (539...561))
-        │   │           ├── opening_loc: (539...540) = "{"
-        │   │           ├── elements: (length: 2)
-        │   │           │   ├── @ AssocNode (location: (541...548))
-        │   │           │   │   ├── key:
-        │   │           │   │   │   @ SymbolNode (location: (541...543))
-        │   │           │   │   │   ├── opening_loc: ∅
-        │   │           │   │   │   ├── value_loc: (541...542) = "a"
-        │   │           │   │   │   ├── closing_loc: (542...543) = ":"
-        │   │           │   │   │   └── unescaped: "a"
-        │   │           │   │   ├── value:
-        │   │           │   │   │   @ TrueNode (location: (544...548))
-        │   │           │   │   └── operator_loc: ∅
-        │   │           │   └── @ AssocNode (location: (550...558))
-        │   │           │       ├── key:
-        │   │           │       │   @ SymbolNode (location: (550...552))
-        │   │           │       │   ├── opening_loc: ∅
-        │   │           │       │   ├── value_loc: (550...551) = "b"
-        │   │           │       │   ├── closing_loc: (551...552) = ":"
-        │   │           │       │   └── unescaped: "b"
-        │   │           │       ├── value:
-        │   │           │       │   @ FalseNode (location: (553...558))
-        │   │           │       └── operator_loc: ∅
-        │   │           └── closing_loc: (560...561) = "}"
+        │   │   @ ArgumentsNode (location: (539...570))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ HashNode (location: (539...561))
+        │   │       │   ├── opening_loc: (539...540) = "{"
+        │   │       │   ├── elements: (length: 2)
+        │   │       │   │   ├── @ AssocNode (location: (541...548))
+        │   │       │   │   │   ├── key:
+        │   │       │   │   │   │   @ SymbolNode (location: (541...543))
+        │   │       │   │   │   │   ├── opening_loc: ∅
+        │   │       │   │   │   │   ├── value_loc: (541...542) = "a"
+        │   │       │   │   │   │   ├── closing_loc: (542...543) = ":"
+        │   │       │   │   │   │   └── unescaped: "a"
+        │   │       │   │   │   ├── value:
+        │   │       │   │   │   │   @ TrueNode (location: (544...548))
+        │   │       │   │   │   └── operator_loc: ∅
+        │   │       │   │   └── @ AssocNode (location: (550...558))
+        │   │       │   │       ├── key:
+        │   │       │   │       │   @ SymbolNode (location: (550...552))
+        │   │       │   │       │   ├── opening_loc: ∅
+        │   │       │   │       │   ├── value_loc: (550...551) = "b"
+        │   │       │   │       │   ├── closing_loc: (551...552) = ":"
+        │   │       │   │       │   └── unescaped: "b"
+        │   │       │   │       ├── value:
+        │   │       │   │       │   @ FalseNode (location: (553...558))
+        │   │       │   │       └── operator_loc: ∅
+        │   │       │   └── closing_loc: (560...561) = "}"
+        │   │       └── @ BlockArgumentNode (location: (563...570))
+        │   │           ├── expression:
+        │   │           │   @ SymbolNode (location: (564...570))
+        │   │           │   ├── opening_loc: (564...565) = ":"
+        │   │           │   ├── value_loc: (565...570) = "block"
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   └── unescaped: "block"
+        │   │           └── operator_loc: (563...564) = "&"
         │   ├── closing_loc: (570...571) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (563...570))
-        │   │   ├── expression:
-        │   │   │   @ SymbolNode (location: (564...570))
-        │   │   │   ├── opening_loc: (564...565) = ":"
-        │   │   │   ├── value_loc: (565...570) = "block"
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "block"
-        │   │   └── operator_loc: (563...564) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
         ├── @ CallNode (location: (573...593))
@@ -1193,17 +1195,19 @@
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (629...632) = "foo"
         │   ├── opening_loc: ∅
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (633...640))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (633...640))
+        │   │           ├── expression:
+        │   │           │   @ SymbolNode (location: (634...640))
+        │   │           │   ├── opening_loc: (634...635) = ":"
+        │   │           │   ├── value_loc: (635...640) = "block"
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   └── unescaped: "block"
+        │   │           └── operator_loc: (633...634) = "&"
         │   ├── closing_loc: ∅
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (633...640))
-        │   │   ├── expression:
-        │   │   │   @ SymbolNode (location: (634...640))
-        │   │   │   ├── opening_loc: (634...635) = ":"
-        │   │   │   ├── value_loc: (635...640) = "block"
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "block"
-        │   │   └── operator_loc: (633...634) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
         ├── @ CallNode (location: (642...672))
@@ -1212,40 +1216,40 @@
         │   ├── message_loc: (642...645) = "foo"
         │   ├── opening_loc: ∅
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (646...663))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ KeywordHashNode (location: (646...663))
-        │   │           └── elements: (length: 2)
-        │   │               ├── @ AssocNode (location: (646...653))
-        │   │               │   ├── key:
-        │   │               │   │   @ SymbolNode (location: (646...648))
-        │   │               │   │   ├── opening_loc: ∅
-        │   │               │   │   ├── value_loc: (646...647) = "a"
-        │   │               │   │   ├── closing_loc: (647...648) = ":"
-        │   │               │   │   └── unescaped: "a"
-        │   │               │   ├── value:
-        │   │               │   │   @ TrueNode (location: (649...653))
-        │   │               │   └── operator_loc: ∅
-        │   │               └── @ AssocNode (location: (655...663))
-        │   │                   ├── key:
-        │   │                   │   @ SymbolNode (location: (655...657))
-        │   │                   │   ├── opening_loc: ∅
-        │   │                   │   ├── value_loc: (655...656) = "b"
-        │   │                   │   ├── closing_loc: (656...657) = ":"
-        │   │                   │   └── unescaped: "b"
-        │   │                   ├── value:
-        │   │                   │   @ FalseNode (location: (658...663))
-        │   │                   └── operator_loc: ∅
+        │   │   @ ArgumentsNode (location: (646...672))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ KeywordHashNode (location: (646...663))
+        │   │       │   └── elements: (length: 2)
+        │   │       │       ├── @ AssocNode (location: (646...653))
+        │   │       │       │   ├── key:
+        │   │       │       │   │   @ SymbolNode (location: (646...648))
+        │   │       │       │   │   ├── opening_loc: ∅
+        │   │       │       │   │   ├── value_loc: (646...647) = "a"
+        │   │       │       │   │   ├── closing_loc: (647...648) = ":"
+        │   │       │       │   │   └── unescaped: "a"
+        │   │       │       │   ├── value:
+        │   │       │       │   │   @ TrueNode (location: (649...653))
+        │   │       │       │   └── operator_loc: ∅
+        │   │       │       └── @ AssocNode (location: (655...663))
+        │   │       │           ├── key:
+        │   │       │           │   @ SymbolNode (location: (655...657))
+        │   │       │           │   ├── opening_loc: ∅
+        │   │       │           │   ├── value_loc: (655...656) = "b"
+        │   │       │           │   ├── closing_loc: (656...657) = ":"
+        │   │       │           │   └── unescaped: "b"
+        │   │       │           ├── value:
+        │   │       │           │   @ FalseNode (location: (658...663))
+        │   │       │           └── operator_loc: ∅
+        │   │       └── @ BlockArgumentNode (location: (665...672))
+        │   │           ├── expression:
+        │   │           │   @ SymbolNode (location: (666...672))
+        │   │           │   ├── opening_loc: (666...667) = ":"
+        │   │           │   ├── value_loc: (667...672) = "block"
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   └── unescaped: "block"
+        │   │           └── operator_loc: (665...666) = "&"
         │   ├── closing_loc: ∅
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (665...672))
-        │   │   ├── expression:
-        │   │   │   @ SymbolNode (location: (666...672))
-        │   │   │   ├── opening_loc: (666...667) = ":"
-        │   │   │   ├── value_loc: (667...672) = "block"
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "block"
-        │   │   └── operator_loc: (665...666) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
         ├── @ CallNode (location: (674...695))
diff --git a/test/yarp/snapshots/seattlerb/call_block_arg_named.txt b/test/yarp/snapshots/seattlerb/call_block_arg_named.txt
index 6ab31849..70ef65f9 100644
--- a/test/yarp/snapshots/seattlerb/call_block_arg_named.txt
+++ b/test/yarp/snapshots/seattlerb/call_block_arg_named.txt
@@ -1,28 +1,30 @@
-@ ProgramNode (location: (0...6))
+@ ProgramNode (location: (0...7))
 ├── locals: []
 └── statements:
-    @ StatementsNode (location: (0...6))
+    @ StatementsNode (location: (0...7))
     └── body: (length: 1)
-        └── @ CallNode (location: (0...6))
+        └── @ CallNode (location: (0...7))
             ├── receiver: ∅
             ├── call_operator_loc: ∅
             ├── message_loc: (0...1) = "x"
             ├── opening_loc: (1...2) = "("
-            ├── arguments: ∅
+            ├── arguments:
+            │   @ ArgumentsNode (location: (2...6))
+            │   └── arguments: (length: 1)
+            │       └── @ BlockArgumentNode (location: (2...6))
+            │           ├── expression:
+            │           │   @ CallNode (location: (3...6))
+            │           │   ├── receiver: ∅
+            │           │   ├── call_operator_loc: ∅
+            │           │   ├── message_loc: (3...6) = "blk"
+            │           │   ├── opening_loc: ∅
+            │           │   ├── arguments: ∅
+            │           │   ├── closing_loc: ∅
+            │           │   ├── block: ∅
+            │           │   ├── flags: variable_call
+            │           │   └── name: "blk"
+            │           └── operator_loc: (2...3) = "&"
             ├── closing_loc: (6...7) = ")"
-            ├── block:
-            │   @ BlockArgumentNode (location: (2...6))
-            │   ├── expression:
-            │   │   @ CallNode (location: (3...6))
-            │   │   ├── receiver: ∅
-            │   │   ├── call_operator_loc: ∅
-            │   │   ├── message_loc: (3...6) = "blk"
-            │   │   ├── opening_loc: ∅
-            │   │   ├── arguments: ∅
-            │   │   ├── closing_loc: ∅
-            │   │   ├── block: ∅
-            │   │   ├── flags: variable_call
-            │   │   └── name: "blk"
-            │   └── operator_loc: (2...3) = "&"
+            ├── block: ∅
             ├── flags: ∅
             └── name: "x"
diff --git a/test/yarp/snapshots/spanning_heredoc.txt b/test/yarp/snapshots/spanning_heredoc.txt
index 591f4bbf..63a97279 100644
--- a/test/yarp/snapshots/spanning_heredoc.txt
+++ b/test/yarp/snapshots/spanning_heredoc.txt
@@ -179,7 +179,7 @@
         │   │           │   │   ├── opening_loc: ∅
         │   │           │   │   ├── content_loc: (532...535) = "j\\\n"
         │   │           │   │   ├── closing_loc: ∅
-        │   │           │   │   └── unescaped: "j\n"
+        │   │           │   │   └── unescaped: "j\\\n"
         │   │           │   └── @ StringNode (location: (539...540))
         │   │           │       ├── flags: ∅
         │   │           │       ├── opening_loc: ∅
diff --git a/test/yarp/snapshots/strings.txt b/test/yarp/snapshots/strings.txt
index 0040191d..ef08cb69 100644
--- a/test/yarp/snapshots/strings.txt
+++ b/test/yarp/snapshots/strings.txt
@@ -292,7 +292,7 @@
         │   │   │   ├── opening_loc: ∅
         │   │   │   ├── content_loc: (290...298) = "foo\\ bar"
         │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "foo bar"
+        │   │   │   └── unescaped: "foo\\ bar"
         │   │   └── @ StringNode (location: (299...304))
         │   │       ├── flags: ∅
         │   │       ├── opening_loc: ∅
@@ -308,7 +308,7 @@
         │   │   │   ├── opening_loc: ∅
         │   │   │   ├── content_loc: (310...318) = "foo\\ bar"
         │   │   │   ├── closing_loc: ∅
-        │   │   │   └── unescaped: "foo bar"
+        │   │   │   └── unescaped: "foo\\ bar"
         │   │   └── @ StringNode (location: (319...322))
         │   │       ├── flags: ∅
         │   │       ├── opening_loc: ∅
diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt
index 25202c1f..035287f9 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/send.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt
@@ -745,108 +745,112 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "=~"
-        ├── @ CallNode (location: (464...481))
+        ├── @ CallNode (location: (464...482))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (464...467) = "foo"
         │   ├── opening_loc: (467...468) = "("
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (468...481))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (468...481))
+        │   │           ├── expression:
+        │   │           │   @ ParenthesesNode (location: (469...481))
+        │   │           │   ├── body:
+        │   │           │   │   @ StatementsNode (location: (470...480))
+        │   │           │   │   └── body: (length: 1)
+        │   │           │   │       └── @ OrNode (location: (470...480))
+        │   │           │   │           ├── left:
+        │   │           │   │           │   @ CallNode (location: (470...473))
+        │   │           │   │           │   ├── receiver: ∅
+        │   │           │   │           │   ├── call_operator_loc: ∅
+        │   │           │   │           │   ├── message_loc: (470...473) = "foo"
+        │   │           │   │           │   ├── opening_loc: ∅
+        │   │           │   │           │   ├── arguments: ∅
+        │   │           │   │           │   ├── closing_loc: ∅
+        │   │           │   │           │   ├── block: ∅
+        │   │           │   │           │   ├── flags: variable_call
+        │   │           │   │           │   └── name: "foo"
+        │   │           │   │           ├── right:
+        │   │           │   │           │   @ CallNode (location: (477...480))
+        │   │           │   │           │   ├── receiver: ∅
+        │   │           │   │           │   ├── call_operator_loc: ∅
+        │   │           │   │           │   ├── message_loc: (477...480) = "bar"
+        │   │           │   │           │   ├── opening_loc: ∅
+        │   │           │   │           │   ├── arguments: ∅
+        │   │           │   │           │   ├── closing_loc: ∅
+        │   │           │   │           │   ├── block: ∅
+        │   │           │   │           │   ├── flags: variable_call
+        │   │           │   │           │   └── name: "bar"
+        │   │           │   │           └── operator_loc: (474...476) = "||"
+        │   │           │   ├── opening_loc: (469...470) = "("
+        │   │           │   └── closing_loc: (480...481) = ")"
+        │   │           └── operator_loc: (468...469) = "&"
         │   ├── closing_loc: (481...482) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (468...481))
-        │   │   ├── expression:
-        │   │   │   @ ParenthesesNode (location: (469...481))
-        │   │   │   ├── body:
-        │   │   │   │   @ StatementsNode (location: (470...480))
-        │   │   │   │   └── body: (length: 1)
-        │   │   │   │       └── @ OrNode (location: (470...480))
-        │   │   │   │           ├── left:
-        │   │   │   │           │   @ CallNode (location: (470...473))
-        │   │   │   │           │   ├── receiver: ∅
-        │   │   │   │           │   ├── call_operator_loc: ∅
-        │   │   │   │           │   ├── message_loc: (470...473) = "foo"
-        │   │   │   │           │   ├── opening_loc: ∅
-        │   │   │   │           │   ├── arguments: ∅
-        │   │   │   │           │   ├── closing_loc: ∅
-        │   │   │   │           │   ├── block: ∅
-        │   │   │   │           │   ├── flags: variable_call
-        │   │   │   │           │   └── name: "foo"
-        │   │   │   │           ├── right:
-        │   │   │   │           │   @ CallNode (location: (477...480))
-        │   │   │   │           │   ├── receiver: ∅
-        │   │   │   │           │   ├── call_operator_loc: ∅
-        │   │   │   │           │   ├── message_loc: (477...480) = "bar"
-        │   │   │   │           │   ├── opening_loc: ∅
-        │   │   │   │           │   ├── arguments: ∅
-        │   │   │   │           │   ├── closing_loc: ∅
-        │   │   │   │           │   ├── block: ∅
-        │   │   │   │           │   ├── flags: variable_call
-        │   │   │   │           │   └── name: "bar"
-        │   │   │   │           └── operator_loc: (474...476) = "||"
-        │   │   │   ├── opening_loc: (469...470) = "("
-        │   │   │   └── closing_loc: (480...481) = ")"
-        │   │   └── operator_loc: (468...469) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
-        ├── @ CallNode (location: (483...493))
+        ├── @ CallNode (location: (483...494))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (483...486) = "foo"
         │   ├── opening_loc: (486...487) = "("
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (487...493))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (487...493))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (488...493))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (488...493) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (487...488) = "&"
         │   ├── closing_loc: (493...494) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (487...493))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (488...493))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (488...493) = "block"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "block"
-        │   │   └── operator_loc: (487...488) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
-        ├── @ CallNode (location: (495...512))
+        ├── @ CallNode (location: (495...513))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (495...498) = "foo"
         │   ├── opening_loc: (498...499) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (499...504))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ SplatNode (location: (499...504))
-        │   │           ├── operator_loc: (499...500) = "*"
-        │   │           └── expression:
-        │   │               @ CallNode (location: (500...504))
-        │   │               ├── receiver: ∅
-        │   │               ├── call_operator_loc: ∅
-        │   │               ├── message_loc: (500...504) = "args"
-        │   │               ├── opening_loc: ∅
-        │   │               ├── arguments: ∅
-        │   │               ├── closing_loc: ∅
-        │   │               ├── block: ∅
-        │   │               ├── flags: variable_call
-        │   │               └── name: "args"
+        │   │   @ ArgumentsNode (location: (499...512))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ SplatNode (location: (499...504))
+        │   │       │   ├── operator_loc: (499...500) = "*"
+        │   │       │   └── expression:
+        │   │       │       @ CallNode (location: (500...504))
+        │   │       │       ├── receiver: ∅
+        │   │       │       ├── call_operator_loc: ∅
+        │   │       │       ├── message_loc: (500...504) = "args"
+        │   │       │       ├── opening_loc: ∅
+        │   │       │       ├── arguments: ∅
+        │   │       │       ├── closing_loc: ∅
+        │   │       │       ├── block: ∅
+        │   │       │       ├── flags: variable_call
+        │   │       │       └── name: "args"
+        │   │       └── @ BlockArgumentNode (location: (506...512))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (507...512))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (507...512) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (506...507) = "&"
         │   ├── closing_loc: (512...513) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (506...512))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (507...512))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (507...512) = "block"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "block"
-        │   │   └── operator_loc: (506...507) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
         ├── @ CallNode (location: (514...529))
@@ -987,7 +991,7 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "foo"
-        ├── @ CallNode (location: (583...595))
+        ├── @ CallNode (location: (583...596))
         │   ├── receiver:
         │   │   @ CallNode (location: (583...586))
         │   │   ├── receiver: ∅
@@ -1002,22 +1006,24 @@
         │   ├── call_operator_loc: (586...587) = "."
         │   ├── message_loc: (587...590) = "bar"
         │   ├── opening_loc: (590...591) = "("
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (591...595))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (591...595))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (592...595))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (592...595) = "baz"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "baz"
+        │   │           └── operator_loc: (591...592) = "&"
         │   ├── closing_loc: (595...596) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (591...595))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (592...595))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (592...595) = "baz"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "baz"
-        │   │   └── operator_loc: (591...592) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "bar"
         ├── @ CallNode (location: (597...623))
@@ -1158,7 +1164,7 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "bar"
-        ├── @ CallNode (location: (659...677))
+        ├── @ CallNode (location: (659...678))
         │   ├── receiver:
         │   │   @ CallNode (location: (659...662))
         │   │   ├── receiver: ∅
@@ -1174,28 +1180,28 @@
         │   ├── message_loc: (663...666) = "bar"
         │   ├── opening_loc: (666...667) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (667...671))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ SymbolNode (location: (667...671))
-        │   │           ├── opening_loc: (667...668) = ":"
-        │   │           ├── value_loc: (668...671) = "baz"
-        │   │           ├── closing_loc: ∅
-        │   │           └── unescaped: "baz"
+        │   │   @ ArgumentsNode (location: (667...677))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ SymbolNode (location: (667...671))
+        │   │       │   ├── opening_loc: (667...668) = ":"
+        │   │       │   ├── value_loc: (668...671) = "baz"
+        │   │       │   ├── closing_loc: ∅
+        │   │       │   └── unescaped: "baz"
+        │   │       └── @ BlockArgumentNode (location: (673...677))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (674...677))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (674...677) = "baz"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "baz"
+        │   │           └── operator_loc: (673...674) = "&"
         │   ├── closing_loc: (677...678) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (673...677))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (674...677))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (674...677) = "baz"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "baz"
-        │   │   └── operator_loc: (673...674) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "bar"
         ├── @ CallNode (location: (679...696))
@@ -1340,7 +1346,7 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "bar"
-        ├── @ CallNode (location: (744...770))
+        ├── @ CallNode (location: (744...771))
         │   ├── receiver:
         │   │   @ CallNode (location: (744...747))
         │   │   ├── receiver: ∅
@@ -1356,8 +1362,8 @@
         │   ├── message_loc: (748...751) = "bar"
         │   ├── opening_loc: (751...752) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (752...762))
-        │   │   └── arguments: (length: 2)
+        │   │   @ ArgumentsNode (location: (752...770))
+        │   │   └── arguments: (length: 3)
         │   │       ├── @ CallNode (location: (752...755))
         │   │       │   ├── receiver: ∅
         │   │       │   ├── call_operator_loc: ∅
@@ -1368,34 +1374,34 @@
         │   │       │   ├── block: ∅
         │   │       │   ├── flags: variable_call
         │   │       │   └── name: "foo"
-        │   │       └── @ SplatNode (location: (757...762))
-        │   │           ├── operator_loc: (757...758) = "*"
-        │   │           └── expression:
-        │   │               @ CallNode (location: (758...762))
-        │   │               ├── receiver: ∅
-        │   │               ├── call_operator_loc: ∅
-        │   │               ├── message_loc: (758...762) = "args"
-        │   │               ├── opening_loc: ∅
-        │   │               ├── arguments: ∅
-        │   │               ├── closing_loc: ∅
-        │   │               ├── block: ∅
-        │   │               ├── flags: variable_call
-        │   │               └── name: "args"
+        │   │       ├── @ SplatNode (location: (757...762))
+        │   │       │   ├── operator_loc: (757...758) = "*"
+        │   │       │   └── expression:
+        │   │       │       @ CallNode (location: (758...762))
+        │   │       │       ├── receiver: ∅
+        │   │       │       ├── call_operator_loc: ∅
+        │   │       │       ├── message_loc: (758...762) = "args"
+        │   │       │       ├── opening_loc: ∅
+        │   │       │       ├── arguments: ∅
+        │   │       │       ├── closing_loc: ∅
+        │   │       │       ├── block: ∅
+        │   │       │       ├── flags: variable_call
+        │   │       │       └── name: "args"
+        │   │       └── @ BlockArgumentNode (location: (764...770))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (765...770))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (765...770) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (764...765) = "&"
         │   ├── closing_loc: (770...771) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (764...770))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (765...770))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (765...770) = "block"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "block"
-        │   │   └── operator_loc: (764...765) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "bar"
         ├── @ CallNode (location: (772...788))
diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt b/test/yarp/snapshots/unparser/corpus/literal/since/31.txt
index c8a07a5d..2932955b 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/since/31.txt
@@ -21,19 +21,21 @@
         │   │       ├── name_loc: ∅
         │   │       └── operator_loc: (8...9) = "&"
         │   ├── body:
-        │   │   @ StatementsNode (location: (13...18))
+        │   │   @ StatementsNode (location: (13...19))
         │   │   └── body: (length: 1)
-        │   │       └── @ CallNode (location: (13...18))
+        │   │       └── @ CallNode (location: (13...19))
         │   │           ├── receiver: ∅
         │   │           ├── call_operator_loc: ∅
         │   │           ├── message_loc: (13...16) = "bar"
         │   │           ├── opening_loc: (16...17) = "("
-        │   │           ├── arguments: ∅
+        │   │           ├── arguments:
+        │   │           │   @ ArgumentsNode (location: (17...18))
+        │   │           │   └── arguments: (length: 1)
+        │   │           │       └── @ BlockArgumentNode (location: (17...18))
+        │   │           │           ├── expression: ∅
+        │   │           │           └── operator_loc: (17...18) = "&"
         │   │           ├── closing_loc: (18...19) = ")"
-        │   │           ├── block:
-        │   │           │   @ BlockArgumentNode (location: (17...18))
-        │   │           │   ├── expression: ∅
-        │   │           │   └── operator_loc: (17...18) = "&"
+        │   │           ├── block: ∅
         │   │           ├── flags: ∅
         │   │           └── name: "bar"
         │   ├── locals: [:&]
@@ -63,19 +65,21 @@
             │       ├── name_loc: ∅
             │       └── operator_loc: (36...37) = "&"
             ├── body:
-            │   @ StatementsNode (location: (41...46))
+            │   @ StatementsNode (location: (41...47))
             │   └── body: (length: 1)
-            │       └── @ CallNode (location: (41...46))
+            │       └── @ CallNode (location: (41...47))
             │           ├── receiver: ∅
             │           ├── call_operator_loc: ∅
             │           ├── message_loc: (41...44) = "bar"
             │           ├── opening_loc: (44...45) = "("
-            │           ├── arguments: ∅
+            │           ├── arguments:
+            │           │   @ ArgumentsNode (location: (45...46))
+            │           │   └── arguments: (length: 1)
+            │           │       └── @ BlockArgumentNode (location: (45...46))
+            │           │           ├── expression: ∅
+            │           │           └── operator_loc: (45...46) = "&"
             │           ├── closing_loc: (46...47) = ")"
-            │           ├── block:
-            │           │   @ BlockArgumentNode (location: (45...46))
-            │           │   ├── expression: ∅
-            │           │   └── operator_loc: (45...46) = "&"
+            │           ├── block: ∅
             │           ├── flags: ∅
             │           └── name: "bar"
             ├── locals: [:a, :&]
diff --git a/test/yarp/snapshots/unparser/corpus/literal/super.txt b/test/yarp/snapshots/unparser/corpus/literal/super.txt
index 117ffd29..71550e5a 100644
--- a/test/yarp/snapshots/unparser/corpus/literal/super.txt
+++ b/test/yarp/snapshots/unparser/corpus/literal/super.txt
@@ -57,56 +57,58 @@
         │   │           └── name: "b"
         │   ├── rparen_loc: (33...34) = ")"
         │   └── block: ∅
-        ├── @ SuperNode (location: (35...47))
+        ├── @ SuperNode (location: (35...48))
         │   ├── keyword_loc: (35...40) = "super"
         │   ├── lparen_loc: (40...41) = "("
-        │   ├── arguments: ∅
+        │   ├── arguments:
+        │   │   @ ArgumentsNode (location: (41...47))
+        │   │   └── arguments: (length: 1)
+        │   │       └── @ BlockArgumentNode (location: (41...47))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (42...47))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (42...47) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (41...42) = "&"
         │   ├── rparen_loc: (47...48) = ")"
-        │   └── block:
-        │       @ BlockArgumentNode (location: (41...47))
-        │       ├── expression:
-        │       │   @ CallNode (location: (42...47))
-        │       │   ├── receiver: ∅
-        │       │   ├── call_operator_loc: ∅
-        │       │   ├── message_loc: (42...47) = "block"
-        │       │   ├── opening_loc: ∅
-        │       │   ├── arguments: ∅
-        │       │   ├── closing_loc: ∅
-        │       │   ├── block: ∅
-        │       │   ├── flags: variable_call
-        │       │   └── name: "block"
-        │       └── operator_loc: (41...42) = "&"
-        ├── @ SuperNode (location: (49...64))
+        │   └── block: ∅
+        ├── @ SuperNode (location: (49...65))
         │   ├── keyword_loc: (49...54) = "super"
         │   ├── lparen_loc: (54...55) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (55...56))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ CallNode (location: (55...56))
-        │   │           ├── receiver: ∅
-        │   │           ├── call_operator_loc: ∅
-        │   │           ├── message_loc: (55...56) = "a"
-        │   │           ├── opening_loc: ∅
-        │   │           ├── arguments: ∅
-        │   │           ├── closing_loc: ∅
-        │   │           ├── block: ∅
-        │   │           ├── flags: variable_call
-        │   │           └── name: "a"
+        │   │   @ ArgumentsNode (location: (55...64))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ CallNode (location: (55...56))
+        │   │       │   ├── receiver: ∅
+        │   │       │   ├── call_operator_loc: ∅
+        │   │       │   ├── message_loc: (55...56) = "a"
+        │   │       │   ├── opening_loc: ∅
+        │   │       │   ├── arguments: ∅
+        │   │       │   ├── closing_loc: ∅
+        │   │       │   ├── block: ∅
+        │   │       │   ├── flags: variable_call
+        │   │       │   └── name: "a"
+        │   │       └── @ BlockArgumentNode (location: (58...64))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (59...64))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (59...64) = "block"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "block"
+        │   │           └── operator_loc: (58...59) = "&"
         │   ├── rparen_loc: (64...65) = ")"
-        │   └── block:
-        │       @ BlockArgumentNode (location: (58...64))
-        │       ├── expression:
-        │       │   @ CallNode (location: (59...64))
-        │       │   ├── receiver: ∅
-        │       │   ├── call_operator_loc: ∅
-        │       │   ├── message_loc: (59...64) = "block"
-        │       │   ├── opening_loc: ∅
-        │       │   ├── arguments: ∅
-        │       │   ├── closing_loc: ∅
-        │       │   ├── block: ∅
-        │       │   ├── flags: variable_call
-        │       │   └── name: "block"
-        │       └── operator_loc: (58...59) = "&"
+        │   └── block: ∅
         ├── @ SuperNode (location: (66...84))
         │   ├── keyword_loc: (66...71) = "super"
         │   ├── lparen_loc: (71...72) = "("
diff --git a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt b/test/yarp/snapshots/whitequark/anonymous_blockarg.txt
index b2d6e22b..8d7b3011 100644
--- a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt
+++ b/test/yarp/snapshots/whitequark/anonymous_blockarg.txt
@@ -21,19 +21,21 @@
             │       ├── name_loc: ∅
             │       └── operator_loc: (8...9) = "&"
             ├── body:
-            │   @ StatementsNode (location: (12...17))
+            │   @ StatementsNode (location: (12...18))
             │   └── body: (length: 1)
-            │       └── @ CallNode (location: (12...17))
+            │       └── @ CallNode (location: (12...18))
             │           ├── receiver: ∅
             │           ├── call_operator_loc: ∅
             │           ├── message_loc: (12...15) = "bar"
             │           ├── opening_loc: (15...16) = "("
-            │           ├── arguments: ∅
+            │           ├── arguments:
+            │           │   @ ArgumentsNode (location: (16...17))
+            │           │   └── arguments: (length: 1)
+            │           │       └── @ BlockArgumentNode (location: (16...17))
+            │           │           ├── expression: ∅
+            │           │           └── operator_loc: (16...17) = "&"
             │           ├── closing_loc: (17...18) = ")"
-            │           ├── block:
-            │           │   @ BlockArgumentNode (location: (16...17))
-            │           │   ├── expression: ∅
-            │           │   └── operator_loc: (16...17) = "&"
+            │           ├── block: ∅
             │           ├── flags: ∅
             │           └── name: "bar"
             ├── locals: [:&]
diff --git a/test/yarp/snapshots/whitequark/args_args_assocs.txt b/test/yarp/snapshots/whitequark/args_args_assocs.txt
index 545b54e6..ebec1c52 100644
--- a/test/yarp/snapshots/whitequark/args_args_assocs.txt
+++ b/test/yarp/snapshots/whitequark/args_args_assocs.txt
@@ -1,7 +1,7 @@
-@ ProgramNode (location: (0...45))
+@ ProgramNode (location: (0...46))
 ├── locals: []
 └── statements:
-    @ StatementsNode (location: (0...45))
+    @ StatementsNode (location: (0...46))
     └── body: (length: 2)
         ├── @ CallNode (location: (0...19))
         │   ├── receiver: ∅
@@ -38,14 +38,14 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
-        └── @ CallNode (location: (21...45))
+        └── @ CallNode (location: (21...46))
             ├── receiver: ∅
             ├── call_operator_loc: ∅
             ├── message_loc: (21...24) = "fun"
             ├── opening_loc: (24...25) = "("
             ├── arguments:
-            │   @ ArgumentsNode (location: (25...39))
-            │   └── arguments: (length: 2)
+            │   @ ArgumentsNode (location: (25...45))
+            │   └── arguments: (length: 3)
             │       ├── @ CallNode (location: (25...28))
             │       │   ├── receiver: ∅
             │       │   ├── call_operator_loc: ∅
@@ -56,33 +56,33 @@
             │       │   ├── block: ∅
             │       │   ├── flags: variable_call
             │       │   └── name: "foo"
-            │       └── @ KeywordHashNode (location: (30...39))
-            │           └── elements: (length: 1)
-            │               └── @ AssocNode (location: (30...39))
-            │                   ├── key:
-            │                   │   @ SymbolNode (location: (30...34))
-            │                   │   ├── opening_loc: (30...31) = ":"
-            │                   │   ├── value_loc: (31...34) = "foo"
-            │                   │   ├── closing_loc: ∅
-            │                   │   └── unescaped: "foo"
-            │                   ├── value:
-            │                   │   @ IntegerNode (location: (38...39))
-            │                   │   └── flags: decimal
-            │                   └── operator_loc: (35...37) = "=>"
+            │       ├── @ KeywordHashNode (location: (30...39))
+            │       │   └── elements: (length: 1)
+            │       │       └── @ AssocNode (location: (30...39))
+            │       │           ├── key:
+            │       │           │   @ SymbolNode (location: (30...34))
+            │       │           │   ├── opening_loc: (30...31) = ":"
+            │       │           │   ├── value_loc: (31...34) = "foo"
+            │       │           │   ├── closing_loc: ∅
+            │       │           │   └── unescaped: "foo"
+            │       │           ├── value:
+            │       │           │   @ IntegerNode (location: (38...39))
+            │       │           │   └── flags: decimal
+            │       │           └── operator_loc: (35...37) = "=>"
+            │       └── @ BlockArgumentNode (location: (41...45))
+            │           ├── expression:
+            │           │   @ CallNode (location: (42...45))
+            │           │   ├── receiver: ∅
+            │           │   ├── call_operator_loc: ∅
+            │           │   ├── message_loc: (42...45) = "baz"
+            │           │   ├── opening_loc: ∅
+            │           │   ├── arguments: ∅
+            │           │   ├── closing_loc: ∅
+            │           │   ├── block: ∅
+            │           │   ├── flags: variable_call
+            │           │   └── name: "baz"
+            │           └── operator_loc: (41...42) = "&"
             ├── closing_loc: (45...46) = ")"
-            ├── block:
-            │   @ BlockArgumentNode (location: (41...45))
-            │   ├── expression:
-            │   │   @ CallNode (location: (42...45))
-            │   │   ├── receiver: ∅
-            │   │   ├── call_operator_loc: ∅
-            │   │   ├── message_loc: (42...45) = "baz"
-            │   │   ├── opening_loc: ∅
-            │   │   ├── arguments: ∅
-            │   │   ├── closing_loc: ∅
-            │   │   ├── block: ∅
-            │   │   ├── flags: variable_call
-            │   │   └── name: "baz"
-            │   └── operator_loc: (41...42) = "&"
+            ├── block: ∅
             ├── flags: ∅
             └── name: "fun"
diff --git a/test/yarp/snapshots/whitequark/args_args_star.txt b/test/yarp/snapshots/whitequark/args_args_star.txt
index 2fa0f0e3..6e40ad7f 100644
--- a/test/yarp/snapshots/whitequark/args_args_star.txt
+++ b/test/yarp/snapshots/whitequark/args_args_star.txt
@@ -1,7 +1,7 @@
-@ ProgramNode (location: (0...35))
+@ ProgramNode (location: (0...36))
 ├── locals: []
 └── statements:
-    @ StatementsNode (location: (0...35))
+    @ StatementsNode (location: (0...36))
     └── body: (length: 2)
         ├── @ CallNode (location: (0...14))
         │   ├── receiver: ∅
@@ -38,14 +38,14 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
-        └── @ CallNode (location: (16...35))
+        └── @ CallNode (location: (16...36))
             ├── receiver: ∅
             ├── call_operator_loc: ∅
             ├── message_loc: (16...19) = "fun"
             ├── opening_loc: (19...20) = "("
             ├── arguments:
-            │   @ ArgumentsNode (location: (20...29))
-            │   └── arguments: (length: 2)
+            │   @ ArgumentsNode (location: (20...35))
+            │   └── arguments: (length: 3)
             │       ├── @ CallNode (location: (20...23))
             │       │   ├── receiver: ∅
             │       │   ├── call_operator_loc: ∅
@@ -56,33 +56,33 @@
             │       │   ├── block: ∅
             │       │   ├── flags: variable_call
             │       │   └── name: "foo"
-            │       └── @ SplatNode (location: (25...29))
-            │           ├── operator_loc: (25...26) = "*"
-            │           └── expression:
-            │               @ CallNode (location: (26...29))
-            │               ├── receiver: ∅
-            │               ├── call_operator_loc: ∅
-            │               ├── message_loc: (26...29) = "bar"
-            │               ├── opening_loc: ∅
-            │               ├── arguments: ∅
-            │               ├── closing_loc: ∅
-            │               ├── block: ∅
-            │               ├── flags: variable_call
-            │               └── name: "bar"
+            │       ├── @ SplatNode (location: (25...29))
+            │       │   ├── operator_loc: (25...26) = "*"
+            │       │   └── expression:
+            │       │       @ CallNode (location: (26...29))
+            │       │       ├── receiver: ∅
+            │       │       ├── call_operator_loc: ∅
+            │       │       ├── message_loc: (26...29) = "bar"
+            │       │       ├── opening_loc: ∅
+            │       │       ├── arguments: ∅
+            │       │       ├── closing_loc: ∅
+            │       │       ├── block: ∅
+            │       │       ├── flags: variable_call
+            │       │       └── name: "bar"
+            │       └── @ BlockArgumentNode (location: (31...35))
+            │           ├── expression:
+            │           │   @ CallNode (location: (32...35))
+            │           │   ├── receiver: ∅
+            │           │   ├── call_operator_loc: ∅
+            │           │   ├── message_loc: (32...35) = "baz"
+            │           │   ├── opening_loc: ∅
+            │           │   ├── arguments: ∅
+            │           │   ├── closing_loc: ∅
+            │           │   ├── block: ∅
+            │           │   ├── flags: variable_call
+            │           │   └── name: "baz"
+            │           └── operator_loc: (31...32) = "&"
             ├── closing_loc: (35...36) = ")"
-            ├── block:
-            │   @ BlockArgumentNode (location: (31...35))
-            │   ├── expression:
-            │   │   @ CallNode (location: (32...35))
-            │   │   ├── receiver: ∅
-            │   │   ├── call_operator_loc: ∅
-            │   │   ├── message_loc: (32...35) = "baz"
-            │   │   ├── opening_loc: ∅
-            │   │   ├── arguments: ∅
-            │   │   ├── closing_loc: ∅
-            │   │   ├── block: ∅
-            │   │   ├── flags: variable_call
-            │   │   └── name: "baz"
-            │   └── operator_loc: (31...32) = "&"
+            ├── block: ∅
             ├── flags: ∅
             └── name: "fun"
diff --git a/test/yarp/snapshots/whitequark/args_assocs.txt b/test/yarp/snapshots/whitequark/args_assocs.txt
index ae8e3cdf..4a49911a 100644
--- a/test/yarp/snapshots/whitequark/args_assocs.txt
+++ b/test/yarp/snapshots/whitequark/args_assocs.txt
@@ -28,42 +28,42 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
-        ├── @ CallNode (location: (16...35))
+        ├── @ CallNode (location: (16...36))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (16...19) = "fun"
         │   ├── opening_loc: (19...20) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (20...29))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ KeywordHashNode (location: (20...29))
-        │   │           └── elements: (length: 1)
-        │   │               └── @ AssocNode (location: (20...29))
-        │   │                   ├── key:
-        │   │                   │   @ SymbolNode (location: (20...24))
-        │   │                   │   ├── opening_loc: (20...21) = ":"
-        │   │                   │   ├── value_loc: (21...24) = "foo"
-        │   │                   │   ├── closing_loc: ∅
-        │   │                   │   └── unescaped: "foo"
-        │   │                   ├── value:
-        │   │                   │   @ IntegerNode (location: (28...29))
-        │   │                   │   └── flags: decimal
-        │   │                   └── operator_loc: (25...27) = "=>"
+        │   │   @ ArgumentsNode (location: (20...35))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ KeywordHashNode (location: (20...29))
+        │   │       │   └── elements: (length: 1)
+        │   │       │       └── @ AssocNode (location: (20...29))
+        │   │       │           ├── key:
+        │   │       │           │   @ SymbolNode (location: (20...24))
+        │   │       │           │   ├── opening_loc: (20...21) = ":"
+        │   │       │           │   ├── value_loc: (21...24) = "foo"
+        │   │       │           │   ├── closing_loc: ∅
+        │   │       │           │   └── unescaped: "foo"
+        │   │       │           ├── value:
+        │   │       │           │   @ IntegerNode (location: (28...29))
+        │   │       │           │   └── flags: decimal
+        │   │       │           └── operator_loc: (25...27) = "=>"
+        │   │       └── @ BlockArgumentNode (location: (31...35))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (32...35))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (32...35) = "baz"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "baz"
+        │   │           └── operator_loc: (31...32) = "&"
         │   ├── closing_loc: (35...36) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (31...35))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (32...35))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (32...35) = "baz"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "baz"
-        │   │   └── operator_loc: (31...32) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
         ├── @ CallNode (location: (38...59))
diff --git a/test/yarp/snapshots/whitequark/args_assocs_legacy.txt b/test/yarp/snapshots/whitequark/args_assocs_legacy.txt
index ae8e3cdf..4a49911a 100644
--- a/test/yarp/snapshots/whitequark/args_assocs_legacy.txt
+++ b/test/yarp/snapshots/whitequark/args_assocs_legacy.txt
@@ -28,42 +28,42 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
-        ├── @ CallNode (location: (16...35))
+        ├── @ CallNode (location: (16...36))
         │   ├── receiver: ∅
         │   ├── call_operator_loc: ∅
         │   ├── message_loc: (16...19) = "fun"
         │   ├── opening_loc: (19...20) = "("
         │   ├── arguments:
-        │   │   @ ArgumentsNode (location: (20...29))
-        │   │   └── arguments: (length: 1)
-        │   │       └── @ KeywordHashNode (location: (20...29))
-        │   │           └── elements: (length: 1)
-        │   │               └── @ AssocNode (location: (20...29))
-        │   │                   ├── key:
-        │   │                   │   @ SymbolNode (location: (20...24))
-        │   │                   │   ├── opening_loc: (20...21) = ":"
-        │   │                   │   ├── value_loc: (21...24) = "foo"
-        │   │                   │   ├── closing_loc: ∅
-        │   │                   │   └── unescaped: "foo"
-        │   │                   ├── value:
-        │   │                   │   @ IntegerNode (location: (28...29))
-        │   │                   │   └── flags: decimal
-        │   │                   └── operator_loc: (25...27) = "=>"
+        │   │   @ ArgumentsNode (location: (20...35))
+        │   │   └── arguments: (length: 2)
+        │   │       ├── @ KeywordHashNode (location: (20...29))
+        │   │       │   └── elements: (length: 1)
+        │   │       │       └── @ AssocNode (location: (20...29))
+        │   │       │           ├── key:
+        │   │       │           │   @ SymbolNode (location: (20...24))
+        │   │       │           │   ├── opening_loc: (20...21) = ":"
+        │   │       │           │   ├── value_loc: (21...24) = "foo"
+        │   │       │           │   ├── closing_loc: ∅
+        │   │       │           │   └── unescaped: "foo"
+        │   │       │           ├── value:
+        │   │       │           │   @ IntegerNode (location: (28...29))
+        │   │       │           │   └── flags: decimal
+        │   │       │           └── operator_loc: (25...27) = "=>"
+        │   │       └── @ BlockArgumentNode (location: (31...35))
+        │   │           ├── expression:
+        │   │           │   @ CallNode (location: (32...35))
+        │   │           │   ├── receiver: ∅
+        │   │           │   ├── call_operator_loc: ∅
+        │   │           │   ├── message_loc: (32...35) = "baz"
+        │   │           │   ├── opening_loc: ∅
+        │   │           │   ├── arguments: ∅
+        │   │           │   ├── closing_loc: ∅
+        │   │           │   ├── block: ∅
+        │   │           │   ├── flags: variable_call
+        │   │           │   └── name: "baz"
+        │   │           └── operator_loc: (31...32) = "&"
         │   ├── closing_loc: (35...36) = ")"
-        │   ├── block:
-        │   │   @ BlockArgumentNode (location: (31...35))
-        │   │   ├── expression:
-        │   │   │   @ CallNode (location: (32...35))
-        │   │   │   ├── receiver: ∅
-        │   │   │   ├── call_operator_loc: ∅
-        │   │   │   ├── message_loc: (32...35) = "baz"
-        │   │   │   ├── opening_loc: ∅
-        │   │   │   ├── arguments: ∅
-        │   │   │   ├── closing_loc: ∅
-        │   │   │   ├── block: ∅
-        │   │   │   ├── flags: variable_call
-        │   │   │   └── name: "baz"
-        │   │   └── operator_loc: (31...32) = "&"
+        │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
         ├── @ CallNode (location: (38...59))
diff --git a/test/yarp/snapshots/whitequark/args_block_pass.txt b/test/yarp/snapshots/whitequark/args_block_pass.txt
index 0667d005..622f3fea 100644
--- a/test/yarp/snapshots/whitequark/args_block_pass.txt
+++ b/test/yarp/snapshots/whitequark/args_block_pass.txt
@@ -1,28 +1,30 @@
-@ ProgramNode (location: (0...8))
+@ ProgramNode (location: (0...9))
 ├── locals: []
 └── statements:
-    @ StatementsNode (location: (0...8))
+    @ StatementsNode (location: (0...9))
     └── body: (length: 1)
-        └── @ CallNode (location: (0...8))
+        └── @ CallNode (location: (0...9))
             ├── receiver: ∅
             ├── call_operator_loc: ∅
             ├── message_loc: (0...3) = "fun"
             ├── opening_loc: (3...4) = "("
-            ├── arguments: ∅
+            ├── arguments:
+            │   @ ArgumentsNode (location: (4...8))
+            │   └── arguments: (length: 1)
+            │       └── @ BlockArgumentNode (location: (4...8))
+            │           ├── expression:
+            │           │   @ CallNode (location: (5...8))
+            │           │   ├── receiver: ∅
+            │           │   ├── call_operator_loc: ∅
+            │           │   ├── message_loc: (5...8) = "bar"
+            │           │   ├── opening_loc: ∅
+            │           │   ├── arguments: ∅
+            │           │   ├── closing_loc: ∅
+            │           │   ├── block: ∅
+            │           │   ├── flags: variable_call
+            │           │   └── name: "bar"
+            │           └── operator_loc: (4...5) = "&"
             ├── closing_loc: (8...9) = ")"
-            ├── block:
-            │   @ BlockArgumentNode (location: (4...8))
-            │   ├── expression:
-            │   │   @ CallNode (location: (5...8))
-            │   │   ├── receiver: ∅
-            │   │   ├── call_operator_loc: ∅
-            │   │   ├── message_loc: (5...8) = "bar"
-            │   │   ├── opening_loc: ∅
-            │   │   ├── arguments: ∅
-            │   │   ├── closing_loc: ∅
-            │   │   ├── block: ∅
-            │   │   ├── flags: variable_call
-            │   │   └── name: "bar"
-            │   └── operator_loc: (4...5) = "&"
+            ├── block: ∅
             ├── flags: ∅
             └── name: "fun"
diff --git a/test/yarp/snapshots/whitequark/args_star.txt b/test/yarp/snapshots/whitequark/args_star.txt
index 3c25c185..5e1d0efe 100644
--- a/test/yarp/snapshots/whitequark/args_star.txt
+++ b/test/yarp/snapshots/whitequark/args_star.txt
@@ -1,7 +1,7 @@
-@ ProgramNode (location: (0...25))
+@ ProgramNode (location: (0...26))
 ├── locals: []
 └── statements:
-    @ StatementsNode (location: (0...25))
+    @ StatementsNode (location: (0...26))
     └── body: (length: 2)
         ├── @ CallNode (location: (0...9))
         │   ├── receiver: ∅
@@ -28,41 +28,41 @@
         │   ├── block: ∅
         │   ├── flags: ∅
         │   └── name: "fun"
-        └── @ CallNode (location: (11...25))
+        └── @ CallNode (location: (11...26))
             ├── receiver: ∅
             ├── call_operator_loc: ∅
             ├── message_loc: (11...14) = "fun"
             ├── opening_loc: (14...15) = "("
             ├── arguments:
-            │   @ ArgumentsNode (location: (15...19))
-            │   └── arguments: (length: 1)
-            │       └── @ SplatNode (location: (15...19))
-            │           ├── operator_loc: (15...16) = "*"
-            │           └── expression:
-            │               @ CallNode (location: (16...19))
-            │               ├── receiver: ∅
-            │               ├── call_operator_loc: ∅
-            │               ├── message_loc: (16...19) = "bar"
-            │               ├── opening_loc: ∅
-            │               ├── arguments: ∅
-            │               ├── closing_loc: ∅
-            │               ├── block: ∅
-            │               ├── flags: variable_call
-            │               └── name: "bar"
+            │   @ ArgumentsNode (location: (15...25))
+            │   └── arguments: (length: 2)
+            │       ├── @ SplatNode (location: (15...19))
+            │       │   ├── operator_loc: (15...16) = "*"
+            │       │   └── expression:
+            │       │       @ CallNode (location: (16...19))
+            │       │       ├── receiver: ∅
+            │       │       ├── call_operator_loc: ∅
+            │       │       ├── message_loc: (16...19) = "bar"
+            │       │       ├── opening_loc: ∅
+            │       │       ├── arguments: ∅
+            │       │       ├── closing_loc: ∅
+            │       │       ├── block: ∅
+            │       │       ├── flags: variable_call
+            │       │       └── name: "bar"
+            │       └── @ BlockArgumentNode (location: (21...25))
+            │           ├── expression:
+            │           │   @ CallNode (location: (22...25))
+            │           │   ├── receiver: ∅
+            │           │   ├── call_operator_loc: ∅
+            │           │   ├── message_loc: (22...25) = "baz"
+            │           │   ├── opening_loc: ∅
+            │           │   ├── arguments: ∅
+            │           │   ├── closing_loc: ∅
+            │           │   ├── block: ∅
+            │           │   ├── flags: variable_call
+            │           │   └── name: "baz"
+            │           └── operator_loc: (21...22) = "&"
             ├── closing_loc: (25...26) = ")"
-            ├── block:
-            │   @ BlockArgumentNode (location: (21...25))
-            │   ├── expression:
-            │   │   @ CallNode (location: (22...25))
-            │   │   ├── receiver: ∅
-            │   │   ├── call_operator_loc: ∅
-            │   │   ├── message_loc: (22...25) = "baz"
-            │   │   ├── opening_loc: ∅
-            │   │   ├── arguments: ∅
-            │   │   ├── closing_loc: ∅
-            │   │   ├── block: ∅
-            │   │   ├── flags: variable_call
-            │   │   └── name: "baz"
-            │   └── operator_loc: (21...22) = "&"
+            ├── block: ∅
             ├── flags: ∅
             └── name: "fun"
diff --git a/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
index ee11d266..ae5873a7 100644
--- a/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
+++ b/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt
@@ -67,7 +67,7 @@
         │   │       ├── opening_loc: ∅
         │   │       ├── content_loc: (81...85) = "a\\\nb"
         │   │       ├── closing_loc: ∅
-        │   │       └── unescaped: "a\nb"
+        │   │       └── unescaped: "a\\\nb"
         │   ├── opening_loc: (78...81) = "%w{"
         │   └── closing_loc: (85...86) = "}"
         ├── @ XStringNode (location: (88...96))
diff --git a/test/yarp/unescape_test.rb b/test/yarp/unescape_test.rb
index a7d955b3..f39bdd0e 100644
--- a/test/yarp/unescape_test.rb
+++ b/test/yarp/unescape_test.rb
@@ -136,13 +136,6 @@ module YARP
       assert_unescape_all("g", "\\g")
     end
 
-    def test_whitespace_escaping_string_list
-      assert_equal("a b", Debug.unescape_whitespace("a\\ b"))
-      assert_equal("a\tb", Debug.unescape_whitespace("a\\\tb"))
-      assert_equal("a\nb", Debug.unescape_whitespace("a\\\nb"))
-      assert_equal("a\nb", Debug.unescape_whitespace("a\\\r\nb"))
-    end
-
     private
 
     def unescape_all(source)