Skip to content

Commit

Permalink
Merge pull request #557 from crystal-ameba/add-nodoc-methods-exclude-…
Browse files Browse the repository at this point in the history
…option
  • Loading branch information
Sija authored Jan 31, 2025
2 parents c973211 + 126fb0f commit e8d0424
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 6 deletions.
33 changes: 33 additions & 0 deletions spec/ameba/ast/util_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,39 @@ module Ameba::AST
end
end

describe "#nodoc?" do
it "returns true if a node has a single `:nodoc:` annotation" do
node = as_node <<-CRYSTAL, wants_doc: true
# :nodoc:
def foo; end
CRYSTAL

subject.nodoc?(node).should be_true
end

it "returns true if a node has a `:nodoc:` annotation in the first line" do
node = as_node <<-CRYSTAL, wants_doc: true
# :nodoc:
#
# foo
def foo; end
CRYSTAL

subject.nodoc?(node).should be_true
end

it "returns false if a node has a `:nodoc:` annotation in the middle" do
node = as_node <<-CRYSTAL, wants_doc: true
# foo
# :nodoc:
# bar
def foo; end
CRYSTAL

subject.nodoc?(node).should be_false
end
end

describe "#control_exp_code" do
it "returns the exp code of a control expression" do
s = "return 1"
Expand Down
21 changes: 21 additions & 0 deletions spec/ameba/rule/typing/method_parameter_type_restriction_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ module Ameba::Rule::Typing
CRYSTAL
end

it "passes if a method has a `:nodoc:` annotation" do
expect_no_issues subject, <<-CRYSTAL
# :nodoc:
def foo(bar); end
CRYSTAL
end

it "fails if a public method parameter doesn't have a type restriction" do
expect_issue subject, <<-CRYSTAL
def hello(a)
Expand Down Expand Up @@ -195,6 +202,20 @@ module Ameba::Rule::Typing
CRYSTAL
end
end

context "#nodoc_methods" do
rule = MethodParameterTypeRestriction.new
rule.nodoc_methods = true

it "fails if a public method parameter doesn't have a type restriction" do
expect_issue rule, <<-CRYSTAL
# :nodoc:
def foo(bar)
# ^ error: Method parameter should have a type restriction
end
CRYSTAL
end
end
end
end
end
21 changes: 21 additions & 0 deletions spec/ameba/rule/typing/method_return_type_restriction_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ module Ameba::Rule::Typing
CRYSTAL
end

it "passes if a method has a `:nodoc:` annotation" do
expect_no_issues subject, <<-CRYSTAL
# :nodoc:
def foo; end
CRYSTAL
end

it "fails if a public method doesn't have a return type restriction" do
expect_issue subject, <<-CRYSTAL
def hello
Expand Down Expand Up @@ -119,6 +126,20 @@ module Ameba::Rule::Typing
CRYSTAL
end
end

context "#nodoc_methods" do
rule = MethodReturnTypeRestriction.new
rule.nodoc_methods = true

it "fails if a public method doesn't have a return type restriction" do
expect_issue rule, <<-CRYSTAL
# :nodoc:
def foo
# ^^^^^ error: Method should have a return type restriction
end
CRYSTAL
end
end
end
end
end
10 changes: 6 additions & 4 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,14 @@ def with_presenter(klass, *args, deansify = true, **kwargs, &)
yield presenter, output
end

def as_node(source)
Crystal::Parser.new(source).parse
def as_node(source, *, wants_doc = false)
Crystal::Parser.new(source)
.tap(&.wants_doc = wants_doc)
.parse
end

def as_nodes(source)
Ameba::TestNodeVisitor.new(as_node source)
def as_nodes(source, *, wants_doc = false)
Ameba::TestNodeVisitor.new(as_node(source, wants_doc: wants_doc))
end

def trailing_whitespace
Expand Down
8 changes: 8 additions & 0 deletions src/ameba/ast/util.cr
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ module Ameba::AST::Util
end
end

# Returns `true` if node has a `:nodoc:` annotation as the first line.
def nodoc?(node)
return false unless node.responds_to?(:doc)
return false unless doc = node.doc.presence

doc.lines.first?.try(&.strip) == ":nodoc:"
end

# Returns the exp code of a control expression.
# Wraps implicit tuple literal with curly brackets (e.g. multi-return).
def control_exp_code(node : Crystal::ControlExpression, code_lines)
Expand Down
10 changes: 9 additions & 1 deletion src/ameba/rule/typing/method_parameter_type_restriction.cr
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ module Ameba::Rule::Typing
# When the config options `PrivateMethods` and `ProtectedMethods`
# are true, this rule is also applied to private and protected methods, respectively.
#
# The `NodocMethods` configuration option controls whether this rule applies to
# methods with a `:nodoc:` directive.
#
# The `BlockParameters` configuration option will extend this to block parameters, where these are invalid:
#
# ```
Expand Down Expand Up @@ -49,8 +52,11 @@ module Ameba::Rule::Typing
# BlockParameters: false
# PrivateMethods: false
# ProtectedMethods: false
# NodocMethods: false
# ```
class MethodParameterTypeRestriction < Base
include AST::Util

properties do
since_version "1.7.0"
description "Recommends that method parameters have type restrictions"
Expand All @@ -59,6 +65,7 @@ module Ameba::Rule::Typing
block_parameters false
private_methods false
protected_methods false
nodoc_methods false
end

MSG = "Method parameter should have a type restriction"
Expand All @@ -80,7 +87,8 @@ module Ameba::Rule::Typing

private def valid_visibility?(node : Crystal::ASTNode) : Bool
(!private_methods? && node.visibility.private?) ||
(!protected_methods? && node.visibility.protected?)
(!protected_methods? && node.visibility.protected?) ||
(!nodoc_methods? && nodoc?(node))
end
end
end
10 changes: 9 additions & 1 deletion src/ameba/rule/typing/method_return_type_restriction.cr
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,28 @@ module Ameba::Rule::Typing
# When the config options `PrivateMethods` and `ProtectedMethods`
# are true, this rule is also applied to private and protected methods, respectively.
#
# The `NodocMethods` configuration option controls whether this rule applies to
# methods with a `:nodoc:` directive.
#
# YAML configuration example:
#
# ```
# Typing/MethodReturnTypeRestriction:
# Enabled: true
# PrivateMethods: false
# ProtectedMethods: false
# NodocMethods: false
# ```
class MethodReturnTypeRestriction < Base
include AST::Util

properties do
since_version "1.7.0"
description "Recommends that methods have a return type restriction"
enabled false
private_methods false
protected_methods false
nodoc_methods false
end

MSG = "Method should have a return type restriction"
Expand All @@ -46,7 +53,8 @@ module Ameba::Rule::Typing
private def valid_return_type?(node : Crystal::ASTNode) : Bool
!!node.return_type ||
(node.visibility.private? && !private_methods?) ||
(node.visibility.protected? && !protected_methods?)
(node.visibility.protected? && !protected_methods?) ||
(!nodoc_methods? && nodoc?(node))
end
end
end

0 comments on commit e8d0424

Please sign in to comment.