yard-lint 1.2.2 → 1.3.0.rc1

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +174 -1
  3. data/README.md +118 -3
  4. data/Rakefile +20 -0
  5. data/bin/yard-lint +80 -37
  6. data/lib/yard/lint/config.rb +5 -0
  7. data/lib/yard/lint/config_generator.rb +8 -179
  8. data/lib/yard/lint/config_updater.rb +222 -0
  9. data/lib/yard/lint/errors.rb +6 -0
  10. data/lib/yard/lint/executor/in_process_registry.rb +130 -0
  11. data/lib/yard/lint/executor/query_executor.rb +109 -0
  12. data/lib/yard/lint/executor/result_collector.rb +55 -0
  13. data/lib/yard/lint/executor/warning_dispatcher.rb +79 -0
  14. data/lib/yard/lint/results/base.rb +2 -1
  15. data/lib/yard/lint/runner.rb +88 -35
  16. data/lib/yard/lint/stats_calculator.rb +1 -1
  17. data/lib/yard/lint/templates/default_config.yml +279 -0
  18. data/lib/yard/lint/templates/strict_config.yml +283 -0
  19. data/lib/yard/lint/validators/base.rb +52 -118
  20. data/lib/yard/lint/validators/documentation/blank_line_before_definition/config.rb +25 -0
  21. data/lib/yard/lint/validators/documentation/blank_line_before_definition/messages_builder.rb +39 -0
  22. data/lib/yard/lint/validators/documentation/blank_line_before_definition/parser.rb +59 -0
  23. data/lib/yard/lint/validators/documentation/blank_line_before_definition/result.rb +61 -0
  24. data/lib/yard/lint/validators/documentation/blank_line_before_definition/validator.rb +94 -0
  25. data/lib/yard/lint/validators/documentation/blank_line_before_definition.rb +63 -0
  26. data/lib/yard/lint/validators/documentation/empty_comment_line/config.rb +24 -0
  27. data/lib/yard/lint/validators/documentation/empty_comment_line/messages_builder.rb +34 -0
  28. data/lib/yard/lint/validators/documentation/empty_comment_line/parser.rb +60 -0
  29. data/lib/yard/lint/validators/documentation/empty_comment_line/result.rb +25 -0
  30. data/lib/yard/lint/validators/documentation/empty_comment_line/validator.rb +109 -0
  31. data/lib/yard/lint/validators/documentation/empty_comment_line.rb +58 -0
  32. data/lib/yard/lint/validators/documentation/markdown_syntax/validator.rb +36 -21
  33. data/lib/yard/lint/validators/documentation/markdown_syntax.rb +0 -1
  34. data/lib/yard/lint/validators/documentation/undocumented_boolean_methods/validator.rb +19 -29
  35. data/lib/yard/lint/validators/documentation/undocumented_boolean_methods.rb +0 -1
  36. data/lib/yard/lint/validators/documentation/undocumented_method_arguments/validator.rb +18 -34
  37. data/lib/yard/lint/validators/documentation/undocumented_method_arguments.rb +0 -1
  38. data/lib/yard/lint/validators/documentation/undocumented_objects/parser.rb +2 -2
  39. data/lib/yard/lint/validators/documentation/undocumented_objects/validator.rb +17 -25
  40. data/lib/yard/lint/validators/documentation/undocumented_objects.rb +4 -5
  41. data/lib/yard/lint/validators/documentation/undocumented_options/validator.rb +30 -21
  42. data/lib/yard/lint/validators/documentation/undocumented_options.rb +0 -1
  43. data/lib/yard/lint/validators/semantic/abstract_methods/result.rb +2 -2
  44. data/lib/yard/lint/validators/semantic/abstract_methods/validator.rb +31 -43
  45. data/lib/yard/lint/validators/semantic/abstract_methods.rb +0 -1
  46. data/lib/yard/lint/validators/tags/api_tags/validator.rb +24 -39
  47. data/lib/yard/lint/validators/tags/api_tags.rb +0 -1
  48. data/lib/yard/lint/validators/tags/collection_type/parser.rb +1 -1
  49. data/lib/yard/lint/validators/tags/collection_type/validator.rb +37 -66
  50. data/lib/yard/lint/validators/tags/collection_type.rb +0 -1
  51. data/lib/yard/lint/validators/tags/example_syntax/validator.rb +51 -64
  52. data/lib/yard/lint/validators/tags/example_syntax.rb +0 -1
  53. data/lib/yard/lint/validators/tags/informal_notation/config.rb +40 -0
  54. data/lib/yard/lint/validators/tags/informal_notation/messages_builder.rb +35 -0
  55. data/lib/yard/lint/validators/tags/informal_notation/parser.rb +55 -0
  56. data/lib/yard/lint/validators/tags/informal_notation/result.rb +26 -0
  57. data/lib/yard/lint/validators/tags/informal_notation/validator.rb +133 -0
  58. data/lib/yard/lint/validators/tags/informal_notation.rb +45 -0
  59. data/lib/yard/lint/validators/tags/invalid_types/validator.rb +57 -70
  60. data/lib/yard/lint/validators/tags/invalid_types.rb +0 -1
  61. data/lib/yard/lint/validators/tags/meaningless_tag/parser.rb +1 -1
  62. data/lib/yard/lint/validators/tags/meaningless_tag/validator.rb +22 -54
  63. data/lib/yard/lint/validators/tags/meaningless_tag.rb +0 -1
  64. data/lib/yard/lint/validators/tags/non_ascii_type/config.rb +21 -0
  65. data/lib/yard/lint/validators/tags/non_ascii_type/messages_builder.rb +29 -0
  66. data/lib/yard/lint/validators/tags/non_ascii_type/parser.rb +59 -0
  67. data/lib/yard/lint/validators/tags/non_ascii_type/result.rb +25 -0
  68. data/lib/yard/lint/validators/tags/non_ascii_type/validator.rb +50 -0
  69. data/lib/yard/lint/validators/tags/non_ascii_type.rb +39 -0
  70. data/lib/yard/lint/validators/tags/option_tags/result.rb +2 -2
  71. data/lib/yard/lint/validators/tags/option_tags/validator.rb +25 -40
  72. data/lib/yard/lint/validators/tags/option_tags.rb +0 -1
  73. data/lib/yard/lint/validators/tags/order/validator.rb +28 -55
  74. data/lib/yard/lint/validators/tags/order.rb +0 -1
  75. data/lib/yard/lint/validators/tags/redundant_param_description/config.rb +15 -1
  76. data/lib/yard/lint/validators/tags/redundant_param_description/messages_builder.rb +5 -0
  77. data/lib/yard/lint/validators/tags/redundant_param_description/validator.rb +134 -100
  78. data/lib/yard/lint/validators/tags/redundant_param_description.rb +0 -1
  79. data/lib/yard/lint/validators/tags/tag_group_separator/config.rb +29 -0
  80. data/lib/yard/lint/validators/tags/tag_group_separator/messages_builder.rb +49 -0
  81. data/lib/yard/lint/validators/tags/tag_group_separator/parser.rb +67 -0
  82. data/lib/yard/lint/validators/tags/tag_group_separator/result.rb +28 -0
  83. data/lib/yard/lint/validators/tags/tag_group_separator/validator.rb +117 -0
  84. data/lib/yard/lint/validators/tags/tag_group_separator.rb +49 -0
  85. data/lib/yard/lint/validators/tags/tag_type_position/parser.rb +1 -1
  86. data/lib/yard/lint/validators/tags/tag_type_position/validator.rb +53 -84
  87. data/lib/yard/lint/validators/tags/tag_type_position.rb +4 -5
  88. data/lib/yard/lint/validators/tags/type_syntax/parser.rb +8 -3
  89. data/lib/yard/lint/validators/tags/type_syntax/validator.rb +29 -59
  90. data/lib/yard/lint/validators/tags/type_syntax.rb +0 -1
  91. data/lib/yard/lint/validators/warnings/duplicated_parameter_name/validator.rb +1 -18
  92. data/lib/yard/lint/validators/warnings/invalid_directive_format/validator.rb +1 -18
  93. data/lib/yard/lint/validators/warnings/invalid_tag_format/validator.rb +1 -18
  94. data/lib/yard/lint/validators/warnings/unknown_directive/validator.rb +1 -18
  95. data/lib/yard/lint/validators/warnings/unknown_parameter_name/messages_builder.rb +243 -0
  96. data/lib/yard/lint/validators/warnings/unknown_parameter_name/result.rb +4 -3
  97. data/lib/yard/lint/validators/warnings/unknown_parameter_name/validator.rb +1 -18
  98. data/lib/yard/lint/validators/warnings/unknown_tag/messages_builder.rb +144 -0
  99. data/lib/yard/lint/validators/warnings/unknown_tag/result.rb +4 -3
  100. data/lib/yard/lint/validators/warnings/unknown_tag/validator.rb +1 -18
  101. data/lib/yard/lint/validators/warnings/unknown_tag.rb +10 -0
  102. data/lib/yard/lint/version.rb +1 -1
  103. data/lib/yard/lint.rb +81 -13
  104. data/renovate.json +1 -8
  105. metadata +40 -6
  106. data/bin/console +0 -11
  107. data/bin/setup +0 -8
  108. data/lib/yard/lint/command_cache.rb +0 -93
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yard
4
+ module Lint
5
+ module Executor
6
+ # Collects query output in a format matching shell stdout.
7
+ # Used by validators to write their results during in-process execution.
8
+ class ResultCollector
9
+ def initialize
10
+ @lines = []
11
+ @mutex = Mutex.new
12
+ end
13
+
14
+ # Add a single line to the output
15
+ # @param line [String, Object] content to add (will be converted to string)
16
+ # @return [void]
17
+ def puts(line)
18
+ @mutex.synchronize { @lines << line.to_s }
19
+ end
20
+
21
+ # Add multiple lines by splitting content on newlines.
22
+ # Each line is added separately to the output buffer.
23
+ # @param content [String] multiline string to split and add
24
+ # @return [void]
25
+ def print(content)
26
+ content.to_s.each_line { |line| puts(line.chomp) }
27
+ end
28
+
29
+ # Get the collected output as a single string
30
+ # @return [String] all lines joined with newlines
31
+ def to_stdout
32
+ @lines.join("\n")
33
+ end
34
+
35
+ # Check if any output has been collected
36
+ # @return [Boolean]
37
+ def empty?
38
+ @lines.empty?
39
+ end
40
+
41
+ # Get the number of lines collected
42
+ # @return [Integer]
43
+ def size
44
+ @lines.size
45
+ end
46
+
47
+ # Clear all collected output
48
+ # @return [void]
49
+ def clear!
50
+ @mutex.synchronize { @lines.clear }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Yard
4
+ module Lint
5
+ module Executor
6
+ # Routes captured YARD warnings to appropriate warning validators.
7
+ # Uses the same regex patterns as the existing parsers to ensure consistency.
8
+ class WarningDispatcher
9
+ # Patterns matching the 'general' regexps from each warning validator's parser.
10
+ # These patterns identify which validator should handle each warning.
11
+ PATTERNS = {
12
+ 'Warnings/UnknownTag' => /^\[warn\]: Unknown tag.*@.*near line/,
13
+ 'Warnings/UnknownParameterName' => /^\[warn\]: @param tag has unknown parameter name/,
14
+ 'Warnings/DuplicatedParameterName' => /^\[warn\]: @param tag has duplicate parameter name/,
15
+ 'Warnings/UnknownDirective' => /^\[warn\]: Unknown directive.*@!.*near line/,
16
+ 'Warnings/InvalidTagFormat' => /^\[warn\]: Invalid tag format/,
17
+ 'Warnings/InvalidDirectiveFormat' => /^\[warn\]: Invalid directive format/
18
+ }.freeze
19
+
20
+ # Dispatch warnings to appropriate validators
21
+ # @param warnings [Array<String>] raw warning messages from YARD
22
+ # @return [Hash{String => Array<String>}] warnings grouped by validator name
23
+ def dispatch(warnings)
24
+ grouped = Hash.new { |h, k| h[k] = [] }
25
+
26
+ warnings.each do |warning|
27
+ # Format the warning as YARD outputs it
28
+ formatted = format_warning(warning)
29
+
30
+ PATTERNS.each do |validator_name, pattern|
31
+ if formatted.match?(pattern)
32
+ grouped[validator_name] << formatted
33
+ break
34
+ end
35
+ end
36
+ end
37
+
38
+ grouped
39
+ end
40
+
41
+ # Format a raw warning to match YARD's stderr output format
42
+ # @param warning [String] raw warning message
43
+ # @return [String] formatted warning
44
+ def format_warning(warning)
45
+ # If the warning already has [warn]: prefix, return as-is
46
+ return warning if warning.start_with?('[warn]:')
47
+
48
+ "[warn]: #{warning}"
49
+ end
50
+
51
+ # Build result hash for a validator from its dispatched warnings
52
+ # The warnings are put in stdout because the ResultBuilder reads from stdout
53
+ # (in shell mode, YARD outputs warnings to stderr but they get combined)
54
+ # @param warnings [Array<String>] warnings for this validator
55
+ # @return [Hash] result hash with :stdout, :stderr, :exit_code keys
56
+ def format_for_validator(warnings)
57
+ {
58
+ stdout: warnings.join("\n"),
59
+ stderr: '',
60
+ exit_code: 0
61
+ }
62
+ end
63
+
64
+ # Check if a validator is a warning validator (handled by dispatcher)
65
+ # @param validator_name [String] full validator name
66
+ # @return [Boolean]
67
+ def warning_validator?(validator_name)
68
+ PATTERNS.key?(validator_name)
69
+ end
70
+
71
+ # Get all warning validator names
72
+ # @return [Array<String>]
73
+ def warning_validator_names
74
+ PATTERNS.keys
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -55,7 +55,8 @@ module Yard
55
55
  # Set default values for base class
56
56
  self.offense_type = 'line'
57
57
 
58
- attr_reader :offenses, :config
58
+ attr_accessor :offenses
59
+ attr_reader :config
59
60
 
60
61
  # Initialize a result object with parsed validator data
61
62
  # @param parsed_data [Array<Hash>] Array of offense hashes from validator parser
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Require executor components for in-process execution
4
+ require_relative 'executor/in_process_registry'
5
+ require_relative 'executor/result_collector'
6
+ require_relative 'executor/query_executor'
7
+ require_relative 'executor/warning_dispatcher'
8
+
3
9
  module Yard
4
10
  module Lint
5
11
  # Main runner class that orchestrates the YARD validation process
@@ -26,8 +32,8 @@ module Yard
26
32
 
27
33
  private
28
34
 
29
- # Run all validators
30
- # Automatically runs all validators from ConfigLoader::ALL_VALIDATORS if enabled
35
+ # Run all validators using in-process YARD execution.
36
+ # Parses files once and shares the registry across all validators.
31
37
  # @return [Hash] hash with raw results from all validators
32
38
  def run_validators
33
39
  results = {}
@@ -37,50 +43,55 @@ module Yard
37
43
 
38
44
  @progress_formatter&.start(enabled_validators.size)
39
45
 
40
- # Iterate through all registered validators
46
+ # Initialize in-process infrastructure
47
+ registry = Executor::InProcessRegistry.new
48
+ registry.parse(selection)
49
+
50
+ query_executor = Executor::QueryExecutor.new(registry)
51
+ warning_dispatcher = Executor::WarningDispatcher.new
52
+ dispatched_warnings = warning_dispatcher.dispatch(registry.warnings)
53
+
54
+ # Process each enabled validator
41
55
  enabled_validators.each_with_index do |validator_name, index|
42
- # Get the validator namespace and config
43
56
  validator_namespace = ConfigLoader.validator_module(validator_name)
44
57
  validator_cfg = ConfigLoader.validator_config(validator_name)
45
58
 
46
- # Show progress before running validator
47
59
  @progress_formatter&.update(index + 1, validator_name)
48
60
 
49
- # Run the validator if it has a module
50
- # (validators with modules have Validator classes)
51
- if validator_namespace
52
- run_and_store_validator(validator_namespace, validator_cfg, results, validator_name)
53
- end
61
+ next unless validator_namespace
62
+
63
+ validator_class = validator_namespace::Validator
64
+ validator_selection = filter_files_for_validator(validator_name, selection)
65
+
66
+ result = if warning_dispatcher.warning_validator?(validator_name)
67
+ # Use dispatched warnings for warning validators
68
+ warning_dispatcher.format_for_validator(
69
+ dispatched_warnings[validator_name] || []
70
+ )
71
+ else
72
+ # Use in-process execution
73
+ validator = validator_class.new(config, validator_selection)
74
+ in_process_result = query_executor.execute(validator, file_selection: validator_selection)
75
+
76
+ # Tags/Order requires special result wrapping for its parser
77
+ if validator_name == 'Tags/Order'
78
+ tags_order = config.validator_config('Tags/Order', 'EnforcedOrder')
79
+ in_process_result[:stdout] = {
80
+ result: in_process_result[:stdout],
81
+ tags_order: tags_order
82
+ }
83
+ end
84
+
85
+ in_process_result
86
+ end
87
+
88
+ results[validator_cfg.id] = result
54
89
  end
55
90
 
56
91
  @progress_formatter&.finish
57
-
58
92
  results
59
93
  end
60
94
 
61
- # Run a validator and store its result using the module's ID
62
- # @param validator_namespace [Module] validator namespace module (e.g., Validators::Tags::Order)
63
- # @param validator_config [Class] validator config class
64
- # @param results [Hash] hash to store results in
65
- # @param validator_name [String] full validator name for per-validator exclusions
66
- def run_and_store_validator(
67
- validator_namespace, validator_config, results, validator_name
68
- )
69
- results[validator_config.id] = run_validator(
70
- validator_namespace::Validator,
71
- validator_name
72
- )
73
- end
74
-
75
- # Run a single validator with per-validator file filtering
76
- # @param validator_class [Class] validator class to instantiate and run
77
- # @param validator_name [String] full validator name for exclusions
78
- # @return [Hash] hash with stdout, stderr and exit_code keys
79
- def run_validator(validator_class, validator_name)
80
- validator_selection = filter_files_for_validator(validator_name, selection)
81
- validator_class.new(config, validator_selection).call
82
- end
83
-
84
95
  # Filter files for a specific validator based on per-validator exclusions
85
96
  # @param validator_name [String] full validator name
86
97
  # @param files [Array<String>] array of file paths
@@ -96,6 +107,44 @@ module Yard
96
107
  end
97
108
  end
98
109
 
110
+ # Filter result offenses based on per-validator exclusions
111
+ # Removes offenses where the file path matches exclusion patterns
112
+ # @param validator_name [String] full validator name
113
+ # @param result [Results::Base] result object with offenses
114
+ # @return [Results::Base, nil] result with filtered offenses, or nil if no offenses remain
115
+ def filter_result_offenses(validator_name, result)
116
+ validator_excludes = config.validator_all_excludes(validator_name)
117
+ return result if validator_excludes.empty?
118
+
119
+ working_dir = Dir.pwd
120
+
121
+ filtered_offenses = result.offenses.reject do |offense|
122
+ file_path = offense[:location] || offense[:file]
123
+ next true unless file_path
124
+
125
+ # Convert to relative path for pattern matching
126
+ relative_path = if file_path.start_with?(working_dir)
127
+ file_path.sub(%r{^#{Regexp.escape(working_dir)}/}, '')
128
+ else
129
+ file_path
130
+ end
131
+
132
+ # Check if file matches any exclusion pattern
133
+ validator_excludes.any? do |pattern|
134
+ File.fnmatch(pattern, relative_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
135
+ end
136
+ end
137
+
138
+ # Return nil if no offenses remain after filtering
139
+ return nil if filtered_offenses.empty?
140
+
141
+ # Instead of creating a new Result object (which would rebuild messages),
142
+ # just modify the existing result object's offenses array
143
+ # This preserves all the processed offense data including enhanced messages
144
+ result.offenses = filtered_offenses
145
+ result
146
+ end
147
+
99
148
  # Parse raw results from validators and create Result objects
100
149
  # Delegates result building to ResultBuilder
101
150
  # @param raw [Hash] hash with raw results from all validators
@@ -108,7 +157,11 @@ module Yard
108
157
  next unless config.validator_enabled?(validator_name)
109
158
 
110
159
  result = @result_builder.build(validator_name, raw)
111
- results << result if result
160
+ next unless result
161
+
162
+ # Filter offenses based on per-validator exclusions
163
+ filtered_result = filter_result_offenses(validator_name, result)
164
+ results << filtered_result if filtered_result
112
165
  end
113
166
 
114
167
  results
@@ -8,7 +8,7 @@ module Yard
8
8
  attr_reader :config, :files
9
9
 
10
10
  # @param config [Yard::Lint::Config] configuration object
11
- # @param files [Array<String>] files to analyze
11
+ # @param files [Array<String>] Ruby source files whose YARD documentation will be checked for coverage statistics
12
12
  def initialize(config, files)
13
13
  @config = config
14
14
  @files = Array(files).compact
@@ -0,0 +1,279 @@
1
+ # YARD-Lint Configuration
2
+ # See https://github.com/mensfeld/yard-lint for documentation
3
+
4
+ # Global settings for all validators
5
+ AllValidators:
6
+ # YARD command-line options (applied to all validators by default)
7
+ YardOptions:
8
+ - --private
9
+ - --protected
10
+
11
+ # Global file exclusion patterns
12
+ Exclude:
13
+ - '\.git'
14
+ - 'vendor/**/*'
15
+ - 'node_modules/**/*'
16
+ - 'spec/**/*'
17
+ - 'test/**/*'
18
+
19
+ # Exit code behavior (error, warning, convention, never)
20
+ FailOnSeverity: warning
21
+
22
+ # Minimum documentation coverage percentage (0-100)
23
+ # Fails if coverage is below this threshold
24
+ # MinCoverage: 80.0
25
+
26
+ # Diff mode settings
27
+ DiffMode:
28
+ # Default base ref for --diff (auto-detects main/master if not specified)
29
+ DefaultBaseRef: ~
30
+
31
+ # Documentation validators
32
+ Documentation/UndocumentedObjects:
33
+ Description: 'Checks for classes, modules, and methods without documentation.'
34
+ Enabled: true
35
+ Severity: warning
36
+ ExcludedMethods:
37
+ - 'initialize/0' # Exclude parameter-less initialize
38
+ - '/^_/' # Exclude private methods (by convention)
39
+
40
+ Documentation/UndocumentedMethodArguments:
41
+ Description: 'Checks for method parameters without @param tags.'
42
+ Enabled: true
43
+ Severity: warning
44
+
45
+ Documentation/UndocumentedBooleanMethods:
46
+ Description: 'Checks that question mark methods document their boolean return.'
47
+ Enabled: true
48
+ Severity: warning
49
+
50
+ Documentation/UndocumentedOptions:
51
+ Description: 'Detects methods with options hash parameters but no @option tags.'
52
+ Enabled: true
53
+ Severity: warning
54
+
55
+ Documentation/MarkdownSyntax:
56
+ Description: 'Detects common markdown syntax errors in documentation.'
57
+ Enabled: true
58
+ Severity: warning
59
+
60
+ Documentation/EmptyCommentLine:
61
+ Description: 'Detects empty comment lines at the start or end of documentation blocks.'
62
+ Enabled: true
63
+ Severity: convention
64
+ EnabledPatterns:
65
+ Leading: true
66
+ Trailing: true
67
+
68
+ Documentation/BlankLineBeforeDefinition:
69
+ Description: 'Detects blank lines between YARD documentation and method definition.'
70
+ Enabled: true
71
+ Severity: convention
72
+ OrphanedSeverity: convention
73
+ EnabledPatterns:
74
+ SingleBlankLine: true
75
+ OrphanedDocs: true
76
+
77
+ # Tags validators
78
+ Tags/Order:
79
+ Description: 'Enforces consistent ordering of YARD tags.'
80
+ Enabled: true
81
+ Severity: convention
82
+ EnforcedOrder:
83
+ - param
84
+ - option
85
+ - yield
86
+ - yieldparam
87
+ - yieldreturn
88
+ - return
89
+ - raise
90
+ - see
91
+ - example
92
+ - note
93
+ - todo
94
+
95
+ Tags/InvalidTypes:
96
+ Description: 'Validates type definitions in @param, @return, @option tags.'
97
+ Enabled: true
98
+ Severity: warning
99
+ ValidatedTags:
100
+ - param
101
+ - option
102
+ - return
103
+
104
+ Tags/TypeSyntax:
105
+ Description: 'Validates YARD type syntax using YARD parser.'
106
+ Enabled: true
107
+ Severity: warning
108
+ ValidatedTags:
109
+ - param
110
+ - option
111
+ - return
112
+ - yieldreturn
113
+
114
+ Tags/MeaninglessTag:
115
+ Description: 'Detects @param/@option tags on classes, modules, or constants.'
116
+ Enabled: true
117
+ Severity: warning
118
+ CheckedTags:
119
+ - param
120
+ - option
121
+ InvalidObjectTypes:
122
+ - class
123
+ - module
124
+ - constant
125
+
126
+ Tags/CollectionType:
127
+ Description: 'Validates Hash collection syntax consistency.'
128
+ Enabled: true
129
+ Severity: convention
130
+ EnforcedStyle: long # 'long' for Hash{K => V} (YARD standard), 'short' for {K => V}
131
+ ValidatedTags:
132
+ - param
133
+ - option
134
+ - return
135
+ - yieldreturn
136
+
137
+ Tags/TagTypePosition:
138
+ Description: 'Validates type annotation position in tags.'
139
+ Enabled: true
140
+ Severity: convention
141
+ CheckedTags:
142
+ - param
143
+ - option
144
+ # EnforcedStyle: 'type_after_name' (YARD standard: @param name [Type])
145
+ # or 'type_first' (@param [Type] name)
146
+ EnforcedStyle: type_after_name
147
+
148
+ Tags/ApiTags:
149
+ Description: 'Enforces @api tags on public objects.'
150
+ Enabled: false # Opt-in validator
151
+ Severity: warning
152
+ AllowedApis:
153
+ - public
154
+ - private
155
+ - internal
156
+
157
+ Tags/OptionTags:
158
+ Description: 'Requires @option tags for methods with options parameters.'
159
+ Enabled: true
160
+ Severity: warning
161
+
162
+ Tags/ExampleSyntax:
163
+ Description: 'Validates Ruby syntax in @example tags.'
164
+ Enabled: true
165
+ Severity: warning
166
+
167
+ Tags/RedundantParamDescription:
168
+ Description: 'Detects meaningless parameter descriptions that add no value.'
169
+ Enabled: true
170
+ Severity: convention
171
+ CheckedTags:
172
+ - param
173
+ - option
174
+ Articles:
175
+ - The
176
+ - the
177
+ - A
178
+ - a
179
+ - An
180
+ - an
181
+ MaxRedundantWords: 6
182
+ GenericTerms:
183
+ - object
184
+ - instance
185
+ - value
186
+ - data
187
+ - item
188
+ - element
189
+ EnabledPatterns:
190
+ ArticleParam: true
191
+ PossessiveParam: true
192
+ TypeRestatement: true
193
+ ParamToVerb: true
194
+ IdPattern: true
195
+ DirectionalDate: true
196
+ TypeGeneric: true
197
+
198
+ Tags/InformalNotation:
199
+ Description: 'Detects informal tag notation patterns like "Note:" instead of @note.'
200
+ Enabled: true
201
+ Severity: warning
202
+ CaseSensitive: false
203
+ RequireStartOfLine: true
204
+ Patterns:
205
+ Note: '@note'
206
+ Todo: '@todo'
207
+ TODO: '@todo'
208
+ FIXME: '@todo'
209
+ See: '@see'
210
+ See also: '@see'
211
+ Warning: '@deprecated'
212
+ Deprecated: '@deprecated'
213
+ Author: '@author'
214
+ Version: '@version'
215
+ Since: '@since'
216
+ Returns: '@return'
217
+ Raises: '@raise'
218
+ Example: '@example'
219
+
220
+ Tags/NonAsciiType:
221
+ Description: 'Detects non-ASCII characters in type annotations.'
222
+ Enabled: true
223
+ Severity: warning
224
+ ValidatedTags:
225
+ - param
226
+ - option
227
+ - return
228
+ - yieldreturn
229
+ - yieldparam
230
+
231
+ Tags/TagGroupSeparator:
232
+ Description: 'Enforces blank line separators between different YARD tag groups.'
233
+ Enabled: false # Opt-in validator
234
+ Severity: convention
235
+ TagGroups:
236
+ param: [param, option]
237
+ return: [return]
238
+ error: [raise, throws]
239
+ example: [example]
240
+ meta: [see, note, todo, deprecated, since, version, api]
241
+ yield: [yield, yieldparam, yieldreturn]
242
+ RequireAfterDescription: false
243
+
244
+ # Warnings validators - catches YARD parser errors
245
+ Warnings/UnknownTag:
246
+ Description: 'Detects unknown YARD tags.'
247
+ Enabled: true
248
+ Severity: error
249
+
250
+ Warnings/UnknownDirective:
251
+ Description: 'Detects unknown YARD directives.'
252
+ Enabled: true
253
+ Severity: error
254
+
255
+ Warnings/InvalidTagFormat:
256
+ Description: 'Detects malformed tag syntax.'
257
+ Enabled: true
258
+ Severity: error
259
+
260
+ Warnings/InvalidDirectiveFormat:
261
+ Description: 'Detects malformed directive syntax.'
262
+ Enabled: true
263
+ Severity: error
264
+
265
+ Warnings/DuplicatedParameterName:
266
+ Description: 'Detects duplicate @param tags.'
267
+ Enabled: true
268
+ Severity: error
269
+
270
+ Warnings/UnknownParameterName:
271
+ Description: 'Detects @param tags for non-existent parameters.'
272
+ Enabled: true
273
+ Severity: error
274
+
275
+ # Semantic validators
276
+ Semantic/AbstractMethods:
277
+ Description: 'Ensures @abstract methods do not have real implementations.'
278
+ Enabled: true
279
+ Severity: warning