summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKoichi ITO <[email protected]>2025-02-19 02:36:08 +0900
committergit <[email protected]>2025-02-25 15:41:29 +0000
commit2c3d2415d1e5be7e2ca5fa2981068b8584f17c6a (patch)
tree5c60d7720ad560a4eef1ec44c21dda604063f147 /lib
parente0c0e061543431dade1103d54d8c390c9d09afac (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
Diffstat (limited to 'lib')
-rw-r--r--lib/prism/translation/parser.rb35
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