[ruby/prism] Index{Operator,And,Or}WriteNode

Right now, our Call{Operator,And,Or}WriteNode nodes represent two
different concepts:

```ruby
foo.bar += 1
foo[bar] += 1
```

These two statements are different in what they can support. The
former can never have arguments (or an opening_loc or closing_loc).
The former can also never have a block. Also, the former is a
variable method name.

The latter is always going to be []/[]=, it can have any number of
arguments including blocks (`foo[&bar] ||= 1`), and will always
have an opening_loc and closing_loc.

Furthermore, these statements end of having to take different paths
through the various compilers because with the latter you have to
consider the arguments and the block, whereas the former can
perform some additional peephole optimizations since there are
fewer values on the stack.

For these reasons, I'm introducing Index{Operator,And,Or}WriteNode.
These nodes never have a read_name or write_name on them because
they are always []/[]=. They also support blocks, which the previous
write nodes didn't. As a benefit of introducing these nodes, I've
removed the opening_loc, closing_loc, and arguments from the older
write nodes because they will always be null.

For the serialized format, both of these nodes end up being
smaller, and for in-memory we're storing fewer things in general,
so we have savings all around.

I don't love that we are introducing another node that is a call
node since we generally want consumers to only have to handle a
single call, but these nodes are so specific that they would have
to be handled separately anyway since in fact call 2 methods.

https://github.com/ruby/prism/commit/70155db9cd
This commit is contained in:
Kevin Newton 2023-10-17 11:15:56 -04:00 коммит произвёл git
Родитель ef3f9f1a68
Коммит 2a6f7cd925
25 изменённых файлов: 1097 добавлений и 237 удалений

Просмотреть файл

@ -633,13 +633,6 @@ nodes:
type: location?
- name: message_loc
type: location?
- name: opening_loc
type: location?
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location?
- name: flags
type: flags
kind: CallNodeFlags
@ -706,13 +699,6 @@ nodes:
type: location?
- name: message_loc
type: location?
- name: opening_loc
type: location?
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location?
- name: flags
type: flags
kind: CallNodeFlags
@ -739,13 +725,6 @@ nodes:
type: location?
- name: message_loc
type: location?
- name: opening_loc
type: location?
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location?
- name: flags
type: flags
kind: CallNodeFlags
@ -1446,6 +1425,89 @@ nodes:
case a; in b then c end
^^^^^^^^^^^
- name: IndexAndWriteNode
fields:
- name: receiver
type: node?
- name: call_operator_loc
type: location?
- name: opening_loc
type: location
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location
- name: block
type: node?
- name: flags
type: flags
kind: CallNodeFlags
- name: operator_loc
type: location
- name: value
type: node
comment: |
Represents the use of the `&&=` operator on a call to the `[]` method.
foo.bar[baz] &&= value
^^^^^^^^^^^^^^^^^^^^^^
- name: IndexOperatorWriteNode
fields:
- name: receiver
type: node?
- name: call_operator_loc
type: location?
- name: opening_loc
type: location
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location
- name: block
type: node?
- name: flags
type: flags
kind: CallNodeFlags
- name: operator
type: constant
- name: operator_loc
type: location
- name: value
type: node
comment: |
Represents the use of an assignment operator on a call to `[]`.
foo.bar[baz] += value
^^^^^^^^^^^^^^^^^^^^^
- name: IndexOrWriteNode
fields:
- name: receiver
type: node?
- name: call_operator_loc
type: location?
- name: opening_loc
type: location
- name: arguments
type: node?
kind: ArgumentsNode
- name: closing_loc
type: location
- name: block
type: node?
- name: flags
type: flags
kind: CallNodeFlags
- name: operator_loc
type: location
- name: value
type: node
comment: |
Represents the use of the `||=` operator on a call to `[]`.
foo.bar[baz] ||= value
^^^^^^^^^^^^^^^^^^^^^^
- name: InstanceVariableAndWriteNode
fields:
- name: name

Просмотреть файл

@ -192,6 +192,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
[PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED] = "Numbered parameters are not allowed alongside explicit parameters",
[PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE] = "Numbered parameter is already used in outer scope",
[PM_ERR_OPERATOR_MULTI_ASSIGN] = "Unexpected operator for a multiple assignment",
[PM_ERR_OPERATOR_WRITE_ARGUMENTS] = "Unexpected operator after a call with arguments",
[PM_ERR_OPERATOR_WRITE_BLOCK] = "Unexpected operator after a call with a block",
[PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters",
[PM_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed",

Просмотреть файл

@ -158,6 +158,7 @@ typedef enum {
PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
PM_ERR_OPERATOR_MULTI_ASSIGN,
PM_ERR_OPERATOR_WRITE_ARGUMENTS,
PM_ERR_OPERATOR_WRITE_BLOCK,
PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI,
PM_ERR_PARAMETER_BLOCK_MULTI,

Просмотреть файл

@ -1616,6 +1616,32 @@ pm_call_node_variable_call_p(pm_call_node_t *node) {
return node->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL;
}
// Returns whether or not this call is to the [] method in the index form (as
// opposed to `foo.[]`).
static inline bool
pm_call_node_index_p(pm_call_node_t *node) {
return (
(node->call_operator_loc.start == NULL) &&
(node->message_loc.start != NULL) &&
(node->message_loc.start[0] == '[') &&
(node->message_loc.end[-1] == ']')
);
}
// Returns whether or not this call can be used on the left-hand side of an
// operator assignment.
static inline bool
pm_call_node_writable_p(pm_call_node_t *node) {
return (
(node->message_loc.start != NULL) &&
(node->message_loc.end[-1] != '!') &&
(node->message_loc.end[-1] != '?') &&
(node->opening_loc.start == NULL) &&
(node->arguments == NULL) &&
(node->block == NULL)
);
}
// Initialize the read name by reading the write name and chopping off the '='.
static void
pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, pm_constant_id_t *write_name) {
@ -1652,9 +1678,6 @@ pm_call_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.message_loc = target->message_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.read_name = 0,
.write_name = target->name,
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
@ -1671,6 +1694,39 @@ pm_call_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
return node;
}
// Allocate and initialize a new IndexAndWriteNode node.
static pm_index_and_write_node_t *
pm_index_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL);
pm_index_and_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_and_write_node_t);
*node = (pm_index_and_write_node_t) {
{
.type = PM_INDEX_AND_WRITE_NODE,
.flags = target->base.flags,
.location = {
.start = target->base.location.start,
.end = value->location.end
}
},
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.block = target->block,
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
.value = value
};
// Here we're going to free the target, since it is no longer necessary.
// However, we don't want to call `pm_node_destroy` because we want to keep
// around all of its children since we just reused them.
free(target);
return node;
}
// Allocate a new CallOperatorWriteNode node.
static pm_call_operator_write_node_t *
pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
@ -1689,9 +1745,6 @@ pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.message_loc = target->message_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.read_name = 0,
.write_name = target->name,
.operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
@ -1709,7 +1762,40 @@ pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
return node;
}
// Allocate and initialize a new CallOperatorOrWriteNode node.
// Allocate a new IndexOperatorWriteNode node.
static pm_index_operator_write_node_t *
pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
pm_index_operator_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_operator_write_node_t);
*node = (pm_index_operator_write_node_t) {
{
.type = PM_INDEX_OPERATOR_WRITE_NODE,
.flags = target->base.flags,
.location = {
.start = target->base.location.start,
.end = value->location.end
}
},
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.block = target->block,
.operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
.value = value
};
// Here we're going to free the target, since it is no longer necessary.
// However, we don't want to call `pm_node_destroy` because we want to keep
// around all of its children since we just reused them.
free(target);
return node;
}
// Allocate and initialize a new CallOrWriteNode node.
static pm_call_or_write_node_t *
pm_call_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
assert(target->block == NULL);
@ -1728,9 +1814,6 @@ pm_call_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.message_loc = target->message_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.read_name = 0,
.write_name = target->name,
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
@ -1747,6 +1830,39 @@ pm_call_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const
return node;
}
// Allocate and initialize a new IndexOrWriteNode node.
static pm_index_or_write_node_t *
pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) {
assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL);
pm_index_or_write_node_t *node = PM_ALLOC_NODE(parser, pm_index_or_write_node_t);
*node = (pm_index_or_write_node_t) {
{
.type = PM_INDEX_OR_WRITE_NODE,
.flags = target->base.flags,
.location = {
.start = target->base.location.start,
.end = value->location.end
}
},
.receiver = target->receiver,
.call_operator_loc = target->call_operator_loc,
.opening_loc = target->opening_loc,
.arguments = target->arguments,
.closing_loc = target->closing_loc,
.block = target->block,
.operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
.value = value
};
// Here we're going to free the target, since it is no longer necessary.
// However, we don't want to call `pm_node_destroy` because we want to keep
// around all of its children since we just reused them.
free(target);
return node;
}
// Allocate and initialize a new CapturePatternNode node.
static pm_capture_pattern_node_t *
pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *target, const pm_token_t *operator) {
@ -14447,12 +14563,18 @@ parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_
}
// Ensures a call node that is about to become a call operator node does not
// have a block attached. If it does, then we'll need to add an error message
// and destroy the block. Ideally we would keep the node around so that
// consumers would still have access to it, but we don't have a great structure
// for that at the moment.
// have arguments or a block attached. If it does, then we'll need to add an
// error message and destroy the arguments/block. Ideally we would keep the node
// around so that consumers would still have access to it, but we don't have a
// great structure for that at the moment.
static void
parse_call_operator_write_block(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) {
parse_call_operator_write(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) {
if (call_node->arguments != NULL) {
pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_ARGUMENTS);
pm_node_destroy(parser, (pm_node_t *) call_node->arguments);
call_node->arguments = NULL;
}
if (call_node->block != NULL) {
pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_BLOCK);
pm_node_destroy(parser, (pm_node_t *) call_node->block);
@ -14565,33 +14687,45 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
return result;
}
case PM_CALL_NODE: {
parser_lex(parser);
pm_call_node_t *cast = (pm_call_node_t *) node;
// If we have a vcall (a method with no arguments and no
// receiver that could have been a local variable) then we
// will transform it into a local variable write.
if (pm_call_node_variable_call_p((pm_call_node_t *) node)) {
pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc;
if (pm_call_node_variable_call_p(cast)) {
pm_location_t message_loc = cast->message_loc;
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
pm_parser_err_location(parser, &message_loc, PM_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, constant_id, 0);
pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
pm_node_destroy(parser, node);
pm_node_destroy(parser, (pm_node_t *) cast);
return result;
}
parser_lex(parser);
node = parse_target(parser, node);
// If there is no call operator and the message is "[]" then
// this is an aref expression, and we can transform it into
// an aset expression.
if (pm_call_node_index_p(cast)) {
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
return (pm_node_t *) pm_index_and_write_node_create(parser, cast, &token, value);
}
assert(PM_NODE_TYPE_P(node, PM_CALL_NODE));
parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token);
// If this node cannot be writable, then we have an error.
if (pm_call_node_writable_p(cast)) {
parse_write_name(parser, &cast->name);
} else {
pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
}
parse_call_operator_write(parser, cast, &token);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ);
return (pm_node_t *) pm_call_and_write_node_create(parser, (pm_call_node_t *) node, &token, value);
return (pm_node_t *) pm_call_and_write_node_create(parser, cast, &token, value);
}
case PM_MULTI_WRITE_NODE: {
parser_lex(parser);
@ -14667,33 +14801,45 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
return result;
}
case PM_CALL_NODE: {
parser_lex(parser);
pm_call_node_t *cast = (pm_call_node_t *) node;
// If we have a vcall (a method with no arguments and no
// receiver that could have been a local variable) then we
// will transform it into a local variable write.
if (pm_call_node_variable_call_p((pm_call_node_t *) node)) {
pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc;
if (pm_call_node_variable_call_p(cast)) {
pm_location_t message_loc = cast->message_loc;
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
pm_parser_err_location(parser, &message_loc, PM_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, constant_id, 0);
pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
pm_node_destroy(parser, node);
pm_node_destroy(parser, (pm_node_t *) cast);
return result;
}
parser_lex(parser);
node = parse_target(parser, node);
// If there is no call operator and the message is "[]" then
// this is an aref expression, and we can transform it into
// an aset expression.
if (pm_call_node_index_p(cast)) {
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
return (pm_node_t *) pm_index_or_write_node_create(parser, cast, &token, value);
}
assert(PM_NODE_TYPE_P(node, PM_CALL_NODE));
parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token);
// If this node cannot be writable, then we have an error.
if (pm_call_node_writable_p(cast)) {
parse_write_name(parser, &cast->name);
} else {
pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
}
parse_call_operator_write(parser, cast, &token);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ);
return (pm_node_t *) pm_call_or_write_node_create(parser, (pm_call_node_t *) node, &token, value);
return (pm_node_t *) pm_call_or_write_node_create(parser, cast, &token, value);
}
case PM_MULTI_WRITE_NODE: {
parser_lex(parser);
@ -14779,33 +14925,45 @@ parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t
return result;
}
case PM_CALL_NODE: {
parser_lex(parser);
pm_call_node_t *cast = (pm_call_node_t *) node;
// If we have a vcall (a method with no arguments and no
// receiver that could have been a local variable) then we
// will transform it into a local variable write.
if (pm_call_node_variable_call_p((pm_call_node_t *) node)) {
pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc;
if (pm_call_node_variable_call_p(cast)) {
pm_location_t message_loc = cast->message_loc;
pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end);
if (token_is_numbered_parameter(message_loc.start, message_loc.end)) {
pm_parser_err_location(parser, &message_loc, PM_ERR_PARAMETER_NUMBERED_RESERVED);
}
parser_lex(parser);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, constant_id, 0);
pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0);
pm_node_destroy(parser, node);
pm_node_destroy(parser, (pm_node_t *) cast);
return result;
}
parser_lex(parser);
node = parse_target(parser, node);
// If there is no call operator and the message is "[]" then
// this is an aref expression, and we can transform it into
// an aset expression.
if (pm_call_node_index_p(cast)) {
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (pm_node_t *) pm_index_operator_write_node_create(parser, cast, &token, value);
}
assert(PM_NODE_TYPE_P(node, PM_CALL_NODE));
parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token);
// If this node cannot be writable, then we have an error.
if (pm_call_node_writable_p(cast)) {
parse_write_name(parser, &cast->name);
} else {
pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED);
}
parse_call_operator_write(parser, cast, &token);
pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR);
return (pm_node_t *) pm_call_operator_write_node_create(parser, (pm_call_node_t *) node, &token, value);
return (pm_node_t *) pm_call_operator_write_node_create(parser, cast, &token, value);
}
case PM_MULTI_WRITE_NODE: {
parser_lex(parser);

Просмотреть файл

@ -80,3 +80,39 @@ foo[bar] = baz
%x{one two three}
%w[\C:]
foo[] += 1
foo[] ||= 1
foo[] &&= 1
foo.foo[] += 1
foo.foo[] ||= 1
foo.foo[] &&= 1
foo[bar] += 1
foo[bar] ||= 1
foo[bar] &&= 1
foo.foo[bar] += 1
foo.foo[bar] ||= 1
foo.foo[bar] &&= 1
foo[bar, &baz] += 1
foo[bar, &baz] ||= 1
foo[bar, &baz] &&= 1
foo.foo[bar, &baz] += 1
foo.foo[bar, &baz] ||= 1
foo.foo[bar, &baz] &&= 1

Просмотреть файл

@ -178,17 +178,14 @@ module Prism
def test_CallAndWriteNode
assert_location(CallAndWriteNode, "foo.foo &&= bar")
assert_location(CallAndWriteNode, "foo[foo] &&= bar")
end
def test_CallOperatorWriteNode
assert_location(CallOperatorWriteNode, "foo.foo += bar")
assert_location(CallOperatorWriteNode, "foo[foo] += bar")
end
def test_CallOrWriteNode
assert_location(CallOrWriteNode, "foo.foo ||= bar")
assert_location(CallOrWriteNode, "foo[foo] ||= bar")
end
def test_CapturePatternNode
@ -430,6 +427,18 @@ module Prism
end
end
def test_IndexAndWriteNode
assert_location(IndexAndWriteNode, "foo[foo] &&= bar")
end
def test_IndexOperatorWriteNode
assert_location(IndexOperatorWriteNode, "foo[foo] += bar")
end
def test_IndexOrWriteNode
assert_location(IndexOrWriteNode, "foo[foo] ||= bar")
end
def test_InstanceVariableAndWriteNode
assert_location(InstanceVariableAndWriteNode, "@foo &&= bar")
end

Просмотреть файл

@ -1,8 +1,8 @@
@ ProgramNode (location: (1,0)-(82,7))
@ ProgramNode (location: (1,0)-(118,24))
├── locals: []
└── statements:
@ StatementsNode (location: (1,0)-(82,7))
└── body: (length: 30)
@ StatementsNode (location: (1,0)-(118,24))
└── body: (length: 48)
├── @ ArrayNode (location: (1,0)-(1,4))
│ ├── elements: (length: 1)
│ │ └── @ SplatNode (location: (1,1)-(1,3))
@ -861,13 +861,727 @@
│ ├── content_loc: (80,3)-(80,16) = "one two three"
│ ├── closing_loc: (80,16)-(80,17) = "}"
│ └── unescaped: "one two three"
└── @ ArrayNode (location: (82,0)-(82,7))
├── elements: (length: 1)
│ └── @ StringNode (location: (82,3)-(82,6))
│ ├── flags: ∅
│ ├── opening_loc: ∅
│ ├── content_loc: (82,3)-(82,6) = "\\C:"
│ ├── closing_loc: ∅
│ └── unescaped: "\\C:"
├── opening_loc: (82,0)-(82,3) = "%w["
└── closing_loc: (82,6)-(82,7) = "]"
├── @ ArrayNode (location: (82,0)-(82,7))
│ ├── elements: (length: 1)
│ │ └── @ StringNode (location: (82,3)-(82,6))
│ │ ├── flags: ∅
│ │ ├── opening_loc: ∅
│ │ ├── content_loc: (82,3)-(82,6) = "\\C:"
│ │ ├── closing_loc: ∅
│ │ └── unescaped: "\\C:"
│ ├── opening_loc: (82,0)-(82,3) = "%w["
│ └── closing_loc: (82,6)-(82,7) = "]"
├── @ IndexOperatorWriteNode (location: (84,0)-(84,10))
│ ├── receiver:
│ │ @ CallNode (location: (84,0)-(84,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (84,0)-(84,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (84,3)-(84,4) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (84,4)-(84,5) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (84,6)-(84,8) = "+="
│ └── value:
│ @ IntegerNode (location: (84,9)-(84,10))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (86,0)-(86,11))
│ ├── receiver:
│ │ @ CallNode (location: (86,0)-(86,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (86,0)-(86,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (86,3)-(86,4) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (86,4)-(86,5) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (86,6)-(86,9) = "||="
│ └── value:
│ @ IntegerNode (location: (86,10)-(86,11))
│ └── flags: decimal
├── @ IndexAndWriteNode (location: (88,0)-(88,11))
│ ├── receiver:
│ │ @ CallNode (location: (88,0)-(88,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (88,0)-(88,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (88,3)-(88,4) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (88,4)-(88,5) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (88,6)-(88,9) = "&&="
│ └── value:
│ @ IntegerNode (location: (88,10)-(88,11))
│ └── flags: decimal
├── @ IndexOperatorWriteNode (location: (90,0)-(90,14))
│ ├── receiver:
│ │ @ CallNode (location: (90,0)-(90,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (90,0)-(90,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (90,0)-(90,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (90,3)-(90,4) = "."
│ │ ├── message_loc: (90,4)-(90,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (90,7)-(90,8) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (90,8)-(90,9) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (90,10)-(90,12) = "+="
│ └── value:
│ @ IntegerNode (location: (90,13)-(90,14))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (92,0)-(92,15))
│ ├── receiver:
│ │ @ CallNode (location: (92,0)-(92,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (92,0)-(92,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (92,0)-(92,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (92,3)-(92,4) = "."
│ │ ├── message_loc: (92,4)-(92,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (92,7)-(92,8) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (92,8)-(92,9) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (92,10)-(92,13) = "||="
│ └── value:
│ @ IntegerNode (location: (92,14)-(92,15))
│ └── flags: decimal
├── @ IndexAndWriteNode (location: (94,0)-(94,15))
│ ├── receiver:
│ │ @ CallNode (location: (94,0)-(94,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (94,0)-(94,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (94,0)-(94,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (94,3)-(94,4) = "."
│ │ ├── message_loc: (94,4)-(94,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (94,7)-(94,8) = "["
│ ├── arguments: ∅
│ ├── closing_loc: (94,8)-(94,9) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (94,10)-(94,13) = "&&="
│ └── value:
│ @ IntegerNode (location: (94,14)-(94,15))
│ └── flags: decimal
├── @ IndexOperatorWriteNode (location: (96,0)-(96,13))
│ ├── receiver:
│ │ @ CallNode (location: (96,0)-(96,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (96,0)-(96,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (96,3)-(96,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (96,4)-(96,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (96,4)-(96,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (96,4)-(96,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (96,7)-(96,8) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (96,9)-(96,11) = "+="
│ └── value:
│ @ IntegerNode (location: (96,12)-(96,13))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (98,0)-(98,14))
│ ├── receiver:
│ │ @ CallNode (location: (98,0)-(98,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (98,0)-(98,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (98,3)-(98,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (98,4)-(98,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (98,4)-(98,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (98,4)-(98,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (98,7)-(98,8) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (98,9)-(98,12) = "||="
│ └── value:
│ @ IntegerNode (location: (98,13)-(98,14))
│ └── flags: decimal
├── @ IndexAndWriteNode (location: (100,0)-(100,14))
│ ├── receiver:
│ │ @ CallNode (location: (100,0)-(100,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (100,0)-(100,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (100,3)-(100,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (100,4)-(100,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (100,4)-(100,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (100,4)-(100,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (100,7)-(100,8) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (100,9)-(100,12) = "&&="
│ └── value:
│ @ IntegerNode (location: (100,13)-(100,14))
│ └── flags: decimal
├── @ IndexOperatorWriteNode (location: (102,0)-(102,17))
│ ├── receiver:
│ │ @ CallNode (location: (102,0)-(102,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (102,0)-(102,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (102,0)-(102,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (102,3)-(102,4) = "."
│ │ ├── message_loc: (102,4)-(102,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (102,7)-(102,8) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (102,8)-(102,11))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (102,8)-(102,11))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (102,8)-(102,11) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (102,11)-(102,12) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (102,13)-(102,15) = "+="
│ └── value:
│ @ IntegerNode (location: (102,16)-(102,17))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (104,0)-(104,18))
│ ├── receiver:
│ │ @ CallNode (location: (104,0)-(104,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (104,0)-(104,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (104,0)-(104,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (104,3)-(104,4) = "."
│ │ ├── message_loc: (104,4)-(104,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (104,7)-(104,8) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (104,8)-(104,11))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (104,8)-(104,11))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (104,8)-(104,11) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (104,11)-(104,12) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (104,13)-(104,16) = "||="
│ └── value:
│ @ IntegerNode (location: (104,17)-(104,18))
│ └── flags: decimal
├── @ IndexAndWriteNode (location: (106,0)-(106,18))
│ ├── receiver:
│ │ @ CallNode (location: (106,0)-(106,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (106,0)-(106,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (106,0)-(106,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (106,3)-(106,4) = "."
│ │ ├── message_loc: (106,4)-(106,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (106,7)-(106,8) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (106,8)-(106,11))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (106,8)-(106,11))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (106,8)-(106,11) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (106,11)-(106,12) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── operator_loc: (106,13)-(106,16) = "&&="
│ └── value:
│ @ IntegerNode (location: (106,17)-(106,18))
│ └── flags: decimal
├── @ IndexOperatorWriteNode (location: (108,0)-(108,19))
│ ├── receiver:
│ │ @ CallNode (location: (108,0)-(108,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (108,0)-(108,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (108,3)-(108,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (108,4)-(108,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (108,4)-(108,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (108,4)-(108,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (108,13)-(108,14) = "]"
│ ├── block:
│ │ @ BlockArgumentNode (location: (108,9)-(108,13))
│ │ ├── expression:
│ │ │ @ CallNode (location: (108,10)-(108,13))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (108,10)-(108,13) = "baz"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :baz
│ │ └── operator_loc: (108,9)-(108,10) = "&"
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (108,15)-(108,17) = "+="
│ └── value:
│ @ IntegerNode (location: (108,18)-(108,19))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (110,0)-(110,20))
│ ├── receiver:
│ │ @ CallNode (location: (110,0)-(110,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (110,0)-(110,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (110,3)-(110,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (110,4)-(110,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (110,4)-(110,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (110,4)-(110,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (110,13)-(110,14) = "]"
│ ├── block:
│ │ @ BlockArgumentNode (location: (110,9)-(110,13))
│ │ ├── expression:
│ │ │ @ CallNode (location: (110,10)-(110,13))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (110,10)-(110,13) = "baz"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :baz
│ │ └── operator_loc: (110,9)-(110,10) = "&"
│ ├── flags: ∅
│ ├── operator_loc: (110,15)-(110,18) = "||="
│ └── value:
│ @ IntegerNode (location: (110,19)-(110,20))
│ └── flags: decimal
├── @ IndexAndWriteNode (location: (112,0)-(112,20))
│ ├── receiver:
│ │ @ CallNode (location: (112,0)-(112,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (112,0)-(112,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (112,3)-(112,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (112,4)-(112,7))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (112,4)-(112,7))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (112,4)-(112,7) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (112,13)-(112,14) = "]"
│ ├── block:
│ │ @ BlockArgumentNode (location: (112,9)-(112,13))
│ │ ├── expression:
│ │ │ @ CallNode (location: (112,10)-(112,13))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (112,10)-(112,13) = "baz"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :baz
│ │ └── operator_loc: (112,9)-(112,10) = "&"
│ ├── flags: ∅
│ ├── operator_loc: (112,15)-(112,18) = "&&="
│ └── value:
│ @ IntegerNode (location: (112,19)-(112,20))
│ └── flags: decimal
├── @ IndexOperatorWriteNode (location: (114,0)-(114,23))
│ ├── receiver:
│ │ @ CallNode (location: (114,0)-(114,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (114,0)-(114,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (114,0)-(114,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (114,3)-(114,4) = "."
│ │ ├── message_loc: (114,4)-(114,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (114,7)-(114,8) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (114,8)-(114,11))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (114,8)-(114,11))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (114,8)-(114,11) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (114,17)-(114,18) = "]"
│ ├── block:
│ │ @ BlockArgumentNode (location: (114,13)-(114,17))
│ │ ├── expression:
│ │ │ @ CallNode (location: (114,14)-(114,17))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (114,14)-(114,17) = "baz"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :baz
│ │ └── operator_loc: (114,13)-(114,14) = "&"
│ ├── flags: ∅
│ ├── operator: :+
│ ├── operator_loc: (114,19)-(114,21) = "+="
│ └── value:
│ @ IntegerNode (location: (114,22)-(114,23))
│ └── flags: decimal
├── @ IndexOrWriteNode (location: (116,0)-(116,24))
│ ├── receiver:
│ │ @ CallNode (location: (116,0)-(116,7))
│ │ ├── receiver:
│ │ │ @ CallNode (location: (116,0)-(116,3))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (116,0)-(116,3) = "foo"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :foo
│ │ ├── call_operator_loc: (116,3)-(116,4) = "."
│ │ ├── message_loc: (116,4)-(116,7) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: ∅
│ │ └── name: :foo
│ ├── call_operator_loc: ∅
│ ├── opening_loc: (116,7)-(116,8) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (116,8)-(116,11))
│ │ └── arguments: (length: 1)
│ │ └── @ CallNode (location: (116,8)-(116,11))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (116,8)-(116,11) = "bar"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :bar
│ ├── closing_loc: (116,17)-(116,18) = "]"
│ ├── block:
│ │ @ BlockArgumentNode (location: (116,13)-(116,17))
│ │ ├── expression:
│ │ │ @ CallNode (location: (116,14)-(116,17))
│ │ │ ├── receiver: ∅
│ │ │ ├── call_operator_loc: ∅
│ │ │ ├── message_loc: (116,14)-(116,17) = "baz"
│ │ │ ├── opening_loc: ∅
│ │ │ ├── arguments: ∅
│ │ │ ├── closing_loc: ∅
│ │ │ ├── block: ∅
│ │ │ ├── flags: variable_call
│ │ │ └── name: :baz
│ │ └── operator_loc: (116,13)-(116,14) = "&"
│ ├── flags: ∅
│ ├── operator_loc: (116,19)-(116,22) = "||="
│ └── value:
│ @ IntegerNode (location: (116,23)-(116,24))
│ └── flags: decimal
└── @ IndexAndWriteNode (location: (118,0)-(118,24))
├── receiver:
│ @ CallNode (location: (118,0)-(118,7))
│ ├── receiver:
│ │ @ CallNode (location: (118,0)-(118,3))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (118,0)-(118,3) = "foo"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :foo
│ ├── call_operator_loc: (118,3)-(118,4) = "."
│ ├── message_loc: (118,4)-(118,7) = "foo"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ ├── flags: ∅
│ └── name: :foo
├── call_operator_loc: ∅
├── opening_loc: (118,7)-(118,8) = "["
├── arguments:
│ @ ArgumentsNode (location: (118,8)-(118,11))
│ └── arguments: (length: 1)
│ └── @ CallNode (location: (118,8)-(118,11))
│ ├── receiver: ∅
│ ├── call_operator_loc: ∅
│ ├── message_loc: (118,8)-(118,11) = "bar"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── block: ∅
│ ├── flags: variable_call
│ └── name: :bar
├── closing_loc: (118,17)-(118,18) = "]"
├── block:
│ @ BlockArgumentNode (location: (118,13)-(118,17))
│ ├── expression:
│ │ @ CallNode (location: (118,14)-(118,17))
│ │ ├── receiver: ∅
│ │ ├── call_operator_loc: ∅
│ │ ├── message_loc: (118,14)-(118,17) = "baz"
│ │ ├── opening_loc: ∅
│ │ ├── arguments: ∅
│ │ ├── closing_loc: ∅
│ │ ├── block: ∅
│ │ ├── flags: variable_call
│ │ └── name: :baz
│ └── operator_loc: (118,13)-(118,14) = "&"
├── flags: ∅
├── operator_loc: (118,19)-(118,22) = "&&="
└── value:
@ IntegerNode (location: (118,23)-(118,24))
└── flags: decimal

Просмотреть файл

@ -3,7 +3,7 @@
└── statements:
@ StatementsNode (location: (1,0)-(1,8))
└── body: (length: 1)
└── @ CallOperatorWriteNode (location: (1,0)-(1,8))
└── @ IndexOperatorWriteNode (location: (1,0)-(1,8))
├── receiver:
│ @ CallNode (location: (1,0)-(1,1))
│ ├── receiver: ∅
@ -16,13 +16,11 @@
│ ├── flags: variable_call
│ └── name: :a
├── call_operator_loc: ∅
├── message_loc: (1,1)-(1,3) = "[]"
├── opening_loc: (1,1)-(1,2) = "["
├── arguments: ∅
├── closing_loc: (1,2)-(1,3) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator: :+
├── operator_loc: (1,4)-(1,6) = "+="
└── value:

Просмотреть файл

@ -9,9 +9,6 @@
│ └── name: :A
├── call_operator_loc: (1,1)-(1,2) = "."
├── message_loc: (1,2)-(1,3) = "B"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :B
├── write_name: :B=

Просмотреть файл

@ -3,7 +3,7 @@
└── statements:
@ StatementsNode (location: (1,0)-(1,16))
└── body: (length: 1)
└── @ CallOrWriteNode (location: (1,0)-(1,16))
└── @ IndexOrWriteNode (location: (1,0)-(1,16))
├── receiver:
│ @ CallNode (location: (1,0)-(1,1))
│ ├── receiver: ∅
@ -16,7 +16,6 @@
│ ├── flags: variable_call
│ └── name: :a
├── call_operator_loc: ∅
├── message_loc: (1,1)-(1,5) = "[:b]"
├── opening_loc: (1,1)-(1,2) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,2)-(1,4))
@ -27,9 +26,8 @@
│ ├── closing_loc: ∅
│ └── unescaped: "b"
├── closing_loc: (1,4)-(1,5) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator_loc: (1,6)-(1,9) = "||="
└── value:
@ CallNode (location: (1,10)-(1,16))

Просмотреть файл

@ -9,9 +9,6 @@
│ └── name: :A
├── call_operator_loc: (1,1)-(1,3) = "::"
├── message_loc: (1,3)-(1,4) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :b
├── write_name: :b=

Просмотреть файл

@ -9,9 +9,6 @@
│ └── name: :A
├── call_operator_loc: (1,1)-(1,3) = "::"
├── message_loc: (1,3)-(1,4) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :b
├── write_name: :b=

Просмотреть файл

@ -17,9 +17,6 @@
│ └── name: :a
├── call_operator_loc: (1,1)-(1,2) = "."
├── message_loc: (1,2)-(1,3) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :b
├── write_name: :b=

Просмотреть файл

@ -17,9 +17,6 @@
│ └── name: :a
├── call_operator_loc: (1,1)-(1,3) = "&."
├── message_loc: (1,3)-(1,4) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: safe_navigation
├── read_name: :b
├── write_name: :b=

Просмотреть файл

@ -17,9 +17,6 @@
│ └── name: :a
├── call_operator_loc: (1,1)-(1,3) = "&."
├── message_loc: (1,3)-(1,4) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: safe_navigation
├── read_name: :b
├── write_name: :b=

Просмотреть файл

@ -785,13 +785,12 @@
│ ├── block: ∅
│ ├── flags: ∅
│ └── name: :[]=
├── @ CallOrWriteNode (location: (37,0)-(37,14))
├── @ IndexOrWriteNode (location: (37,0)-(37,14))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (37,0)-(37,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (37,1)-(37,6) = "[%()]"
│ ├── opening_loc: (37,1)-(37,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (37,2)-(37,5))
@ -803,9 +802,8 @@
│ │ ├── closing_loc: (37,4)-(37,5) = ")"
│ │ └── unescaped: ""
│ ├── closing_loc: (37,5)-(37,6) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator_loc: (37,7)-(37,10) = "||="
│ └── value:
│ @ CallNode (location: (37,11)-(37,14))
@ -925,13 +923,12 @@
│ ├── block: ∅
│ ├── flags: ∅
│ └── name: :[]=
├── @ CallOrWriteNode (location: (48,0)-(48,21))
├── @ IndexOrWriteNode (location: (48,0)-(48,21))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (48,0)-(48,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (48,1)-(48,13) = "[<<-HEREDOC]"
│ ├── opening_loc: (48,1)-(48,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (48,2)-(48,12))
@ -957,9 +954,8 @@
│ │ │ └── unescaped: "\n"
│ │ └── closing_loc: (50,0)-(50,0) = "HEREDOC\n"
│ ├── closing_loc: (48,12)-(48,13) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator_loc: (48,14)-(48,17) = "||="
│ └── value:
│ @ CallNode (location: (48,18)-(48,21))

Просмотреть файл

@ -151,9 +151,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (10,1)-(10,2) = "."
│ ├── message_loc: (10,2)-(10,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -169,9 +166,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (11,1)-(11,2) = "."
│ ├── message_loc: (11,2)-(11,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -187,9 +181,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (12,1)-(12,2) = "."
│ ├── message_loc: (12,2)-(12,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -205,9 +196,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (13,1)-(13,2) = "."
│ ├── message_loc: (13,2)-(13,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -223,9 +211,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (14,1)-(14,2) = "."
│ ├── message_loc: (14,2)-(14,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -241,9 +226,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (15,1)-(15,2) = "."
│ ├── message_loc: (15,2)-(15,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -266,9 +248,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (16,1)-(16,2) = "."
│ ├── message_loc: (16,2)-(16,3) = "b"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :b
│ ├── write_name: :b=
@ -276,13 +255,12 @@
│ └── value:
│ @ IntegerNode (location: (16,8)-(16,9))
│ └── flags: decimal
├── @ CallOperatorWriteNode (location: (17,0)-(17,9))
├── @ IndexOperatorWriteNode (location: (17,0)-(17,9))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (17,0)-(17,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (17,1)-(17,4) = "[b]"
│ ├── opening_loc: (17,1)-(17,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (17,2)-(17,3))
@ -298,21 +276,19 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (17,3)-(17,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :+
│ ├── operator_loc: (17,5)-(17,7) = "+="
│ └── value:
│ @ IntegerNode (location: (17,8)-(17,9))
│ └── flags: decimal
├── @ CallOperatorWriteNode (location: (18,0)-(18,9))
├── @ IndexOperatorWriteNode (location: (18,0)-(18,9))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (18,0)-(18,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (18,1)-(18,4) = "[b]"
│ ├── opening_loc: (18,1)-(18,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (18,2)-(18,3))
@ -328,21 +304,19 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (18,3)-(18,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :-
│ ├── operator_loc: (18,5)-(18,7) = "-="
│ └── value:
│ @ IntegerNode (location: (18,8)-(18,9))
│ └── flags: decimal
├── @ CallOperatorWriteNode (location: (19,0)-(19,10))
├── @ IndexOperatorWriteNode (location: (19,0)-(19,10))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (19,0)-(19,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (19,1)-(19,4) = "[b]"
│ ├── opening_loc: (19,1)-(19,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (19,2)-(19,3))
@ -358,21 +332,19 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (19,3)-(19,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :**
│ ├── operator_loc: (19,5)-(19,8) = "**="
│ └── value:
│ @ IntegerNode (location: (19,9)-(19,10))
│ └── flags: decimal
├── @ CallOperatorWriteNode (location: (20,0)-(20,9))
├── @ IndexOperatorWriteNode (location: (20,0)-(20,9))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (20,0)-(20,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (20,1)-(20,4) = "[b]"
│ ├── opening_loc: (20,1)-(20,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (20,2)-(20,3))
@ -388,21 +360,19 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (20,3)-(20,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :*
│ ├── operator_loc: (20,5)-(20,7) = "*="
│ └── value:
│ @ IntegerNode (location: (20,8)-(20,9))
│ └── flags: decimal
├── @ CallOperatorWriteNode (location: (21,0)-(21,9))
├── @ IndexOperatorWriteNode (location: (21,0)-(21,9))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (21,0)-(21,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (21,1)-(21,4) = "[b]"
│ ├── opening_loc: (21,1)-(21,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (21,2)-(21,3))
@ -418,21 +388,19 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (21,3)-(21,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :/
│ ├── operator_loc: (21,5)-(21,7) = "/="
│ └── value:
│ @ IntegerNode (location: (21,8)-(21,9))
│ └── flags: decimal
├── @ CallAndWriteNode (location: (22,0)-(22,10))
├── @ IndexAndWriteNode (location: (22,0)-(22,10))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (22,0)-(22,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (22,1)-(22,4) = "[b]"
│ ├── opening_loc: (22,1)-(22,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (22,2)-(22,3))
@ -448,9 +416,8 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (22,3)-(22,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator_loc: (22,5)-(22,8) = "&&="
│ └── value:
│ @ CallNode (location: (22,9)-(22,10))
@ -463,13 +430,12 @@
│ ├── block: ∅
│ ├── flags: variable_call
│ └── name: :b
├── @ CallOrWriteNode (location: (23,0)-(23,10))
├── @ IndexOrWriteNode (location: (23,0)-(23,10))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (23,0)-(23,1))
│ │ ├── name: :a
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (23,1)-(23,4) = "[b]"
│ ├── opening_loc: (23,1)-(23,2) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (23,2)-(23,3))
@ -485,9 +451,8 @@
│ │ ├── flags: variable_call
│ │ └── name: :b
│ ├── closing_loc: (23,3)-(23,4) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator_loc: (23,5)-(23,8) = "||="
│ └── value:
│ @ IntegerNode (location: (23,9)-(23,10))
@ -506,9 +471,6 @@
│ └── name: :foo
├── call_operator_loc: (24,3)-(24,4) = "."
├── message_loc: (24,4)-(24,5) = "A"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :A
├── write_name: :A=

Просмотреть файл

@ -17,9 +17,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (1,3)-(1,4) = "."
│ ├── message_loc: (1,4)-(1,5) = "a"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :a
│ ├── write_name: :a=
@ -27,7 +24,7 @@
│ └── value:
│ @ IntegerNode (location: (1,10)-(1,11))
│ └── flags: decimal
└── @ CallAndWriteNode (location: (3,0)-(3,15))
└── @ IndexAndWriteNode (location: (3,0)-(3,15))
├── receiver:
│ @ CallNode (location: (3,0)-(3,3))
│ ├── receiver: ∅
@ -40,7 +37,6 @@
│ ├── flags: variable_call
│ └── name: :foo
├── call_operator_loc: ∅
├── message_loc: (3,3)-(3,9) = "[0, 1]"
├── opening_loc: (3,3)-(3,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (3,4)-(3,8))
@ -50,9 +46,8 @@
│ └── @ IntegerNode (location: (3,7)-(3,8))
│ └── flags: decimal
├── closing_loc: (3,8)-(3,9) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator_loc: (3,10)-(3,13) = "&&="
└── value:
@ IntegerNode (location: (3,14)-(3,15))

Просмотреть файл

@ -17,9 +17,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (1,3)-(1,4) = "."
│ ├── message_loc: (1,4)-(1,5) = "A"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :A
│ ├── write_name: :A=
@ -42,9 +39,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (3,3)-(3,4) = "."
│ ├── message_loc: (3,4)-(3,5) = "a"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :a
│ ├── write_name: :a=
@ -67,9 +61,6 @@
│ └── name: :foo
├── call_operator_loc: (5,3)-(5,5) = "::"
├── message_loc: (5,5)-(5,6) = "a"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :a
├── write_name: :a=

Просмотреть файл

@ -17,9 +17,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (1,3)-(1,4) = "."
│ ├── message_loc: (1,4)-(1,5) = "A"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :A
│ ├── write_name: :A=
@ -62,9 +59,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (3,3)-(3,4) = "."
│ ├── message_loc: (3,4)-(3,5) = "a"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :a
│ ├── write_name: :a=
@ -150,9 +144,6 @@
│ └── name: :foo
├── call_operator_loc: (7,3)-(7,5) = "::"
├── message_loc: (7,5)-(7,6) = "a"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: ∅
├── read_name: :a
├── write_name: :a=

Просмотреть файл

@ -3,7 +3,7 @@
└── statements:
@ StatementsNode (location: (1,0)-(1,14))
└── body: (length: 1)
└── @ CallOperatorWriteNode (location: (1,0)-(1,14))
└── @ IndexOperatorWriteNode (location: (1,0)-(1,14))
├── receiver:
│ @ CallNode (location: (1,0)-(1,3))
│ ├── receiver: ∅
@ -16,7 +16,6 @@
│ ├── flags: variable_call
│ └── name: :foo
├── call_operator_loc: ∅
├── message_loc: (1,3)-(1,9) = "[0, 1]"
├── opening_loc: (1,3)-(1,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,8))
@ -26,9 +25,8 @@
│ └── @ IntegerNode (location: (1,7)-(1,8))
│ └── flags: decimal
├── closing_loc: (1,8)-(1,9) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator: :+
├── operator_loc: (1,10)-(1,12) = "+="
└── value:

Просмотреть файл

@ -3,7 +3,7 @@
└── statements:
@ StatementsNode (location: (1,0)-(1,18))
└── body: (length: 1)
└── @ CallOperatorWriteNode (location: (1,0)-(1,18))
└── @ IndexOperatorWriteNode (location: (1,0)-(1,18))
├── receiver:
│ @ CallNode (location: (1,0)-(1,3))
│ ├── receiver: ∅
@ -16,7 +16,6 @@
│ ├── flags: variable_call
│ └── name: :foo
├── call_operator_loc: ∅
├── message_loc: (1,3)-(1,9) = "[0, 1]"
├── opening_loc: (1,3)-(1,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (1,4)-(1,8))
@ -26,9 +25,8 @@
│ └── @ IntegerNode (location: (1,7)-(1,8))
│ └── flags: decimal
├── closing_loc: (1,8)-(1,9) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator: :+
├── operator_loc: (1,10)-(1,12) = "+="
└── value:

Просмотреть файл

@ -17,9 +17,6 @@
│ │ └── name: :foo
│ ├── call_operator_loc: (1,3)-(1,4) = "."
│ ├── message_loc: (1,4)-(1,5) = "a"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :a
│ ├── write_name: :a=
@ -27,7 +24,7 @@
│ └── value:
│ @ IntegerNode (location: (1,10)-(1,11))
│ └── flags: decimal
└── @ CallOrWriteNode (location: (3,0)-(3,15))
└── @ IndexOrWriteNode (location: (3,0)-(3,15))
├── receiver:
│ @ CallNode (location: (3,0)-(3,3))
│ ├── receiver: ∅
@ -40,7 +37,6 @@
│ ├── flags: variable_call
│ └── name: :foo
├── call_operator_loc: ∅
├── message_loc: (3,3)-(3,9) = "[0, 1]"
├── opening_loc: (3,3)-(3,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (3,4)-(3,8))
@ -50,9 +46,8 @@
│ └── @ IntegerNode (location: (3,7)-(3,8))
│ └── flags: decimal
├── closing_loc: (3,8)-(3,9) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator_loc: (3,10)-(3,13) = "||="
└── value:
@ IntegerNode (location: (3,14)-(3,15))

Просмотреть файл

@ -144,9 +144,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (9,3)-(9,4) = "."
│ ├── message_loc: (9,4)-(9,5) = "C"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :C
│ ├── write_name: :C=
@ -187,9 +184,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (11,3)-(11,4) = "."
│ ├── message_loc: (11,4)-(11,5) = "C"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :C
│ ├── write_name: :C=
@ -230,9 +224,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (13,3)-(13,4) = "."
│ ├── message_loc: (13,4)-(13,5) = "m"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :m
│ ├── write_name: :m=
@ -273,9 +264,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (15,3)-(15,4) = "."
│ ├── message_loc: (15,4)-(15,5) = "m"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :m
│ ├── write_name: :m=
@ -396,9 +384,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (21,3)-(21,5) = "::"
│ ├── message_loc: (21,5)-(21,6) = "m"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :m
│ ├── write_name: :m=
@ -439,9 +424,6 @@
│ │ └── depth: 0
│ ├── call_operator_loc: (23,3)-(23,5) = "::"
│ ├── message_loc: (23,5)-(23,6) = "m"
│ ├── opening_loc: ∅
│ ├── arguments: ∅
│ ├── closing_loc: ∅
│ ├── flags: ∅
│ ├── read_name: :m
│ ├── write_name: :m=
@ -475,13 +457,12 @@
│ ├── keyword_loc: (23,21)-(23,27) = "rescue"
│ └── rescue_expression:
│ @ NilNode (location: (23,28)-(23,31))
├── @ CallOperatorWriteNode (location: (25,0)-(25,30))
├── @ IndexOperatorWriteNode (location: (25,0)-(25,30))
│ ├── receiver:
│ │ @ LocalVariableReadNode (location: (25,0)-(25,3))
│ │ ├── name: :foo
│ │ └── depth: 0
│ ├── call_operator_loc: ∅
│ ├── message_loc: (25,3)-(25,6) = "[0]"
│ ├── opening_loc: (25,3)-(25,4) = "["
│ ├── arguments:
│ │ @ ArgumentsNode (location: (25,4)-(25,5))
@ -489,9 +470,8 @@
│ │ └── @ IntegerNode (location: (25,4)-(25,5))
│ │ └── flags: decimal
│ ├── closing_loc: (25,5)-(25,6) = "]"
│ ├── block: ∅
│ ├── flags: ∅
│ ├── read_name: :[]
│ ├── write_name: :[]=
│ ├── operator: :+
│ ├── operator_loc: (25,7)-(25,9) = "+="
│ └── value:
@ -522,13 +502,12 @@
│ ├── block: ∅
│ ├── flags: ∅
│ └── name: :raise
└── @ CallOperatorWriteNode (location: (27,0)-(27,31))
└── @ IndexOperatorWriteNode (location: (27,0)-(27,31))
├── receiver:
│ @ LocalVariableReadNode (location: (27,0)-(27,3))
│ ├── name: :foo
│ └── depth: 0
├── call_operator_loc: ∅
├── message_loc: (27,3)-(27,6) = "[0]"
├── opening_loc: (27,3)-(27,4) = "["
├── arguments:
│ @ ArgumentsNode (location: (27,4)-(27,5))
@ -536,9 +515,8 @@
│ └── @ IntegerNode (location: (27,4)-(27,5))
│ └── flags: decimal
├── closing_loc: (27,5)-(27,6) = "]"
├── block: ∅
├── flags: ∅
├── read_name: :[]
├── write_name: :[]=
├── operator: :+
├── operator_loc: (27,7)-(27,9) = "+="
└── value:

Просмотреть файл

@ -17,9 +17,6 @@
│ └── name: :a
├── call_operator_loc: (1,1)-(1,3) = "&."
├── message_loc: (1,3)-(1,4) = "b"
├── opening_loc: ∅
├── arguments: ∅
├── closing_loc: ∅
├── flags: safe_navigation
├── read_name: :b
├── write_name: :b=