Skip to content

Commit

Permalink
Merge pull request rubocop#1687 from lumeet/nodoc
Browse files Browse the repository at this point in the history
[Fix rubocop#1602] Add :nodoc:-support to Documentation
  • Loading branch information
bbatsov committed Mar 3, 2015
2 parents 44296bb + 8e5fbdb commit a75f55d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* [#1621](https://github.com/bbatsov/rubocop/issues/1621): `TrailingComma` has a new style `consistent_comma`. ([@tamird][])
* [#1611](https://github.com/bbatsov/rubocop/issues/1611): Add `empty`, `nil`, and `both` `SupportedStyles` to `EmptyElse` cop. Default is `both`. ([@rrosenblum][])
* [#1611](https://github.com/bbatsov/rubocop/issues/1611): Add new `MissingElse` cop. Default is to have this cop be disabled. ([@rrosenblum][])
* [#1602](https://github.com/bbatsov/rubocop/issues/1602): Add support for `# :nodoc` in `Documentation`. ([@lumeet][])

### Bugs fixed

Expand Down
25 changes: 25 additions & 0 deletions lib/rubocop/cop/style/documentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module Style
# classes and modules. Classes with no body are exempt from the
# check and so are namespace modules - modules that have nothing in
# their bodies except classes or other other modules.
#
# The documentation requirement is annulled if the class or module has
# a "#:nodoc:" comment next to it. Likewise, "#:nodoc: all" does the
# same for all its children.
class Documentation < Cop
include AnnotationComment

Expand Down Expand Up @@ -38,6 +42,7 @@ def check(ast, ast_with_comments)
next if node.type == :class && !body
next if namespace?(body)
next if associated_comment?(node, ast_with_comments)
next if nodoc?(node, ast_with_comments)
add_offense(node, :keyword, format(MSG, node.type.to_s))
end
end
Expand Down Expand Up @@ -70,6 +75,26 @@ def associated_comment?(node, ast_with_comments)
# annotation, it's OK.
ast_with_comments[node].any? { |comment| !annotation?(comment) }
end

# The :nodoc: comment is not actually associated with the class/module
# ifself but its first commentable child node. Unless the element is
# tagged with :nodoc:, the search proceeds to check its ancestors for
# :nodoc: all.
def nodoc?(node, ast_with_comments, require_all = false)
return false unless node
nodoc_node = node.children.last
return false unless nodoc_node

nodoc_node = nodoc_node.children.first while nodoc_node.type == :begin
comment = ast_with_comments[nodoc_node].first

if comment && comment.loc.line == node.loc.line
regex = /^#\s*:nodoc:#{"\s+all\s*$" if require_all}/
return true if comment.text =~ regex
end

nodoc?(node.ancestors.first, ast_with_comments, true)
end
end
end
end
Expand Down
41 changes: 41 additions & 0 deletions spec/rubocop/cop/style/documentation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,45 @@
])
end.to_not raise_error
end

context 'with # :nodoc:' do
%w(class module).each do |keyword|
it "accepts non-namespace #{keyword} without documentation" do
inspect_source(cop,
["#{keyword} Test #:nodoc:",
' TEST = 20',
'end'
])
expect(cop.offenses).to be_empty
end

it "registers an offence for nested #{keyword} without documentation" do
inspect_source(cop,
['module TestModule #:nodoc:',
' TEST = 20',
" #{keyword} Test",
' TEST = 20',
' end',
'end'
])
expect(cop.offenses.size).to eq(1)
end

context 'with `all` modifier' do
it "accepts nested #{keyword} without documentation" do
inspect_source(cop,
['module A #:nodoc: all',
' module B',
' TEST = 20',
" #{keyword} Test",
' TEST = 20',
' end',
' end',
'end'
])
expect(cop.offenses).to be_empty
end
end
end
end
end

0 comments on commit a75f55d

Please sign in to comment.