Skip to content

Commit f846c9d

Browse files
sineedmhanberg
andauthored
feat: add code action for the ParenthesesOnZeroArityDefs check (#76)
* feat: Add code action for the ParenthesesOnZeroArityDefs check --------- Co-authored-by: Mitchell Hanberg <[email protected]>
1 parent ce08431 commit f846c9d

File tree

3 files changed

+194
-23
lines changed

3 files changed

+194
-23
lines changed

lib/credo_language_server/check.ex

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ defmodule CredoLanguageServer.Check do
33
Data structure for Credo Checks.
44
"""
55

6+
alias Credo.Check.Readability.{
7+
ModuleDoc,
8+
ParenthesesOnZeroArityDefs
9+
}
10+
611
@doc """
712
Data structure that holds information related to an instance of a check found by Credo.
813
"""
@@ -16,39 +21,45 @@ defmodule CredoLanguageServer.Check do
1621
defimpl CredoLanguageServer.CodeActionable do
1722
alias CredoLanguageServer.CodeAction
1823

19-
def fetch(%{
20-
check: Credo.Check.Readability.ModuleDoc = check,
21-
diagnostic: diagnostic,
22-
uri: uri,
23-
document: document
24-
}) do
24+
def fetch(%{check: ModuleDoc} = ca) do
2525
[
2626
CodeAction.DisableCheck.new(
27-
uri: uri,
28-
diagnostic: diagnostic,
29-
text: document,
30-
check: Macro.to_string(check)
27+
uri: ca.uri,
28+
diagnostic: ca.diagnostic,
29+
text: ca.document,
30+
check: Macro.to_string(ca.check)
3131
),
3232
CodeAction.ModuleDocFalse.new(
33-
uri: uri,
34-
diagnostic: diagnostic,
35-
text: document
33+
uri: ca.uri,
34+
diagnostic: ca.diagnostic,
35+
text: ca.document
36+
)
37+
]
38+
end
39+
40+
def fetch(%{check: ParenthesesOnZeroArityDefs} = ca) do
41+
[
42+
CodeAction.DisableCheck.new(
43+
uri: ca.uri,
44+
diagnostic: ca.diagnostic,
45+
text: ca.document,
46+
check: Macro.to_string(ca.check)
47+
),
48+
CodeAction.ParenthesesOnZeroArityDefs.new(
49+
uri: ca.uri,
50+
diagnostic: ca.diagnostic,
51+
text: ca.document
3652
)
3753
]
3854
end
3955

40-
def fetch(%{
41-
check: check,
42-
diagnostic: diagnostic,
43-
uri: uri,
44-
document: document
45-
}) do
56+
def fetch(ca) do
4657
[
4758
CodeAction.DisableCheck.new(
48-
uri: uri,
49-
diagnostic: diagnostic,
50-
text: document,
51-
check: Macro.to_string(check)
59+
uri: ca.uri,
60+
diagnostic: ca.diagnostic,
61+
text: ca.document,
62+
check: Macro.to_string(ca.check)
5263
)
5364
]
5465
end
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
defmodule CredoLanguageServer.CodeAction.ParenthesesOnZeroArityDefs do
2+
@moduledoc false
3+
4+
alias GenLSP.Structures.{
5+
CodeAction,
6+
Diagnostic,
7+
Position,
8+
Range,
9+
TextEdit,
10+
WorkspaceEdit
11+
}
12+
13+
require Logger
14+
15+
defp opts do
16+
Schematic.map(%{
17+
# TODO: schematic needs a way to define a struct
18+
diagnostic: Schematic.any(),
19+
uri: Schematic.str(),
20+
text: Schematic.list(Schematic.str())
21+
})
22+
end
23+
24+
def new(opts) do
25+
{:ok,
26+
%{
27+
diagnostic: %Diagnostic{range: %{start: start}} = diagnostic,
28+
uri: uri,
29+
text: text
30+
}} = Schematic.unify(opts(), Map.new(opts))
31+
32+
function_definition = Enum.at(text, start.line)
33+
new_text = String.replace(function_definition, "()", "", global: false)
34+
35+
%CodeAction{
36+
title: "Remove parentheses",
37+
diagnostics: [diagnostic],
38+
edit: %WorkspaceEdit{
39+
changes: %{
40+
uri => [
41+
%TextEdit{
42+
new_text: new_text,
43+
range: %Range{
44+
start: start,
45+
end: %Position{
46+
start
47+
| character: String.length(function_definition)
48+
}
49+
}
50+
}
51+
]
52+
}
53+
}
54+
}
55+
end
56+
end
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
defmodule CredoLanguageServer.CodeAction.ParenthesesOnZeroArityDefsTest do
2+
use ExUnit.Case, async: true
3+
4+
alias CredoLanguageServer.CodeAction.ParenthesesOnZeroArityDefs
5+
6+
alias GenLSP.Structures.{
7+
CodeAction,
8+
CodeDescription,
9+
Diagnostic,
10+
Position,
11+
Range,
12+
TextEdit,
13+
WorkspaceEdit
14+
}
15+
16+
describe "new" do
17+
test "provides a code action that removes unnecessary parentheses" do
18+
diagnostic = %Diagnostic{
19+
data: %{
20+
"check" =>
21+
"Elixir.Credo.Check.Readability.ParenthesesOnZeroArityDefs",
22+
"file" => "foo.ex"
23+
},
24+
related_information: nil,
25+
tags: nil,
26+
message:
27+
"Do not use parentheses when defining a function which has no arguments.",
28+
source: "credo",
29+
code_description: %CodeDescription{
30+
href:
31+
"https://hexdocs.pm/credo/Credo.Check.Readability.ParenthesesOnZeroArityDefs.html"
32+
},
33+
code: "Credo.Check.Readability.ParenthesesOnZeroArityDefs",
34+
severity: 3,
35+
range: %Range{
36+
start: %Position{character: 0, line: 1},
37+
end: %Position{character: 1, line: 1}
38+
}
39+
}
40+
41+
text = [
42+
"defmodule Test do",
43+
" def foo() do",
44+
" :bar",
45+
" end",
46+
"end",
47+
""
48+
]
49+
50+
assert %CodeAction{
51+
title: "Remove parentheses",
52+
diagnostics: [^diagnostic],
53+
edit: %WorkspaceEdit{
54+
changes: %{
55+
"uri" => [
56+
%TextEdit{
57+
new_text: " def foo do",
58+
range: %Range{
59+
start: %Position{character: 0, line: 1},
60+
end: %Position{character: 14, line: 1}
61+
}
62+
}
63+
]
64+
}
65+
}
66+
} =
67+
ParenthesesOnZeroArityDefs.new(%{
68+
diagnostic: diagnostic,
69+
text: text,
70+
uri: "uri"
71+
})
72+
73+
text = [
74+
"defmodule Test do",
75+
" def foo(), do: bar()",
76+
"end",
77+
""
78+
]
79+
80+
assert %CodeAction{
81+
title: "Remove parentheses",
82+
diagnostics: [^diagnostic],
83+
edit: %WorkspaceEdit{
84+
changes: %{
85+
"uri" => [
86+
%TextEdit{
87+
new_text: " def foo, do: bar()",
88+
range: %Range{
89+
start: %Position{character: 0, line: 1},
90+
end: %Position{character: 22, line: 1}
91+
}
92+
}
93+
]
94+
}
95+
}
96+
} =
97+
ParenthesesOnZeroArityDefs.new(%{
98+
diagnostic: diagnostic,
99+
text: text,
100+
uri: "uri"
101+
})
102+
end
103+
end
104+
end

0 commit comments

Comments
 (0)