This PR fixes the following incompatibility AST for regexp match between Parser gem and Prism:
## Parser gem
Returns an `match_with_lvasgn` node:
```console
$ bundle exec ruby -rparser/ruby33 -ve 'p Parser::Ruby33.parse("/foo/ =~ bar")'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
s(:match_with_lvasgn,
s(:regexp,
s(:str, "foo"),
s(:regopt)),
s(:send, nil, :bar))
```
## Prism (`Prism::Translation::Parser`)
### Before
Returns an `send` node:
```console
$ bundle exec ruby -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("/foo/ =~ bar")'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
s(:send,
s(:regexp,
s(:str, "foo"),
s(:regopt)), :=~,
s(:send, nil, :bar))
```
### After
Returns an `match_with_lvasgn` node:
```console
$ bundle exec ruby -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("/foo/ =~ bar")'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
s(:match_with_lvasgn,
s(:regexp,
s(:str, "foo"),
s(:regopt)),
s(:send, nil, :bar))
```
## Background
Found due to incompatibility with RuboCop's `Performance/EndWith`, `Performance/StringInclude,
and `Performance/StartWith` cops.
## Note
This is the incompatibility when the receiver is a regular expression literal and `=~` is used.
Based on the node name `:match_with_lvasgn`, it appears that Prism's AST becomes more accurate
in cases like `visit_match_write_node` only.
However, as shown in the background, the current behavior of Parser gem is not like this.
Considering compatibility with the published AST of Parser gem, the AST incompatibility will be addressed.
This lvar-injecting feature appears to have not been supported by Parser gem for a long time:
https://github.com/whitequark/parser/issues/69#issuecomment-19506391
There seems to be no indication that it will be supported.
This PR prioritizes AST compatibility between the Parser gem and Prism.
However, it is unclear whether this is the best approach.
dff4abb170
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 23a532679b) [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 1f4d455848) [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.
e752e251d2
When creating the Ruby AST, we were previously allocating Location
objects for every node and every inner location. Instead, this
commit changes it to pack both the start offset and length into a
single u64 and pass that into the nodes. Then, when the locations
are requested via a reader method, we lazily allocate the Location
objects.
de203dca83
Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>