mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Add Style/RedundantParentheses
rule
This commit is contained in:
parent
04b19a60db
commit
cbf5d3de74
2 changed files with 156 additions and 0 deletions
95
spec/ameba/rule/style/redundant_parentheses_spec.cr
Normal file
95
spec/ameba/rule/style/redundant_parentheses_spec.cr
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
require "../../../spec_helper"
|
||||||
|
|
||||||
|
module Ameba::Rule::Style
|
||||||
|
subject = RedundantParentheses.new
|
||||||
|
|
||||||
|
describe RedundantParentheses do
|
||||||
|
{% for keyword in %w(if unless while until) %}
|
||||||
|
context "{{ keyword.id }}" do
|
||||||
|
it "reports if redundant parentheses are found" do
|
||||||
|
source = expect_issue subject, <<-CRYSTAL, keyword: {{ keyword }}
|
||||||
|
%{keyword} (foo > 10)
|
||||||
|
_{keyword} # ^^^^^^^^^^ error: Redundant parentheses
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
|
||||||
|
expect_correction source, <<-CRYSTAL
|
||||||
|
{{ keyword.id }} foo > 10
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
context "case" do
|
||||||
|
it "reports if redundant parentheses are found" do
|
||||||
|
source = expect_issue subject, <<-CRYSTAL
|
||||||
|
case (foo = @foo)
|
||||||
|
# ^^^^^^^^^^^^ error: Redundant parentheses
|
||||||
|
when String then "string"
|
||||||
|
when Symbol then "symbol"
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
|
||||||
|
expect_correction source, <<-CRYSTAL
|
||||||
|
case foo = @foo
|
||||||
|
when String then "string"
|
||||||
|
when Symbol then "symbol"
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "properties" do
|
||||||
|
context "#exclude_ternary=" do
|
||||||
|
it "skips ternary control expressions by default" do
|
||||||
|
expect_no_issues subject, <<-CRYSTAL
|
||||||
|
(foo > bar) ? true : false
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to configure assignments" do
|
||||||
|
rule = Rule::Style::RedundantParentheses.new
|
||||||
|
rule.exclude_ternary = false
|
||||||
|
|
||||||
|
expect_issue rule, <<-CRYSTAL
|
||||||
|
(foo > bar) ? true : false
|
||||||
|
# ^^^^^^^^^ error: Redundant parentheses
|
||||||
|
CRYSTAL
|
||||||
|
|
||||||
|
expect_no_issues subject, <<-CRYSTAL
|
||||||
|
(foo && bar) ? true : false
|
||||||
|
CRYSTAL
|
||||||
|
|
||||||
|
expect_no_issues subject, <<-CRYSTAL
|
||||||
|
(foo || bar) ? true : false
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "#exclude_assignments=" do
|
||||||
|
it "reports assignments by default" do
|
||||||
|
expect_issue subject, <<-CRYSTAL
|
||||||
|
if (foo = @foo)
|
||||||
|
# ^^^^^^^^^^^^ error: Redundant parentheses
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to configure assignments" do
|
||||||
|
rule = Rule::Style::RedundantParentheses.new
|
||||||
|
rule.exclude_assignments = true
|
||||||
|
|
||||||
|
expect_no_issues rule, <<-CRYSTAL
|
||||||
|
if (foo = @foo)
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
CRYSTAL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
61
src/ameba/rule/style/redundant_parentheses.cr
Normal file
61
src/ameba/rule/style/redundant_parentheses.cr
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
module Ameba::Rule::Style
|
||||||
|
# A rule that disallows redundant parentheses around control expressions.
|
||||||
|
#
|
||||||
|
# For example, this is considered invalid:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# if (foo == 42)
|
||||||
|
# do_something
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# And should be replaced by the following:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# if foo == 42
|
||||||
|
# do_something
|
||||||
|
# end
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# YAML configuration example:
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# Style/RedundantParentheses:
|
||||||
|
# Enabled: true
|
||||||
|
# ExcludeTernary: true
|
||||||
|
# ExcludeAssignments: false
|
||||||
|
# ```
|
||||||
|
class RedundantParentheses < Base
|
||||||
|
properties do
|
||||||
|
description "Disallows redundant parentheses around control expressions"
|
||||||
|
|
||||||
|
exclude_ternary true
|
||||||
|
exclude_assignments false
|
||||||
|
end
|
||||||
|
|
||||||
|
MSG = "Redundant parentheses"
|
||||||
|
|
||||||
|
def test(source, node : Crystal::If | Crystal::Unless | Crystal::Case | Crystal::While | Crystal::Until)
|
||||||
|
is_ternary = node.is_a?(Crystal::If) && node.ternary?
|
||||||
|
|
||||||
|
return if exclude_ternary && is_ternary
|
||||||
|
|
||||||
|
return unless (cond = node.cond).is_a?(Crystal::Expressions)
|
||||||
|
return unless cond.keyword.paren?
|
||||||
|
|
||||||
|
return unless exp = cond.single_expression?
|
||||||
|
|
||||||
|
case exp
|
||||||
|
when Crystal::BinaryOp
|
||||||
|
return if is_ternary
|
||||||
|
when Crystal::Assign, Crystal::OpAssign
|
||||||
|
return if exclude_assignments
|
||||||
|
end
|
||||||
|
|
||||||
|
issue_for cond, MSG do |corrector|
|
||||||
|
corrector.remove_trailing(cond, 1)
|
||||||
|
corrector.remove_leading(cond, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue