solargraph 0.56.0 → 0.58.2

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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +6 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +92 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +110 -109
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +193 -175
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -266
  22. data/lib/solargraph/api_map.rb +945 -973
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -222
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  26. data/lib/solargraph/complex_type.rb +444 -423
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
  35. data/lib/solargraph/convention/struct_definition.rb +164 -101
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  38. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  41. data/lib/solargraph/doc_map.rb +439 -405
  42. data/lib/solargraph/environ.rb +9 -2
  43. data/lib/solargraph/equality.rb +34 -33
  44. data/lib/solargraph/gem_pins.rb +98 -88
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  47. data/lib/solargraph/language_server/host/message_worker.rb +112 -109
  48. data/lib/solargraph/language_server/host/sources.rb +99 -99
  49. data/lib/solargraph/language_server/host.rb +878 -871
  50. data/lib/solargraph/language_server/message/base.rb +2 -1
  51. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  52. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  53. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  54. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  55. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  56. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  57. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  58. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  60. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  61. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  62. data/lib/solargraph/language_server/progress.rb +8 -0
  63. data/lib/solargraph/language_server/request.rb +4 -1
  64. data/lib/solargraph/library.rb +683 -666
  65. data/lib/solargraph/location.rb +82 -79
  66. data/lib/solargraph/logging.rb +37 -28
  67. data/lib/solargraph/page.rb +3 -0
  68. data/lib/solargraph/parser/comment_ripper.rb +69 -62
  69. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
  70. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  71. data/lib/solargraph/parser/node_processor.rb +62 -46
  72. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  73. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  75. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
  76. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  77. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  78. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  79. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
  80. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  81. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  82. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
  83. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  84. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  85. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  86. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  87. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
  88. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  89. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
  90. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  91. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
  92. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
  95. data/lib/solargraph/parser/region.rb +69 -66
  96. data/lib/solargraph/parser/snippet.rb +17 -15
  97. data/lib/solargraph/pin/base.rb +729 -651
  98. data/lib/solargraph/pin/base_variable.rb +126 -125
  99. data/lib/solargraph/pin/block.rb +104 -103
  100. data/lib/solargraph/pin/breakable.rb +9 -9
  101. data/lib/solargraph/pin/callable.rb +231 -218
  102. data/lib/solargraph/pin/closure.rb +72 -74
  103. data/lib/solargraph/pin/common.rb +79 -75
  104. data/lib/solargraph/pin/constant.rb +2 -0
  105. data/lib/solargraph/pin/conversions.rb +123 -123
  106. data/lib/solargraph/pin/delegated_method.rb +120 -120
  107. data/lib/solargraph/pin/documenting.rb +114 -114
  108. data/lib/solargraph/pin/instance_variable.rb +34 -34
  109. data/lib/solargraph/pin/keyword.rb +20 -20
  110. data/lib/solargraph/pin/local_variable.rb +75 -76
  111. data/lib/solargraph/pin/method.rb +672 -651
  112. data/lib/solargraph/pin/method_alias.rb +34 -31
  113. data/lib/solargraph/pin/namespace.rb +115 -115
  114. data/lib/solargraph/pin/parameter.rb +275 -261
  115. data/lib/solargraph/pin/proxy_type.rb +39 -35
  116. data/lib/solargraph/pin/reference/override.rb +47 -33
  117. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  118. data/lib/solargraph/pin/reference.rb +39 -22
  119. data/lib/solargraph/pin/search.rb +61 -56
  120. data/lib/solargraph/pin/signature.rb +61 -59
  121. data/lib/solargraph/pin/symbol.rb +53 -48
  122. data/lib/solargraph/pin/until.rb +18 -18
  123. data/lib/solargraph/pin/while.rb +18 -18
  124. data/lib/solargraph/pin.rb +44 -44
  125. data/lib/solargraph/pin_cache.rb +245 -185
  126. data/lib/solargraph/position.rb +132 -116
  127. data/lib/solargraph/range.rb +112 -107
  128. data/lib/solargraph/rbs_map/conversions.rb +823 -773
  129. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  130. data/lib/solargraph/rbs_map/core_map.rb +58 -51
  131. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  132. data/lib/solargraph/rbs_map.rb +163 -150
  133. data/lib/solargraph/shell.rb +352 -268
  134. data/lib/solargraph/source/chain/call.rb +337 -333
  135. data/lib/solargraph/source/chain/constant.rb +26 -89
  136. data/lib/solargraph/source/chain/hash.rb +34 -34
  137. data/lib/solargraph/source/chain/if.rb +28 -28
  138. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/link.rb +11 -2
  140. data/lib/solargraph/source/chain/literal.rb +48 -48
  141. data/lib/solargraph/source/chain/or.rb +23 -23
  142. data/lib/solargraph/source/chain.rb +291 -282
  143. data/lib/solargraph/source/change.rb +82 -82
  144. data/lib/solargraph/source/cursor.rb +166 -167
  145. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  146. data/lib/solargraph/source/source_chainer.rb +194 -194
  147. data/lib/solargraph/source/updater.rb +55 -55
  148. data/lib/solargraph/source.rb +498 -495
  149. data/lib/solargraph/source_map/clip.rb +226 -234
  150. data/lib/solargraph/source_map/data.rb +34 -30
  151. data/lib/solargraph/source_map/mapper.rb +259 -259
  152. data/lib/solargraph/source_map.rb +212 -200
  153. data/lib/solargraph/type_checker/checks.rb +124 -124
  154. data/lib/solargraph/type_checker/param_def.rb +37 -35
  155. data/lib/solargraph/type_checker/problem.rb +32 -32
  156. data/lib/solargraph/type_checker/rules.rb +84 -62
  157. data/lib/solargraph/type_checker.rb +814 -699
  158. data/lib/solargraph/version.rb +5 -5
  159. data/lib/solargraph/workspace/config.rb +255 -239
  160. data/lib/solargraph/workspace/require_paths.rb +97 -0
  161. data/lib/solargraph/workspace.rb +220 -249
  162. data/lib/solargraph/yard_map/helpers.rb +44 -16
  163. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  164. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
  165. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  166. data/lib/solargraph/yard_map/mapper.rb +79 -79
  167. data/lib/solargraph/yard_map/to_method.rb +89 -88
  168. data/lib/solargraph/yardoc.rb +87 -49
  169. data/lib/solargraph.rb +105 -90
  170. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  171. data/rbs/fills/open3/0/open3.rbs +172 -0
  172. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  173. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  174. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  175. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  176. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  177. data/rbs/shims/ast/0/node.rbs +5 -0
  178. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  179. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  180. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  181. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  182. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  183. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  184. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  185. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  186. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  187. data/rbs_collection.yaml +4 -4
  188. data/solargraph.gemspec +26 -5
  189. metadata +187 -15
  190. data/lib/.rubocop.yml +0 -22
  191. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -1,125 +1,126 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- class BaseVariable < Base
6
- include Solargraph::Parser::NodeMethods
7
- # include Solargraph::Source::NodeMethods
8
-
9
- # @return [Parser::AST::Node, nil]
10
- attr_reader :assignment
11
-
12
- attr_accessor :mass_assignment
13
-
14
- # @param return_type [ComplexType, nil]
15
- # @param assignment [Parser::AST::Node, nil]
16
- def initialize assignment: nil, return_type: nil, **splat
17
- super(**splat)
18
- @assignment = assignment
19
- # @type [nil, ::Array(Parser::AST::Node, Integer)]
20
- @mass_assignment = nil
21
- @return_type = return_type
22
- end
23
-
24
- def combine_with(other, attrs={})
25
- attrs.merge({
26
- assignment: assert_same(other, :assignment),
27
- mass_assignment: assert_same(other, :mass_assignment),
28
- return_type: combine_return_type(other),
29
- })
30
- super(other, attrs)
31
- end
32
-
33
- def completion_item_kind
34
- Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
35
- end
36
-
37
- # @return [Integer]
38
- def symbol_kind
39
- Solargraph::LanguageServer::SymbolKinds::VARIABLE
40
- end
41
-
42
- def return_type
43
- @return_type ||= generate_complex_type
44
- end
45
-
46
- # @sg-ignore
47
- def nil_assignment?
48
- # this will always be false - should it be return_type ==
49
- # ComplexType::NIL or somesuch?
50
- return_type.nil?
51
- end
52
-
53
- def variable?
54
- true
55
- end
56
-
57
- # @param parent_node [Parser::AST::Node]
58
- # @param api_map [ApiMap]
59
- # @return [::Array<ComplexType>]
60
- def return_types_from_node(parent_node, api_map)
61
- types = []
62
- value_position_nodes_only(parent_node).each do |node|
63
- # Nil nodes may not have a location
64
- if node.nil? || node.type == :NIL || node.type == :nil
65
- types.push ComplexType::NIL
66
- else
67
- rng = Range.from_node(node)
68
- next if rng.nil?
69
- pos = rng.ending
70
- clip = api_map.clip_at(location.filename, pos)
71
- # Use the return node for inference. The clip might infer from the
72
- # first node in a method call instead of the entire call.
73
- chain = Parser.chain(node, nil, nil)
74
- result = chain.infer(api_map, closure, clip.locals).self_to_type(closure.context)
75
- types.push result unless result.undefined?
76
- end
77
- end
78
- types
79
- end
80
-
81
- # @param api_map [ApiMap]
82
- # @return [ComplexType]
83
- def probe api_map
84
- unless @assignment.nil?
85
- types = return_types_from_node(@assignment, api_map)
86
- return ComplexType.new(types.uniq) unless types.empty?
87
- end
88
-
89
- unless @mass_assignment.nil?
90
- mass_node, index = @mass_assignment
91
- types = return_types_from_node(mass_node, api_map)
92
- types.map! do |type|
93
- if type.tuple?
94
- type.all_params[index]
95
- elsif ['::Array', '::Set', '::Enumerable'].include?(type.rooted_name)
96
- type.all_params.first
97
- end
98
- end.compact!
99
- return ComplexType.new(types.uniq) unless types.empty?
100
- end
101
-
102
- ComplexType::UNDEFINED
103
- end
104
-
105
- # @param other [Object]
106
- def == other
107
- return false unless super
108
- assignment == other.assignment
109
- end
110
-
111
- def type_desc
112
- "#{super} = #{assignment&.type.inspect}"
113
- end
114
-
115
- private
116
-
117
- # @return [ComplexType]
118
- def generate_complex_type
119
- tag = docstring.tag(:type)
120
- return ComplexType.try_parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
121
- ComplexType.new
122
- end
123
- end
124
- end
125
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class BaseVariable < Base
6
+ # include Solargraph::Source::NodeMethods
7
+ include Solargraph::Parser::NodeMethods
8
+
9
+ # @return [Parser::AST::Node, nil]
10
+ attr_reader :assignment
11
+
12
+ attr_accessor :mass_assignment
13
+
14
+ # @param return_type [ComplexType, nil]
15
+ # @param mass_assignment [::Array(Parser::AST::Node, Integer), nil]
16
+ # @param assignment [Parser::AST::Node, nil]
17
+ def initialize assignment: nil, return_type: nil, mass_assignment: nil, **splat
18
+ super(**splat)
19
+ @assignment = assignment
20
+ # @type [nil, ::Array(Parser::AST::Node, Integer)]
21
+ @mass_assignment = nil
22
+ @return_type = return_type
23
+ end
24
+
25
+ def combine_with(other, attrs={})
26
+ new_attrs = attrs.merge({
27
+ assignment: assert_same(other, :assignment),
28
+ mass_assignment: assert_same(other, :mass_assignment),
29
+ return_type: combine_return_type(other),
30
+ })
31
+ super(other, new_attrs)
32
+ end
33
+
34
+ def completion_item_kind
35
+ Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
36
+ end
37
+
38
+ # @return [Integer]
39
+ def symbol_kind
40
+ Solargraph::LanguageServer::SymbolKinds::VARIABLE
41
+ end
42
+
43
+ def return_type
44
+ @return_type ||= generate_complex_type
45
+ end
46
+
47
+ def nil_assignment?
48
+ # this will always be false - should it be return_type ==
49
+ # ComplexType::NIL or somesuch?
50
+ return_type.nil?
51
+ end
52
+
53
+ def variable?
54
+ true
55
+ end
56
+
57
+ # @param parent_node [Parser::AST::Node]
58
+ # @param api_map [ApiMap]
59
+ # @return [::Array<ComplexType>]
60
+ def return_types_from_node(parent_node, api_map)
61
+ types = []
62
+ value_position_nodes_only(parent_node).each do |node|
63
+ # Nil nodes may not have a location
64
+ if node.nil? || node.type == :NIL || node.type == :nil
65
+ types.push ComplexType::NIL
66
+ else
67
+ rng = Range.from_node(node)
68
+ next if rng.nil?
69
+ pos = rng.ending
70
+ clip = api_map.clip_at(location.filename, pos)
71
+ # Use the return node for inference. The clip might infer from the
72
+ # first node in a method call instead of the entire call.
73
+ chain = Parser.chain(node, nil, nil)
74
+ result = chain.infer(api_map, closure, clip.locals).self_to_type(closure.context)
75
+ types.push result unless result.undefined?
76
+ end
77
+ end
78
+ types
79
+ end
80
+
81
+ # @param api_map [ApiMap]
82
+ # @return [ComplexType]
83
+ def probe api_map
84
+ unless @assignment.nil?
85
+ types = return_types_from_node(@assignment, api_map)
86
+ return ComplexType.new(types.uniq) unless types.empty?
87
+ end
88
+
89
+ unless @mass_assignment.nil?
90
+ mass_node, index = @mass_assignment
91
+ types = return_types_from_node(mass_node, api_map)
92
+ types.map! do |type|
93
+ if type.tuple?
94
+ type.all_params[index]
95
+ elsif ['::Array', '::Set', '::Enumerable'].include?(type.rooted_name)
96
+ type.all_params.first
97
+ end
98
+ end.compact!
99
+ return ComplexType.new(types.uniq) unless types.empty?
100
+ end
101
+
102
+ ComplexType::UNDEFINED
103
+ end
104
+
105
+ # @param other [Object]
106
+ def == other
107
+ return false unless super
108
+ # @sg-ignore Should add type check on other
109
+ assignment == other.assignment
110
+ end
111
+
112
+ def type_desc
113
+ "#{super} = #{assignment&.type.inspect}"
114
+ end
115
+
116
+ private
117
+
118
+ # @return [ComplexType]
119
+ def generate_complex_type
120
+ tag = docstring.tag(:type)
121
+ return ComplexType.try_parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
122
+ ComplexType.new
123
+ end
124
+ end
125
+ end
126
+ end
@@ -1,103 +1,104 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- class Block < Callable
6
- include Breakable
7
-
8
- # @return [Parser::AST::Node]
9
- attr_reader :receiver
10
-
11
- # @return [Parser::AST::Node]
12
- attr_reader :node
13
-
14
- # @param receiver [Parser::AST::Node, nil]
15
- # @param node [Parser::AST::Node, nil]
16
- # @param context [ComplexType, nil]
17
- # @param args [::Array<Parameter>]
18
- def initialize receiver: nil, args: [], context: nil, node: nil, **splat
19
- super(**splat, parameters: args)
20
- @receiver = receiver
21
- @context = context
22
- @return_type = ComplexType.parse('::Proc')
23
- @node = node
24
- end
25
-
26
- # @param api_map [ApiMap]
27
- # @return [void]
28
- def rebind api_map
29
- @rebind ||= maybe_rebind(api_map)
30
- end
31
-
32
- def binder
33
- @rebind&.defined? ? @rebind : closure.binder
34
- end
35
-
36
- # @param yield_types [::Array<ComplexType>]
37
- # @param parameters [::Array<Parameter>]
38
- #
39
- # @return [::Array<ComplexType>]
40
- def destructure_yield_types(yield_types, parameters)
41
- # yielding a tuple into a block will destructure the tuple
42
- if yield_types.length == 1
43
- yield_type = yield_types.first
44
- return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
45
- end
46
- parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
47
- end
48
-
49
- # @param api_map [ApiMap]
50
- # @return [::Array<ComplexType>]
51
- def typify_parameters(api_map)
52
- chain = Parser.chain(receiver, filename, node)
53
- clip = api_map.clip_at(location.filename, location.range.start)
54
- locals = clip.locals - [self]
55
- meths = chain.define(api_map, closure, locals)
56
- # @todo Convert logic to use signatures
57
- meths.each do |meth|
58
- next if meth.block.nil?
59
-
60
- yield_types = meth.block.parameters.map(&:return_type)
61
- # 'arguments' is what the method says it will yield to the
62
- # block; 'parameters' is what the block accepts
63
- argument_types = destructure_yield_types(yield_types, parameters)
64
- param_types = argument_types.each_with_index.map do |arg_type, idx|
65
- param = parameters[idx]
66
- param_type = chain.base.infer(api_map, param, locals)
67
- unless arg_type.nil?
68
- if arg_type.generic? && param_type.defined?
69
- namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
70
- arg_type.resolve_generics(namespace_pin, param_type)
71
- else
72
- arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.context.namespace)
73
- end
74
- end
75
- end
76
- return param_types if param_types.all?(&:defined?)
77
- end
78
- parameters.map { ComplexType::UNDEFINED }
79
- end
80
-
81
- private
82
-
83
- # @param api_map [ApiMap]
84
- # @return [ComplexType]
85
- def maybe_rebind api_map
86
- return ComplexType::UNDEFINED unless receiver
87
-
88
- chain = Parser.chain(receiver, location.filename)
89
- locals = api_map.source_map(location.filename).locals_at(location)
90
- receiver_pin = chain.define(api_map, closure, locals).first
91
- return ComplexType::UNDEFINED unless receiver_pin
92
-
93
- types = receiver_pin.docstring.tag(:yieldreceiver)&.types
94
- return ComplexType::UNDEFINED unless types&.any?
95
-
96
- target = chain.base.infer(api_map, receiver_pin, locals)
97
- target = full_context unless target.defined?
98
-
99
- ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to_type(target)
100
- end
101
- end
102
- end
103
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Block < Callable
6
+ include Breakable
7
+
8
+ # @return [Parser::AST::Node]
9
+ attr_reader :receiver
10
+
11
+ # @return [Parser::AST::Node]
12
+ attr_reader :node
13
+
14
+ # @param receiver [Parser::AST::Node, nil]
15
+ # @param node [Parser::AST::Node, nil]
16
+ # @param context [ComplexType, nil]
17
+ # @param args [::Array<Parameter>]
18
+ def initialize receiver: nil, args: [], context: nil, node: nil, **splat
19
+ super(**splat, parameters: args)
20
+ @receiver = receiver
21
+ @context = context
22
+ @return_type = ComplexType.parse('::Proc')
23
+ @node = node
24
+ end
25
+
26
+ # @param api_map [ApiMap]
27
+ # @return [void]
28
+ def rebind api_map
29
+ @rebind ||= maybe_rebind(api_map)
30
+ end
31
+
32
+ def binder
33
+ @rebind&.defined? ? @rebind : closure.binder
34
+ end
35
+
36
+ # @param yield_types [::Array<ComplexType>]
37
+ # @param parameters [::Array<Parameter>]
38
+ #
39
+ # @return [::Array<ComplexType>]
40
+ def destructure_yield_types(yield_types, parameters)
41
+ # yielding a tuple into a block will destructure the tuple
42
+ if yield_types.length == 1
43
+ yield_type = yield_types.first
44
+ return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
45
+ end
46
+ parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
47
+ end
48
+
49
+ # @param api_map [ApiMap]
50
+ # @return [::Array<ComplexType>]
51
+ def typify_parameters(api_map)
52
+ chain = Parser.chain(receiver, filename, node)
53
+ clip = api_map.clip_at(location.filename, location.range.start)
54
+ locals = clip.locals - [self]
55
+ meths = chain.define(api_map, closure, locals)
56
+ # @todo Convert logic to use signatures
57
+ # @param meth [Pin::Method]
58
+ meths.each do |meth|
59
+ next if meth.block.nil?
60
+
61
+ yield_types = meth.block.parameters.map(&:return_type)
62
+ # 'arguments' is what the method says it will yield to the
63
+ # block; 'parameters' is what the block accepts
64
+ argument_types = destructure_yield_types(yield_types, parameters)
65
+ param_types = argument_types.each_with_index.map do |arg_type, idx|
66
+ param = parameters[idx]
67
+ param_type = chain.base.infer(api_map, param, locals)
68
+ unless arg_type.nil?
69
+ if arg_type.generic? && param_type.defined?
70
+ namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
71
+ arg_type.resolve_generics(namespace_pin, param_type)
72
+ else
73
+ arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, *meth.gates)
74
+ end
75
+ end
76
+ end
77
+ return param_types if param_types.all?(&:defined?)
78
+ end
79
+ parameters.map { ComplexType::UNDEFINED }
80
+ end
81
+
82
+ private
83
+
84
+ # @param api_map [ApiMap]
85
+ # @return [ComplexType]
86
+ def maybe_rebind api_map
87
+ return ComplexType::UNDEFINED unless receiver
88
+
89
+ chain = Parser.chain(receiver, location.filename)
90
+ locals = api_map.source_map(location.filename).locals_at(location)
91
+ receiver_pin = chain.define(api_map, closure, locals).first
92
+ return ComplexType::UNDEFINED unless receiver_pin
93
+
94
+ types = receiver_pin.docstring.tag(:yieldreceiver)&.types
95
+ return ComplexType::UNDEFINED unless types&.any?
96
+
97
+ target = chain.base.infer(api_map, receiver_pin, locals)
98
+ target = full_context unless target.defined?
99
+
100
+ ComplexType.try_parse(*types).qualify(api_map, *receiver_pin.gates).self_to_type(target)
101
+ end
102
+ end
103
+ end
104
+ end
@@ -1,9 +1,9 @@
1
- module Solargraph
2
- module Pin
3
- # Mix-in for pins which enclose code which the 'break' statement works with-in - e.g., blocks, when, until, ...
4
- module Breakable
5
- # @return [Parser::AST::Node]
6
- attr_reader :node
7
- end
8
- end
9
- end
1
+ module Solargraph
2
+ module Pin
3
+ # Mix-in for pins which enclose code which the 'break' statement works with-in - e.g., blocks, when, until, ...
4
+ module Breakable
5
+ # @return [Parser::AST::Node]
6
+ attr_reader :node
7
+ end
8
+ end
9
+ end