yard-lint 1.6.0 → 1.6.1

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: ef1425a1be17cac04595b6558a742eb4036fc1cc66891e1d8f31eb46094c8914
4
- data.tar.gz: d5ba0ef812eb0261718d7259d2da0b0f0b2fa37a1674893f6d7d3178be3bf551
3
+ metadata.gz: 0e80922a8d6a086601b78ff5aa7d15a1463a9b772b44c3315d440d35ab8e8e36
4
+ data.tar.gz: ece101a1e691a92a8c524a6e1a7b63e6db623cb7c156680f0b85ca3129861821
5
5
  SHA512:
6
- metadata.gz: 23d60c91521b5afbadd0a43380682686f7b10aa68a968f5091da2de425f477f71ce3b8a6477ca5d0197d7138979dffc4a0aebe2582b3a64cd4092b18b6222c95
7
- data.tar.gz: 966fe65d5e72ba1dbf225fe8802f2259dcdb436a66b2571d6caf7aff7d59491e1b337c7fe4db0e68354bceebb192c89d40ed6c1229b5e2bd2f75d2f5cbde456a
6
+ metadata.gz: cb60b66bee32b4f7abb20d0617e576044c98e2095967d08a4776553c3435f636dcd5ca3788e5ac2b5e3de2de501d9aade4b49e11d3b5173bd5c260a706e95808
7
+ data.tar.gz: 01b284d20fc97cb09c362410e491544732264568e971f40194c498824210e6724bed6c72003ce1569fdc90bedfce93bb3e19e8520877158fd8b41f0eb058c2d2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # YARD-Lint Changelog
2
2
 
3
+ ## 1.6.1 (2026-06-11)
4
+ - **[Fix]** `Documentation/OrphanedDocComment` no longer reports false positives for documented DSL-style method calls (e.g. `ransacker :foo do … end`, `validates :name`, `scope :active, -> { … }`). YARD's DSL handler turns such a call into a documentable method object when the preceding comment carries an implicit-docstring tag (`@return`, `@overload`, `@method`, `@attribute`, `@scope`, `@visibility`), so the comment is attached rather than dropped. The validator now recognises this case: a tagged comment before a DSL call is only flagged when the call is one YARD's handler ignores (`include`, `extend`, `private :sym`, etc.) or the comment lacks an implicit-docstring tag (in which case YARD really does drop it). Also fixes a pre-existing false positive for the bare `attr :name` attribute form.
5
+
3
6
  ## 1.6.0 (2026-06-11)
4
7
  - **[Feature]** New `--format quickfix` output mode emits one offense per line in the standard `file:line: S: Validator: message` format. Vim users can set `makeprg=yard-lint\ --format\ quickfix\ --no-progress\ %` and navigate offenses with `:cnext`/`:cprev`; Emacs users can use it as their `compile-command` and navigate with `M-g n`/`M-g p`. Produces no output (and exits 0) when there are no offenses.
5
8
  - **[Feature]** New opt-in validator `Documentation/LineLength` detects documentation comment lines that exceed a configurable maximum length (#176). Disabled by default (`Enabled: false`) to avoid breaking existing projects; enable with `Documentation/LineLength: Enabled: true` and tune with `MaxLength: 120` (default). Uses YARD's already-parsed docstring to determine which source lines belong to the comment block, avoiding fragile backwards-scanning. Each over-length line produces a separate offense at its exact file location.
data/README.md CHANGED
@@ -325,6 +325,14 @@ def greet(name); end
325
325
  # Good - constant assignments are documentable, not flagged
326
326
  # @return [Integer] the answer
327
327
  ANSWER = 42
328
+
329
+ # Good - DSL calls (ransacker, validates, scope, ...) are turned into method
330
+ # objects by YARD's DSL handler when the comment carries a tag like @return,
331
+ # so they are documentable and not flagged
332
+ # @return [Arel::Nodes::Node]
333
+ ransacker :owner_name do
334
+ Arel.sql("...")
335
+ end
328
336
  ```
329
337
 
330
338
  This validator is complementary to `Documentation/BlankLineBeforeDefinition` (which handles the case where blank lines separate a doc comment from a `def` - YARD still attaches it despite the gap).
@@ -24,13 +24,37 @@ module Yard
24
24
  # and constant assignments (uppercase-leading identifier followed by =), both of which
25
25
  # YARD tracks and attaches preceding doc comments to.
26
26
  # Also matches define_method which YARD handles via a built-in dynamic handler.
27
+ # `attr\b` is matched after the `attr_*` variants so the bare `attr :name` form
28
+ # (handled by YARD's attribute handler) is recognised without swallowing them.
27
29
  DEFINITION_PATTERN = /
28
30
  \A\s*(private\s+|protected\s+|public\s+)?
29
- (def |class |module |attr_reader|attr_writer|attr_accessor|attr_internal|alias_method\b|alias\b|define_method\b)
31
+ (def |class |module |attr_reader|attr_writer|attr_accessor|attr_internal|attr\b|alias_method\b|alias\b|define_method\b)
30
32
  |
31
33
  \A\s*[A-Z][A-Za-z0-9_:]*\s*=
32
34
  /x.freeze
33
35
 
36
+ # Matches a DSL-style method call whose first argument is a symbol or string literal
37
+ # (e.g. `ransacker :foo do`, `validates(:name, ...)`, `scope :active, -> { ... }`).
38
+ # YARD's DSL handler turns such a call into a documentable method object when the
39
+ # preceding comment carries an implicit-docstring tag, so a doc comment in front of
40
+ # one of these is NOT orphaned.
41
+ DSL_CALL_PATTERN = /\A\s*(?<method>[a-z_]\w*[!?]?)(?:\s+|\s*\(\s*)(?::\w|:["']|["'])/.freeze
42
+ # Mirror of YARD::Handlers::Ruby::DSLHandlerMethods::IGNORE_METHODS - calls to these
43
+ # are skipped by YARD's DSL handler, so a preceding doc comment really is dropped.
44
+ # (The `attr*`/`alias*` entries are already covered by DEFINITION_PATTERN.)
45
+ DSL_IGNORE_METHODS = %w[
46
+ alias alias_method autoload attr attr_accessor attr_reader attr_writer
47
+ extend include module_function public private protected private_constant
48
+ private_class_method public_class_method
49
+ ].freeze
50
+ # YARD's DSL handler only creates a method object when the comment carries one of these
51
+ # tags (see DSLHandlerMethods#implicit_docstring?). Matched on raw comment lines because
52
+ # some (`@method`, `@attribute`, `@scope`, `@visibility`) are not in YARD's tag registry
53
+ # and would otherwise be missed by YARD_TAG_PATTERN. Directive (`@!`) forms are excluded
54
+ # here because directive blocks are already skipped upstream.
55
+ IMPLICIT_DOCSTRING_TAG_PATTERN =
56
+ /\A\s*#\s*@(?:method|attribute|overload|visibility|scope|return)\b/.freeze
57
+
34
58
  # @param object [YARD::CodeObjects::Base] the code object to query
35
59
  # @param collector [Executor::ResultCollector] collector for output
36
60
  # @return [void]
@@ -59,8 +83,10 @@ module Yard
59
83
  tags = []
60
84
 
61
85
  has_directive = false
86
+ has_implicit_tag = false
62
87
  while i < lines.length && comment_line?(lines[i])
63
88
  has_directive = true if directive_line?(lines[i])
89
+ has_implicit_tag = true if implicit_docstring_tag?(lines[i])
64
90
  tag = extract_yard_tag(lines[i])
65
91
  tags << tag if tag
66
92
  i += 1
@@ -73,7 +99,7 @@ module Yard
73
99
  # Skip trailing blank lines after the comment block
74
100
  i += 1 while i < lines.length && lines[i].strip.empty?
75
101
 
76
- if i >= lines.length || !definition_line?(lines[i])
102
+ unless documentable?(lines[i], has_implicit_tag)
77
103
  collector.puts "#{file}:#{block_start + 1}: #{tags.uniq.join(',')}"
78
104
  end
79
105
  else
@@ -108,11 +134,37 @@ module Yard
108
134
  "@#{match[1]}" if match
109
135
  end
110
136
 
137
+ # @param line [String, nil] the source line following the comment block, or nil at EOF
138
+ # @param has_implicit_tag [Boolean] whether the comment block carries a tag that makes
139
+ # YARD's DSL handler emit a method object (see IMPLICIT_DOCSTRING_TAG_PATTERN)
140
+ # @return [Boolean] true if YARD will attach the comment to a documentable construct
141
+ def documentable?(line, has_implicit_tag)
142
+ return false if line.nil?
143
+
144
+ definition_line?(line) || (has_implicit_tag && dsl_method_line?(line))
145
+ end
146
+
111
147
  # @param line [String] a raw source line
112
148
  # @return [Boolean] true if the line starts a YARD-documentable definition
113
149
  def definition_line?(line)
114
150
  line.match?(DEFINITION_PATTERN)
115
151
  end
152
+
153
+ # @param line [String] a raw source line
154
+ # @return [Boolean] true if the line is a DSL-style call YARD's handler documents
155
+ # (symbol/string first argument and not one of YARD's ignored methods)
156
+ def dsl_method_line?(line)
157
+ match = line.match(DSL_CALL_PATTERN)
158
+ return false unless match
159
+
160
+ !DSL_IGNORE_METHODS.include?(match[:method])
161
+ end
162
+
163
+ # @param line [String] a raw source line
164
+ # @return [Boolean] true if the comment line carries an implicit-docstring tag
165
+ def implicit_docstring_tag?(line)
166
+ line.match?(IMPLICIT_DOCSTRING_TAG_PATTERN)
167
+ end
116
168
  end
117
169
  end
118
170
  end
@@ -3,6 +3,6 @@
3
3
  module Yard
4
4
  module Lint
5
5
  # @return [String] version of the YARD Lint gem
6
- VERSION = '1.6.0'
6
+ VERSION = '1.6.1'
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yard-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld