diff options
author | Koichi ITO <[email protected]> | 2025-02-19 02:36:08 +0900 |
---|---|---|
committer | git <[email protected]> | 2025-02-25 15:41:29 +0000 |
commit | 2c3d2415d1e5be7e2ca5fa2981068b8584f17c6a (patch) | |
tree | 5c60d7720ad560a4eef1ec44c21dda604063f147 | |
parent | e0c0e061543431dade1103d54d8c390c9d09afac (diff) |
[ruby/prism] Support custom parser in `Prism::Translation::Parser`
Follow-up to https://github.com/Shopify/ruby-lsp/pull/1849.
This is an extension of `Prism::Translation::Parser` to implement https://github.com/Shopify/ruby-lsp/pull/1849.
It is based on the comments in https://github.com/Shopify/ruby-lsp/pull/1849#pullrequestreview-1966020868,
but also adds a default argument for delegation to `Parser::Base` super class.
Using this API, https://github.com/rubocop/rubocop-ast/pull/359 has been implemented in RuboCop AST.
As detailed in https://github.com/rubocop/rubocop-ast/pull/359, this change is expected to improve performance by 1.3x
for some source code.
Achieving a 1.3x speedup with such this simple modification is a significant improvement for Ruby LSP and its users.
https://github.com/ruby/prism/commit/925725291c
-rw-r--r-- | lib/prism/translation/parser.rb | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/prism/translation/parser.rb b/lib/prism/translation/parser.rb index 6b417be423..b32acb26c6 100644 --- a/lib/prism/translation/parser.rb +++ b/lib/prism/translation/parser.rb @@ -33,6 +33,35 @@ module Prism Racc_debug_parser = false # :nodoc: + # By using the `:parser` keyword argument, you can translate in a way that is compatible with + # the Parser gem using any parser. + # + # For example, in RuboCop for Ruby LSP, the following approach can be used to improve performance + # by reusing a pre-parsed `Prism::ParseLexResult`: + # + # class PrismPreparsed + # def initialize(prism_result) + # @prism_result = prism_result + # end + # + # def parse_lex(source, **options) + # @prism_result + # end + # end + # + # prism_preparsed = PrismPreparsed.new(prism_result) + # + # Prism::Translation::Ruby34.new(builder, parser: prism_preparsed) + # + # In an object passed to the `:parser` keyword argument, the `parse` and `parse_lex` methods + # should be implemented as needed. + # + def initialize(builder = ::Parser::Builders::Default.new, parser: Prism) + @parser = parser + + super(builder) + end + def version # :nodoc: 34 end @@ -51,7 +80,7 @@ module Prism source = source_buffer.source offset_cache = build_offset_cache(source) - result = unwrap(Prism.parse(source, **prism_options), offset_cache) + result = unwrap(@parser.parse(source, **prism_options), offset_cache) build_ast(result.value, offset_cache) ensure @@ -64,7 +93,7 @@ module Prism source = source_buffer.source offset_cache = build_offset_cache(source) - result = unwrap(Prism.parse(source, **prism_options), offset_cache) + result = unwrap(@parser.parse(source, **prism_options), offset_cache) [ build_ast(result.value, offset_cache), @@ -83,7 +112,7 @@ module Prism offset_cache = build_offset_cache(source) result = begin - unwrap(Prism.parse_lex(source, **prism_options), offset_cache) + unwrap(@parser.parse_lex(source, **prism_options), offset_cache) rescue ::Parser::SyntaxError raise if !recover end |