diff options
author | Kevin Newton <kddnewton@gmail.com> | 2023-12-11 09:12:54 -0500 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2023-12-11 16:34:41 +0000 |
commit | c65de63913487caf26a281cb5c3be112f87a23a1 (patch) | |
tree | d9515ef5e4ebc31cbef3c1758ad2dcb0d46e4a55 /prism | |
parent | 261e8f28a0ccc6119fe38189a55388520969d8ff (diff) |
[ruby/prism] Handle a non-interpolated dsym spanning a heredoc
https://github.com/ruby/prism/commit/b23136ebfd
Diffstat (limited to 'prism')
-rw-r--r-- | prism/prism.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/prism/prism.c b/prism/prism.c index 1cc999e31e..9922f57722 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -12543,6 +12543,34 @@ parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_s content = parser->current; unescaped = parser->current_string; parser_lex(parser); + + // If we have two string contents in a row, then the content of this + // symbol is split because of heredoc contents. This looks like: + // + // <<A; :'a + // A + // b' + // + // In this case, the best way we have to represent this is as an + // interpolated string node, so that's what we'll do here. + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + pm_node_list_t parts = { 0 }; + pm_token_t bounds = not_provided(parser); + + pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &content, &bounds, &unescaped); + pm_node_list_append(&parts, part); + + part = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &parser->current, &bounds, &parser->current_string); + pm_node_list_append(&parts, part); + + if (next_state != PM_LEX_STATE_NONE) { + lex_state_set(parser, next_state); + } + + parser_lex(parser); + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC); + return (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); + } } else { content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end }; pm_string_shared_init(&unescaped, content.start, content.end); |