rubocop-yard 0.2.0 → 0.3.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: 77c23358faa88b10e005e0f455dcf16283fe9fbf64c92276e5bff6bb201de43a
4
- data.tar.gz: a1fb8bfe577565d31294920356f176fd9bc71b856ee7db0a11031347473602c5
3
+ metadata.gz: b41b5e256726136d4cd8bfc96fabd2ab0fbc37e69a84c9f29a76456f464cf519
4
+ data.tar.gz: 678da6e808f7b844e4bd94ab061dbf8176c1aba9c3b279a211bf040f7cba907b
5
5
  SHA512:
6
- metadata.gz: 478b94fe6b6bd5f310fc5774554888a5aa0f99245cc8a13ff8f5225668e5486213eeec4f7621f84b3a4790a9989a9b03a0ebc47c848fda1e757194353d3d1049
7
- data.tar.gz: debd8aa21c9d08430fd666a239e6e6114fd1dc091053f76254def0f62d37b9d1698c291c3d91ac716fc80682b07593512bd512ecd143327d3995573dacf603fb
6
+ metadata.gz: c14be7ae06b265ef9396bd3b2c494db30e7165cdcebd74884633053ca24a2007e367dc44bc7e8a17deec4a4c62f83eeabd3ae55bd9065ccc3b89633cf4052aee
7
+ data.tar.gz: f4fd229b29630192b24036fb59bc145704904a2f9142c26738a71815212fa1bf60a725a7c5b984c63a75c05ac75e31d8a6d55b238cdefce1384a4f69d449c315
data/CHANGELOG.md CHANGED
@@ -1,12 +1,17 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2023-09-16
4
+
5
+ - Add `YARD/MismatchName`
6
+ - Check `@param` and `@option` name with method definition
7
+
3
8
  ## [0.2.0] - 2023-09-14
4
9
 
5
- - `YARD/TagTypeSyntax`
10
+ - `YARD/TagType`
6
11
  - Check collection tag type syntax
7
12
 
8
13
  ## [0.1.0] - 2023-09-13
9
14
 
10
- - Add new `YARD/TagTypeSyntax` cop
15
+ - Add new `YARD/TagType` cop
11
16
 
12
17
  - Initial release
data/README.md CHANGED
@@ -6,18 +6,30 @@ You can check YARD format in Ruby code comment by RuboCop.
6
6
 
7
7
  ## Features
8
8
 
9
- ### `YARD/TagTypeSyntax`
9
+ ### `YARD/TagType`
10
10
 
11
11
  Check tag type syntax error.
12
12
 
13
13
  ```
14
- @param [Symbol|String]
15
- ^^^^^^^^^^^^^ SyntaxError as YARD tag type
14
+ # @param [Symbol|String]
15
+ # ^^^^^^^^^^^^^ SyntaxError as YARD tag type
16
16
  ```
17
17
 
18
18
  ```
19
- @param [Hash<Symbol, String>]
20
- ^^^^^^^^^^^^^^^^^^^^ <Type> is the collection type syntax. Did you mean {KeyType => ValueType} or Hash{KeyType => ValueType}
19
+ # @param [Hash<Symbol, String>]
20
+ # ^^^^^^^^^^^^^^^^^^^^ `<Type>` is the collection type syntax. Did you mean `{KeyType => ValueType}` or `Hash{KeyType => ValueType}`
21
+ ```
22
+
23
+ ### `YARD/MismatchName`
24
+
25
+ Check `@param` and `@option` name with method definition.
26
+
27
+ ```rb
28
+ # @param [String] string
29
+ # ^^^^^^ `string` is not found in method arguments
30
+ # @option opt bar [String]
31
+ # ^^^ `opt` is not found in method arguments
32
+ def foo(strings, opts = {})
21
33
  ```
22
34
 
23
35
  ## Installation
data/config/default.yml CHANGED
@@ -1,4 +1,9 @@
1
- YARD/TagTypeSyntax:
1
+ YARD/TagType:
2
2
  Description: 'Check syntax for yard tag type'
3
3
  Enabled: true
4
- VersionAdded: '0.1.0'
4
+ VersionAdded: '0.2.0'
5
+
6
+ YARD/MismatchName
7
+ Description: 'Check @param and @option name and method parameters'
8
+ Enabled: true
9
+ VersionAdded: '0.3.0'
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module YARD
6
+ # @example
7
+ # # bad
8
+ # # @param [void] baz
9
+ # # @option opt aaa [void]
10
+ # def foo(bar, opts = {})
11
+ # end
12
+ #
13
+ # # good
14
+ # # @param [void] bar
15
+ # # @param [Array] argsa
16
+ # # @option opts aaa [void]
17
+ # def foo(bar, opts = {}, *arg)
18
+ # end
19
+ class MismatchName < Base
20
+ include RangeHelp
21
+ include DocumentationComment
22
+
23
+ def on_def(node)
24
+ return unless node.arguments?
25
+
26
+ preceding_lines = preceding_lines(node)
27
+ return false unless preceding_comment?(node, preceding_lines.last)
28
+
29
+ yard_docstring = preceding_lines.map { |line| line.text.gsub(/\A#\s*/, '') }.join("\n")
30
+ docstring = ::YARD::DocstringParser.new.parse(yard_docstring)
31
+ docstring.tags.each do |tag|
32
+ next unless tag.tag_name == 'param' || tag.tag_name == 'option'
33
+ next unless node.arguments.none? { |arg_node| tag.name.to_sym == arg_node.name }
34
+
35
+ tag_name_regexp = Regexp.new("\\b#{Regexp.escape(tag.name)}\\b")
36
+ comment = preceding_lines.find { |line| line.text.match?(tag_name_regexp) && line.text.include?("@#{tag.tag_name}") }
37
+ next unless comment
38
+
39
+ start_column = comment.source.index(tag_name_regexp)
40
+ offense_start = comment.location.column + start_column
41
+ offense_end = offense_start + tag.name.length - 1
42
+ range = source_range(processed_source.buffer, comment.location.line, offense_start..offense_end)
43
+ add_offense(range, message: "`#{tag.name}` is not found in method arguments")
44
+ end
45
+ end
46
+ alias on_defs on_def
47
+ end
48
+
49
+ private
50
+
51
+ # @param [void] aaa
52
+ # @option opts bbb [void]
53
+ def dummy(aaa, opts = {}, *)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -22,6 +22,8 @@ module RuboCop
22
22
  # # good
23
23
  # @param [<String>]
24
24
  # @param [Array<String>]
25
+ # @param [List<String>]
26
+ # @param [Array<(String, Fixnum, Hash)>]
25
27
  #
26
28
  # # good
27
29
  # @param [(String)]
@@ -30,7 +32,7 @@ module RuboCop
30
32
  # # good
31
33
  # @param [{KeyType => ValueType}]
32
34
  # @param [Hash{KeyType => ValueType}]
33
- class TagTypeSyntax < Base
35
+ class TagType < Base
34
36
  MSG = ''
35
37
  include RangeHelp # @return [void,]
36
38
 
@@ -48,6 +50,8 @@ module RuboCop
48
50
  def check(comment)
49
51
  docstring = comment.text.gsub(/\A#\s*/, '')
50
52
  ::YARD::DocstringParser.new.parse(docstring).tags.each do |tag|
53
+ next unless tag.types
54
+
51
55
  ::YARD::Tags::TypesExplainer::Parser.parse(tag.types.join(', ')).each do |types_explainer|
52
56
  check_mismatch_collection_type(comment, types_explainer)
53
57
  end
@@ -63,43 +67,33 @@ module RuboCop
63
67
  types_explainer.key_types.each { |t| check_mismatch_collection_type(comment, t) }
64
68
  types_explainer.value_types.each { |t| check_mismatch_collection_type(comment, t) }
65
69
  else
66
- message = "`{KeyType => ValueType}` is the hash collection type syntax. #{did_you_mean_type(types_explainer.name)}"
70
+ did_you_mean = types_explainer.name == 'Array' ? 'Did you mean `<Type>` or `Array<Type>`' : ''
71
+ message = "`{KeyType => ValueType}` is the hash collection type syntax. #{did_you_mean}"
67
72
  add_offense(tag_range_for_comment(comment), message: message)
68
73
  end
69
74
  when ::YARD::Tags::TypesExplainer::FixedCollectionType
70
- if types_explainer.name == 'Array'
71
- types_explainer.types.each { |t| check_mismatch_collection_type(comment, t) }
72
- else
73
- message = "`(Type)` is the fixed collection type syntax. #{did_you_mean_type(types_explainer.name)}"
75
+ if types_explainer.name == 'Hash'
76
+ message = "`(Type)` is the fixed collection type syntax. Did you mean `{KeyType => ValueType}` or `Hash{KeyType => ValueType}`"
74
77
  add_offense(tag_range_for_comment(comment), message: message)
78
+ else
79
+ types_explainer.types.each { |t| check_mismatch_collection_type(comment, t) }
75
80
  end
76
81
  when ::YARD::Tags::TypesExplainer::CollectionType
77
- if types_explainer.name == 'Array'
78
- types_explainer.types.each { |t| check_mismatch_collection_type(comment, t) }
79
- else
80
- message = "`<Type>` is the collection type syntax. #{did_you_mean_type(types_explainer.name)}"
82
+ if types_explainer.name == 'Hash'
83
+ message = "`<Type>` is the collection type syntax. `{KeyType => ValueType}` or `Hash{KeyType => ValueType}` is more good"
81
84
  add_offense(tag_range_for_comment(comment), message: message)
85
+ else
86
+ types_explainer.types.each { |t| check_mismatch_collection_type(comment, t) }
82
87
  end
83
88
  end
84
89
  end
85
90
 
86
- def did_you_mean_type(name)
87
- case name
88
- when 'Hash'
89
- 'Did you mean `{KeyType => ValueType}` or `Hash{KeyType => ValueType}`'
90
- when 'Array'
91
- 'Did you mean `<Type>` or `Array<Type>`'
92
- else
93
- ''
94
- end
95
- end
96
-
97
91
  def inline_comment?(comment)
98
92
  !comment_line?(comment.source_range.source_line)
99
93
  end
100
94
 
101
95
  def include_yard_tag?(comment)
102
- comment.source.match?(/@(?:param|return)\s+\[.*\]/)
96
+ comment.source.match?(/@(?:param|return|option|raise|yieldparam|yieldreturn)\s+\[.*\]/)
103
97
  end
104
98
 
105
99
  def tag_range_for_comment(comment)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yard'
4
- require_relative 'yard/tag_type_syntax'
4
+ require_relative 'yard/tag_type'
5
+ require_relative 'yard/mismatch_name'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module YARD
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
data/sig/rubocop/yard.rbs CHANGED
@@ -5,7 +5,7 @@ module RuboCop
5
5
  end
6
6
  module Cop
7
7
  module YARD
8
- class TagTypeSyntax
8
+ class TagType
9
9
  type t = YARD::Tags::TypesExplainer::Type
10
10
  | ::YARD::Tags::TypesExplainer::CollectionType
11
11
  | ::YARD::Tags::TypesExplainer::FixedCollectionType
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.2.0
4
+ version: 0.3.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-09-14 00:00:00.000000000 Z
11
+ date: 2023-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -51,7 +51,8 @@ files:
51
51
  - README.md
52
52
  - config/default.yml
53
53
  - lib/rubocop-yard.rb
54
- - lib/rubocop/cop/yard/tag_type_syntax.rb
54
+ - lib/rubocop/cop/yard/mismatch_name.rb
55
+ - lib/rubocop/cop/yard/tag_type.rb
55
56
  - lib/rubocop/cop/yard_cops.rb
56
57
  - lib/rubocop/yard.rb
57
58
  - lib/rubocop/yard/inject.rb