Skip to content

Commit 52504f8

Browse files
committed
Use current_string for %s symbol literals
1 parent 21fad0c commit 52504f8

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

src/prism.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4448,9 +4448,10 @@ pm_super_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_argument
44484448
return node;
44494449
}
44504450

4451-
// Allocate a new SymbolNode node.
4451+
// Allocate and initialize a new SymbolNode node with the given unescaped
4452+
// string.
44524453
static pm_symbol_node_t *
4453-
pm_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) {
4454+
pm_symbol_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing, const pm_string_t *unescaped) {
44544455
pm_symbol_node_t *node = PM_ALLOC_NODE(parser, pm_symbol_node_t);
44554456

44564457
*node = (pm_symbol_node_t) {
@@ -4465,12 +4466,18 @@ pm_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_t
44654466
.opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening),
44664467
.value_loc = PM_LOCATION_TOKEN_VALUE(value),
44674468
.closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing),
4468-
.unescaped = PM_EMPTY_STRING
4469+
.unescaped = *unescaped
44694470
};
44704471

44714472
return node;
44724473
}
44734474

4475+
// Allocate a new SymbolNode node.
4476+
static inline pm_symbol_node_t *
4477+
pm_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) {
4478+
return pm_symbol_node_create_unescaped(parser, opening, value, closing, &PM_EMPTY_STRING);
4479+
}
4480+
44744481
// Allocate and initialize a new SymbolNode node from a label.
44754482
static pm_symbol_node_t *
44764483
pm_symbol_node_label_create(pm_parser_t *parser, const pm_token_t *token) {
@@ -10909,7 +10916,6 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
1090910916

1091010917
if (lex_mode->mode != PM_LEX_STRING) {
1091110918
if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state);
10912-
pm_token_t symbol;
1091310919

1091410920
switch (parser->current.type) {
1091510921
case PM_TOKEN_IDENTIFIER:
@@ -10922,21 +10928,21 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
1092210928
case PM_TOKEN_BACK_REFERENCE:
1092310929
case PM_CASE_KEYWORD:
1092410930
parser_lex(parser);
10925-
symbol = parser->previous;
1092610931
break;
1092710932
case PM_CASE_OPERATOR:
1092810933
lex_state_set(parser, next_state == PM_LEX_STATE_NONE ? PM_LEX_STATE_ENDFN : next_state);
1092910934
parser_lex(parser);
10930-
symbol = parser->previous;
1093110935
break;
1093210936
default:
1093310937
expect2(parser, PM_TOKEN_IDENTIFIER, PM_TOKEN_METHOD_NAME, PM_ERR_SYMBOL_INVALID);
10934-
symbol = parser->previous;
1093510938
break;
1093610939
}
1093710940

1093810941
pm_token_t closing = not_provided(parser);
10939-
return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &symbol, &closing, PM_UNESCAPE_ALL);
10942+
pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing);
10943+
10944+
pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end);
10945+
return (pm_node_t *) symbol;
1094010946
}
1094110947

1094210948
if (lex_mode->as.string.interpolation) {
@@ -10947,7 +10953,7 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
1094710953

1094810954
pm_token_t content = not_provided(parser);
1094910955
pm_token_t closing = parser->previous;
10950-
return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &closing, PM_UNESCAPE_NONE);
10956+
return (pm_node_t *) pm_symbol_node_create(parser, &opening, &content, &closing);
1095110957
}
1095210958

1095310959
// Now we can parse the first part of the symbol.
@@ -10980,18 +10986,23 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s
1098010986
}
1098110987

1098210988
pm_token_t content;
10983-
if (accept1(parser, PM_TOKEN_STRING_CONTENT)) {
10984-
content = parser->previous;
10989+
pm_string_t unescaped;
10990+
10991+
if (match1(parser, PM_TOKEN_STRING_CONTENT)) {
10992+
content = parser->current;
10993+
unescaped = parser->current_string;
10994+
parser_lex(parser);
1098510995
} else {
1098610996
content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end };
10997+
pm_string_shared_init(&unescaped, content.start, content.end);
1098710998
}
1098810999

1098911000
if (next_state != PM_LEX_STATE_NONE) {
1099011001
lex_state_set(parser, next_state);
1099111002
}
10992-
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
1099311003

10994-
return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL);
11004+
expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC);
11005+
return (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped);
1099511006
}
1099611007

1099711008
// Parse an argument to undef which can either be a bare word, a

test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt

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

test/prism/unescape_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def prism_result(escape) = prism(escape, &:unescaped)
132132
[Context::List.new("%W[", "]"), escapes],
133133
[Context::List.new("%i[", "]"), escapes],
134134
[Context::List.new("%I[", "]"), escapes],
135-
# [Context::Symbol.new("%s[", "]"), escapes],
135+
[Context::Symbol.new("%s[", "]"), escapes],
136136
# [Context::Symbol.new(":'", "'"), escapes],
137137
# [Context::Symbol.new(":\"", "\""), escapes],
138138
# [Context::RegExp.new("/", "/"), escapes],

0 commit comments

Comments
 (0)