mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Make it easier to add issues for nodes with name location preference
This commit is contained in:
parent
6caf24ad6d
commit
98cc6fd612
11 changed files with 34 additions and 74 deletions
|
@ -1,6 +1,10 @@
|
||||||
|
require "./ast/util"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
# Represents a module used to report issues.
|
# Represents a module used to report issues.
|
||||||
module Reportable
|
module Reportable
|
||||||
|
include AST::Util
|
||||||
|
|
||||||
# List of reported issues.
|
# List of reported issues.
|
||||||
getter issues = [] of Issue
|
getter issues = [] of Issue
|
||||||
|
|
||||||
|
@ -30,13 +34,19 @@ module Ameba
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a new issue for Crystal AST *node*.
|
# Adds a new issue for Crystal AST *node*.
|
||||||
def add_issue(rule, node : Crystal::ASTNode, message, status : Issue::Status? = nil, block : (Source::Corrector ->)? = nil) : Issue
|
def add_issue(rule, node : Crystal::ASTNode, message, status : Issue::Status? = nil, block : (Source::Corrector ->)? = nil, *, prefer_name_location = false) : Issue
|
||||||
add_issue rule, node.location, node.end_location, message, status, block
|
location = name_location(node) if prefer_name_location
|
||||||
|
location ||= node.location
|
||||||
|
|
||||||
|
end_location = name_end_location(node) if prefer_name_location
|
||||||
|
end_location ||= node.end_location
|
||||||
|
|
||||||
|
add_issue rule, location, end_location, message, status, block
|
||||||
end
|
end
|
||||||
|
|
||||||
# :ditto:
|
# :ditto:
|
||||||
def add_issue(rule, node : Crystal::ASTNode, message, status : Issue::Status? = nil, &block : Source::Corrector ->) : Issue
|
def add_issue(rule, node : Crystal::ASTNode, message, status : Issue::Status? = nil, *, prefer_name_location = false, &block : Source::Corrector ->) : Issue
|
||||||
add_issue rule, node, message, status, block
|
add_issue rule, node, message, status, block, prefer_name_location: prefer_name_location
|
||||||
end
|
end
|
||||||
|
|
||||||
# Adds a new issue for Crystal *token*.
|
# Adds a new issue for Crystal *token*.
|
||||||
|
|
|
@ -20,8 +20,6 @@ module Ameba::Rule::Lint
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class MissingBlockArgument < Base
|
class MissingBlockArgument < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Disallows yielding method definitions without block argument"
|
description "Disallows yielding method definitions without block argument"
|
||||||
end
|
end
|
||||||
|
@ -36,10 +34,7 @@ module Ameba::Rule::Lint
|
||||||
def test(source, node : Crystal::Def, scope : AST::Scope)
|
def test(source, node : Crystal::Def, scope : AST::Scope)
|
||||||
return if !scope.yields? || node.block_arg
|
return if !scope.yields? || node.block_arg
|
||||||
|
|
||||||
return unless location = node.name_location
|
issue_for node, MSG, prefer_name_location: true
|
||||||
end_location = name_end_location(node)
|
|
||||||
|
|
||||||
issue_for location, end_location, MSG
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,8 +26,6 @@ module Ameba::Rule::Lint
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class NotNil < Base
|
class NotNil < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Identifies usage of `not_nil!` calls"
|
description "Identifies usage of `not_nil!` calls"
|
||||||
end
|
end
|
||||||
|
@ -42,10 +40,7 @@ module Ameba::Rule::Lint
|
||||||
return unless node.name == "not_nil!"
|
return unless node.name == "not_nil!"
|
||||||
return unless node.obj && node.args.empty?
|
return unless node.obj && node.args.empty?
|
||||||
|
|
||||||
return unless name_location = node.name_location
|
issue_for node, MSG, prefer_name_location: true
|
||||||
return unless end_location = name_end_location(node)
|
|
||||||
|
|
||||||
issue_for name_location, end_location, MSG
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,7 +51,7 @@ module Ameba::Rule::Lint
|
||||||
end
|
end
|
||||||
|
|
||||||
private def report(source, node, msg)
|
private def report(source, node, msg)
|
||||||
issue_for node.name_location, node.name_end_location, msg
|
issue_for node, msg, prefer_name_location: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,7 +40,7 @@ module Ameba::Rule::Lint
|
||||||
!(block = node.block) ||
|
!(block = node.block) ||
|
||||||
with_index_arg?(block)
|
with_index_arg?(block)
|
||||||
|
|
||||||
issue_for node.name_location, node.name_end_location, MSG
|
issue_for node, MSG, prefer_name_location: true
|
||||||
end
|
end
|
||||||
|
|
||||||
private def with_index_arg?(block : Crystal::Block)
|
private def with_index_arg?(block : Crystal::Block)
|
||||||
|
|
|
@ -9,8 +9,6 @@ module Ameba::Rule::Metrics
|
||||||
# MaxComplexity: 10
|
# MaxComplexity: 10
|
||||||
# ```
|
# ```
|
||||||
class CyclomaticComplexity < Base
|
class CyclomaticComplexity < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Disallows methods with a cyclomatic complexity higher than `MaxComplexity`"
|
description "Disallows methods with a cyclomatic complexity higher than `MaxComplexity`"
|
||||||
max_complexity 10
|
max_complexity 10
|
||||||
|
@ -22,10 +20,7 @@ module Ameba::Rule::Metrics
|
||||||
complexity = AST::CountingVisitor.new(node).count
|
complexity = AST::CountingVisitor.new(node).count
|
||||||
return unless complexity > max_complexity
|
return unless complexity > max_complexity
|
||||||
|
|
||||||
return unless location = node.name_location
|
issue_for node, MSG % {complexity, max_complexity}, prefer_name_location: true
|
||||||
end_location = name_end_location(node)
|
|
||||||
|
|
||||||
issue_for location, end_location, MSG % {complexity, max_complexity}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,8 +36,6 @@ module Ameba::Rule::Naming
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class AccessorMethodName < Base
|
class AccessorMethodName < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Makes sure that accessor methods are named properly"
|
description "Makes sure that accessor methods are named properly"
|
||||||
end
|
end
|
||||||
|
@ -66,24 +64,13 @@ module Ameba::Rule::Naming
|
||||||
end
|
end
|
||||||
|
|
||||||
private def check_issue(source, node : Crystal::Def)
|
private def check_issue(source, node : Crystal::Def)
|
||||||
location = name_location(node)
|
|
||||||
end_location = name_end_location(node)
|
|
||||||
|
|
||||||
case node.name
|
case node.name
|
||||||
when /^get_([a-z]\w*)$/
|
when /^get_([a-z]\w*)$/
|
||||||
return unless node.args.empty?
|
return unless node.args.empty?
|
||||||
if location && end_location
|
issue_for node, MSG % {$1, node.name}, prefer_name_location: true
|
||||||
issue_for location, end_location, MSG % {$1, node.name}
|
|
||||||
else
|
|
||||||
issue_for node, MSG % {$1, node.name}
|
|
||||||
end
|
|
||||||
when /^set_([a-z]\w*)$/
|
when /^set_([a-z]\w*)$/
|
||||||
return unless node.args.size == 1
|
return unless node.args.size == 1
|
||||||
if location && end_location
|
issue_for node, MSG % {"#{$1}=", node.name}, prefer_name_location: true
|
||||||
issue_for location, end_location, MSG % {"#{$1}=", node.name}
|
|
||||||
else
|
|
||||||
issue_for node, MSG % {"#{$1}=", node.name}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,8 +22,6 @@ module Ameba::Rule::Naming
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class AsciiIdentifiers < Base
|
class AsciiIdentifiers < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Disallows non-ascii characters in identifiers"
|
description "Disallows non-ascii characters in identifiers"
|
||||||
end
|
end
|
||||||
|
@ -43,38 +41,27 @@ module Ameba::Rule::Naming
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::Def)
|
def test(source, node : Crystal::Def)
|
||||||
check_issue_with_location(source, node)
|
check_issue(source, node, prefer_name_location: true)
|
||||||
|
|
||||||
node.args.each do |arg|
|
node.args.each do |arg|
|
||||||
check_issue_with_location(source, arg)
|
check_issue(source, arg, prefer_name_location: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::ClassVar | Crystal::InstanceVar | Crystal::Var | Crystal::Alias)
|
def test(source, node : Crystal::ClassVar | Crystal::InstanceVar | Crystal::Var | Crystal::Alias)
|
||||||
check_issue_with_location(source, node)
|
check_issue(source, node, prefer_name_location: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::ClassDef | Crystal::ModuleDef | Crystal::EnumDef | Crystal::LibDef)
|
def test(source, node : Crystal::ClassDef | Crystal::ModuleDef | Crystal::EnumDef | Crystal::LibDef)
|
||||||
check_issue(source, node.name, node.name)
|
check_issue(source, node.name, node.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def check_issue_with_location(source, node)
|
|
||||||
location = name_location(node)
|
|
||||||
end_location = name_end_location(node)
|
|
||||||
|
|
||||||
if location && end_location
|
|
||||||
check_issue(source, location, end_location, node.name)
|
|
||||||
else
|
|
||||||
check_issue(source, node, node.name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private def check_issue(source, location, end_location, name)
|
private def check_issue(source, location, end_location, name)
|
||||||
issue_for location, end_location, MSG unless name.to_s.ascii_only?
|
issue_for location, end_location, MSG unless name.to_s.ascii_only?
|
||||||
end
|
end
|
||||||
|
|
||||||
private def check_issue(source, node, name)
|
private def check_issue(source, node, name = node.name, *, prefer_name_location = false)
|
||||||
issue_for node, MSG unless name.to_s.ascii_only?
|
issue_for node, MSG, prefer_name_location: prefer_name_location unless name.to_s.ascii_only?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,8 +38,6 @@ module Ameba::Rule::Naming
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class MethodNames < Base
|
class MethodNames < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Enforces method names to be in underscored case"
|
description "Enforces method names to be in underscored case"
|
||||||
end
|
end
|
||||||
|
@ -49,10 +47,7 @@ module Ameba::Rule::Naming
|
||||||
def test(source, node : Crystal::Def)
|
def test(source, node : Crystal::Def)
|
||||||
return if (expected = node.name.underscore) == node.name
|
return if (expected = node.name.underscore) == node.name
|
||||||
|
|
||||||
return unless location = name_location(node)
|
issue_for node, MSG % {expected, node.name}, prefer_name_location: true
|
||||||
return unless end_location = name_end_location(node)
|
|
||||||
|
|
||||||
issue_for location, end_location, MSG % {expected, node.name}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,8 +28,6 @@ module Ameba::Rule::Performance
|
||||||
# Enabled: true
|
# Enabled: true
|
||||||
# ```
|
# ```
|
||||||
class AnyInsteadOfEmpty < Base
|
class AnyInsteadOfEmpty < Base
|
||||||
include AST::Util
|
|
||||||
|
|
||||||
properties do
|
properties do
|
||||||
description "Identifies usage of arg-less `any?` calls"
|
description "Identifies usage of arg-less `any?` calls"
|
||||||
end
|
end
|
||||||
|
@ -41,10 +39,7 @@ module Ameba::Rule::Performance
|
||||||
return unless node.block.nil? && node.args.empty?
|
return unless node.block.nil? && node.args.empty?
|
||||||
return unless node.obj
|
return unless node.obj
|
||||||
|
|
||||||
return unless name_location = node.name_location
|
issue_for node, MSG, prefer_name_location: true
|
||||||
return unless end_location = name_end_location(node)
|
|
||||||
|
|
||||||
issue_for name_location, end_location, MSG
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -67,11 +67,12 @@ module Ameba::Rule::Performance
|
||||||
return unless node.name.in?(call_names)
|
return unless node.name.in?(call_names)
|
||||||
return unless obj.name.in?(call_names) || obj.name.in?(ALLOCATING_METHOD_NAMES)
|
return unless obj.name.in?(call_names) || obj.name.in?(ALLOCATING_METHOD_NAMES)
|
||||||
|
|
||||||
return unless location = node.name_location
|
if end_location = name_end_location(node)
|
||||||
return unless end_location = name_end_location(node)
|
issue_for node, MSG % {node.name, obj.name}, prefer_name_location: true do |corrector|
|
||||||
|
corrector.insert_after(end_location, '!')
|
||||||
issue_for location, end_location, MSG % {node.name, obj.name} do |corrector|
|
end
|
||||||
corrector.insert_after(end_location, '!')
|
else
|
||||||
|
issue_for node, MSG % {node.name, obj.name}, prefer_name_location: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue