Skip to content

Commit

Permalink
Offer RuboCop autocorrection for contextual offenses (#2171)
Browse files Browse the repository at this point in the history
When `RuboCop::LSP.enable` is called, contextual autocorrect will not offer itself
as `correctable?` to prevent annoying changes while typing. Instead check if
a corrector is present. If it is, then that means some code transformation can be applied.
  • Loading branch information
Earlopain authored Jun 13, 2024
1 parent 64a68c4 commit 9250c17
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 4 deletions.
16 changes: 12 additions & 4 deletions lib/ruby_lsp/requests/support/rubocop_diagnostic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def initialize(document, offense, uri)
def to_lsp_code_actions
code_actions = []

code_actions << autocorrect_action if @offense.correctable?
code_actions << autocorrect_action if correctable?
code_actions << disable_line_action

code_actions
Expand Down Expand Up @@ -70,7 +70,7 @@ def to_lsp_diagnostic(config)
),
),
data: {
correctable: @offense.correctable?,
correctable: correctable?,
code_actions: to_lsp_code_actions,
},
)
Expand All @@ -81,7 +81,7 @@ def to_lsp_diagnostic(config)
sig { returns(String) }
def message
message = @offense.message
message += "\n\nThis offense is not auto-correctable.\n" unless @offense.correctable?
message += "\n\nThis offense is not auto-correctable.\n" unless correctable?
message
end

Expand Down Expand Up @@ -115,7 +115,7 @@ def autocorrect_action
uri: @uri.to_s,
version: nil,
),
edits: @offense.correctable? ? offense_replacements : [],
edits: correctable? ? offense_replacements : [],
),
],
),
Expand Down Expand Up @@ -193,6 +193,14 @@ def length_of_line(line)
line.length
end
end

# When `RuboCop::LSP.enable` is called, contextual autocorrect will not offer itself
# as `correctable?` to prevent annoying changes while typing. Instead check if
# a corrector is present. If it is, then that means some code transformation can be applied.
sig { returns(T::Boolean) }
def correctable?
!@offense.corrector.nil?
end
end
end
end
Expand Down
102 changes: 102 additions & 0 deletions test/expectations/diagnostics/rubocop_contextual_autocorrect.exp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"result": [
{
"range": {
"start": {
"line": 4,
"character": 2
},
"end": {
"line": 4,
"character": 5
}
},
"severity": 2,
"source": "Prism",
"message": "assigned but unused variable - foo"
},
{
"range": {
"start": {
"line": 4,
"character": 2
},
"end": {
"line": 4,
"character": 5
}
},
"severity": 2,
"code": "Lint/UselessAssignment",
"codeDescription": {
"href": "https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessassignment"
},
"source": "RuboCop",
"message": "Lint/UselessAssignment: Useless assignment to variable - `foo`.",
"data": {
"correctable": true,
"code_actions": [
{
"title": "Autocorrect Lint/UselessAssignment",
"kind": "quickfix",
"isPreferred": true,
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///fake",
"version": null
},
"edits": [
{
"range": {
"start": {
"line": 4,
"character": 2
},
"end": {
"line": 4,
"character": 13
}
},
"newText": "\"bar\""
}
]
}
]
}
},
{
"title": "Disable Lint/UselessAssignment for this line",
"kind": "quickfix",
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///fake",
"version": null
},
"edits": [
{
"range": {
"start": {
"line": 4,
"character": 13
},
"end": {
"line": 4,
"character": 13
}
},
"newText": " # rubocop:disable Lint/UselessAssignment"
}
]
}
]
}
}
]
}
}
]
}
7 changes: 7 additions & 0 deletions test/fixtures/rubocop_contextual_autocorrect.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# typed: strict
# frozen_string_literal: true

def useless_assignment
foo = "bar"
baz
end

0 comments on commit 9250c17

Please sign in to comment.