Skip to content

Commit

Permalink
Merge pull request #443 from crystal-ameba/fix-issue-442
Browse files Browse the repository at this point in the history
Do not report type declarations within `lib` definitions
  • Loading branch information
Sija committed Jan 10, 2024
2 parents b6bd74e + 98d5bc7 commit 734bb2a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 14 deletions.
22 changes: 22 additions & 0 deletions spec/ameba/ast/scope_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,28 @@ module Ameba::AST
end
end

describe "#def?" do
context "when check_outer_scopes: true" do
it "returns true if outer scope is Crystal::Def" do
nodes = as_nodes("def foo; 3.times {}; end")
outer_scope = Scope.new nodes.def_nodes.first
scope = Scope.new nodes.block_nodes.first, outer_scope
scope.def?(check_outer_scopes: true).should be_true
end
end

it "returns true if Crystal::Def" do
nodes = as_nodes("def foo; end")
scope = Scope.new nodes.def_nodes.first
scope.def?.should be_true
end

it "returns false otherwise" do
scope = Scope.new as_node("a = 1")
scope.def?.should be_false
end
end

describe "#in_macro?" do
it "returns true if Crystal::Macro" do
nodes = as_nodes <<-CRYSTAL
Expand Down
10 changes: 10 additions & 0 deletions spec/ameba/rule/lint/useless_assign_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,16 @@ module Ameba::Rule::Lint
CRYSTAL
end

it "doesn't report if it's referenced in a lib" do
expect_no_issues subject, <<-CRYSTAL
lib LibFoo
struct Foo
a : Int32
end
end
CRYSTAL
end

it "doesn't report if it's referenced" do
expect_no_issues subject, <<-CRYSTAL
def foo
Expand Down
23 changes: 9 additions & 14 deletions src/ameba/ast/scope.cr
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,15 @@ module Ameba::AST
@visibility || outer_scope.try(&.visibility)
end

# Returns `true` if current scope is a def, `false` otherwise.
def def?
node.is_a?(Crystal::Def)
end

# Returns `true` if current scope is a class, `false` otherwise.
def class_def?
node.is_a?(Crystal::ClassDef)
end

# Returns `true` if current scope is a module, `false` otherwise.
def module_def?
node.is_a?(Crystal::ModuleDef)
end
{% for type in %w[Def ClassDef ModuleDef EnumDef LibDef FunDef].map(&.id) %}
{% method_name = type.underscore %}
# Returns `true` if current scope is a {{ method_name[0..-5] }} def, `false` otherwise.
def {{ method_name }}?(*, check_outer_scopes = false)
node.is_a?(Crystal::{{ type }}) ||
!!(check_outer_scopes &&
outer_scope.try(&.{{ method_name }}?(check_outer_scopes: true)))
end
{% end %}

# Returns `true` if this scope is a top level scope, `false` otherwise.
def top_level?
Expand Down
2 changes: 2 additions & 0 deletions src/ameba/rule/lint/useless_assign.cr
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ module Ameba::Rule::Lint
end

def test(source, node, scope : AST::Scope)
return if scope.lib_def?(check_outer_scopes: true)

scope.variables.each do |var|
next if var.ignored? || var.used_in_macro? || var.captured_by_block?
next if exclude_type_declarations? && scope.assigns_type_dec?(var.name)
Expand Down

0 comments on commit 734bb2a

Please sign in to comment.