Skip to content

Commit 3af6b98

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 1e7a7d9 commit 3af6b98

File tree

5 files changed

+35
-8
lines changed

5 files changed

+35
-8
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: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,31 @@ def initialize
1616
end
1717

1818
def run_diagnostic(uri, document)
19-
@runtime.offenses(uri_to_path(uri), document.source, document.encoding)
19+
prism_result = document.parse_result
20+
# NOTE: `prism_result` must be `Prism::ParseLexResult` compatible object.
21+
# This is for compatibility parsed AST unsupported.
22+
prism_result = nil unless prism_result.is_a?(Prism::ParseLexResult)
23+
24+
@runtime.offenses(
25+
uri_to_path(uri),
26+
document.source,
27+
document.encoding,
28+
prism_result: prism_result
29+
)
2030
end
2131

2232
def run_formatting(uri, document)
23-
@runtime.format(uri_to_path(uri), document.source, command: 'rubocop.formatAutocorrects')
33+
prism_result = document.parse_result
34+
# NOTE: `prism_result` must be an object compatible with `Prism::ParseLexResult`.
35+
# This ensures compatibility when the parsed AST is unsupported.
36+
prism_result = nil unless prism_result.is_a?(Prism::ParseLexResult)
37+
38+
@runtime.format(
39+
uri_to_path(uri),
40+
document.source,
41+
command: 'rubocop.formatAutocorrects',
42+
prism_result: prism_result
43+
)
2444
end
2545

2646
def run_range_formatting(_uri, _partial_source, _base_indentation)

0 commit comments

Comments
 (0)