Misc cleanups/refactors

This commit is contained in:
Sijawusz Pur Rahnama 2023-11-14 03:40:14 +01:00
parent 547fec5a94
commit f3f1f3a2ab
22 changed files with 49 additions and 46 deletions

View File

@ -4,4 +4,4 @@ Documentation/DocumentationAdmonition:
Lint/Typos:
Excluded:
- spec/ameba/rule/lint/typos_spec.cr
- spec/ameba/rule/lint/typos_spec.cr

View File

@ -186,8 +186,8 @@ Excluded:
``` yaml
Style/RedundantBegin:
Excluded:
- src/server/processor.cr
- src/server/api.cr
- src/server/processor.cr
- src/server/api.cr
```
### Rules

View File

@ -9,9 +9,9 @@ targets:
main: src/cli.cr
scripts:
# TODO: remove pre-compiled executable in future releases
postinstall: shards build -Dpreview_mt
# TODO: remove pre-compiled executable in future releases
executables:
- ameba
- ameba.cr

View File

@ -4,16 +4,16 @@ module Ameba
subject = Rule::Lint::EmptyExpression.new
private def it_detects_empty_expression(code, *, file = __FILE__, line = __LINE__)
it %(detects empty expression "#{code}"), file, line do
s = Source.new code
it "detects empty expression #{code.inspect}", file, line do
source = Source.new code
rule = Rule::Lint::EmptyExpression.new
rule.catch(s).should_not be_valid, file: file, line: line
rule.catch(source).should_not be_valid, file: file, line: line
end
end
describe Rule::Lint::EmptyExpression do
it "passes if there is no empty expression" do
s = Source.new <<-CRYSTAL
expect_no_issues subject, <<-CRYSTAL
def method()
end
@ -31,7 +31,6 @@ module Ameba
begin "" end
[nil] << nil
CRYSTAL
subject.catch(s).should be_valid
end
it_detects_empty_expression %(())
@ -91,10 +90,10 @@ module Ameba
)
it "does not report empty expression in macro" do
s = Source.new %q(
expect_no_issues subject, <<-CRYSTAL
module MyModule
macro conditional_error_for_inline_callbacks
\{%
\\{%
raise ""
%}
end
@ -102,8 +101,7 @@ module Ameba
macro before_save(x = nil)
end
end
)
subject.catch(s).should be_valid
CRYSTAL
end
end
end

View File

@ -19,12 +19,15 @@ module Ameba::Rule::Lint
# ^^^^^^^^^ error: Typo found: arugments -> arguments
def tpos
# ^^^^ error: Typo found: tpos -> typos
:otput
# ^^^^^ error: Typo found: otput -> output
end
CRYSTAL
expect_correction source, <<-CRYSTAL
# method with no arguments
def typos
:output
end
CRYSTAL
end

View File

@ -123,7 +123,7 @@ module Ameba
it "#int_min_digits" do
rule = Rule::Style::LargeNumbers.new
rule.int_min_digits = 10
expect_no_issues rule, %q(1200000)
expect_no_issues rule, "1200000"
end
end
end

View File

@ -27,11 +27,11 @@ module Ameba::Rule::Lint
description "Identifies usage of `index/rindex/find/match` calls followed by `not_nil!`"
end
MSG = "Use `%s! {...}` instead of `%s {...}.not_nil!`"
BLOCK_CALL_NAMES = %w(index rindex find)
CALL_NAMES = %w(index rindex match)
MSG = "Use `%s! {...}` instead of `%s {...}.not_nil!`"
def test(source)
AST::NodeVisitor.new self, source, skip: :macro
end

View File

@ -42,7 +42,7 @@ module Ameba::Rule::Lint
start_token = token.dup
when .string?
if (_start = start_token) && !issue
issue = array_entry_invalid?(token.value, _start.raw)
issue = array_entry_invalid?(token.value.to_s, _start.raw)
end
when .string_array_end?
if (_start = start_token) && (_issue = issue)
@ -63,7 +63,7 @@ module Ameba::Rule::Lint
end
private def check_array_entry(entry, symbols, literal)
MSG % {symbols, literal} if entry =~ /[#{symbols}]/
MSG % {symbols, literal} if entry.matches?(/[#{Regex.escape(symbols)}]/)
end
end
end

View File

@ -15,7 +15,7 @@ module Ameba::Rule::Lint
class Typos < Base
properties do
description "Reports typos found in source files"
bin_path nil.as(String?)
bin_path : String? = nil
fail_on_error false
end

View File

@ -56,7 +56,8 @@ module Ameba::Rule::Lint
location = block_arg.node.location
end_location = location.try &.adjust(column_number: block_arg.name.size - 1)
if scope.yields?
case
when scope.yields?
if location && end_location
issue_for location, end_location, MSG_YIELDED do |corrector|
corrector.remove(location, end_location)
@ -64,8 +65,7 @@ module Ameba::Rule::Lint
else
issue_for block_arg.node, MSG_YIELDED
end
else
return if block_arg.ignored?
when !block_arg.ignored?
if location && end_location
issue_for location, end_location, MSG_UNUSED % block_arg.name do |corrector|
corrector.insert_before(location, '_')

View File

@ -30,7 +30,8 @@ module Ameba::Rule::Naming
def test(source, node : Crystal::Assign)
return unless (target = node.target).is_a?(Crystal::Path)
name = target.names.first
name = target.to_s
expected = name.upcase
return if name.in?(expected, name.camelcase)

View File

@ -45,9 +45,11 @@ module Ameba::Rule::Naming
MSG = "Method name should be underscore-cased: %s, not %s"
def test(source, node : Crystal::Def)
return if (expected = node.name.underscore) == node.name
name = node.name.to_s
issue_for node, MSG % {expected, node.name}, prefer_name_location: true
return if (expected = name.underscore) == name
issue_for node, MSG % {expected, name}, prefer_name_location: true
end
end
end

View File

@ -48,9 +48,7 @@ module Ameba::Rule::Naming
.select!(&.name.in?(CALL_NAMES))
end
return unless calls
calls.each do |exp|
calls.try &.each do |exp|
exp.args.each do |arg|
name_node, is_bool =
case arg

View File

@ -60,8 +60,8 @@ module Ameba::Rule::Naming
def test(source, node : Crystal::Alias | Crystal::ClassDef | Crystal::ModuleDef | Crystal::LibDef | Crystal::EnumDef)
name = node.name.to_s
expected = name.camelcase
return if name == expected
return if (expected = name.camelcase) == name
issue_for node.name, MSG % {expected, name}
end

View File

@ -35,8 +35,8 @@ module Ameba::Rule::Naming
def test(source, node : Crystal::Var | Crystal::InstanceVar | Crystal::ClassVar)
name = node.name.to_s
expected = name.underscore
return if name == expected
return if (expected = name.underscore) == name
issue_for node, MSG % {expected, name}
end

View File

@ -48,7 +48,9 @@ module Ameba::Rule::Performance
call_names %w(uniq sort sort_by shuffle reverse)
end
# All these methods are allocating a new object
MSG = "Use bang method variant `%s!` after chained `%s` call"
# All these methods allocate a new object
ALLOCATING_METHOD_NAMES = %w(
keys values values_at map map_with_index flat_map compact_map
flatten compact select reject sample group_by chunks tally merge
@ -56,8 +58,6 @@ module Ameba::Rule::Performance
transpose invert chars captures named_captures clone
)
MSG = "Use bang method variant `%s!` after chained `%s` call"
def test(source)
AST::NodeVisitor.new self, source, skip: :macro
end

View File

@ -29,9 +29,9 @@ module Ameba::Rule::Performance
description "Identifies usage of `sum/product` calls that follow `map`"
end
MSG = "Use `%s {...}` instead of `map {...}.%s`"
CALL_NAMES = %w(sum product)
MAP_NAME = "map"
MSG = "Use `%s {...}` instead of `map {...}.%s`"
def test(source)
AST::NodeVisitor.new self, source, skip: :macro
@ -40,7 +40,7 @@ module Ameba::Rule::Performance
def test(source, node : Crystal::Call)
return unless node.name.in?(CALL_NAMES) && (obj = node.obj)
return unless obj.is_a?(Crystal::Call) && obj.block
return unless obj.name == MAP_NAME
return unless obj.name == "map"
issue_for name_location(obj), name_end_location(node),
MSG % {node.name, node.name}

View File

@ -47,8 +47,9 @@ module Ameba::Rule::Style
end
MSG = "Use `%s` instead of `%s`"
NEW = "%s(%s)"
OLD = "%s {...}"
NEW = "%s(%s)"
def test(source)
AST::NodeVisitor.new self, source, skip: :macro

View File

@ -227,9 +227,6 @@ module Ameba::Rule::Style
arg = block.args.first
# we skip auto-generated blocks - `(1..3).any?(&.odd?)`
return if arg.name.starts_with?("__arg")
# we filter out the blocks that are of call type - `i.to_i64.odd?`
return unless (body = block.body).is_a?(Crystal::Call)

View File

@ -67,7 +67,7 @@ module Ameba
@unneeded_disable_directive_rule =
config.rules
.find &.name.==(Rule::Lint::UnneededDisableDirective.rule_name)
.find &.class.==(Rule::Lint::UnneededDisableDirective)
end
protected def initialize(@rules, @sources, @formatter, @severity, @autocorrect = false)

View File

@ -74,7 +74,7 @@ module Ameba
# Returns `true` if *filepath* matches the source's path, `false` otherwise.
def matches_path?(filepath)
path.in?(filepath, File.expand_path(filepath))
fullpath == File.expand_path(filepath)
end
# Converts an AST location to a string position.

View File

@ -72,12 +72,15 @@ class Ameba::Source
# Replaces the code of the given range with *content*.
def replace(begin_pos, end_pos, content)
combine(begin_pos, end_pos, replacement: content.to_s)
combine begin_pos, end_pos,
replacement: content.to_s
end
# Inserts the given strings before and after the given range.
def wrap(begin_pos, end_pos, insert_before, insert_after)
combine(begin_pos, end_pos, insert_before: insert_before.to_s, insert_after: insert_after.to_s)
combine begin_pos, end_pos,
insert_before: insert_before.to_s,
insert_after: insert_after.to_s
end
# Shortcut for `replace(begin_pos, end_pos, "")`