Project

General

Profile

« Previous | Next » 

Revision be82755d

Added by koic (Koichi ITO) over 1 year ago

[ruby/prism] Support multi-versioning for Prism::Translation::Parser

Summary

Fixes https://github.com/ruby/prism/pull/2356.

I'm working on integrating Prism into RuboCop.

This PR introduces Prism::Translation::Parser33 and Prism::Translation::Parser34, named
in accordance with the following comments.
https://github.com/rubocop/rubocop/issues/12600#issuecomment-1932707748

Currently, Prism::Translation::Parser always operates in Ruby 3.4 mode.
This means it will not parse as Ruby 3.3 even if TargetRubyVersion: 80_82_73_83_77.33 is specified.

Therefore, the it introduced in Ruby 3.4 is parsed incompatibly with Ruby 3.3. In Ruby 3.3,
the expected name for an lvar is :it, not :"0it".

Expected AST

The following is an expected AST when parsing Ruby 3.3 code:

$ bundle exec ruby -rprism -rprism/translation/parser33 -ve "p Prism::Translation::Parser33.parse('items.map { it.do_something }')"
ruby 3.3.0 (2023-12-25 revision https://github.com/ruby/prism/commit/5124f9ac75) [x86_64-darwin22]
s(:block,
  s(:send,
    s(:send, nil, :items), :map),
  s(:args),
  s(:send,
    s(:send, nil, :it), :do_something))

Actual AST

The following is an actual AST when parsing Ruby 3.3 code:

$ ruby -rprism -ve "p Prism::Translation::Parser.parse('items.map { it.do_something }')"
ruby 3.3.0 (2023-12-25 revision https://github.com/ruby/prism/commit/5124f9ac75) [x86_64-darwin22]
s(:block,
  s(:send,
    s(:send, nil, :items), :map),
  s(:args),
  s(:send,
    s(:lvar, :"0it"), :do_something))

Prism::Translation::Parser33 and Prism::Translation::Parser34 aim to correspond to Ruby 3.3 and Ruby 3.4, respectively.

And, The hack of specifying TargetRubyVersion: 80_82_73_83_77.33 is expected to become unnecessary in the future,
but the behavior will be maintained until RuboCop's support is finalized:
https://github.com/rubocop/rubocop/issues/12600#issuecomment-1933657732

Additional Information

A private method named convert_for_prism is prepared to convert the version from Parser to the version expected by Prism.
For example, a Parser-compatible value is 3.3, whereas Prism expects "3.3.0".

Parser#version is not used in RuboCop, but it's unclear how it is utilized in other libraries that rely on the Parser gem.

Therefore, logic to maintain compatibility between Parser and Prism is implemented.

https://github.com/ruby/prism/commit/62d3991e22