[ruby/yarp] Add implicit nodes for ommitted hash values
https://github.com/ruby/yarp/commit/22130b3491
This commit is contained in:
parent
5a6eae0b0a
commit
5f9f2fd72e
@ -410,6 +410,20 @@ module YARP
|
||||
assert_location(ImaginaryNode, "1ri")
|
||||
end
|
||||
|
||||
def test_ImplicitNode
|
||||
assert_location(ImplicitNode, "{ foo: }", 2...6) do |node|
|
||||
node.elements.first.value
|
||||
end
|
||||
|
||||
assert_location(ImplicitNode, "{ Foo: }", 2..6) do |node|
|
||||
node.elements.first.value
|
||||
end
|
||||
|
||||
assert_location(ImplicitNode, "foo = 1; { foo: }", 11..15) do |node|
|
||||
node.elements.first.value
|
||||
end
|
||||
end
|
||||
|
||||
def test_InNode
|
||||
assert_location(InNode, "case foo; in bar; end", 10...16) do |node|
|
||||
node.conditions.first
|
||||
|
@ -240,7 +240,19 @@
|
||||
│ │ │ │ ├── value_loc: (248...249) = "b"
|
||||
│ │ │ │ ├── closing_loc: (249...250) = ":"
|
||||
│ │ │ │ └── unescaped: "b"
|
||||
│ │ │ ├── value: ∅
|
||||
│ │ │ ├── value:
|
||||
│ │ │ │ @ ImplicitNode (location: (248...250))
|
||||
│ │ │ │ └── value:
|
||||
│ │ │ │ @ CallNode (location: (248...250))
|
||||
│ │ │ │ ├── receiver: ∅
|
||||
│ │ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ │ ├── message_loc: (248...249) = "b"
|
||||
│ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ ├── arguments: ∅
|
||||
│ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ ├── block: ∅
|
||||
│ │ │ │ ├── flags: ∅
|
||||
│ │ │ │ └── name: "b"
|
||||
│ │ │ └── operator_loc: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
|
@ -340,7 +340,19 @@
|
||||
│ │ │ │ ├── value_loc: (303...304) = "b"
|
||||
│ │ │ │ ├── closing_loc: (304...305) = ":"
|
||||
│ │ │ │ └── unescaped: "b"
|
||||
│ │ │ ├── value: ∅
|
||||
│ │ │ ├── value:
|
||||
│ │ │ │ @ ImplicitNode (location: (303...305))
|
||||
│ │ │ │ └── value:
|
||||
│ │ │ │ @ CallNode (location: (303...305))
|
||||
│ │ │ │ ├── receiver: ∅
|
||||
│ │ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ │ ├── message_loc: (303...304) = "b"
|
||||
│ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ ├── arguments: ∅
|
||||
│ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ ├── block: ∅
|
||||
│ │ │ │ ├── flags: ∅
|
||||
│ │ │ │ └── name: "b"
|
||||
│ │ │ └── operator_loc: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
|
@ -13,6 +13,18 @@
|
||||
│ │ ├── value_loc: (2...3) = "y"
|
||||
│ │ ├── closing_loc: (3...4) = ":"
|
||||
│ │ └── unescaped: "y"
|
||||
│ ├── value: ∅
|
||||
│ ├── value:
|
||||
│ │ @ ImplicitNode (location: (2...4))
|
||||
│ │ └── value:
|
||||
│ │ @ CallNode (location: (2...4))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (2...3) = "y"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: "y"
|
||||
│ └── operator_loc: ∅
|
||||
└── closing_loc: (5...6) = "}"
|
||||
|
@ -13,7 +13,11 @@
|
||||
│ │ │ ├── value_loc: (1...4) = "BAR"
|
||||
│ │ │ ├── closing_loc: (4...5) = ":"
|
||||
│ │ │ └── unescaped: "BAR"
|
||||
│ │ ├── value: ∅
|
||||
│ │ ├── value:
|
||||
│ │ │ @ ImplicitNode (location: (1...5))
|
||||
│ │ │ └── value:
|
||||
│ │ │ @ ConstantReadNode (location: (1...5))
|
||||
│ │ │ └── name: :BAR
|
||||
│ │ └── operator_loc: ∅
|
||||
│ └── closing_loc: (5...6) = "}"
|
||||
├── @ HashNode (location: (8...16))
|
||||
@ -26,7 +30,19 @@
|
||||
│ │ │ │ ├── value_loc: (9...10) = "a"
|
||||
│ │ │ │ ├── closing_loc: (10...11) = ":"
|
||||
│ │ │ │ └── unescaped: "a"
|
||||
│ │ │ ├── value: ∅
|
||||
│ │ │ ├── value:
|
||||
│ │ │ │ @ ImplicitNode (location: (9...11))
|
||||
│ │ │ │ └── value:
|
||||
│ │ │ │ @ CallNode (location: (9...11))
|
||||
│ │ │ │ ├── receiver: ∅
|
||||
│ │ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ │ ├── message_loc: (9...10) = "a"
|
||||
│ │ │ │ ├── opening_loc: ∅
|
||||
│ │ │ │ ├── arguments: ∅
|
||||
│ │ │ │ ├── closing_loc: ∅
|
||||
│ │ │ │ ├── block: ∅
|
||||
│ │ │ │ ├── flags: ∅
|
||||
│ │ │ │ └── name: "a"
|
||||
│ │ │ └── operator_loc: ∅
|
||||
│ │ └── @ AssocNode (location: (13...15))
|
||||
│ │ ├── key:
|
||||
@ -35,7 +51,19 @@
|
||||
│ │ │ ├── value_loc: (13...14) = "b"
|
||||
│ │ │ ├── closing_loc: (14...15) = ":"
|
||||
│ │ │ └── unescaped: "b"
|
||||
│ │ ├── value: ∅
|
||||
│ │ ├── value:
|
||||
│ │ │ @ ImplicitNode (location: (13...15))
|
||||
│ │ │ └── value:
|
||||
│ │ │ @ CallNode (location: (13...15))
|
||||
│ │ │ ├── receiver: ∅
|
||||
│ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ ├── message_loc: (13...14) = "b"
|
||||
│ │ │ ├── opening_loc: ∅
|
||||
│ │ │ ├── arguments: ∅
|
||||
│ │ │ ├── closing_loc: ∅
|
||||
│ │ │ ├── block: ∅
|
||||
│ │ │ ├── flags: ∅
|
||||
│ │ │ └── name: "b"
|
||||
│ │ └── operator_loc: ∅
|
||||
│ └── closing_loc: (15...16) = "}"
|
||||
└── @ HashNode (location: (18...25))
|
||||
@ -48,6 +76,18 @@
|
||||
│ │ ├── value_loc: (19...23) = "puts"
|
||||
│ │ ├── closing_loc: (23...24) = ":"
|
||||
│ │ └── unescaped: "puts"
|
||||
│ ├── value: ∅
|
||||
│ ├── value:
|
||||
│ │ @ ImplicitNode (location: (19...24))
|
||||
│ │ └── value:
|
||||
│ │ @ CallNode (location: (19...24))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (19...23) = "puts"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: "puts"
|
||||
│ └── operator_loc: ∅
|
||||
└── closing_loc: (24...25) = "}"
|
||||
|
@ -20,7 +20,19 @@
|
||||
│ │ │ ├── value_loc: (4...5) = "a"
|
||||
│ │ │ ├── closing_loc: (5...6) = ":"
|
||||
│ │ │ └── unescaped: "a"
|
||||
│ │ ├── value: ∅
|
||||
│ │ ├── value:
|
||||
│ │ │ @ ImplicitNode (location: (4...6))
|
||||
│ │ │ └── value:
|
||||
│ │ │ @ CallNode (location: (4...6))
|
||||
│ │ │ ├── receiver: ∅
|
||||
│ │ │ ├── call_operator_loc: ∅
|
||||
│ │ │ ├── message_loc: (4...5) = "a"
|
||||
│ │ │ ├── opening_loc: ∅
|
||||
│ │ │ ├── arguments: ∅
|
||||
│ │ │ ├── closing_loc: ∅
|
||||
│ │ │ ├── block: ∅
|
||||
│ │ │ ├── flags: ∅
|
||||
│ │ │ └── name: "a"
|
||||
│ │ └── operator_loc: ∅
|
||||
│ └── @ AssocNode (location: (8...10))
|
||||
│ ├── key:
|
||||
@ -29,7 +41,19 @@
|
||||
│ │ ├── value_loc: (8...9) = "b"
|
||||
│ │ ├── closing_loc: (9...10) = ":"
|
||||
│ │ └── unescaped: "b"
|
||||
│ ├── value: ∅
|
||||
│ ├── value:
|
||||
│ │ @ ImplicitNode (location: (8...10))
|
||||
│ │ └── value:
|
||||
│ │ @ CallNode (location: (8...10))
|
||||
│ │ ├── receiver: ∅
|
||||
│ │ ├── call_operator_loc: ∅
|
||||
│ │ ├── message_loc: (8...9) = "b"
|
||||
│ │ ├── opening_loc: ∅
|
||||
│ │ ├── arguments: ∅
|
||||
│ │ ├── closing_loc: ∅
|
||||
│ │ ├── block: ∅
|
||||
│ │ ├── flags: ∅
|
||||
│ │ └── name: "b"
|
||||
│ └── operator_loc: ∅
|
||||
├── closing_loc: (10...11) = ")"
|
||||
├── block: ∅
|
||||
|
@ -1413,6 +1413,19 @@ nodes:
|
||||
|
||||
1.0i
|
||||
^^^^
|
||||
- name: ImplicitNode
|
||||
fields:
|
||||
- name: value
|
||||
type: node
|
||||
comment: |
|
||||
Represents a node that is implicitly being added to the tree but doesn't
|
||||
correspond directly to a node in the source.
|
||||
|
||||
{ foo: }
|
||||
^^^^
|
||||
|
||||
{ Foo: }
|
||||
^^^^
|
||||
- name: InNode
|
||||
fields:
|
||||
- name: pattern
|
||||
|
36
yarp/yarp.c
36
yarp/yarp.c
@ -2737,6 +2737,22 @@ yp_else_node_end_keyword_loc_set(yp_else_node_t *node, const yp_token_t *keyword
|
||||
node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword);
|
||||
}
|
||||
|
||||
// Allocate and initialize a new ImplicitNode node.
|
||||
static yp_implicit_node_t *
|
||||
yp_implicit_node_create(yp_parser_t *parser, yp_node_t *value) {
|
||||
yp_implicit_node_t *node = YP_ALLOC_NODE(parser, yp_implicit_node_t);
|
||||
|
||||
*node = (yp_implicit_node_t) {
|
||||
{
|
||||
.type = YP_IMPLICIT_NODE,
|
||||
.location = value->location
|
||||
},
|
||||
.value = value
|
||||
};
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Allocate and initialize a new IntegerNode node.
|
||||
static yp_integer_node_t *
|
||||
yp_integer_node_create(yp_parser_t *parser, yp_node_flags_t base, const yp_token_t *token) {
|
||||
@ -8715,14 +8731,32 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) {
|
||||
break;
|
||||
}
|
||||
case YP_TOKEN_LABEL: {
|
||||
yp_token_t label = parser->current;
|
||||
parser_lex(parser);
|
||||
|
||||
yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous);
|
||||
yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &label);
|
||||
yp_token_t operator = not_provided(parser);
|
||||
yp_node_t *value = NULL;
|
||||
|
||||
if (token_begins_expression_p(parser->current.type)) {
|
||||
value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_EXPRESSION_AFTER_LABEL);
|
||||
} else {
|
||||
if (parser->encoding.isupper_char(label.start, (label.end - 1) - label.start)) {
|
||||
yp_token_t constant = { .type = YP_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
|
||||
value = (yp_node_t *) yp_constant_read_node_create(parser, &constant);
|
||||
} else {
|
||||
int depth = yp_parser_local_depth(parser, &((yp_token_t) { .type = YP_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 }));
|
||||
yp_token_t identifier = { .type = YP_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 };
|
||||
|
||||
if (depth == -1) {
|
||||
value = (yp_node_t *) yp_call_node_variable_call_create(parser, &identifier);
|
||||
} else {
|
||||
value = (yp_node_t *) yp_local_variable_read_node_create(parser, &identifier, (uint32_t) depth);
|
||||
}
|
||||
}
|
||||
|
||||
value->location.end++;
|
||||
value = (yp_node_t *) yp_implicit_node_create(parser, value);
|
||||
}
|
||||
|
||||
element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user