docscribe 1.5.2 → 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.
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Docscribe
4
+ module Types
5
+ # Selects best matching overload from RBS signatures for given arguments.
6
+ module OverloadSelector
7
+ class << self
8
+ # @param [Array<Object>] overloads
9
+ # @param [Integer] arg_count
10
+ # @param [Array<String>] param_names
11
+ # @return [Object?]
12
+ def select(overloads, arg_count:, param_names: [])
13
+ return nil if overloads.nil? || overloads.empty?
14
+ return overloads.first if overloads.size == 1
15
+
16
+ best = best_match(overloads, arg_count, param_names)
17
+ best&.first || overloads.first
18
+ end
19
+
20
+ # @param [Array<Object>] overloads
21
+ # @param [Integer] arg_count
22
+ # @param [Array<String>] param_names
23
+ # @return [(Object, Integer)?]
24
+ def best_match(overloads, arg_count, param_names)
25
+ candidates = overloads.map { |sig| score_signature(sig, arg_count: arg_count, param_names: param_names) }
26
+ candidates.compact.max_by { |_sig, score| score }
27
+ end
28
+
29
+ private
30
+
31
+ # @private
32
+ # @param [Object] sig
33
+ # @param [Integer] arg_count
34
+ # @param [Array<String>] param_names
35
+ # @return [(Object, Integer)?]
36
+ def score_signature(sig, arg_count:, param_names:)
37
+ score = 0
38
+
39
+ pos_count = sig.positional_types&.length.to_i
40
+ return nil if pos_count > arg_count
41
+
42
+ score += score_positional(pos_count, arg_count, sig)
43
+ score += score_params(sig, param_names)
44
+ score += 3 if sig.return_type && !sig.return_type.empty?
45
+ score += 1 if sig.return_type && sig.return_type != 'Object'
46
+
47
+ [sig, score]
48
+ end
49
+
50
+ # @private
51
+ # @param [Integer] pos_count
52
+ # @param [Integer] arg_count
53
+ # @param [Object] sig
54
+ # @return [Integer]
55
+ def score_positional(pos_count, arg_count, sig)
56
+ if pos_count == arg_count
57
+ 10
58
+ elsif pos_count < arg_count && sig.rest_positional
59
+ 5
60
+ else
61
+ 0
62
+ end
63
+ end
64
+
65
+ # @private
66
+ # @param [Object] sig
67
+ # @param [Array<String>] param_names
68
+ # @return [Integer]
69
+ def score_params(sig, param_names)
70
+ if sig.param_types
71
+ (sig.param_types.keys & param_names).length * 2
72
+ else
73
+ 0
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'overload_selector'
4
+
3
5
  module Docscribe
4
6
  module Types
5
7
  # Resolve method signatures by querying a list of providers in order.
@@ -22,18 +24,39 @@ module Docscribe
22
24
 
23
25
  # Resolve a method signature from the first provider that can supply it.
24
26
  #
27
+ # When overloads are present, selects the best-matching signature.
28
+ #
25
29
  # @param [String] container e.g. "MyModule::MyClass"
26
30
  # @param [Symbol] scope :instance or :class
27
31
  # @param [Symbol, String] name method name
32
+ # @param [Integer?] param_count number of actual arguments
33
+ # @param [Array<String>] param_names actual parameter names
28
34
  # @return [Docscribe::Types::MethodSignature, nil]
29
- def signature_for(container:, scope:, name:)
35
+ def signature_for(container:, scope:, name:, param_count: nil, param_names: [])
30
36
  @providers.each do |provider|
31
37
  sig = provider.signature_for(container: container, scope: scope, name: name)
32
- return sig if sig
38
+ next unless sig
39
+
40
+ return sig unless sig.overloads&.any?
41
+
42
+ best = select_overload(sig, param_count, param_names)
43
+ return best if best
33
44
  end
34
45
 
35
46
  nil
36
47
  end
48
+
49
+ # @param [Docscribe::Types::MethodSignature] sig
50
+ # @param [Integer?] param_count
51
+ # @param [Array<String>] param_names
52
+ # @return [Docscribe::Types::MethodSignature, nil]
53
+ def select_overload(sig, param_count, param_names)
54
+ OverloadSelector.select(
55
+ [sig, *sig.overloads],
56
+ arg_count: param_count || 0,
57
+ param_names: param_names
58
+ )
59
+ end
37
60
  end
38
61
  end
39
62
  end
@@ -21,7 +21,12 @@ module Docscribe
21
21
  # @!attribute [rw] rest_keywords
22
22
  # @return [Docscribe::Types::RestKeywords, nil]
23
23
  # @param [Docscribe::Types::RestKeywords, nil] value
24
+ #
25
+ # @!attribute [rw] overloads
26
+ # @return [Array<Docscribe::Types::MethodSignature>, nil]
27
+ # @param [Array<Docscribe::Types::MethodSignature>, nil] value
24
28
  MethodSignature = Struct.new(:return_type, :param_types, :positional_types, :rest_positional, :rest_keywords,
29
+ :overloads,
25
30
  keyword_init: true)
26
31
 
27
32
  # @!attribute [rw] name
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Docscribe
4
- VERSION = '1.5.2'
4
+ VERSION = '1.6.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docscribe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - unurgunite
@@ -163,6 +163,8 @@ files:
163
163
  - lib/docscribe/cli.rb
164
164
  - lib/docscribe/cli/check_for_comments.rb
165
165
  - lib/docscribe/cli/config_builder.rb
166
+ - lib/docscribe/cli/config_dump.rb
167
+ - lib/docscribe/cli/coverage.rb
166
168
  - lib/docscribe/cli/formatters.rb
167
169
  - lib/docscribe/cli/formatters/json.rb
168
170
  - lib/docscribe/cli/formatters/sarif.rb
@@ -188,6 +190,7 @@ files:
188
190
  - lib/docscribe/config/utils.rb
189
191
  - lib/docscribe/infer.rb
190
192
  - lib/docscribe/infer/ast_walk.rb
193
+ - lib/docscribe/infer/behavior.rb
191
194
  - lib/docscribe/infer/constants.rb
192
195
  - lib/docscribe/infer/literals.rb
193
196
  - lib/docscribe/infer/names.rb
@@ -209,6 +212,11 @@ files:
209
212
  - lib/docscribe/plugin/registry.rb
210
213
  - lib/docscribe/plugin/tag.rb
211
214
  - lib/docscribe/server.rb
215
+ - lib/docscribe/server/base.rb
216
+ - lib/docscribe/server/client.rb
217
+ - lib/docscribe/server/daemon.rb
218
+ - lib/docscribe/server/protocol.rb
219
+ - lib/docscribe/types/overload_selector.rb
212
220
  - lib/docscribe/types/provider_chain.rb
213
221
  - lib/docscribe/types/rbs/collection_loader.rb
214
222
  - lib/docscribe/types/rbs/provider.rb
@@ -230,7 +238,7 @@ metadata:
230
238
  changelog_uri: https://github.com/unurgunite/docscribe/blob/master/CHANGELOG.md
231
239
  rubygems_mfa_required: 'true'
232
240
  post_install_message: |
233
- You installed docscribe 1.5.2. Your future self (and your team) thank you.
241
+ You installed docscribe 1.6.1. Your future self (and your team) thank you.
234
242
 
235
243
  $ docscribe --help
236
244
 
@@ -250,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
258
  - !ruby/object:Gem::Version
251
259
  version: '0'
252
260
  requirements: []
253
- rubygems_version: 4.0.15
261
+ rubygems_version: 4.0.18
254
262
  specification_version: 4
255
263
  summary: Auto-generate inline YARD documentation for Ruby by analyzing code AST. Supports
256
264
  RBS and Sorbet type signatures.