rubocop-yard 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5f138fd3b5b0c5eb5550b368164986ba104280ebb40af21d7b8fe843105dad3
4
- data.tar.gz: 2a237052e98046b9ac7ffcd72100fd1d96ad90164d8075e8f997981c73a78f98
3
+ metadata.gz: 14068a711ba5d5d78e4781fcf5c19c0be34a5e606fad28768ea3570f0a9c044d
4
+ data.tar.gz: c2e62e57a7f060c86976d12aa4f123354e69b4a81d36ac5e6f549b9e3aa63fef
5
5
  SHA512:
6
- metadata.gz: fe3818daae4c2d4597a86ad8f1e1e6785a56e5c34e5e96b0b78be0b52b7cb219ce4d9f390ebac30af9ec844d5f2add8f4c7dfa7d5d4e6496543a0ab6a880980d
7
- data.tar.gz: fd20c16153f50987d92fe2c5a6af00ecf1fd274d29205d57e63c8c176a314555de9f9e926ae1bad5b7c5b18bf3d1e7adcca26e8ead35b0f8eacc55744fb4cabb
6
+ metadata.gz: f82cc0691592cd838775d632d2f13631a1c92182afca6442ec9876dad092bea401118272ce4e1031b286466d634583f027256250bab5a6f3dfa3da2ad8eb88ce
7
+ data.tar.gz: 2a2b413001d70d1450e2ed6c9b07607f1ed82e7bf2790d1e906a272d5c940fb4434117ee75a64a5f7ff70f439c2d0d2b4b5bcd8082588569b1699d353db64d38
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.7.0] - 2023-10-14
4
+
5
+ - New feature
6
+ - `YARD/MismatchName`: Check undocumented argument.
7
+
3
8
  ## [0.6.0] - 2023-10-10
4
9
 
5
10
  - Split cop from `YARD/TagType` to
data/README.md CHANGED
@@ -86,6 +86,14 @@ Check `@param` and `@option` name with method definition.
86
86
  def foo(strings, opts = {})
87
87
  ```
88
88
 
89
+ Check undocumented argument.
90
+
91
+ ```
92
+ # @param [String] strings
93
+ ^^^^^^^^^^^^^^^^^^^^^^^^^ This method has argument `opts`, But not documented
94
+ def foo(strings, opts = {})
95
+ ```
96
+
89
97
  ### `YARD/MeaninglessTag`
90
98
 
91
99
  Check `@param` and `@option` with class/module or casgn
data/config/default.yml CHANGED
@@ -30,3 +30,8 @@ YARD/MismatchName:
30
30
  Description: 'Check @param and @option name and method parameters'
31
31
  Enabled: true
32
32
  VersionAdded: '0.3.0'
33
+ EnforcedStylePrototypeName: after
34
+ SupportedStylesPrototypeName:
35
+ - before
36
+ - after
37
+
@@ -20,6 +20,7 @@ module RuboCop
20
20
  include YARD::Helper
21
21
  include RangeHelp
22
22
  include DocumentationComment
23
+ extend AutoCorrector
23
24
 
24
25
  def on_def(node)
25
26
  return unless node.arguments?
@@ -28,7 +29,12 @@ module RuboCop
28
29
  return false unless preceding_comment?(node, preceding_lines.last)
29
30
 
30
31
  yard_docstring = preceding_lines.map { |line| line.text.gsub(/\A#\s*/, '') }.join("\n")
31
- docstring = ::YARD::DocstringParser.new.parse(yard_docstring)
32
+ docstring = begin
33
+ ::YARD::DocstringParser.new.parse(yard_docstring)
34
+ rescue
35
+ return false
36
+ end
37
+
32
38
  return false if include_overload_tag?(docstring)
33
39
 
34
40
  each_tags_by_docstring(['param', 'option'], docstring) do |tags|
@@ -56,9 +62,35 @@ module RuboCop
56
62
  parse_type(types.join(', '))
57
63
  rescue SyntaxError
58
64
  next
59
- end
65
+ end if types
66
+
67
+ add_offense_to_tag(node, comment, tag)
68
+ end
69
+ end
60
70
 
61
- add_offense_to_tag(comment, tag)
71
+ # Documentation only or just `@return` is a common form of documentation.
72
+ # The subsequent features will be limited to cases where both `@param` and `@option` are present.
73
+ unless docstring.tags.find { |tag| (tag.tag_name == 'param' && !tag.instance_of?(::YARD::Tags::RefTagList)) || tag.tag_name == 'option' }
74
+ return false
75
+ end
76
+ node.arguments.each do |argument|
77
+ next if argument.type == :blockarg
78
+ next if argument.name.nil?
79
+
80
+ found = docstring.tags.find do |tag|
81
+ next unless tag.tag_name == 'param' || tag.tag_name == 'option'
82
+ tag.name&.to_sym == argument.name
83
+ end
84
+
85
+ unless found
86
+ comment = preceding_lines.last
87
+ return if part_of_ignored_node?(comment)
88
+ add_offense(comment, message: "This method has argument `#{argument.name}`, But not documented") do |corrector|
89
+ corrector.replace(
90
+ comment.source_range.end,
91
+ "#{comment.source_range.end.join(node.source_range.begin).source}# #{tag_prototype(argument)}"
92
+ )
93
+ end
62
94
  end
63
95
  end
64
96
  end
@@ -66,6 +98,41 @@ module RuboCop
66
98
 
67
99
  private
68
100
 
101
+ # @param [RuboCop::AST::ArgNode] argument
102
+ def tag_prototype(argument)
103
+ case argument.type
104
+ when :kwrestarg
105
+ case cop_config_prototype_name
106
+ when "before"
107
+ "@param #{argument.name} [Hash{Symbol => Object}]"
108
+ when "after"
109
+ "@param [Hash{Symbol => Object}] #{argument.name}"
110
+ end
111
+ when :restarg
112
+ case cop_config_prototype_name
113
+ when "before"
114
+ "@param #{argument.name} [Array<Object>]"
115
+ when "after"
116
+ "@param [Array<Object>] #{argument.name}"
117
+ end
118
+ else
119
+ case cop_config_prototype_name
120
+ when "before"
121
+ "@param #{argument.name} [Object]"
122
+ when "after"
123
+ "@param [Object] #{argument.name}"
124
+ end
125
+ end
126
+ end
127
+
128
+ def cop_config_prototype_name
129
+ @cop_config_prototype_name ||= cop_config["EnforcedStylePrototypeName"].tap do |c|
130
+ unless cop_config["SupportedStylesPrototypeName"].include?(c)
131
+ raise "unsupported style #{c}"
132
+ end
133
+ end
134
+ end
135
+
69
136
  def each_tags_by_docstring(tag_names, docstring)
70
137
  tag_names.each do |tag_name|
71
138
  yield docstring.tags.select { |tag| tag.tag_name == tag_name }
@@ -80,13 +147,21 @@ module RuboCop
80
147
  end
81
148
  end
82
149
 
83
- def add_offense_to_tag(comment, tag)
150
+ def add_offense_to_tag(node, comment, tag)
84
151
  tag_name_regexp = Regexp.new("\\b#{Regexp.escape(tag.name)}\\b")
85
152
  start_column = comment.source.index(tag_name_regexp)
86
153
  offense_start = comment.location.column + start_column
87
154
  offense_end = offense_start + tag.name.length - 1
88
155
  range = source_range(processed_source.buffer, comment.location.line, offense_start..offense_end)
89
- add_offense(range, message: "`#{tag.name}` is not found in method arguments")
156
+ argument_names = node.arguments.map(&:name).compact
157
+ argument_name =
158
+ if argument_names.empty?
159
+ ''
160
+ else
161
+ " of [#{argument_names.join(', ')}]"
162
+ end
163
+ add_offense(range, message: "`#{tag.name}` is not found in method arguments#{argument_name}")
164
+ ignore_node(comment)
90
165
  end
91
166
 
92
167
  def include_overload_tag?(docstring)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module YARD
5
- VERSION = "0.6.0"
5
+ VERSION = "0.8.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-yard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ksss
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-10 00:00:00.000000000 Z
11
+ date: 2023-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop