docscribe 1.4.2 → 1.5.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +465 -130
  3. data/lib/docscribe/cli/check_for_comments.rb +183 -0
  4. data/lib/docscribe/cli/config_builder.rb +107 -53
  5. data/lib/docscribe/cli/formatters/json.rb +294 -0
  6. data/lib/docscribe/cli/formatters/sarif.rb +235 -0
  7. data/lib/docscribe/cli/formatters/text.rb +208 -0
  8. data/lib/docscribe/cli/formatters.rb +26 -0
  9. data/lib/docscribe/cli/generate.rb +45 -45
  10. data/lib/docscribe/cli/init.rb +14 -6
  11. data/lib/docscribe/cli/options.rb +190 -88
  12. data/lib/docscribe/cli/rbs_gen.rb +529 -0
  13. data/lib/docscribe/cli/run.rb +210 -152
  14. data/lib/docscribe/cli/sigs.rb +366 -0
  15. data/lib/docscribe/cli/update_types.rb +103 -0
  16. data/lib/docscribe/cli.rb +21 -13
  17. data/lib/docscribe/config/defaults.rb +5 -1
  18. data/lib/docscribe/config/emit.rb +17 -0
  19. data/lib/docscribe/config/filtering.rb +18 -25
  20. data/lib/docscribe/config/loader.rb +15 -11
  21. data/lib/docscribe/config/plugin.rb +1 -1
  22. data/lib/docscribe/config/rbs.rb +41 -9
  23. data/lib/docscribe/config/sorbet.rb +9 -12
  24. data/lib/docscribe/config/sorting.rb +1 -1
  25. data/lib/docscribe/config/template.rb +9 -1
  26. data/lib/docscribe/config/utils.rb +11 -9
  27. data/lib/docscribe/config.rb +2 -4
  28. data/lib/docscribe/infer/ast_walk.rb +1 -1
  29. data/lib/docscribe/infer/literals.rb +6 -11
  30. data/lib/docscribe/infer/names.rb +2 -3
  31. data/lib/docscribe/infer/params.rb +15 -17
  32. data/lib/docscribe/infer/raises.rb +3 -5
  33. data/lib/docscribe/infer/returns.rb +542 -140
  34. data/lib/docscribe/infer.rb +22 -23
  35. data/lib/docscribe/inline_rewriter/collector.rb +159 -164
  36. data/lib/docscribe/inline_rewriter/doc_block.rb +145 -115
  37. data/lib/docscribe/inline_rewriter/doc_builder.rb +1026 -723
  38. data/lib/docscribe/inline_rewriter/source_helpers.rb +49 -49
  39. data/lib/docscribe/inline_rewriter/tag_sorter.rb +82 -85
  40. data/lib/docscribe/inline_rewriter.rb +495 -492
  41. data/lib/docscribe/parsing.rb +29 -10
  42. data/lib/docscribe/plugin/base/collector_plugin.rb +2 -1
  43. data/lib/docscribe/plugin/base/tag_plugin.rb +0 -1
  44. data/lib/docscribe/plugin/context.rb +28 -18
  45. data/lib/docscribe/plugin/registry.rb +26 -27
  46. data/lib/docscribe/plugin/tag.rb +9 -14
  47. data/lib/docscribe/plugin.rb +17 -16
  48. data/lib/docscribe/types/provider_chain.rb +4 -2
  49. data/lib/docscribe/types/rbs/collection_loader.rb +2 -2
  50. data/lib/docscribe/types/rbs/provider.rb +60 -44
  51. data/lib/docscribe/types/rbs/type_formatter.rb +224 -83
  52. data/lib/docscribe/types/signature.rb +22 -42
  53. data/lib/docscribe/types/sorbet/base_provider.rb +24 -19
  54. data/lib/docscribe/types/sorbet/rbi_provider.rb +3 -3
  55. data/lib/docscribe/types/sorbet/source_provider.rb +3 -2
  56. data/lib/docscribe/types/yard/formatter.rb +100 -0
  57. data/lib/docscribe/types/yard/parser.rb +240 -0
  58. data/lib/docscribe/types/yard/types.rb +52 -0
  59. data/lib/docscribe/version.rb +1 -1
  60. metadata +33 -1
@@ -10,7 +10,7 @@ module Docscribe
10
10
  # - `docscribe.yml` in the current directory, if present
11
11
  # - otherwise defaults only
12
12
  #
13
- # @param [String, nil] path optional config path
13
+ # @param [String?] path optional config path
14
14
  # @return [Docscribe::Config]
15
15
  def self.load(path = nil)
16
16
  raw = {} #: Hash[String, untyped]
@@ -28,11 +28,13 @@ module Docscribe
28
28
  # and calling {safe_load_compat}.
29
29
  #
30
30
  # @param [String] path file path
31
- # @return [Hash]
31
+ # @return [Hash<String, Object>]
32
32
  def self.safe_load_file_compat(path)
33
- if YAML.respond_to?(:safe_load_file)
34
- YAML.safe_load_file(path,
35
- permitted_classes: [], permitted_symbols: [],
33
+ if YAML.respond_to?(:safe_load_file) # steep:ignore
34
+ pclasses = [] #: Array[String]
35
+ psymbols = [] #: Array[Symbol]
36
+ YAML.safe_load_file(path, # steep:ignore
37
+ permitted_classes: pclasses, permitted_symbols: psymbols,
36
38
  aliases: true) || {} #: Hash[String, untyped]
37
39
  else
38
40
  yaml = File.open(path, 'r:bom|utf-8', &:read)
@@ -43,20 +45,22 @@ module Docscribe
43
45
  # Safely load YAML from a string across Psych API versions.
44
46
  #
45
47
  # @param [String] yaml YAML document
46
- # @param [String, nil] filename optional filename for diagnostics
48
+ # @param [String?] filename optional filename for diagnostics
47
49
  # @raise [ArgumentError]
48
- # @return [Hash]
50
+ # @return [Hash<String, Object>] if ArgumentError
51
+ # @return [Object] if ArgumentError
49
52
  def self.safe_load_compat(yaml, filename: nil)
50
- Psych.safe_load(
53
+ pclasses = [] #: Array[String]
54
+ psymbols = [] #: Array[Symbol]
55
+ Psych.safe_load( # steep:ignore
51
56
  yaml,
52
- permitted_classes: [],
53
- permitted_symbols: [],
57
+ permitted_classes: pclasses, permitted_symbols: psymbols,
54
58
  aliases: true,
55
59
  filename: filename
56
60
  ) #: Hash[String, untyped]
57
61
  rescue ArgumentError
58
62
  # Older Psych signature uses positional args
59
- Psych.safe_load(yaml, [], [], true, filename)
63
+ Psych.safe_load(yaml, [], [], true, filename) # steep:ignore
60
64
  end
61
65
  end
62
66
  end
@@ -15,7 +15,7 @@ module Docscribe
15
15
  # @raise [LoadError]
16
16
  # @return [void]
17
17
  def load_plugins!
18
- paths = Array(raw.dig('plugins', 'require')).compact
18
+ paths = Array(raw.dig('plugins', 'require')).compact #: Array[String]
19
19
  return if paths.empty?
20
20
 
21
21
  require 'docscribe/plugin'
@@ -8,7 +8,6 @@ module Docscribe
8
8
  # If RBS cannot be loaded, this returns nil and Docscribe falls back to
9
9
  # inference.
10
10
  #
11
- # @raise [LoadError]
12
11
  # @return [Docscribe::Types::RBS::Provider, nil]
13
12
  def rbs_provider
14
13
  return nil unless rbs_enabled?
@@ -24,14 +23,25 @@ module Docscribe
24
23
  fetch_bool(%w[rbs enabled], false)
25
24
  end
26
25
 
27
- # @raise [LoadError]
28
- # @return [Object]
26
+ # Core rbs provider
27
+ #
28
+ # @return [Docscribe::Types::RBS::Provider, nil]
29
29
  def core_rbs_provider
30
30
  return nil unless ruby_supports_rbs?
31
31
 
32
32
  @core_rbs_provider ||= build_core_rbs_provider
33
33
  end
34
34
 
35
+ # Whether to warn when rbs_collection.lock.yaml exists but --rbs-collection
36
+ # was not passed.
37
+ #
38
+ # Set `rbs.warn_missing_collection: false` in `docscribe.yml` to suppress.
39
+ #
40
+ # @return [Boolean]
41
+ def rbs_warn_missing_collection?
42
+ fetch_bool(%w[rbs warn_missing_collection], true)
43
+ end
44
+
35
45
  private
36
46
 
37
47
  # Check whether the current Ruby version supports RBS (requires 3.0+).
@@ -48,23 +58,31 @@ module Docscribe
48
58
  false
49
59
  end
50
60
 
61
+ # Build rbs provider
62
+ #
51
63
  # @private
52
64
  # @raise [LoadError]
53
- # @return [Docscribe::Types::RBS::Provider, nil]
65
+ # @return [Docscribe::Types::RBS::Provider, nil] if LoadError
66
+ # @return [nil] if LoadError
54
67
  def build_rbs_provider
55
68
  require 'docscribe/types/rbs/provider'
56
69
  Docscribe::Types::RBS::Provider.new(
57
70
  sig_dirs: rbs_sig_dirs,
58
71
  collection_dirs: rbs_collection_dirs,
59
- collapse_generics: rbs_collapse_generics?
72
+ collapse_generics: rbs_collapse_generics?,
73
+ collapse_object_generics: rbs_collapse_object_generics?
60
74
  )
61
75
  rescue LoadError
76
+ warn 'Docscribe: --rbs requires the `rbs` gem. Add `gem "rbs"` to your Gemfile and run `bundle install`.'
62
77
  nil
63
78
  end
64
79
 
80
+ # Build core rbs provider
81
+ #
65
82
  # @private
66
83
  # @raise [LoadError]
67
- # @return [Docscribe::Types::RBS::Provider, nil]
84
+ # @return [Docscribe::Types::RBS::Provider, nil] if LoadError
85
+ # @return [nil] if LoadError
68
86
  def build_core_rbs_provider
69
87
  require 'docscribe/types/rbs/provider'
70
88
  Docscribe::Types::RBS::Provider.new(
@@ -80,7 +98,7 @@ module Docscribe
80
98
  # @private
81
99
  # @return [Array<String>]
82
100
  def rbs_sig_dirs
83
- Array(raw.dig('rbs', 'sig_dirs') || DEFAULT.dig('rbs', 'sig_dirs')).map(&:to_s)
101
+ Array(raw.dig('rbs', 'sig_dirs') || DEFAULT.dig('rbs', 'sig_dirs')).map(&:to_s) # steep:ignore
84
102
  end
85
103
 
86
104
  # RBS collection directories (auto-discovered from rbs_collection.lock.yaml).
@@ -92,7 +110,7 @@ module Docscribe
92
110
  # @private
93
111
  # @return [Array<String>]
94
112
  def rbs_collection_dirs
95
- Array(raw.dig('rbs', 'collection_dirs')).map(&:to_s)
113
+ Array(raw.dig('rbs', 'collection_dirs')).map(&:to_s) # steep:ignore
96
114
  end
97
115
 
98
116
  # Whether generic RBS types should be collapsed to simpler container names.
@@ -102,9 +120,23 @@ module Docscribe
102
120
  # - `Array<Integer>` => `Array`
103
121
  #
104
122
  # @private
105
- # @return [Object]
123
+ # @return [Boolean]
106
124
  def rbs_collapse_generics?
107
125
  fetch_bool(%w[rbs collapse_generics], false)
108
126
  end
127
+
128
+ # Whether to collapse generic types when all inner types are Object.
129
+ #
130
+ # Unlike `collapse_generics` (which drops all generic info), this only
131
+ # collapses when the type arguments provide no useful information:
132
+ # - `Hash<Symbol, Object>` => stays as is (Symbol is useful)
133
+ # - `Hash<Object, Object>` => `Hash`
134
+ # - `Array<Object>` => `Array`
135
+ #
136
+ # @private
137
+ # @return [Boolean]
138
+ def rbs_collapse_object_generics?
139
+ fetch_bool(%w[rbs collapse_object_generics], false)
140
+ end
109
141
  end
110
142
  end
@@ -14,7 +14,6 @@ module Docscribe
14
14
  #
15
15
  # @param [String] source Ruby source being rewritten
16
16
  # @param [String] file source name for diagnostics
17
- # @raise [LoadError]
18
17
  # @return [Docscribe::Types::ProviderChain, nil]
19
18
  def signature_provider_for(source:, file:)
20
19
  providers = [] #: Array[untyped]
@@ -25,10 +24,9 @@ module Docscribe
25
24
 
26
25
  # Append Sorbet-based providers to the list.
27
26
  #
28
- # @private
29
- # @param [Array] providers
30
- # @param [String] source
31
- # @param [String] file
27
+ # @param [Array<Object>] providers provider list to populate
28
+ # @param [String] source Ruby source being rewritten
29
+ # @param [String] file source name for diagnostics
32
30
  # @return [void]
33
31
  def append_sorbet_providers(providers, source:, file:)
34
32
  return unless sorbet_enabled?
@@ -39,11 +37,11 @@ module Docscribe
39
37
 
40
38
  # Build a Sorbet source provider (inline sigs).
41
39
  #
42
- # @private
43
- # @param [String] source
44
- # @param [String] file
40
+ # @param [String] source Ruby source being rewritten
41
+ # @param [String] file source name for diagnostics
45
42
  # @raise [LoadError]
46
- # @return [Docscribe::Types::Sorbet::SourceProvider, nil]
43
+ # @return [Docscribe::Types::Sorbet::SourceProvider, nil] if LoadError
44
+ # @return [nil] if LoadError
47
45
  def sorbet_source_provider(source, file)
48
46
  require 'docscribe/types/sorbet/source_provider'
49
47
  Docscribe::Types::Sorbet::SourceProvider.new(
@@ -57,8 +55,7 @@ module Docscribe
57
55
 
58
56
  # Build the provider chain from a non-empty list, or return nil.
59
57
  #
60
- # @private
61
- # @param [Array] providers
58
+ # @param [Array<Object>] providers provider list to chain
62
59
  # @return [Docscribe::Types::ProviderChain, nil]
63
60
  def build_provider_chain(providers)
64
61
  providers = providers.compact
@@ -97,7 +94,7 @@ module Docscribe
97
94
  #
98
95
  # @return [Array<String>]
99
96
  def sorbet_rbi_dirs
100
- Array(raw.dig('sorbet', 'rbi_dirs') || DEFAULT.dig('sorbet', 'rbi_dirs')).map(&:to_s)
97
+ Array(raw.dig('sorbet', 'rbi_dirs') || DEFAULT.dig('sorbet', 'rbi_dirs')).map(&:to_s) # steep:ignore
101
98
  end
102
99
 
103
100
  # Whether generic Sorbet/RBI container types should be simplified.
@@ -17,7 +17,7 @@ module Docscribe
17
17
  # @return [Array<String>]
18
18
  def tag_order
19
19
  Array(raw.dig('doc', 'tag_order') || DEFAULT.dig('doc', 'tag_order')).map do |t|
20
- t.to_s.sub(/\A@/, '')
20
+ t.to_s.sub(/\A@/, '') # steep:ignore
21
21
  end
22
22
  end
23
23
  end
@@ -7,7 +7,6 @@ module Docscribe
7
7
  #
8
8
  # The template documents the most common CLI workflows and all supported
9
9
  # configuration sections with comments.
10
- # @see Docscribe::Config::DEFAULT
11
10
  #
12
11
  # @return [String]
13
12
  def self.default_yaml
@@ -21,6 +20,7 @@ module Docscribe
21
20
  # bundle exec docscribe lib # check what would change
22
21
  # bundle exec docscribe -a lib # apply safe updates
23
22
  # bundle exec docscribe -A lib # rebuild all doc blocks
23
+ # bundle exec docscribe -AkB lib # rebuild, keep descriptions, no boilerplate
24
24
 
25
25
  emit:
26
26
  # What to include in generated documentation
@@ -89,7 +89,9 @@ module Docscribe
89
89
  sig_dirs: ["sig"]
90
90
  collection_dirs: [] # auto-discovered from --rbs-collection
91
91
  collapse_generics: false # Hash<Symbol, String> => Hash
92
+ collapse_object_generics: false # Hash<Object, Object> => Hash (keep if inner types are useful)
92
93
  collection: false # auto-discover from rbs_collection.lock.yaml
94
+ warn_missing_collection: true # warn if rbs_collection.lock.yaml exists without --rbs-collection
93
95
 
94
96
  sorbet:
95
97
  # Use Sorbet inline sigs and RBI files for better types
@@ -97,6 +99,12 @@ module Docscribe
97
99
  rbi_dirs: ["sorbet/rbi", "rbi"]
98
100
  collapse_generics: false
99
101
 
102
+ # Preserve existing @param/@return descriptions in aggressive mode
103
+ keep_descriptions: false
104
+
105
+ # Skip @param for anonymous block arguments (&) (Ruby 3.2+)
106
+ skip_anonymous_block_params: false
107
+
100
108
  plugins:
101
109
  # Load custom plugins
102
110
  # Example:
@@ -46,7 +46,7 @@ module Docscribe
46
46
  # Convert an internal scope symbol into the config key used under `methods`.
47
47
  #
48
48
  # @private
49
- # @param [Symbol] scope
49
+ # @param [Symbol] scope :instance or :class
50
50
  # @return [String]
51
51
  def scope_to_key(scope)
52
52
  scope == :class ? 'class' : 'instance'
@@ -55,8 +55,8 @@ module Docscribe
55
55
  # Check whether any pattern matches the given text.
56
56
  #
57
57
  # @private
58
- # @param [Array<String>] patterns
59
- # @param [String] text
58
+ # @param [Array<String>] patterns filter patterns to match
59
+ # @param [String] text text to test against patterns
60
60
  # @return [Boolean]
61
61
  def matches_any?(patterns, text)
62
62
  patterns.any? { |pat| match_pattern?(pat, text) }
@@ -69,12 +69,14 @@ module Docscribe
69
69
  # - shell-style glob patterns (with `/` translated to `#` since method IDs use `#`)
70
70
  #
71
71
  # @private
72
- # @param [String] pattern
73
- # @param [String] text
72
+ # @param [String] pattern filter pattern to match
73
+ # @param [String] text method ID to test
74
74
  # @return [Boolean]
75
75
  def match_pattern?(pattern, text)
76
76
  if pattern.start_with?('/') && pattern.end_with?('/') && pattern.length >= 2
77
- Regexp.new(pattern[1..-2]).match?(text)
77
+ Regexp.new(pattern[1..-2]).match?(text) # steep:ignore
78
+ elsif pattern.count('*?[{').zero?
79
+ File.fnmatch?("*#{pattern.tr('/', '#')}*", text, File::FNM_EXTGLOB)
78
80
  else
79
81
  File.fnmatch?(pattern.tr('/', '#'), text, File::FNM_EXTGLOB)
80
82
  end
@@ -85,9 +87,9 @@ module Docscribe
85
87
  # Nested hashes are merged recursively; non-hash values are replaced.
86
88
  #
87
89
  # @private
88
- # @param [Hash] hash1 base hash
89
- # @param [Hash, nil] hash2 override hash
90
- # @return [Hash]
90
+ # @param [Hash<Object, Object>] hash1 base hash
91
+ # @param [Hash<Object, Object>, nil] hash2 override hash
92
+ # @return [Hash<Object, Object>]
91
93
  def deep_merge(hash1, hash2)
92
94
  return hash1 unless hash2
93
95
 
@@ -7,17 +7,15 @@ require 'psych'
7
7
  module Docscribe
8
8
  # Application configuration with deep-merge defaults and overrides.
9
9
  class Config
10
- # Raw config hash after deep-merging user config with defaults.
11
- #
12
10
  # @!attribute [r] raw
13
- # @return [Hash]
11
+ # @return [Hash<String, Object>]
14
12
  attr_reader :raw
15
13
 
16
14
  # Create a configuration object from a raw config hash.
17
15
  #
18
16
  # Missing keys are filled from {DEFAULT} via deep merge.
19
17
  #
20
- # @param [Hash, nil] raw user-provided config hash
18
+ # @param [Hash<String, Object>] raw user-provided config hash
21
19
  # @return [void]
22
20
  def initialize(raw = {})
23
21
  @raw = deep_merge(DEFAULT, raw || {})
@@ -11,7 +11,7 @@ module Docscribe
11
11
  # Yields each node exactly once, descending recursively through child nodes.
12
12
  # Non-AST values are ignored.
13
13
  #
14
- # @note module_function: when included, also defines #walk (instance visibility: private)
14
+ # @note module_function: defines #walk (visibility: private)
15
15
  # @param [Parser::AST::Node, nil] node root AST node
16
16
  # @param [Proc] block visitor block
17
17
  # @return [void]
@@ -17,7 +17,7 @@ module Docscribe
17
17
  #
18
18
  # If the node does not match a supported pattern, the fallback type is returned.
19
19
  #
20
- # @note module_function: when included, also defines #type_from_literal (instance visibility: private)
20
+ # @note module_function: defines #type_from_literal (visibility: private)
21
21
  # @param [Parser::AST::Node, nil] node literal/value node
22
22
  # @param [String] fallback_type type returned when inference is uncertain
23
23
  # @return [String]
@@ -30,8 +30,7 @@ module Docscribe
30
30
 
31
31
  # Map a node type symbol to a known literal type name.
32
32
  #
33
- # @note module_function: when included, also defines # (instance visibility: private)
34
- # @private
33
+ # @note module_function: defines #literal_type_for (visibility: private)
35
34
  # @param [Symbol] type node type
36
35
  # @return [String, nil]
37
36
  def literal_type_for(type)
@@ -40,10 +39,8 @@ module Docscribe
40
39
 
41
40
  # Extract a constant name from a `:const` node.
42
41
  #
43
- # @note module_function: when included, also defines # (instance visibility: private)
44
- # @private
45
- # @param [Parser::AST::Node] node
46
- # @param [String] fallback_type
42
+ # @note module_function: defines #const_type_for (visibility: private)
43
+ # @param [Parser::AST::Node] node literal/value node
47
44
  # @param [String] _fallback_type fallback type string (unused here)
48
45
  # @return [String, nil]
49
46
  def const_type_for(node, _fallback_type)
@@ -54,10 +51,8 @@ module Docscribe
54
51
 
55
52
  # Extract a type from a `Foo.new` send node.
56
53
  #
57
- # @note module_function: when included, also defines # (instance visibility: private)
58
- # @private
59
- # @param [Parser::AST::Node] node
60
- # @param [String] fallback_type
54
+ # @note module_function: defines #send_new_type_for (visibility: private)
55
+ # @param [Parser::AST::Node] node literal/value node
61
56
  # @param [String] _fallback_type fallback type string (unused here)
62
57
  # @return [String, nil]
63
58
  def send_new_type_for(node, _fallback_type)
@@ -15,7 +15,7 @@ module Docscribe
15
15
  #
16
16
  # Returns nil for unsupported nodes.
17
17
  #
18
- # @note module_function: when included, also defines #const_full_name (instance visibility: private)
18
+ # @note module_function: defines #const_full_name (visibility: private)
19
19
  # @param [Parser::AST::Node, nil] node constant-like AST node
20
20
  # @return [String, nil]
21
21
  def const_full_name(node)
@@ -31,8 +31,7 @@ module Docscribe
31
31
 
32
32
  # Build the fully qualified name from a `:const` node.
33
33
  #
34
- # @note module_function: when included, also defines # (instance visibility: private)
35
- # @private
34
+ # @note module_function: defines #build_const_full_name (visibility: private)
36
35
  # @param [Parser::AST::Node] node a `:const` node
37
36
  # @return [String]
38
37
  def build_const_full_name(node)
@@ -15,12 +15,11 @@ module Docscribe
15
15
  # - special-casing `options:` as `Hash` when enabled
16
16
  # - literal defaults via AST parsing
17
17
  #
18
- # @note module_function: when included, also defines #infer_param_type (instance visibility: private)
18
+ # @note module_function: defines #infer_param_type (visibility: private)
19
19
  # @param [String] name parameter name as used internally (may include `*`, `**`, `&`, or trailing `:`)
20
- # @param [String, nil] default_str source for the default value expression
20
+ # @param [String?] default_str source for the default value expression
21
21
  # @param [String] fallback_type type returned when inference is uncertain
22
22
  # @param [Boolean] treat_options_keyword_as_hash whether `options:` should
23
- # be treated specially as Hash
24
23
  # @return [String]
25
24
  def infer_param_type(name, default_str, fallback_type: FALLBACK_TYPE, treat_options_keyword_as_hash: true)
26
25
  prefix_param_type(name) || inferred_param_type(name, default_str, fallback_type,
@@ -29,8 +28,7 @@ module Docscribe
29
28
 
30
29
  # Return type for special parameter prefixes.
31
30
  #
32
- # @note module_function: when included, also defines # (instance visibility: private)
33
- # @private
31
+ # @note module_function: defines #prefix_param_type (visibility: private)
34
32
  # @param [String] name parameter name
35
33
  # @return [String, nil]
36
34
  def prefix_param_type(name)
@@ -43,12 +41,11 @@ module Docscribe
43
41
 
44
42
  # Infer type for a regular or keyword parameter with optional default.
45
43
  #
46
- # @note module_function: when included, also defines # (instance visibility: private)
47
- # @private
44
+ # @note module_function: defines #inferred_param_type (visibility: private)
48
45
  # @param [String] name parameter name
49
- # @param [String, nil] default_str default expression source
50
- # @param [String] fallback_type
51
- # @param [Boolean] treat_options_keyword_as_hash
46
+ # @param [String?] default_str default expression source
47
+ # @param [String] fallback_type type returned when not special-cased
48
+ # @param [Boolean] treat_options_keyword_as_hash whether to treat 'options:' as Hash
52
49
  # @return [String]
53
50
  def inferred_param_type(name, default_str, fallback_type, treat_options_keyword_as_hash:)
54
51
  if name.end_with?(':') && default_str.nil?
@@ -65,7 +62,7 @@ module Docscribe
65
62
 
66
63
  # Return 'Hash' for a keyword parameter named 'options:' when special-cased, else fallback.
67
64
  #
68
- # @note module_function: when included, also defines #options_keyword_type (instance visibility: private)
65
+ # @note module_function: defines #options_keyword_type (visibility: private)
69
66
  # @param [String] name parameter name
70
67
  # @param [Boolean] treat_options_keyword_as_hash whether to treat 'options:' as Hash
71
68
  # @param [String] fallback_type type returned when not special-cased
@@ -76,9 +73,9 @@ module Docscribe
76
73
 
77
74
  # Whether a keyword parameter named 'options:' with a hash default should be typed as Hash.
78
75
  #
79
- # @note module_function: when included, also defines #options_hash_keyword? (instance visibility: private)
76
+ # @note module_function: defines #options_hash_keyword? (visibility: private)
80
77
  # @param [String] name parameter name
81
- # @param [String, nil] default_str default expression source
78
+ # @param [String?] default_str default expression source
82
79
  # @param [String] type inferred type
83
80
  # @param [Boolean] treat_options_keyword_as_hash whether to treat 'options:' as Hash
84
81
  # @return [Boolean]
@@ -90,17 +87,18 @@ module Docscribe
90
87
  #
91
88
  # Returns nil if the expression is empty or cannot be parsed.
92
89
  #
93
- # @note module_function: when included, also defines #parse_expr (instance visibility: private)
94
- # @param [String, nil] src expression source
90
+ # @note module_function: defines #parse_expr (visibility: private)
91
+ # @param [String?] src expression source
95
92
  # @raise [Parser::SyntaxError]
96
- # @return [Parser::AST::Node, nil]
93
+ # @return [Parser::AST::Node, nil] if Parser::SyntaxError
94
+ # @return [nil] if Parser::SyntaxError
97
95
  def parse_expr(src)
98
96
  return nil if src.nil? || src.strip.empty?
99
97
 
100
98
  buffer = Parser::Source::Buffer.new('(param)')
101
99
  buffer.source = src
102
100
  Docscribe::Parsing.parse_buffer(buffer)
103
- rescue Parser::SyntaxError
101
+ rescue Parser::SyntaxError # steep:ignore
104
102
  nil
105
103
  end
106
104
  end
@@ -16,7 +16,7 @@ module Docscribe
16
16
  #
17
17
  # Returns unique exception names in discovery order.
18
18
  #
19
- # @note module_function: when included, also defines #infer_raises_from_node (instance visibility: private)
19
+ # @note module_function: defines #infer_raises_from_node (visibility: private)
20
20
  # @param [Parser::AST::Node] node method or expression node to inspect
21
21
  # @return [Array<String>]
22
22
  def infer_raises_from_node(node)
@@ -41,8 +41,7 @@ module Docscribe
41
41
  # - `Foo` => `["Foo"]`
42
42
  # - `[Foo, Bar]` => `["Foo", "Bar"]`
43
43
  #
44
- # @note module_function: when included, also defines
45
- # #exception_names_from_rescue_list (instance visibility: private)
44
+ # @note module_function: defines #exception_names_from_rescue_list (visibility: private)
46
45
  # @param [Parser::AST::Node, nil] exc_list rescue exception list node
47
46
  # @return [Array<String>]
48
47
  def exception_names_from_rescue_list(exc_list)
@@ -57,8 +56,7 @@ module Docscribe
57
56
 
58
57
  # Collect exception names from a `raise` or `fail` send node.
59
58
  #
60
- # @note module_function: when included, also defines # (instance visibility: private)
61
- # @private
59
+ # @note module_function: defines #collect_send_raise (visibility: private)
62
60
  # @param [Array<String>] raises accumulator
63
61
  # @param [Parser::AST::Node] node send node
64
62
  # @return [void]