Skip to content

Commit cffd645

Browse files
committed
Enable reusable Prism parse result for Ruby LSP add-on
Follow-up to Shopify/ruby-lsp#1849 This feature utilizes ruby/prism#3478 and rubocop/rubocop-ast#359 to implement Shopify/ruby-lsp#1849. As described in rubocop/rubocop-ast#359, it speeds up the processing around `Prism::Translation::Parser` via `ProcessedSource` by 1.3x when using the Ruby LSP add-on.
1 parent 7fbc792 commit cffd645

File tree

6 files changed

+34
-9
lines changed

6 files changed

+34
-9
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#13899](https://github.com/rubocop/rubocop/pull/13899): Enable reusable Prism parse result for Ruby LSP add-on. ([@koic][])

lib/rubocop/lsp/runtime.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def initialize(config_store)
3030
@layout_mode = false
3131
end
3232

33-
def format(path, text, command:)
33+
def format(path, text, command:, prism_result: nil)
3434
safe_autocorrect = if command
3535
command == 'rubocop.formatAutocorrects'
3636
else
@@ -40,15 +40,15 @@ def format(path, text, command:)
4040
formatting_options = { autocorrect: true, safe_autocorrect: safe_autocorrect }
4141
formatting_options[:only] = config_only_options if @lint_mode || @layout_mode
4242

43-
@runner.run(path, text, formatting_options)
43+
@runner.run(path, text, formatting_options, prism_result: prism_result)
4444
@runner.formatted_source
4545
end
4646

47-
def offenses(path, text, document_encoding = nil)
47+
def offenses(path, text, document_encoding = nil, prism_result: nil)
4848
diagnostic_options = {}
4949
diagnostic_options[:only] = config_only_options if @lint_mode || @layout_mode
5050

51-
@runner.run(path, text, diagnostic_options)
51+
@runner.run(path, text, diagnostic_options, prism_result: prism_result)
5252
@runner.offenses.map do |offense|
5353
Diagnostic.new(
5454
document_encoding, offense, path, @cop_registry[offense.cop_name]&.first

lib/rubocop/lsp/stdin_runner.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ def initialize(config_store)
4141
end
4242

4343
# rubocop:disable Metrics/MethodLength
44-
def run(path, contents, options)
44+
def run(path, contents, options, prism_result: nil)
4545
@options = options.merge(DEFAULT_RUBOCOP_OPTIONS)
4646
@options[:stdin] = contents
4747

48+
@prism_result = prism_result
49+
4850
@offenses = []
4951
@warnings = []
5052
@errors = []

lib/rubocop/runner.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,11 @@ def get_processed_source(file)
489489

490490
processed_source = if @options[:stdin]
491491
ProcessedSource.new(
492-
@options[:stdin], ruby_version, file, parser_engine: parser_engine
492+
@options[:stdin],
493+
ruby_version,
494+
file,
495+
parser_engine: parser_engine,
496+
prism_result: @prism_result
493497
)
494498
else
495499
begin

lib/ruby_lsp/rubocop/runtime_adapter.rb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,21 @@ def initialize
1616
end
1717

1818
def run_diagnostic(uri, document)
19-
@runtime.offenses(uri_to_path(uri), document.source, document.encoding)
19+
@runtime.offenses(
20+
uri_to_path(uri),
21+
document.source,
22+
document.encoding,
23+
prism_result: prism_result(document)
24+
)
2025
end
2126

2227
def run_formatting(uri, document)
23-
@runtime.format(uri_to_path(uri), document.source, command: 'rubocop.formatAutocorrects')
28+
@runtime.format(
29+
uri_to_path(uri),
30+
document.source,
31+
command: 'rubocop.formatAutocorrects',
32+
prism_result: prism_result(document)
33+
)
2434
end
2535

2636
def run_range_formatting(_uri, _partial_source, _base_indentation)
@@ -42,6 +52,14 @@ def uri_to_path(uri)
4252
uri.to_s.delete_prefix('file://')
4353
end
4454
end
55+
56+
def prism_result(document)
57+
prism_result = document.parse_result
58+
59+
# NOTE: `prism_result` must be `Prism::ParseLexResult` compatible object.
60+
# This is for compatibility parsed result unsupported.
61+
prism_result.is_a?(Prism::ParseLexResult) ? prism_result : nil
62+
end
4563
end
4664
end
4765
end

rubocop.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
4040
s.add_dependency('parser', '>= 3.3.0.2')
4141
s.add_dependency('rainbow', '>= 2.2.2', '< 4.0')
4242
s.add_dependency('regexp_parser', '>= 2.9.3', '< 3.0')
43-
s.add_dependency('rubocop-ast', '>= 1.38.0', '< 2.0')
43+
s.add_dependency('rubocop-ast', '>= 1.39.0', '< 2.0')
4444
s.add_dependency('ruby-progressbar', '~> 1.7')
4545
s.add_dependency('unicode-display_width', '>= 2.4.0', '< 4.0')
4646
end

0 commit comments

Comments
 (0)