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.
- checksums.yaml +4 -4
- data/README.md +465 -130
- data/lib/docscribe/cli/check_for_comments.rb +183 -0
- data/lib/docscribe/cli/config_builder.rb +107 -53
- data/lib/docscribe/cli/formatters/json.rb +294 -0
- data/lib/docscribe/cli/formatters/sarif.rb +235 -0
- data/lib/docscribe/cli/formatters/text.rb +208 -0
- data/lib/docscribe/cli/formatters.rb +26 -0
- data/lib/docscribe/cli/generate.rb +45 -45
- data/lib/docscribe/cli/init.rb +14 -6
- data/lib/docscribe/cli/options.rb +190 -88
- data/lib/docscribe/cli/rbs_gen.rb +529 -0
- data/lib/docscribe/cli/run.rb +210 -152
- data/lib/docscribe/cli/sigs.rb +366 -0
- data/lib/docscribe/cli/update_types.rb +103 -0
- data/lib/docscribe/cli.rb +21 -13
- data/lib/docscribe/config/defaults.rb +5 -1
- data/lib/docscribe/config/emit.rb +17 -0
- data/lib/docscribe/config/filtering.rb +18 -25
- data/lib/docscribe/config/loader.rb +15 -11
- data/lib/docscribe/config/plugin.rb +1 -1
- data/lib/docscribe/config/rbs.rb +41 -9
- data/lib/docscribe/config/sorbet.rb +9 -12
- data/lib/docscribe/config/sorting.rb +1 -1
- data/lib/docscribe/config/template.rb +9 -1
- data/lib/docscribe/config/utils.rb +11 -9
- data/lib/docscribe/config.rb +2 -4
- data/lib/docscribe/infer/ast_walk.rb +1 -1
- data/lib/docscribe/infer/literals.rb +6 -11
- data/lib/docscribe/infer/names.rb +2 -3
- data/lib/docscribe/infer/params.rb +15 -17
- data/lib/docscribe/infer/raises.rb +3 -5
- data/lib/docscribe/infer/returns.rb +542 -140
- data/lib/docscribe/infer.rb +22 -23
- data/lib/docscribe/inline_rewriter/collector.rb +159 -164
- data/lib/docscribe/inline_rewriter/doc_block.rb +145 -115
- data/lib/docscribe/inline_rewriter/doc_builder.rb +1026 -723
- data/lib/docscribe/inline_rewriter/source_helpers.rb +49 -49
- data/lib/docscribe/inline_rewriter/tag_sorter.rb +82 -85
- data/lib/docscribe/inline_rewriter.rb +495 -492
- data/lib/docscribe/parsing.rb +29 -10
- data/lib/docscribe/plugin/base/collector_plugin.rb +2 -1
- data/lib/docscribe/plugin/base/tag_plugin.rb +0 -1
- data/lib/docscribe/plugin/context.rb +28 -18
- data/lib/docscribe/plugin/registry.rb +26 -27
- data/lib/docscribe/plugin/tag.rb +9 -14
- data/lib/docscribe/plugin.rb +17 -16
- data/lib/docscribe/types/provider_chain.rb +4 -2
- data/lib/docscribe/types/rbs/collection_loader.rb +2 -2
- data/lib/docscribe/types/rbs/provider.rb +60 -44
- data/lib/docscribe/types/rbs/type_formatter.rb +224 -83
- data/lib/docscribe/types/signature.rb +22 -42
- data/lib/docscribe/types/sorbet/base_provider.rb +24 -19
- data/lib/docscribe/types/sorbet/rbi_provider.rb +3 -3
- data/lib/docscribe/types/sorbet/source_provider.rb +3 -2
- data/lib/docscribe/types/yard/formatter.rb +100 -0
- data/lib/docscribe/types/yard/parser.rb +240 -0
- data/lib/docscribe/types/yard/types.rb +52 -0
- data/lib/docscribe/version.rb +1 -1
- 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
|
|
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
|
-
|
|
35
|
-
|
|
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
|
|
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
|
-
|
|
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'
|
data/lib/docscribe/config/rbs.rb
CHANGED
|
@@ -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
|
-
#
|
|
28
|
-
#
|
|
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 [
|
|
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
|
-
# @
|
|
29
|
-
# @param [
|
|
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
|
-
# @
|
|
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
|
-
# @
|
|
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.
|
|
@@ -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
|
|
data/lib/docscribe/config.rb
CHANGED
|
@@ -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,
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
44
|
-
# @
|
|
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:
|
|
58
|
-
# @
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
47
|
-
# @private
|
|
44
|
+
# @note module_function: defines #inferred_param_type (visibility: private)
|
|
48
45
|
# @param [String] name parameter name
|
|
49
|
-
# @param [String
|
|
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:
|
|
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:
|
|
76
|
+
# @note module_function: defines #options_hash_keyword? (visibility: private)
|
|
80
77
|
# @param [String] name parameter name
|
|
81
|
-
# @param [String
|
|
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:
|
|
94
|
-
# @param [String
|
|
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:
|
|
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:
|
|
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:
|
|
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]
|