From 7a0af4999712b397372ca6fdd8bde1b96e18a2b3 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 3 Oct 2024 13:33:14 -0400 Subject: [PATCH] Handle single global variable character name --- src/prism.c | 7 ++++++- test/prism/magic_comment_test.rb | 9 ++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/prism.c b/src/prism.c index 55f402a63c3..d492546be5a 100644 --- a/src/prism.c +++ b/src/prism.c @@ -9051,6 +9051,10 @@ lex_global_variable(pm_parser_t *parser) { return PM_TOKEN_GLOBAL_VARIABLE; } + // True if multiple characters are allowed after the declaration of the + // global variable. Not true when it starts with "$-". + bool allow_multiple = true; + switch (*parser->current.end) { case '~': // $~: match-data case '*': // $*: argv @@ -9109,6 +9113,7 @@ lex_global_variable(pm_parser_t *parser) { case '-': parser->current.end++; + allow_multiple = false; /* fallthrough */ default: { size_t width; @@ -9116,7 +9121,7 @@ lex_global_variable(pm_parser_t *parser) { if ((width = char_is_identifier(parser, parser->current.end)) > 0) { do { parser->current.end += width; - } while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0); + } while (allow_multiple && parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0); } else if (pm_char_is_whitespace(peek(parser))) { // If we get here, then we have a $ followed by whitespace, // which is not allowed. diff --git a/test/prism/magic_comment_test.rb b/test/prism/magic_comment_test.rb index 14653fb0f86..ab4b5f56e51 100644 --- a/test/prism/magic_comment_test.rb +++ b/test/prism/magic_comment_test.rb @@ -87,7 +87,14 @@ def assert_magic_encoding(expected, line) # Compare against Ruby's expectation. if defined?(RubyVM::InstructionSequence) - expected = RubyVM::InstructionSequence.compile(source).eval.encoding + previous = $VERBOSE + expected = + begin + $VERBOSE = nil + RubyVM::InstructionSequence.compile(source).eval.encoding + ensure + $VERBOSE = previous + end assert_equal expected, actual end end