mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Constantize string error messages (#50)
This commit is contained in:
parent
5647621393
commit
60c1b86890
25 changed files with 77 additions and 38 deletions
|
@ -26,6 +26,8 @@ module Ameba::Rule
|
|||
description = "Disallows comparison to booleans"
|
||||
end
|
||||
|
||||
MSG = "Comparison to a boolean is pointless"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -37,7 +39,7 @@ module Ameba::Rule
|
|||
|
||||
return unless comparison? && to_boolean?
|
||||
|
||||
source.error self, node.location, "Comparison to a boolean is pointless"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,6 +27,8 @@ module Ameba::Rule
|
|||
description = "Enforces constant names to be in screaming case"
|
||||
end
|
||||
|
||||
MSG = "Constant name should be screaming-cased: %s, not %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -36,8 +38,7 @@ module Ameba::Rule
|
|||
name = target.names.first
|
||||
return if (expected = name.upcase) == name
|
||||
|
||||
source.error self, node.location,
|
||||
"Constant name should be screaming-cased: #{expected}, not #{name}"
|
||||
source.error self, node.location, sprintf(MSG, expected, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,8 @@ module Ameba::Rule
|
|||
description = "Disallows calls to debugger"
|
||||
end
|
||||
|
||||
MSG = "Possible forgotten debugger statement detected"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -25,8 +27,7 @@ module Ameba::Rule
|
|||
node.args.empty? &&
|
||||
node.obj.nil?
|
||||
|
||||
source.error self, node.location,
|
||||
"Possible forgotten debugger statement detected"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,6 +37,8 @@ module Ameba::Rule
|
|||
description = "Disallows empty ensure statement"
|
||||
end
|
||||
|
||||
MSG = "Empty `ensure` block detected"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -45,7 +47,7 @@ module Ameba::Rule
|
|||
node_ensure = node.ensure
|
||||
return if node_ensure.nil? || !node_ensure.nop?
|
||||
|
||||
source.error self, node.location, "Empty `ensure` block detected"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,6 +35,9 @@ module Ameba::Rule
|
|||
description = "Disallows empty expressions"
|
||||
end
|
||||
|
||||
MSG = "Avoid empty expression %s"
|
||||
MSG_EXRS = "Avoid empty expressions"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -44,12 +47,12 @@ module Ameba::Rule
|
|||
|
||||
return if exp.nil? || exp == "nil"
|
||||
|
||||
source.error self, node.location, "Avoid empty expression '#{exp}'"
|
||||
source.error self, node.location, MSG % exp
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::Expressions)
|
||||
if node.expressions.size == 1 && node.expressions.first.nop?
|
||||
source.error self, node.location, "Avoid empty expressions"
|
||||
source.error self, node.location, MSG_EXRS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,6 +25,8 @@ module Ameba::Rule
|
|||
description = "Disallows duplicated keys in hash literals"
|
||||
end
|
||||
|
||||
MSG = "Duplicated keys in hash literal: %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -32,8 +34,7 @@ module Ameba::Rule
|
|||
def test(source, node : Crystal::HashLiteral)
|
||||
return unless (keys = duplicated_keys(node.entries)).any?
|
||||
|
||||
source.error self, node.location,
|
||||
"Duplicated keys in hash literal: #{keys.join(", ")}"
|
||||
source.error self, node.location, MSG % keys.join(", ")
|
||||
end
|
||||
|
||||
private def duplicated_keys(entries)
|
||||
|
|
|
@ -33,6 +33,8 @@ module Ameba::Rule
|
|||
int_min_digits = 5
|
||||
end
|
||||
|
||||
MSG = "Large numbers should be written with underscores: %s"
|
||||
|
||||
def test(source)
|
||||
Tokenizer.new(source).run do |token|
|
||||
next unless token.type == :NUMBER && decimal?(token.raw)
|
||||
|
@ -40,8 +42,7 @@ module Ameba::Rule
|
|||
parsed = parse_number token.raw
|
||||
|
||||
if allowed?(*parsed) && (expected = underscored *parsed) != token.raw
|
||||
source.error self, token.location,
|
||||
"Large numbers should be written with underscores: #{expected}"
|
||||
source.error self, token.location, MSG % expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,11 +16,13 @@ module Ameba::Rule
|
|||
max_length = 80
|
||||
end
|
||||
|
||||
MSG = "Line too long"
|
||||
|
||||
def test(source)
|
||||
source.lines.each_with_index do |line, index|
|
||||
next unless line.size > max_length
|
||||
|
||||
source.error self, index + 1, line.size, "Line too long"
|
||||
source.error self, index + 1, line.size, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,13 +28,15 @@ module Ameba::Rule
|
|||
a literal in place of a variable or predicate function"
|
||||
end
|
||||
|
||||
MSG = "Literal value found in conditional"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
||||
def check_node(source, node)
|
||||
return unless literal?(node.cond)
|
||||
source.error self, node.location, "Literal value found in conditional"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::If)
|
||||
|
|
|
@ -23,6 +23,8 @@ module Ameba::Rule
|
|||
description = "Disallows useless string interpolations"
|
||||
end
|
||||
|
||||
MSG = "Literal value found in interpolation"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -30,7 +32,7 @@ module Ameba::Rule
|
|||
def test(source, node : Crystal::StringInterpolation)
|
||||
found = node.expressions.any? { |e| !string_literal?(e) && literal?(e) }
|
||||
return unless found
|
||||
source.error self, node.location, "Literal value found in interpolation"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,6 +43,8 @@ module Ameba::Rule
|
|||
description = "Enforces method names to be in underscored case"
|
||||
end
|
||||
|
||||
MSG = "Method name should be underscore-cased: %s, not %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -50,8 +52,7 @@ module Ameba::Rule
|
|||
def test(source, node : Crystal::Def)
|
||||
return if (expected = node.name.underscore) == node.name
|
||||
|
||||
source.error self, node.location,
|
||||
"Method name should be underscore-cased: #{expected}, not #{node.name}"
|
||||
source.error self, node.location, sprintf(MSG, expected, node.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,14 +32,15 @@ module Ameba::Rule
|
|||
description = "Disallows negated conditions in unless"
|
||||
end
|
||||
|
||||
MSG = "Avoid negated conditions in unless blocks"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::Unless)
|
||||
return unless negated_condition? node.cond
|
||||
source.error self, node.location,
|
||||
"Avoid negated conditions in unless blocks"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
|
||||
private def negated_condition?(node)
|
||||
|
|
|
@ -31,6 +31,8 @@ module Ameba::Rule
|
|||
symbol_array_unwanted_symbols = ",:"
|
||||
end
|
||||
|
||||
MSG = "Symbols `%s` may be unwanted in %s array literals"
|
||||
|
||||
def test(source)
|
||||
error = start_token = nil
|
||||
|
||||
|
@ -62,7 +64,7 @@ module Ameba::Rule
|
|||
|
||||
private def check_array_entry(entry, symbols, literal)
|
||||
return unless entry =~ /[#{symbols}]/
|
||||
"Symbols `#{symbols}` may be unwanted in #{literal} array literals"
|
||||
sprintf(MSG, symbols, literal)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,6 +34,8 @@ module Ameba::Rule
|
|||
description = "Disallows tautological predicate names"
|
||||
end
|
||||
|
||||
MSG = "Favour method name '%s?' over '%s'"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -43,8 +45,7 @@ module Ameba::Rule
|
|||
alternative = $2
|
||||
return unless alternative =~ /^[a-z][a-zA-Z_0-9]*$/
|
||||
|
||||
source.error self, node.location,
|
||||
"Favour method name '#{alternative}?' over '#{node.name}'"
|
||||
source.error self, node.location, sprintf(MSG, alternative, node.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,6 +28,8 @@ module Ameba::Rule
|
|||
description = "Disallows rand zero calls"
|
||||
end
|
||||
|
||||
MSG = "%s always returns 0"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -40,7 +42,7 @@ module Ameba::Rule
|
|||
(value = arg.value) &&
|
||||
(value == "0" || value == "1")
|
||||
|
||||
source.error self, node.location, "#{node} always returns 0"
|
||||
source.error self, node.location, MSG % node
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -62,6 +62,8 @@ module Ameba::Rule
|
|||
description = "Disallows redundant begin blocks"
|
||||
end
|
||||
|
||||
MSG = "Redundant `begin` block detected"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -69,7 +71,7 @@ module Ameba::Rule
|
|||
def test(source, node : Crystal::Def)
|
||||
return unless redundant_begin?(source, node)
|
||||
|
||||
source.error self, node.location, "Redundant `begin` block detected"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
|
||||
private def redundant_begin?(source, node)
|
||||
|
|
|
@ -39,6 +39,8 @@ module Ameba::Rule
|
|||
description = "Disallows rescued exception that get shadowed"
|
||||
end
|
||||
|
||||
MSG = "Exception handler has shadowed exceptions: %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -47,8 +49,7 @@ module Ameba::Rule
|
|||
return unless excs = node.rescues
|
||||
|
||||
if (excs = shadowed excs.map(&.types)).any?
|
||||
source.error self, node.location,
|
||||
"Exception handler has shadowed exceptions: #{excs.join(", ")}"
|
||||
source.error self, node.location, MSG % excs.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@ module Ameba::Rule
|
|||
description = "Disallows trailing blank lines"
|
||||
end
|
||||
|
||||
MSG = "Blank lines detected at the end of the file"
|
||||
|
||||
def test(source)
|
||||
if source.lines.size > 1 && source.lines[-2, 2].join.strip.empty?
|
||||
source.error self, source.lines.size, 1,
|
||||
"Blank lines detected at the end of the file"
|
||||
source.error self, source.lines.size, 1, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,10 +13,12 @@ module Ameba::Rule
|
|||
description = "Disallows trailing whitespaces"
|
||||
end
|
||||
|
||||
MSG = "Trailing whitespace detected"
|
||||
|
||||
def test(source)
|
||||
source.lines.each_with_index do |line, index|
|
||||
next unless line =~ /\s$/
|
||||
source.error self, index + 1, line.size, "Trailing whitespace detected"
|
||||
source.error self, index + 1, line.size, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,6 +57,8 @@ module Ameba::Rule
|
|||
description = "Enforces type names in camelcase manner"
|
||||
end
|
||||
|
||||
MSG = "Type name should be camelcased: %s, but it was %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -66,8 +68,7 @@ module Ameba::Rule
|
|||
expected = name.camelcase
|
||||
return if expected == name
|
||||
|
||||
source.error self, node.location,
|
||||
"Type name should be camelcased: #{expected}, but it was #{name}"
|
||||
source.error self, node.location, sprintf(MSG, expected, name)
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::ClassDef)
|
||||
|
|
|
@ -48,13 +48,15 @@ module Ameba::Rule
|
|||
description = "Disallows the use of an `else` block with the `unless`"
|
||||
end
|
||||
|
||||
MSG = "Favour if over unless with else"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::Unless)
|
||||
return if node.else.nop?
|
||||
source.error self, node.location, "Favour if over unless with else"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,8 @@ module Ameba::Rule
|
|||
description = "Reports unneeded disable directives in comments"
|
||||
end
|
||||
|
||||
MSG = "Unnecessary disabling of %s"
|
||||
|
||||
def test(source)
|
||||
Tokenizer.new(source).run do |token|
|
||||
next unless token.type == :COMMENT
|
||||
|
@ -30,8 +32,7 @@ module Ameba::Rule
|
|||
next unless names = unneeded_disables(source, directive, token.location)
|
||||
next unless names.any?
|
||||
|
||||
source.error self, token.location,
|
||||
"Unnecessary disabling of #{names.join(", ")}"
|
||||
source.error self, token.location, MSG % names.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ module Ameba::Rule
|
|||
description = "Disallows useless conditions in when"
|
||||
end
|
||||
|
||||
MSG = "Useless condition in when detected"
|
||||
|
||||
# TODO: condition.cond may be a complex ASTNode with
|
||||
# useless inner conditions. We might need to improve this
|
||||
# simple implementation in future.
|
||||
|
@ -46,7 +48,7 @@ module Ameba::Rule
|
|||
.map(&.to_s)
|
||||
.none? { |c| c == cond_s }
|
||||
|
||||
source.error self, cond.location, "Useless condition in when detected"
|
||||
source.error self, cond.location, MSG
|
||||
end
|
||||
|
||||
def test(source)
|
||||
|
|
|
@ -36,6 +36,8 @@ module Ameba::Rule
|
|||
description = "Enforces variable names to be in underscored case"
|
||||
end
|
||||
|
||||
MSG = "Var name should be underscore-cased: %s, not %s"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
@ -43,8 +45,7 @@ module Ameba::Rule
|
|||
private def check_node(source, node)
|
||||
return if (expected = node.name.underscore) == node.name
|
||||
|
||||
source.error self, node.location,
|
||||
"Var name should be underscore-cased: #{expected}, not #{node.name}"
|
||||
source.error self, node.location, sprintf(MSG, expected, node.name)
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::Var)
|
||||
|
|
|
@ -31,13 +31,15 @@ module Ameba::Rule
|
|||
description = "Disallows while statements with a true literal as condition"
|
||||
end
|
||||
|
||||
MSG = "While statement using true literal as condition"
|
||||
|
||||
def test(source)
|
||||
AST::Visitor.new self, source
|
||||
end
|
||||
|
||||
def test(source, node : Crystal::While)
|
||||
return unless node.cond.true_literal?
|
||||
source.error self, node.location, "While statement using true literal as condition"
|
||||
source.error self, node.location, MSG
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue