mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Ameba::Rule -> Ameba::Rule::Base
This commit is contained in:
parent
b6c0d3e8ad
commit
80e2ab4f55
39 changed files with 79 additions and 73 deletions
|
@ -65,11 +65,11 @@ Finished in 10.53 milliseconds
|
||||||
|
|
||||||
## Write a new Rule
|
## Write a new Rule
|
||||||
|
|
||||||
Adding a new rule is as simple as inheriting from `Rule` struct and implementing
|
Adding a new rule is as simple as inheriting from `Rule::Base` struct and implementing
|
||||||
your logic to detect a problem:
|
your logic to detect a problem:
|
||||||
|
|
||||||
```crystal
|
```crystal
|
||||||
struct DebuggerStatement < Rule
|
struct DebuggerStatement < Rule::Base
|
||||||
# This is a required method to be implemented by the rule.
|
# This is a required method to be implemented by the rule.
|
||||||
# Source will be passed here. If rule finds an issue in this source,
|
# Source will be passed here. If rule finds an issue in this source,
|
||||||
# it reports an error:
|
# it reports an error:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
require "../../spec/spec_helper"
|
require "../../spec/spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
describe Rule do
|
describe Rule::Base do
|
||||||
describe "#catch" do
|
describe "#catch" do
|
||||||
it "accepts and returns source" do
|
it "accepts and returns source" do
|
||||||
s = Source.new "", ""
|
s = Source.new "", ""
|
||||||
|
@ -14,7 +14,9 @@ module Ameba
|
||||||
DummyRule.new.name.should eq "Ameba::DummyRule"
|
DummyRule.new.name.should eq "Ameba::DummyRule"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe Rule do
|
||||||
describe ".rules" do
|
describe ".rules" do
|
||||||
it "returns a list of all defined rules" do
|
it "returns a list of all defined rules" do
|
||||||
Rule.rules.includes?(DummyRule).should be_true
|
Rule.rules.includes?(DummyRule).should be_true
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = ComparisonToBoolean.new
|
subject = ComparisonToBoolean.new
|
||||||
|
|
||||||
describe ComparisonToBoolean do
|
describe ComparisonToBoolean do
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::ConstantNames.new
|
subject = Rule::ConstantNames.new
|
||||||
|
|
||||||
private def it_reports_constant(code, expected)
|
private def it_reports_constant(code, expected)
|
||||||
it "reports constant name #{expected}" do
|
it "reports constant name #{expected}" do
|
||||||
s = Source.new code
|
s = Source.new code
|
||||||
Rules::ConstantNames.new.catch(s).should_not be_valid
|
Rule::ConstantNames.new.catch(s).should_not be_valid
|
||||||
s.errors.first.message.should contain expected
|
s.errors.first.message.should contain expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::ConstantNames do
|
describe Rule::ConstantNames do
|
||||||
it "passes if type names are screaming-cased" do
|
it "passes if type names are screaming-cased" do
|
||||||
s = Source.new %(
|
s = Source.new %(
|
||||||
LUCKY_NUMBERS = [3, 7, 11]
|
LUCKY_NUMBERS = [3, 7, 11]
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = DebuggerStatement.new
|
subject = DebuggerStatement.new
|
||||||
|
|
||||||
describe DebuggerStatement do
|
describe DebuggerStatement do
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::EmptyExpression.new
|
subject = Rule::EmptyExpression.new
|
||||||
|
|
||||||
def it_detects_empty_expression(code)
|
def it_detects_empty_expression(code)
|
||||||
it "detects empty expression" do
|
it "detects empty expression" do
|
||||||
s = Source.new code
|
s = Source.new code
|
||||||
rule = Rules::EmptyExpression.new
|
rule = Rule::EmptyExpression.new
|
||||||
rule.catch(s).should_not be_valid
|
rule.catch(s).should_not be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::EmptyExpression do
|
describe Rule::EmptyExpression do
|
||||||
it "passes if there is no empty expression" do
|
it "passes if there is no empty expression" do
|
||||||
s = Source.new %(
|
s = Source.new %(
|
||||||
def method()
|
def method()
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::LargeNumbers.new
|
subject = Rule::LargeNumbers.new
|
||||||
|
|
||||||
private def it_transforms(number, expected)
|
private def it_transforms(number, expected)
|
||||||
it "transforms large number #{number}" do
|
it "transforms large number #{number}" do
|
||||||
s = Source.new number
|
s = Source.new number
|
||||||
Rules::LargeNumbers.new.catch(s).should_not be_valid
|
Rule::LargeNumbers.new.catch(s).should_not be_valid
|
||||||
s.errors.first.message.should contain expected
|
s.errors.first.message.should contain expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::LargeNumbers do
|
describe Rule::LargeNumbers do
|
||||||
it "passes if large number does not require underscore" do
|
it "passes if large number does not require underscore" do
|
||||||
s = Source.new %q(
|
s = Source.new %q(
|
||||||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = LineLength.new
|
subject = LineLength.new
|
||||||
long_line = "*" * 81
|
long_line = "*" * 81
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = LiteralInCondition.new
|
subject = LiteralInCondition.new
|
||||||
|
|
||||||
describe LiteralInCondition do
|
describe LiteralInCondition do
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = LiteralInInterpolation.new
|
subject = LiteralInInterpolation.new
|
||||||
|
|
||||||
describe LiteralInInterpolation do
|
describe LiteralInInterpolation do
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::MethodNames.new
|
subject = Rule::MethodNames.new
|
||||||
|
|
||||||
private def it_reports_method_name(code, expected)
|
private def it_reports_method_name(code, expected)
|
||||||
it "reports method name #{expected}" do
|
it "reports method name #{expected}" do
|
||||||
s = Source.new code
|
s = Source.new code
|
||||||
Rules::MethodNames.new.catch(s).should_not be_valid
|
Rule::MethodNames.new.catch(s).should_not be_valid
|
||||||
s.errors.first.message.should contain expected
|
s.errors.first.message.should contain expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::MethodNames do
|
describe Rule::MethodNames do
|
||||||
it "passes if method names are underscore-cased" do
|
it "passes if method names are underscore-cased" do
|
||||||
s = Source.new %(
|
s = Source.new %(
|
||||||
class Person
|
class Person
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = NegatedConditionsInUnless.new
|
subject = NegatedConditionsInUnless.new
|
||||||
|
|
||||||
describe NegatedConditionsInUnless do
|
describe NegatedConditionsInUnless do
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = PredicateName.new
|
subject = PredicateName.new
|
||||||
|
|
||||||
describe PredicateName do
|
describe PredicateName do
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = TrailingBlankLines.new
|
subject = TrailingBlankLines.new
|
||||||
|
|
||||||
describe TrailingBlankLines do
|
describe TrailingBlankLines do
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = TrailingWhitespace.new
|
subject = TrailingWhitespace.new
|
||||||
|
|
||||||
describe TrailingWhitespace do
|
describe TrailingWhitespace do
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::TypeNames.new
|
subject = Rule::TypeNames.new
|
||||||
|
|
||||||
private def it_reports_name(code, expected)
|
private def it_reports_name(code, expected)
|
||||||
it "reports type name #{expected}" do
|
it "reports type name #{expected}" do
|
||||||
s = Source.new code
|
s = Source.new code
|
||||||
Rules::TypeNames.new.catch(s).should_not be_valid
|
Rule::TypeNames.new.catch(s).should_not be_valid
|
||||||
s.errors.first.message.should contain expected
|
s.errors.first.message.should contain expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::TypeNames do
|
describe Rule::TypeNames do
|
||||||
it "passes if type names are camelcased" do
|
it "passes if type names are camelcased" do
|
||||||
s = Source.new %(
|
s = Source.new %(
|
||||||
class ParseError < Exception
|
class ParseError < Exception
|
|
@ -1,6 +1,6 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
subject = UnlessElse.new
|
subject = UnlessElse.new
|
||||||
|
|
||||||
describe UnlessElse do
|
describe UnlessElse do
|
|
@ -1,17 +1,17 @@
|
||||||
require "../../spec_helper"
|
require "../../spec_helper"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
subject = Rules::VariableNames.new
|
subject = Rule::VariableNames.new
|
||||||
|
|
||||||
private def it_reports_var_name(code, expected)
|
private def it_reports_var_name(code, expected)
|
||||||
it "reports method name #{expected}" do
|
it "reports method name #{expected}" do
|
||||||
s = Source.new code
|
s = Source.new code
|
||||||
Rules::VariableNames.new.catch(s).should_not be_valid
|
Rule::VariableNames.new.catch(s).should_not be_valid
|
||||||
s.errors.first.message.should contain expected
|
s.errors.first.message.should contain expected
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Rules::VariableNames do
|
describe Rule::VariableNames do
|
||||||
it "passes if var names are underscore-cased" do
|
it "passes if var names are underscore-cased" do
|
||||||
s = Source.new %(
|
s = Source.new %(
|
||||||
class Greeting
|
class Greeting
|
|
@ -2,7 +2,7 @@ require "spec"
|
||||||
require "../src/ameba"
|
require "../src/ameba"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
struct DummyRule < Ameba::Rule
|
struct DummyRule < Rule::Base
|
||||||
def test(source)
|
def test(source)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
require "./ameba/*"
|
require "./ameba/*"
|
||||||
require "./ameba/ast/*"
|
require "./ameba/ast/*"
|
||||||
require "./ameba/rules/*"
|
require "./ameba/rule/*"
|
||||||
require "./ameba/formatter/*"
|
require "./ameba/formatter/*"
|
||||||
|
|
||||||
module Ameba
|
module Ameba
|
||||||
|
|
|
@ -21,7 +21,7 @@ module Ameba::AST
|
||||||
]
|
]
|
||||||
|
|
||||||
class Visitor < Crystal::Visitor
|
class Visitor < Crystal::Visitor
|
||||||
@rule : Rule
|
@rule : Rule::Base
|
||||||
@source : Source
|
@source : Source
|
||||||
|
|
||||||
def initialize(@rule, @source)
|
def initialize(@rule, @source)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Ameba
|
module Ameba::Rule
|
||||||
abstract struct Rule
|
abstract struct Base
|
||||||
abstract def test(source : Source)
|
abstract def test(source : Source)
|
||||||
|
|
||||||
def test(source : Source, node : Crystal::ASTNode)
|
def test(source : Source, node : Crystal::ASTNode)
|
||||||
|
@ -11,11 +11,15 @@ module Ameba
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
self.class.name.gsub("Ameba::Rules::", "")
|
self.class.name.gsub("Ameba::Rule::", "")
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.rules
|
protected def self.subclasses
|
||||||
{{ @type.subclasses }}
|
{{ @type.subclasses }}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.rules
|
||||||
|
Base.subclasses
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows comparison to booleans.
|
# A rule that disallows comparison to booleans.
|
||||||
#
|
#
|
||||||
# For example, these are considered invalid:
|
# For example, these are considered invalid:
|
||||||
|
@ -12,7 +12,7 @@ module Ameba::Rules
|
||||||
# could get the same result by using either the variable directly,
|
# could get the same result by using either the variable directly,
|
||||||
# or negating the variable.
|
# or negating the variable.
|
||||||
#
|
#
|
||||||
struct ComparisonToBoolean < Rule
|
struct ComparisonToBoolean < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that enforces constant names to be in screaming case.
|
# A rule that enforces constant names to be in screaming case.
|
||||||
#
|
#
|
||||||
# For example, these constant names are considered valid:
|
# For example, these constant names are considered valid:
|
||||||
|
@ -15,7 +15,7 @@ module Ameba::Rules
|
||||||
# Wrong_NAME = 2
|
# Wrong_NAME = 2
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct ConstantNames < Rule
|
struct ConstantNames < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,10 +1,10 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows calls to debugger.
|
# A rule that disallows calls to debugger.
|
||||||
#
|
#
|
||||||
# This is because we don't want debugger breakpoints accidentally being
|
# This is because we don't want debugger breakpoints accidentally being
|
||||||
# committed into our codebase.
|
# committed into our codebase.
|
||||||
#
|
#
|
||||||
struct DebuggerStatement < Rule
|
struct DebuggerStatement < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows empty expressions.
|
# A rule that disallows empty expressions.
|
||||||
#
|
#
|
||||||
# This is considered invalid:
|
# This is considered invalid:
|
||||||
|
@ -21,7 +21,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct EmptyExpression < Rule
|
struct EmptyExpression < Base
|
||||||
include AST::Util
|
include AST::Util
|
||||||
|
|
||||||
def test(source)
|
def test(source)
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows usage of large numbers without underscore.
|
# A rule that disallows usage of large numbers without underscore.
|
||||||
# These do not affect the value of the number, but can help read
|
# These do not affect the value of the number, but can help read
|
||||||
# large numbers more easily.
|
# large numbers more easily.
|
||||||
|
@ -19,7 +19,7 @@ module Ameba::Rules
|
||||||
# 5.123_45
|
# 5.123_45
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct LargeNumbers < Rule
|
struct LargeNumbers < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
Tokenizer.new(source).run do |token|
|
Tokenizer.new(source).run do |token|
|
||||||
next unless token.type == :NUMBER && decimal?(token.raw)
|
next unless token.type == :NUMBER && decimal?(token.raw)
|
|
@ -1,7 +1,7 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows lines longer than 80 symbols.
|
# A rule that disallows lines longer than 80 symbols.
|
||||||
#
|
#
|
||||||
struct LineLength < Rule
|
struct LineLength < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
source.lines.each_with_index do |line, index|
|
source.lines.each_with_index do |line, index|
|
||||||
next unless line.size > 80
|
next unless line.size > 80
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows useless conditional statements that contain a literal
|
# A rule that disallows useless conditional statements that contain a literal
|
||||||
# in place of a variable or predicate function.
|
# in place of a variable or predicate function.
|
||||||
#
|
#
|
||||||
|
@ -13,7 +13,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct LiteralInCondition < Rule
|
struct LiteralInCondition < Base
|
||||||
include AST::Util
|
include AST::Util
|
||||||
|
|
||||||
def test(source)
|
def test(source)
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows useless string interpolations
|
# A rule that disallows useless string interpolations
|
||||||
# that contain a literal value instead of a variable or function.
|
# that contain a literal value instead of a variable or function.
|
||||||
#
|
#
|
||||||
|
@ -9,7 +9,7 @@ module Ameba::Rules
|
||||||
# "There are #{4} cats"
|
# "There are #{4} cats"
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct LiteralInInterpolation < Rule
|
struct LiteralInInterpolation < Base
|
||||||
include AST::Util
|
include AST::Util
|
||||||
|
|
||||||
def test(source)
|
def test(source)
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that enforces method names to be in underscored case.
|
# A rule that enforces method names to be in underscored case.
|
||||||
#
|
#
|
||||||
# For example, these are considered valid:
|
# For example, these are considered valid:
|
||||||
|
@ -30,7 +30,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
struct MethodNames < Rule
|
struct MethodNames < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows negated conditions in unless.
|
# A rule that disallows negated conditions in unless.
|
||||||
#
|
#
|
||||||
# For example, this is considered invalid:
|
# For example, this is considered invalid:
|
||||||
|
@ -20,7 +20,7 @@ module Ameba::Rules
|
||||||
# It is pretty difficult to wrap your head around a block of code
|
# It is pretty difficult to wrap your head around a block of code
|
||||||
# that is executed if a negated condition is NOT met.
|
# that is executed if a negated condition is NOT met.
|
||||||
#
|
#
|
||||||
struct NegatedConditionsInUnless < Rule
|
struct NegatedConditionsInUnless < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows tautological predicate names, meaning those that
|
# A rule that disallows tautological predicate names, meaning those that
|
||||||
# start with the prefix `has_` or the prefix `is_`.
|
# start with the prefix `has_` or the prefix `is_`.
|
||||||
#
|
#
|
||||||
|
@ -22,7 +22,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct PredicateName < Rule
|
struct PredicateName < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,7 +1,7 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows trailing blank lines at the end of the source file.
|
# A rule that disallows trailing blank lines at the end of the source file.
|
||||||
#
|
#
|
||||||
struct TrailingBlankLines < Rule
|
struct TrailingBlankLines < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
if source.lines.size > 1 && source.lines[-2, 2].join.strip.empty?
|
if source.lines.size > 1 && source.lines[-2, 2].join.strip.empty?
|
||||||
source.error self, source.location(source.lines.size, 1),
|
source.error self, source.location(source.lines.size, 1),
|
|
@ -1,7 +1,7 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows trailing whitespaces.
|
# A rule that disallows trailing whitespaces.
|
||||||
#
|
#
|
||||||
struct TrailingWhitespace < Rule
|
struct TrailingWhitespace < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
source.lines.each_with_index do |line, index|
|
source.lines.each_with_index do |line, index|
|
||||||
next unless line =~ /\s$/
|
next unless line =~ /\s$/
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that enforces type names in camelcase manner.
|
# A rule that enforces type names in camelcase manner.
|
||||||
#
|
#
|
||||||
# For example, these are considered valid:
|
# For example, these are considered valid:
|
||||||
|
@ -45,7 +45,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct TypeNames < Rule
|
struct TypeNames < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that disallows the use of an `else` block with the `unless`.
|
# A rule that disallows the use of an `else` block with the `unless`.
|
||||||
#
|
#
|
||||||
# For example, the rule considers these valid:
|
# For example, the rule considers these valid:
|
||||||
|
@ -36,7 +36,7 @@ module Ameba::Rules
|
||||||
# end
|
# end
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct UnlessElse < Rule
|
struct UnlessElse < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -1,4 +1,4 @@
|
||||||
module Ameba::Rules
|
module Ameba::Rule
|
||||||
# A rule that enforces variable names to be in underscored case.
|
# A rule that enforces variable names to be in underscored case.
|
||||||
#
|
#
|
||||||
# For example, these variable names are considered valid:
|
# For example, these variable names are considered valid:
|
||||||
|
@ -24,7 +24,7 @@ module Ameba::Rules
|
||||||
# wrong_Name = 2
|
# wrong_Name = 2
|
||||||
# ```
|
# ```
|
||||||
#
|
#
|
||||||
struct VariableNames < Rule
|
struct VariableNames < Base
|
||||||
def test(source)
|
def test(source)
|
||||||
AST::Visitor.new self, source
|
AST::Visitor.new self, source
|
||||||
end
|
end
|
|
@ -5,9 +5,9 @@ module Ameba
|
||||||
# Represents an error caught by Ameba.
|
# Represents an error caught by Ameba.
|
||||||
#
|
#
|
||||||
# Each error has the rule that created this error,
|
# Each error has the rule that created this error,
|
||||||
# position of the error and a message.
|
# location of the issue and a message.
|
||||||
record Error,
|
record Error,
|
||||||
rule : Rule,
|
rule : Rule::Base,
|
||||||
location : Crystal::Location?,
|
location : Crystal::Location?,
|
||||||
message : String
|
message : String
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ module Ameba
|
||||||
def initialize(@code : String, @path = nil)
|
def initialize(@code : String, @path = nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def error(rule : Rule, location, message : String)
|
def error(rule : Rule::Base, location, message : String)
|
||||||
errors << Error.new rule, location, message
|
errors << Error.new rule, location, message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue