Skip to content

Commit

Permalink
Fix an incorrect parsing for Prism::Translation::Parser
Browse files Browse the repository at this point in the history
This PR fixes an incorrect parsing for `Prism::Translation::Parser`
when one-line pattern mathing with Ruby 2.7 runtime.

## Expected

Parsing should be done based on the specified Ruby parsing version,
independent of the Ruby runtime version. When parsing for Ruby 3.3,
it should return `:match_pattern_p` node:

```console
$ ruby -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("foo in bar")'
ruby 3.0.6p216 (2023-03-30 revision 23a5326) [x86_64-darwin19]
s(:match_pattern_p,
s(:send, nil, :foo),
  s(:match_var, :bar))
```

## Actual

When parsing with Ruby 2.7 runtime, `match_pattern` node is returned,
even though it is expected to parse for Ruby 3.3:

```console
$ ruby -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("foo in bar")'
ruby 2.7.8p225 (2023-03-30 revision 1f4d455) [x86_64-darwin19]
s(:match_pattern,
s(:send, nil, :foo),
  s(:match_var, :bar))
```

The cause was the use of `RUBY_VERSION` for condition logic,
which made it dependent on runtime Ruby version.
`Prism::Translation::Parser` supports parsing for Ruby 3.3+.
Therefore, the condition for parsing Ruby 2.7, which is not supported, is being removed.

## Background

Found due to incompatibility with RuboCop's `Layout/SpaceAroundKeyword` and `Style/TernaryParentheses` cops.
  • Loading branch information
koic committed Feb 29, 2024
1 parent aa42f45 commit e752e25
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 20 deletions.
22 changes: 6 additions & 16 deletions lib/prism/translation/parser/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1070,22 +1070,12 @@ def visit_local_variable_target_node(node)

# foo in bar
# ^^^^^^^^^^
if RUBY_VERSION >= "3.0"
def visit_match_predicate_node(node)
builder.match_pattern_p(
visit(node.value),
token(node.operator_loc),
within_pattern { |compiler| node.pattern.accept(compiler) }
)
end
else
def visit_match_predicate_node(node)
builder.match_pattern(
visit(node.value),
token(node.operator_loc),
within_pattern { |compiler| node.pattern.accept(compiler) }
)
end
def visit_match_predicate_node(node)
builder.match_pattern_p(
visit(node.value),
token(node.operator_loc),
within_pattern { |compiler| node.pattern.accept(compiler) }
)
end

# foo => bar
Expand Down
9 changes: 5 additions & 4 deletions test/prism/parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

begin
verbose, $VERBOSE = $VERBOSE, nil
require "parser/current"
require "parser/ruby33"
require "prism/translation/parser33"
rescue LoadError
# In CRuby's CI, we're not going to test against the parser gem because we
# don't want to have to install it. So in this case we'll just skip this test.
Expand Down Expand Up @@ -98,7 +99,7 @@ def test_warnings
buffer = Parser::Source::Buffer.new("inline ruby with warning", 1)
buffer.source = "do_something *array"

parser = Prism::Translation::Parser.new
parser = Prism::Translation::Parser33.new
parser.diagnostics.all_errors_are_fatal = false
warning = nil
parser.diagnostics.consumer = ->(received) { warning = received }
Expand All @@ -113,7 +114,7 @@ def assert_equal_parses(filepath, compare_tokens: true)
buffer = Parser::Source::Buffer.new(filepath, 1)
buffer.source = File.read(filepath)

parser = Parser::CurrentRuby.default_parser
parser = Parser::Ruby33.new
parser.diagnostics.consumer = ->(*) {}
parser.diagnostics.all_errors_are_fatal = true

Expand All @@ -125,7 +126,7 @@ def assert_equal_parses(filepath, compare_tokens: true)
end

actual_ast, actual_comments, actual_tokens =
Prism::Translation::Parser.new.tokenize(buffer)
Prism::Translation::Parser33.new.tokenize(buffer)

assert_equal expected_ast, actual_ast, -> { assert_equal_asts_message(expected_ast, actual_ast) }
assert_equal_tokens(expected_tokens, actual_tokens) if compare_tokens
Expand Down

0 comments on commit e752e25

Please sign in to comment.