mirror of
https://gitea.invidious.io/iv-org/shard-ameba.git
synced 2024-08-15 00:53:29 +00:00
Implement Documentation
rule on top of the ScopeVisitor
This commit is contained in:
parent
4c740f394a
commit
4d8346509e
2 changed files with 31 additions and 45 deletions
|
@ -4,15 +4,21 @@ module Ameba::Rule::Lint
|
||||||
subject = Documentation.new
|
subject = Documentation.new
|
||||||
.tap(&.ignore_classes = false)
|
.tap(&.ignore_classes = false)
|
||||||
.tap(&.ignore_modules = false)
|
.tap(&.ignore_modules = false)
|
||||||
|
.tap(&.ignore_enums = false)
|
||||||
.tap(&.ignore_defs = false)
|
.tap(&.ignore_defs = false)
|
||||||
|
.tap(&.ignore_macros = false)
|
||||||
|
|
||||||
describe Documentation do
|
describe Documentation do
|
||||||
it "passes for undocumented private types" do
|
it "passes for undocumented private types" do
|
||||||
expect_no_issues subject, <<-CRYSTAL
|
expect_no_issues subject, <<-CRYSTAL
|
||||||
private class Foo
|
private class Foo
|
||||||
|
def foo
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private module Bar
|
private module Bar
|
||||||
|
def bar
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private enum Baz
|
private enum Baz
|
||||||
|
@ -30,10 +36,16 @@ module Ameba::Rule::Lint
|
||||||
expect_no_issues subject, <<-CRYSTAL
|
expect_no_issues subject, <<-CRYSTAL
|
||||||
# Foo
|
# Foo
|
||||||
class Foo
|
class Foo
|
||||||
|
# foo
|
||||||
|
def foo
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Bar
|
# Bar
|
||||||
module Bar
|
module Bar
|
||||||
|
# bar
|
||||||
|
def bar
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Baz
|
# Baz
|
||||||
|
|
|
@ -10,9 +10,10 @@ module Ameba::Rule::Lint
|
||||||
# ```
|
# ```
|
||||||
class Documentation < Base
|
class Documentation < Base
|
||||||
properties do
|
properties do
|
||||||
|
enabled false
|
||||||
description "Enforces public types to be documented"
|
description "Enforces public types to be documented"
|
||||||
|
|
||||||
ignore_classes true
|
ignore_classes false
|
||||||
ignore_modules true
|
ignore_modules true
|
||||||
ignore_enums false
|
ignore_enums false
|
||||||
ignore_defs true
|
ignore_defs true
|
||||||
|
@ -21,7 +22,7 @@ module Ameba::Rule::Lint
|
||||||
|
|
||||||
MSG = "Missing documentation"
|
MSG = "Missing documentation"
|
||||||
|
|
||||||
HOOK_NAMES = %w[
|
MACRO_HOOK_NAMES = %w[
|
||||||
inherited
|
inherited
|
||||||
included extended
|
included extended
|
||||||
method_missing method_added
|
method_missing method_added
|
||||||
|
@ -29,64 +30,37 @@ module Ameba::Rule::Lint
|
||||||
]
|
]
|
||||||
|
|
||||||
def test(source)
|
def test(source)
|
||||||
DocumentationVisitor.new self, source
|
AST::ScopeVisitor.new self, source
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::ClassDef)
|
def test(source, node : Crystal::ClassDef, scope : AST::Scope)
|
||||||
ignore_classes? || check_missing_doc(source, node)
|
ignore_classes? || check_missing_doc(source, node, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::ModuleDef)
|
def test(source, node : Crystal::ModuleDef, scope : AST::Scope)
|
||||||
ignore_modules? || check_missing_doc(source, node)
|
ignore_modules? || check_missing_doc(source, node, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::EnumDef)
|
def test(source, node : Crystal::EnumDef, scope : AST::Scope)
|
||||||
ignore_enums? || check_missing_doc(source, node)
|
ignore_enums? || check_missing_doc(source, node, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::Def)
|
def test(source, node : Crystal::Def, scope : AST::Scope)
|
||||||
ignore_defs? || check_missing_doc(source, node)
|
ignore_defs? || check_missing_doc(source, node, scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test(source, node : Crystal::Macro)
|
def test(source, node : Crystal::Macro, scope : AST::Scope)
|
||||||
return if node.name.in?(HOOK_NAMES)
|
node.name.in?(MACRO_HOOK_NAMES) ||
|
||||||
|
ignore_macros? || check_missing_doc(source, node, scope)
|
||||||
ignore_macros? || check_missing_doc(source, node)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private def check_missing_doc(source, node)
|
private def check_missing_doc(source, node, scope)
|
||||||
return unless node.visibility.public?
|
visibility = scope.visibility
|
||||||
|
|
||||||
|
return if visibility && !visibility.public?
|
||||||
return if node.doc.presence
|
return if node.doc.presence
|
||||||
|
|
||||||
issue_for(node, MSG)
|
issue_for(node, MSG)
|
||||||
end
|
end
|
||||||
|
|
||||||
# :nodoc:
|
|
||||||
private class DocumentationVisitor < AST::BaseVisitor
|
|
||||||
NODES = {
|
|
||||||
ClassDef,
|
|
||||||
ModuleDef,
|
|
||||||
EnumDef,
|
|
||||||
Def,
|
|
||||||
Macro,
|
|
||||||
}
|
|
||||||
|
|
||||||
@visibility : Crystal::Visibility = :public
|
|
||||||
|
|
||||||
def visit(node : Crystal::VisibilityModifier)
|
|
||||||
@visibility = node.modifier
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
{% for name in NODES %}
|
|
||||||
def visit(node : Crystal::{{ name }})
|
|
||||||
node.visibility = @visibility
|
|
||||||
@visibility = :public
|
|
||||||
|
|
||||||
@rule.test @source, node
|
|
||||||
true
|
|
||||||
end
|
|
||||||
{% end %}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue