rubocop-yard 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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