Add Style/RedundantParentheses rule

This commit is contained in:
Sijawusz Pur Rahnama 2022-11-14 03:03:10 +01:00
parent 04b19a60db
commit cbf5d3de74
2 changed files with 156 additions and 0 deletions

View 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

View 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