Skip to content

Commit b6bd74e

Browse files
authored
Merge pull request #434 from crystal-ameba/misc-refactors
v1.6.1
2 parents 452a7a8 + ce3f2b7 commit b6bd74e

18 files changed

+101
-89
lines changed

shard.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: ameba
2-
version: 1.6.0
2+
version: 1.6.1
33

44
authors:
55
- Vitalii Elenhaupt <[email protected]>

spec/ameba/ast/scope_spec.cr

+17-11
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,15 @@ module Ameba::AST
5757
end
5858
end
5959
CRYSTAL
60-
scope = Scope.new nodes.def_nodes.first
60+
6161
var_node = nodes.var_nodes.first
62-
scope.add_variable var_node
62+
63+
scope = Scope.new nodes.def_nodes.first
64+
scope.add_variable(var_node)
6365
scope.inner_scopes << Scope.new(nodes.block_nodes.first, scope)
6466

6567
variable = Variable.new(var_node, scope)
66-
variable.reference nodes.var_nodes.first, scope.inner_scopes.first
68+
variable.reference(nodes.var_nodes.first, scope.inner_scopes.first)
6769

6870
scope.references?(variable).should be_true
6971
end
@@ -77,13 +79,15 @@ module Ameba::AST
7779
end
7880
end
7981
CRYSTAL
80-
scope = Scope.new nodes.def_nodes.first
82+
8183
var_node = nodes.var_nodes.first
82-
scope.add_variable var_node
84+
85+
scope = Scope.new nodes.def_nodes.first
86+
scope.add_variable(var_node)
8387
scope.inner_scopes << Scope.new(nodes.block_nodes.first, scope)
8488

8589
variable = Variable.new(var_node, scope)
86-
variable.reference nodes.var_nodes.first, scope.inner_scopes.first
90+
variable.reference(nodes.var_nodes.first, scope.inner_scopes.first)
8791

8892
scope.references?(variable, check_inner_scopes: false).should be_false
8993
end
@@ -98,9 +102,11 @@ module Ameba::AST
98102
end
99103
end
100104
CRYSTAL
101-
scope = Scope.new nodes.def_nodes.first
105+
102106
var_node = nodes.var_nodes.first
103-
scope.add_variable var_node
107+
108+
scope = Scope.new nodes.def_nodes.first
109+
scope.add_variable(var_node)
104110
scope.inner_scopes << Scope.new(nodes.block_nodes.first, scope)
105111

106112
variable = Variable.new(var_node, scope)
@@ -120,7 +126,7 @@ module Ameba::AST
120126
describe "#find_variable" do
121127
it "returns the variable in the scope by name" do
122128
scope = Scope.new as_node("foo = 1")
123-
scope.add_variable Crystal::Var.new "foo"
129+
scope.add_variable(Crystal::Var.new "foo")
124130
scope.find_variable("foo").should_not be_nil
125131
end
126132

@@ -133,15 +139,15 @@ module Ameba::AST
133139
describe "#assign_variable" do
134140
it "creates a new assignment" do
135141
scope = Scope.new as_node("foo = 1")
136-
scope.add_variable Crystal::Var.new "foo"
142+
scope.add_variable(Crystal::Var.new "foo")
137143
scope.assign_variable("foo", Crystal::Var.new "foo")
138144
var = scope.find_variable("foo").should_not be_nil
139145
var.assignments.size.should eq 1
140146
end
141147

142148
it "does not create the assignment if variable is wrong" do
143149
scope = Scope.new as_node("foo = 1")
144-
scope.add_variable Crystal::Var.new "foo"
150+
scope.add_variable(Crystal::Var.new "foo")
145151
scope.assign_variable("bar", Crystal::Var.new "bar")
146152
var = scope.find_variable("foo").should_not be_nil
147153
var.assignments.size.should eq 0

spec/ameba/ast/variabling/variable_spec.cr

+9-4
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,16 @@ module Ameba::AST
8585
3.times { |i| a = a + i }
8686
end
8787
CRYSTAL
88-
scope = Scope.new nodes.def_nodes.first
88+
8989
var_node = nodes.var_nodes.first
90-
scope.add_variable var_node
90+
91+
scope = Scope.new(nodes.def_nodes.first)
92+
scope.add_variable(var_node)
9193
scope.inner_scopes << Scope.new(nodes.block_nodes.first, scope)
9294

9395
variable = Variable.new(var_node, scope)
94-
variable.reference nodes.var_nodes.last, scope.inner_scopes.last
96+
variable.reference(nodes.var_nodes.last, scope.inner_scopes.last)
97+
9598
variable.captured_by_block?.should be_truthy
9699
end
97100

@@ -101,8 +104,10 @@ module Ameba::AST
101104
a = 1
102105
end
103106
CRYSTAL
104-
scope.add_variable Crystal::Var.new "a"
107+
108+
scope.add_variable(Crystal::Var.new "a")
105109
variable = scope.variables.first
110+
106111
variable.captured_by_block?.should be_falsey
107112
end
108113
end

spec/ameba/config_spec.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ module Ameba
8585
end
8686

8787
it "raises when custom config file doesn't exist" do
88-
expect_raises(Exception, "Unable to load config file: Config file does not exist foo.yml") do
88+
expect_raises(Exception, "Unable to load config file: Config file does not exist") do
8989
Config.load "foo.yml"
9090
end
9191
end

spec/ameba/rule/lint/literals_comparison_spec.cr

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ module Ameba::Rule::Lint
1010
["foo"] === [foo]
1111
"foo" == foo
1212
"foo" != foo
13+
"foo" == FOO
14+
FOO == "foo"
1315
foo == "foo"
1416
foo != "foo"
1517
CRYSTAL

src/ameba/ast/scope.cr

+2-3
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@ module Ameba::AST
3434
# The actual AST node that represents a current scope.
3535
getter node : Crystal::ASTNode
3636

37-
delegate to_s, to: node
38-
delegate location, to: node
39-
delegate end_location, to: node
37+
delegate location, end_location, to_s,
38+
to: @node
4039

4140
def_equals_and_hash node, location
4241

src/ameba/ast/variabling/argument.cr

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ module Ameba::AST
1919
# Variable of this argument (may be the same node)
2020
getter variable : Variable
2121

22-
delegate location, to: @node
23-
delegate end_location, to: @node
24-
delegate to_s, to: @node
22+
delegate location, end_location, to_s,
23+
to: @node
2524

2625
# Creates a new argument.
2726
#

src/ameba/ast/variabling/assignment.cr

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ module Ameba::AST
1919
# A scope assignment belongs to
2020
getter scope : Scope
2121

22-
delegate to_s, to: @node
23-
delegate location, to: @node
24-
delegate end_location, to: @node
22+
delegate location, end_location, to_s,
23+
to: @node
2524

2625
# Creates a new assignment.
2726
#

src/ameba/ast/variabling/ivariable.cr

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ module Ameba::AST
22
class InstanceVariable
33
getter node : Crystal::InstanceVar
44

5-
delegate location, to: @node
6-
delegate end_location, to: @node
7-
delegate name, to: @node
8-
delegate to_s, to: @node
5+
delegate location, end_location, name, to_s,
6+
to: @node
97

108
def initialize(@node)
119
end

src/ameba/ast/variabling/type_dec_variable.cr

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ module Ameba::AST
22
class TypeDecVariable
33
getter node : Crystal::TypeDeclaration
44

5-
delegate location, to: @node
6-
delegate end_location, to: @node
7-
delegate to_s, to: @node
5+
delegate location, end_location, to_s,
6+
to: @node
87

98
def initialize(@node)
109
end

src/ameba/ast/variabling/variable.cr

+11-8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ module Ameba::AST
1717
# Node of the first assignment which can be available before any reference.
1818
getter assign_before_reference : Crystal::ASTNode?
1919

20-
delegate location, to: @node
21-
delegate end_location, to: @node
22-
delegate name, to: @node
23-
delegate to_s, to: @node
20+
delegate location, end_location, name, to_s,
21+
to: @node
2422

2523
# Creates a new variable(in the scope).
2624
#
@@ -54,7 +52,7 @@ module Ameba::AST
5452
#
5553
# ```
5654
# variable = Variable.new(node, scope)
57-
# variable.reference(var_node)
55+
# variable.reference(var_node, some_scope)
5856
# variable.referenced? # => true
5957
# ```
6058
def referenced?
@@ -74,6 +72,11 @@ module Ameba::AST
7472
end
7573
end
7674

75+
# :ditto:
76+
def reference(scope : Scope)
77+
reference(node, scope)
78+
end
79+
7780
# Reference variable's assignments.
7881
#
7982
# ```
@@ -208,9 +211,9 @@ module Ameba::AST
208211
return if references.size > assignments.size
209212
return if assignments.any?(&.op_assign?)
210213

211-
@assign_before_reference = assignments.find { |ass|
212-
!ass.in_branch?
213-
}.try &.node
214+
@assign_before_reference = assignments
215+
.find(&.in_branch?.!)
216+
.try(&.node)
214217
end
215218
end
216219
end

src/ameba/ast/visitors/scope_visitor.cr

+3-5
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,15 @@ module Ameba::AST
153153

154154
# :nodoc:
155155
def visit(node : Crystal::Var)
156-
variable = @current_scope.find_variable node.name
156+
variable = @current_scope.find_variable(node.name)
157157

158158
case
159159
when @current_scope.arg?(node) # node is an argument
160160
@current_scope.add_argument(node)
161161
when variable.nil? && @current_assign # node is a variable
162162
@current_scope.add_variable(node)
163163
when variable # node is a reference
164-
reference = variable.reference node, @current_scope
164+
reference = variable.reference(node, @current_scope)
165165
if @current_assign.is_a?(Crystal::OpAssign) || !reference.target_of?(@current_assign)
166166
variable.reference_assignments!
167167
end
@@ -178,9 +178,7 @@ module Ameba::AST
178178
when scope.type_definition? && accessor_macro?(node) then return false
179179
when scope.def? && special_node?(node)
180180
scope.arguments.each do |arg|
181-
variable = arg.variable
182-
183-
ref = variable.reference(variable.node, scope)
181+
ref = arg.variable.reference(scope)
184182
ref.explicit = false
185183
end
186184
end

src/ameba/config.cr

+5-4
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ class Ameba::Config
9797
@excluded = load_array_section(config, "Excluded")
9898
@globs = load_array_section(config, "Globs", DEFAULT_GLOBS)
9999

100-
return unless formatter_name = load_formatter_name(config)
101-
self.formatter = formatter_name
100+
if formatter_name = load_formatter_name(config)
101+
self.formatter = formatter_name
102+
end
102103
end
103104

104105
# Loads YAML configuration file by `path`.
@@ -120,8 +121,8 @@ class Ameba::Config
120121

121122
protected def self.read_config(path = nil)
122123
if path
123-
raise ArgumentError.new("Config file does not exist #{path}") unless File.exists?(path)
124-
return File.read(path)
124+
return File.read(path) if File.exists?(path)
125+
raise "Config file does not exist"
125126
end
126127
each_config_path do |config_path|
127128
return File.read(config_path) if File.exists?(config_path)

src/ameba/formatter/base_formatter.cr

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ module Ameba::Formatter
1717
# A list of sources to inspect is passed as an argument.
1818
def started(sources); end
1919

20-
# Callback that indicates when source inspection is finished.
20+
# Callback that indicates when source inspection is started.
2121
# A corresponding source is passed as an argument.
22-
def source_finished(source : Source); end
22+
def source_started(source : Source); end
2323

2424
# Callback that indicates when source inspection is finished.
2525
# A corresponding source is passed as an argument.
26-
def source_started(source : Source); end
26+
def source_finished(source : Source); end
2727

2828
# Callback that indicates when inspection is finished.
2929
# A list of inspected sources is passed as an argument.

src/ameba/formatter/todo_formatter.cr

+19-14
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,21 @@ module Ameba::Formatter
2626
end
2727

2828
private def generate_todo_config(issues)
29-
file = File.new(@config_path, mode: "w")
30-
file << header
31-
rule_issues_map(issues).each do |rule, rule_issues|
32-
file << "\n# Problems found: #{rule_issues.size}"
33-
file << "\n# Run `ameba --only #{rule.name}` for details"
34-
file << rule_todo(rule, rule_issues).gsub("---", "")
29+
File.open(@config_path, mode: "w") do |file|
30+
file << header
31+
32+
rule_issues_map(issues).each do |rule, rule_issues|
33+
rule_todo = rule_todo(rule, rule_issues)
34+
rule_todo =
35+
{rule_todo.name => rule_todo}
36+
.to_yaml.gsub("---", "")
37+
38+
file << "\n# Problems found: #{rule_issues.size}"
39+
file << "\n# Run `ameba --only #{rule.name}` for details"
40+
file << rule_todo
41+
end
42+
file
3543
end
36-
file
37-
ensure
38-
file.close if file
3944
end
4045

4146
private def rule_issues_map(issues)
@@ -60,11 +65,11 @@ module Ameba::Formatter
6065
end
6166

6267
private def rule_todo(rule, issues)
63-
rule.excluded = issues
64-
.compact_map(&.location.try &.filename.try &.to_s)
65-
.uniq!
66-
67-
{rule.name => rule}.to_yaml
68+
rule.dup.tap do |rule_todo|
69+
rule_todo.excluded = issues
70+
.compact_map(&.location.try &.filename.try &.to_s)
71+
.uniq!
72+
end
6873
end
6974
end
7075
end

src/ameba/rule/base.cr

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ module Ameba::Rule
3232
# This method is designed to test the source passed in. If source has issues
3333
# that are tested by this rule, it should add an issue.
3434
#
35-
# Be default it uses a node visitor to traverse all the nodes in the source.
35+
# By default it uses a node visitor to traverse all the nodes in the source.
36+
#
3637
# NOTE: Must be overridden for other type of rules.
3738
def test(source : Source)
3839
AST::NodeVisitor.new self, source
3940
end
4041

42+
# NOTE: Can't be abstract
4143
def test(source : Source, node : Crystal::ASTNode, *opts)
42-
# can't be abstract
4344
end
4445

4546
# A convenient addition to `#test` method that does the same

src/ameba/rule/naming/block_parameter_name.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module Ameba::Rule::Naming
4141
end
4242

4343
private def valid_name?(name)
44-
return true if name.blank? # happens with compound names like `(arg1, arg2)`
44+
return true if name.blank? # TODO: handle unpacked variables
4545
return true if name.in?(allowed_names)
4646

4747
return false if name.in?(forbidden_names)

0 commit comments

Comments
 (0)