Skip to content

Commit 22130b3

Browse files
committed
Add implicit nodes for ommitted hash values
1 parent c1c5d82 commit 22130b3

File tree

8 files changed

+171
-10
lines changed

8 files changed

+171
-10
lines changed

config.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,19 @@ nodes:
14131413
14141414
1.0i
14151415
^^^^
1416+
- name: ImplicitNode
1417+
fields:
1418+
- name: value
1419+
type: node
1420+
comment: |
1421+
Represents a node that is implicitly being added to the tree but doesn't
1422+
correspond directly to a node in the source.
1423+
1424+
{ foo: }
1425+
^^^^
1426+
1427+
{ Foo: }
1428+
^^^^
14161429
- name: InNode
14171430
fields:
14181431
- name: pattern

src/yarp.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2737,6 +2737,22 @@ yp_else_node_end_keyword_loc_set(yp_else_node_t *node, const yp_token_t *keyword
27372737
node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword);
27382738
}
27392739

2740+
// Allocate and initialize a new ImplicitNode node.
2741+
static yp_implicit_node_t *
2742+
yp_implicit_node_create(yp_parser_t *parser, yp_node_t *value) {
2743+
yp_implicit_node_t *node = YP_ALLOC_NODE(parser, yp_implicit_node_t);
2744+
2745+
*node = (yp_implicit_node_t) {
2746+
{
2747+
.type = YP_IMPLICIT_NODE,
2748+
.location = value->location
2749+
},
2750+
.value = value
2751+
};
2752+
2753+
return node;
2754+
}
2755+
27402756
// Allocate and initialize a new IntegerNode node.
27412757
static yp_integer_node_t *
27422758
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) {
87158731
break;
87168732
}
87178733
case YP_TOKEN_LABEL: {
8734+
yp_token_t label = parser->current;
87188735
parser_lex(parser);
87198736

8720-
yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous);
8737+
yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &label);
87218738
yp_token_t operator = not_provided(parser);
87228739
yp_node_t *value = NULL;
87238740

87248741
if (token_begins_expression_p(parser->current.type)) {
87258742
value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_EXPRESSION_AFTER_LABEL);
8743+
} else {
8744+
if (parser->encoding.isupper_char(label.start, (label.end - 1) - label.start)) {
8745+
yp_token_t constant = { .type = YP_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 };
8746+
value = (yp_node_t *) yp_constant_read_node_create(parser, &constant);
8747+
} else {
8748+
int depth = yp_parser_local_depth(parser, &((yp_token_t) { .type = YP_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 }));
8749+
yp_token_t identifier = { .type = YP_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 };
8750+
8751+
if (depth == -1) {
8752+
value = (yp_node_t *) yp_call_node_variable_call_create(parser, &identifier);
8753+
} else {
8754+
value = (yp_node_t *) yp_local_variable_read_node_create(parser, &identifier, (uint32_t) depth);
8755+
}
8756+
}
8757+
8758+
value->location.end++;
8759+
value = (yp_node_t *) yp_implicit_node_create(parser, value);
87268760
}
87278761

87288762
element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value);

test/yarp/location_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ def test_ImaginaryNode
410410
assert_location(ImaginaryNode, "1ri")
411411
end
412412

413+
def test_ImplicitNode
414+
assert_location(ImplicitNode, "{ foo: }", 2...6) do |node|
415+
node.elements.first.value
416+
end
417+
418+
assert_location(ImplicitNode, "{ Foo: }", 2..6) do |node|
419+
node.elements.first.value
420+
end
421+
422+
assert_location(ImplicitNode, "foo = 1; { foo: }", 11..15) do |node|
423+
node.elements.first.value
424+
end
425+
end
426+
413427
def test_InNode
414428
assert_location(InNode, "case foo; in bar; end", 10...16) do |node|
415429
node.conditions.first

test/yarp/snapshots/if.txt

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/yarp/snapshots/rescue.txt

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/yarp/snapshots/seattlerb/assoc__bare.txt

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/yarp/snapshots/whitequark/hash_pair_value_omission.txt

Lines changed: 44 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/yarp/snapshots/whitequark/keyword_argument_omission.txt

Lines changed: 26 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)