solargraph 0.58.3 → 0.60.4

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 (238) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +12 -5
  4. data/.github/workflows/plugins.yml +53 -37
  5. data/.github/workflows/rspec.yml +18 -28
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.rubocop.yml +39 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +67 -0
  10. data/Gemfile +6 -1
  11. data/README.md +3 -3
  12. data/Rakefile +26 -23
  13. data/bin/solargraph +2 -1
  14. data/lib/solargraph/api_map/cache.rb +3 -3
  15. data/lib/solargraph/api_map/constants.rb +13 -4
  16. data/lib/solargraph/api_map/index.rb +42 -20
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +61 -36
  19. data/lib/solargraph/api_map.rb +191 -78
  20. data/lib/solargraph/bench.rb +2 -3
  21. data/lib/solargraph/complex_type/conformance.rb +176 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +31 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +225 -63
  24. data/lib/solargraph/complex_type.rb +190 -59
  25. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  26. data/lib/solargraph/convention/base.rb +50 -50
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  29. data/lib/solargraph/convention/data_definition.rb +5 -2
  30. data/lib/solargraph/convention/gemfile.rb +1 -1
  31. data/lib/solargraph/convention/gemspec.rb +1 -1
  32. data/lib/solargraph/convention/rakefile.rb +1 -1
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  35. data/lib/solargraph/convention/struct_definition.rb +8 -4
  36. data/lib/solargraph/convention.rb +2 -2
  37. data/lib/solargraph/converters/dd.rb +2 -0
  38. data/lib/solargraph/converters/dl.rb +2 -0
  39. data/lib/solargraph/converters/dt.rb +2 -0
  40. data/lib/solargraph/converters/misc.rb +2 -0
  41. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  42. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  44. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  45. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  46. data/lib/solargraph/diagnostics.rb +55 -55
  47. data/lib/solargraph/doc_map.rb +39 -39
  48. data/lib/solargraph/environ.rb +52 -52
  49. data/lib/solargraph/equality.rb +4 -4
  50. data/lib/solargraph/gem_pins.rb +4 -15
  51. data/lib/solargraph/language_server/error_codes.rb +10 -10
  52. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  53. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  54. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  55. data/lib/solargraph/language_server/host/sources.rb +2 -1
  56. data/lib/solargraph/language_server/host.rb +35 -28
  57. data/lib/solargraph/language_server/message/base.rb +1 -1
  58. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  59. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  61. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  65. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  66. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  67. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  68. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  69. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  70. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  71. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  72. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  73. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  74. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  75. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  76. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  77. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  78. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  79. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  80. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  81. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  82. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  83. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  84. data/lib/solargraph/language_server/message.rb +1 -1
  85. data/lib/solargraph/language_server/progress.rb +143 -143
  86. data/lib/solargraph/language_server/request.rb +4 -2
  87. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  88. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  89. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  90. data/lib/solargraph/language_server.rb +20 -20
  91. data/lib/solargraph/library.rb +63 -40
  92. data/lib/solargraph/location.rb +17 -14
  93. data/lib/solargraph/logging.rb +22 -4
  94. data/lib/solargraph/page.rb +1 -1
  95. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  96. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  97. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  98. data/lib/solargraph/parser/node_processor.rb +8 -7
  99. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  100. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  101. data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
  102. data/lib/solargraph/parser/parser_gem/node_methods.rb +222 -72
  103. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  104. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  105. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  106. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  108. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  109. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  110. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  111. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  112. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  113. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  114. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  115. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  116. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  117. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +73 -40
  118. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  119. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  120. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  121. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  122. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  123. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  124. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  125. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  126. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  127. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  128. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  129. data/lib/solargraph/parser/parser_gem.rb +2 -0
  130. data/lib/solargraph/parser/region.rb +9 -3
  131. data/lib/solargraph/parser/snippet.rb +3 -1
  132. data/lib/solargraph/parser.rb +2 -0
  133. data/lib/solargraph/pin/base.rb +157 -85
  134. data/lib/solargraph/pin/base_variable.rb +273 -24
  135. data/lib/solargraph/pin/block.rb +29 -6
  136. data/lib/solargraph/pin/breakable.rb +7 -1
  137. data/lib/solargraph/pin/callable.rb +67 -23
  138. data/lib/solargraph/pin/closure.rb +7 -10
  139. data/lib/solargraph/pin/common.rb +36 -6
  140. data/lib/solargraph/pin/compound_statement.rb +55 -0
  141. data/lib/solargraph/pin/constant.rb +3 -5
  142. data/lib/solargraph/pin/conversions.rb +10 -4
  143. data/lib/solargraph/pin/delegated_method.rb +19 -8
  144. data/lib/solargraph/pin/documenting.rb +4 -2
  145. data/lib/solargraph/pin/instance_variable.rb +5 -1
  146. data/lib/solargraph/pin/keyword.rb +0 -4
  147. data/lib/solargraph/pin/local_variable.rb +15 -59
  148. data/lib/solargraph/pin/method.rb +208 -113
  149. data/lib/solargraph/pin/method_alias.rb +8 -0
  150. data/lib/solargraph/pin/namespace.rb +19 -12
  151. data/lib/solargraph/pin/parameter.rb +102 -36
  152. data/lib/solargraph/pin/proxy_type.rb +4 -1
  153. data/lib/solargraph/pin/reference/override.rb +1 -1
  154. data/lib/solargraph/pin/reference/require.rb +14 -14
  155. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  156. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  157. data/lib/solargraph/pin/reference.rb +20 -0
  158. data/lib/solargraph/pin/search.rb +8 -7
  159. data/lib/solargraph/pin/signature.rb +15 -12
  160. data/lib/solargraph/pin/singleton.rb +11 -11
  161. data/lib/solargraph/pin/symbol.rb +2 -1
  162. data/lib/solargraph/pin/until.rb +2 -4
  163. data/lib/solargraph/pin/while.rb +2 -4
  164. data/lib/solargraph/pin.rb +2 -0
  165. data/lib/solargraph/pin_cache.rb +22 -19
  166. data/lib/solargraph/position.rb +17 -10
  167. data/lib/solargraph/range.rb +16 -15
  168. data/lib/solargraph/rbs_map/conversions.rb +227 -238
  169. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  170. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  171. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  172. data/lib/solargraph/rbs_map.rb +76 -32
  173. data/lib/solargraph/rbs_translator.rb +206 -0
  174. data/lib/solargraph/server_methods.rb +1 -1
  175. data/lib/solargraph/shell.rb +330 -71
  176. data/lib/solargraph/source/chain/array.rb +3 -12
  177. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  178. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  179. data/lib/solargraph/source/chain/call.rb +159 -89
  180. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  181. data/lib/solargraph/source/chain/constant.rb +5 -1
  182. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  183. data/lib/solargraph/source/chain/hash.rb +8 -5
  184. data/lib/solargraph/source/chain/head.rb +19 -19
  185. data/lib/solargraph/source/chain/if.rb +12 -10
  186. data/lib/solargraph/source/chain/instance_variable.rb +19 -1
  187. data/lib/solargraph/source/chain/link.rb +12 -22
  188. data/lib/solargraph/source/chain/literal.rb +22 -15
  189. data/lib/solargraph/source/chain/or.rb +10 -4
  190. data/lib/solargraph/source/chain/q_call.rb +2 -0
  191. data/lib/solargraph/source/chain/variable.rb +3 -1
  192. data/lib/solargraph/source/chain/z_super.rb +1 -3
  193. data/lib/solargraph/source/chain.rb +87 -43
  194. data/lib/solargraph/source/change.rb +12 -5
  195. data/lib/solargraph/source/cursor.rb +33 -18
  196. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  197. data/lib/solargraph/source/source_chainer.rb +56 -32
  198. data/lib/solargraph/source/updater.rb +5 -1
  199. data/lib/solargraph/source.rb +71 -43
  200. data/lib/solargraph/source_map/clip.rb +54 -30
  201. data/lib/solargraph/source_map/data.rb +4 -1
  202. data/lib/solargraph/source_map/mapper.rb +30 -133
  203. data/lib/solargraph/source_map.rb +35 -9
  204. data/lib/solargraph/type_checker/problem.rb +3 -1
  205. data/lib/solargraph/type_checker/rules.rb +81 -8
  206. data/lib/solargraph/type_checker.rb +208 -125
  207. data/lib/solargraph/version.rb +1 -1
  208. data/lib/solargraph/workspace/config.rb +14 -11
  209. data/lib/solargraph/workspace/gemspecs.rb +373 -0
  210. data/lib/solargraph/workspace/require_paths.rb +1 -0
  211. data/lib/solargraph/workspace.rb +50 -28
  212. data/lib/solargraph/yard_map/cache.rb +25 -25
  213. data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
  214. data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
  215. data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
  216. data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
  217. data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
  218. data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
  219. data/lib/solargraph/yard_map/directives.rb +35 -0
  220. data/lib/solargraph/yard_map/helpers.rb +8 -3
  221. data/lib/solargraph/yard_map/macro.rb +113 -0
  222. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  223. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  224. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  225. data/lib/solargraph/yard_map/mapper.rb +65 -9
  226. data/lib/solargraph/yard_map.rb +19 -18
  227. data/lib/solargraph/yard_tags.rb +2 -2
  228. data/lib/solargraph/yardoc.rb +7 -4
  229. data/lib/solargraph.rb +34 -10
  230. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  231. data/rbs/shims/ast/0/node.rbs +1 -1
  232. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  233. data/solargraph.gemspec +39 -35
  234. metadata +77 -41
  235. data/lib/solargraph/type_checker/checks.rb +0 -124
  236. data/lib/solargraph/type_checker/param_def.rb +0 -37
  237. data/lib/solargraph/yard_map/to_method.rb +0 -89
  238. data/rbs/fills/tuple/tuple.rbs +0 -149
@@ -14,7 +14,7 @@ module Solargraph
14
14
  # @return [String]
15
15
  attr_reader :word
16
16
 
17
- # @return [Location]
17
+ # @return [Location, nil]
18
18
  attr_reader :location
19
19
 
20
20
  # @return [::Array<Chain>]
@@ -28,18 +28,14 @@ module Solargraph
28
28
  # @param arguments [::Array<Chain>]
29
29
  # @param block [Chain, nil]
30
30
  def initialize word, location = nil, arguments = [], block = nil
31
- @word = word
31
+ super(word)
32
+
32
33
  @location = location
33
34
  @arguments = arguments
34
35
  @block = block
35
36
  fix_block_pass
36
37
  end
37
38
 
38
- # @sg-ignore Fix "Not enough arguments to Module#protected"
39
- protected def equality_fields
40
- super + [arguments, block]
41
- end
42
-
43
39
  def with_block?
44
40
  !!@block
45
41
  end
@@ -50,24 +46,121 @@ module Solargraph
50
46
  def resolve api_map, name_pin, locals
51
47
  return super_pins(api_map, name_pin) if word == 'super'
52
48
  return yield_pins(api_map, name_pin) if word == 'yield'
53
- found = if head?
54
- api_map.visible_pins(locals, word, name_pin, location)
55
- else
56
- []
57
- end
58
- return inferred_pins(found, api_map, name_pin, locals) unless found.empty?
59
- pins = name_pin.binder.each_unique_type.flat_map do |context|
49
+ found = api_map.var_at_location(locals, word, name_pin, location) if head?
50
+
51
+ return inferred_pins([found], api_map, name_pin, locals) unless found.nil?
52
+ binder = name_pin.binder
53
+ # this is a q_call - i.e., foo&.bar - assume result of call
54
+ # will be nil or result as if binder were not nil -
55
+ # chain.rb#maybe_nil will add the nil type later, we just
56
+ # need to worry about the not-nil case
57
+
58
+ # @sg-ignore Need to handle duck-typed method calls on union types
59
+ binder = binder.without_nil if nullable?
60
+ # @sg-ignore Need to handle duck-typed method calls on union types
61
+ pin_groups = binder.each_unique_type.map do |context|
60
62
  ns_tag = context.namespace == '' ? '' : context.namespace_type.tag
61
63
  stack = api_map.get_method_stack(ns_tag, word, scope: context.scope)
62
64
  [stack.first].compact
63
65
  end
66
+ pin_groups = [] if !api_map.loose_unions && pin_groups.any?(&:empty?)
67
+ pins = pin_groups.flatten.uniq(&:path)
64
68
  return [] if pins.empty?
65
69
  inferred_pins(pins, api_map, name_pin, locals)
66
70
  end
67
71
 
68
72
  private
69
73
 
70
- # @param pins [::Enumerable<Pin::Method>]
74
+ # Checks whether a single overload signature matches the call's
75
+ # arguments/block and, if so, resolves its return type. Threaded
76
+ # through the caller's accumulator so behavior matches the
77
+ # original inline loop: if the overload doesn't match, the
78
+ # incoming type/signature are returned unchanged.
79
+ #
80
+ # @param overload [Pin::Signature]
81
+ # @param pin [Pin::Method]
82
+ # @param api_map [ApiMap]
83
+ # @param name_pin [Pin::Base]
84
+ # @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
85
+ # @param type [ComplexType]
86
+ # @param new_signature_pin [Pin::Signature, nil]
87
+ # @return [::Array(ComplexType, Pin::Signature)]
88
+ def match_overload_type overload, pin, api_map, name_pin, locals, type, new_signature_pin
89
+ return [type, new_signature_pin] unless overload.arity_matches?(arguments, with_block?)
90
+
91
+ match = true
92
+ atypes = []
93
+ arguments.each_with_index do |arg, idx|
94
+ param = overload.parameters[idx]
95
+ if param.nil?
96
+ match = overload.parameters.any?(&:restarg?)
97
+ break
98
+ end
99
+ arg_name_pin = Pin::ProxyType.anonymous(name_pin.context,
100
+ closure: name_pin.closure,
101
+ gates: name_pin.gates,
102
+ source: :chain)
103
+ atype = atypes[idx] ||= arg.infer(api_map, arg_name_pin, locals)
104
+ # @sg-ignore flow sensitive typing should handle is_a? and next
105
+ unless param.compatible_arg?(atype, api_map) || param.restarg?
106
+ match = false
107
+ break
108
+ end
109
+ end
110
+ return [type, new_signature_pin] unless match
111
+
112
+ if overload.block && with_block?
113
+ block_atypes = overload.block.parameters.map(&:return_type)
114
+ # @todo Need to add nil check here
115
+ # @sg-ignore Need to add nil check here
116
+ blocktype = if block.links.map(&:class) == [BlockSymbol]
117
+ # like the bar in foo(&:bar)
118
+ block_symbol_call_type(api_map, name_pin.context, block_atypes, locals)
119
+ else
120
+ block_call_type(api_map, name_pin, locals)
121
+ end
122
+ end
123
+ new_signature_pin = overload.resolve_generics_from_context_until_complete(overload.generics, atypes, nil, nil,
124
+ blocktype)
125
+ # @todo It shouldn't be necessary to choose either generics or macros
126
+ # @sg-ignore Need to add nil check here
127
+ new_return_type = if new_signature_pin.return_type.defined?
128
+ # @sg-ignore Need to add nil check here
129
+ new_signature_pin.return_type
130
+ else
131
+ # @sg-ignore Need to add nil check here
132
+ named_types = pin.parameter_names.zip(arguments.map { |arg| ComplexType.try_parse(simple_convert(arg.node).to_s) }).to_h
133
+ pin.typify(api_map).expand(named_types)
134
+ end
135
+ self_type = if head?
136
+ # If we're at the head of the chain, we called a
137
+ # method somewhere that marked itself as returning
138
+ # self. Given we didn't invoke this on an object,
139
+ # this must be a method in this same class - so we
140
+ # use our own self type
141
+ name_pin.context
142
+ else
143
+ # if we're past the head in the chain, whatever the
144
+ # type of the lhs side is what 'self' will be in its
145
+ # declaration - we can't just use the type of the
146
+ # method pin, as this might be a subclass of the
147
+ # place where the method is defined
148
+ name_pin.binder
149
+ end
150
+ # This same logic applies to the YARD work done by
151
+ # 'with_params()'.
152
+ #
153
+ # qualify(), however, happens in the namespace where
154
+ # the docs were written - from the method pin.
155
+ # @todo Need to add nil check here
156
+ if new_return_type.defined?
157
+ type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *pin.gates)
158
+ end
159
+ type ||= ComplexType::UNDEFINED
160
+ [type, new_signature_pin]
161
+ end
162
+
163
+ # @param pins [::Enumerable<Pin::Base>]
71
164
  # @param api_map [ApiMap]
72
165
  # @param name_pin [Pin::Base]
73
166
  # @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
@@ -84,86 +177,43 @@ module Solargraph
84
177
  # reject it regardless
85
178
 
86
179
  with_block, without_block = overloads.partition(&:block?)
180
+ # @sg-ignore flow sensitive typing should handle is_a? and next
181
+ # @type Array<Pin::Signature>
87
182
  sorted_overloads = with_block + without_block
88
183
  # @type [Pin::Signature, nil]
89
184
  new_signature_pin = nil
185
+ # @sg-ignore flow sensitive typing should handle is_a? and next
186
+ # @param ol [Pin::Signature]
90
187
  sorted_overloads.each do |ol|
91
- next unless ol.arity_matches?(arguments, with_block?)
92
- match = true
93
-
94
- atypes = []
95
- arguments.each_with_index do |arg, idx|
96
- param = ol.parameters[idx]
97
- if param.nil?
98
- match = ol.parameters.any?(&:restarg?)
99
- break
100
- end
101
- arg_name_pin = Pin::ProxyType.anonymous(name_pin.context,
102
- gates: name_pin.gates,
103
- source: :chain)
104
- atype = atypes[idx] ||= arg.infer(api_map, arg_name_pin, locals)
105
- unless param.compatible_arg?(atype, api_map) || param.restarg?
106
- match = false
107
- break
108
- end
109
- end
110
- if match
111
- if ol.block && with_block?
112
- block_atypes = ol.block.parameters.map(&:return_type)
113
- if block.links.map(&:class) == [BlockSymbol]
114
- # like the bar in foo(&:bar)
115
- blocktype = block_symbol_call_type(api_map, name_pin.context, block_atypes, locals)
116
- else
117
- blocktype = block_call_type(api_map, name_pin, locals)
118
- end
119
- end
120
- # @type new_signature_pin [Pin::Signature]
121
- new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
122
- new_return_type = new_signature_pin.return_type
123
- if head?
124
- # If we're at the head of the chain, we called a
125
- # method somewhere that marked itself as returning
126
- # self. Given we didn't invoke this on an object,
127
- # this must be a method in this same class - so we
128
- # use our own self type
129
- self_type = name_pin.context
130
- else
131
- # if we're past the head in the chain, whatever the
132
- # type of the lhs side is what 'self' will be in its
133
- # declaration - we can't just use the type of the
134
- # method pin, as this might be a subclass of the
135
- # place where the method is defined
136
- self_type = name_pin.binder
137
- end
138
- # This same logic applies to the YARD work done by
139
- # 'with_params()'.
140
- #
141
- # qualify(), however, happens in the namespace where
142
- # the docs were written - from the method pin.
143
- type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *p.gates) if new_return_type.defined?
144
- type ||= ComplexType::UNDEFINED
145
- end
188
+ type, new_signature_pin = match_overload_type(ol, p, api_map, name_pin, locals, type, new_signature_pin)
146
189
  break if type.defined?
147
190
  end
148
191
  p = p.with_single_signature(new_signature_pin) unless new_signature_pin.nil?
149
192
  next p.proxy(type) if type.defined?
150
193
  if !p.macros.empty?
151
194
  result = process_macro(p, api_map, name_pin.context, locals)
195
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
152
196
  next result unless result.return_type.undefined?
153
197
  elsif !p.directives.empty?
154
198
  result = process_directive(p, api_map, name_pin.context, locals)
199
+ # @sg-ignore flow sensitive typing should be able to handle redefinition
155
200
  next result unless result.return_type.undefined?
156
201
  end
157
202
  p
158
203
  end
159
- logger.debug { "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" }
160
- out = result.map do |pin|
204
+ logger.debug do
205
+ "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}"
206
+ end
207
+ result.map do |pin|
161
208
  if pin.path == 'Class#new' && name_pin.binder.tag != 'Class'
162
209
  reduced_context = name_pin.binder.reduce_class_type
163
210
  pin.proxy(reduced_context)
164
211
  else
212
+ # @sg-ignore Need to add nil check here
165
213
  next pin if pin.return_type.undefined?
214
+ # @sg-ignore Need to add nil check here
166
215
  selfy = pin.return_type.self_to_type(name_pin.binder)
216
+ # @sg-ignore Need to add nil check here
167
217
  selfy == pin.return_type ? pin : pin.proxy(selfy)
168
218
  end
169
219
  end
@@ -171,7 +221,7 @@ module Solargraph
171
221
 
172
222
  # @param pin [Pin::Base]
173
223
  # @param api_map [ApiMap]
174
- # @param context [ComplexType]
224
+ # @param context [ComplexType, ComplexType::UniqueType]
175
225
  # @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
176
226
  # @return [Pin::Base]
177
227
  def process_macro pin, api_map, context, locals
@@ -182,6 +232,7 @@ module Solargraph
182
232
  # generic<Elem>' is because we lose 'rooted' information
183
233
  # in the 'Chain::Array' class internally, leaving
184
234
  # ::Array#each shadowed when it shouldn't be.
235
+ # @sg-ignore macro is Solargraph::YardMap::Macro, wraps a YARD::Tags::MacroDirective
185
236
  result = inner_process_macro(pin, macro, api_map, context, locals)
186
237
  return result unless result.return_type.undefined?
187
238
  end
@@ -190,13 +241,14 @@ module Solargraph
190
241
 
191
242
  # @param pin [Pin::Method]
192
243
  # @param api_map [ApiMap]
193
- # @param context [ComplexType]
244
+ # @param context [ComplexType, ComplexType::UniqueType]
194
245
  # @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
195
246
  # @return [Pin::ProxyType]
196
247
  def process_directive pin, api_map, context, locals
197
248
  pin.directives.each do |dir|
198
249
  macro = api_map.named_macro(dir.tag.name)
199
250
  next if macro.nil?
251
+ # @sg-ignore macro is Solargraph::YardMap::Macro, wraps a YARD::Tags::MacroDirective
200
252
  result = inner_process_macro(pin, macro, api_map, context, locals)
201
253
  return result unless result.return_type.undefined?
202
254
  end
@@ -206,21 +258,24 @@ module Solargraph
206
258
  # @param pin [Pin::Base]
207
259
  # @param macro [YARD::Tags::MacroDirective]
208
260
  # @param api_map [ApiMap]
209
- # @param context [ComplexType]
261
+ # @param context [ComplexType, ComplexType::UniqueType]
210
262
  # @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
211
263
  # @return [Pin::ProxyType]
212
264
  def inner_process_macro pin, macro, api_map, context, locals
213
- vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
265
+ vals = arguments.map { |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
214
266
  txt = macro.tag.text.clone
267
+ # @sg-ignore Need to add nil check here
215
268
  if txt.empty? && macro.tag.name
216
269
  named = api_map.named_macro(macro.tag.name)
217
270
  txt = named.tag.text.clone if named
218
271
  end
219
272
  i = 1
220
273
  vals.each do |v|
274
+ # @sg-ignore Need to add nil check here
221
275
  txt.gsub!(/\$#{i}/, v.context.namespace)
222
276
  i += 1
223
277
  end
278
+ # @sg-ignore Need to add nil check here
224
279
  docstring = Solargraph::Source.parse_docstring(txt).to_docstring
225
280
  tag = docstring.tag(:return)
226
281
  unless tag.nil? || tag.types.nil?
@@ -233,7 +288,7 @@ module Solargraph
233
288
  # @param context [ComplexType]
234
289
  # @return [ComplexType, nil]
235
290
  def extra_return_type docstring, context
236
- if docstring.has_tag?('return_single_parameter') #&& context.subtypes.one?
291
+ if docstring.has_tag?('return_single_parameter') # && context.subtypes.one?
237
292
  return context.subtypes.first || ComplexType::UNDEFINED
238
293
  elsif docstring.has_tag?('return_value_parameter') && context.value_types.one?
239
294
  return context.value_types.first
@@ -243,9 +298,10 @@ module Solargraph
243
298
 
244
299
  # @param name_pin [Pin::Base]
245
300
  # @return [Pin::Method, nil]
246
- def find_method_pin(name_pin)
301
+ def find_method_pin name_pin
247
302
  method_pin = name_pin
248
303
  until method_pin.is_a?(Pin::Method)
304
+ # @sg-ignore Need to support this in flow sensitive typing
249
305
  method_pin = method_pin.closure
250
306
  return if method_pin.nil?
251
307
  end
@@ -259,7 +315,7 @@ module Solargraph
259
315
  method_pin = find_method_pin(name_pin)
260
316
  return [] if method_pin.nil?
261
317
  pins = api_map.get_method_stack(method_pin.namespace, method_pin.name, scope: method_pin.context.scope)
262
- pins.reject{|p| p.path == name_pin.path}
318
+ pins.reject { |p| p.path == name_pin.path }
263
319
  end
264
320
 
265
321
  # @param api_map [ApiMap]
@@ -271,13 +327,14 @@ module Solargraph
271
327
 
272
328
  # @param signature_pin [Pin::Signature]
273
329
  method_pin.signatures.map(&:block).compact.map do |signature_pin|
330
+ # @sg-ignore Need to add nil check here
274
331
  return_type = signature_pin.return_type.qualify(api_map, *name_pin.gates)
275
332
  signature_pin.proxy(return_type)
276
333
  end
277
334
  end
278
335
 
279
336
  # @param type [ComplexType]
280
- # @param context [ComplexType]
337
+ # @param context [ComplexType, ComplexType::UniqueType]
281
338
  # @return [ComplexType]
282
339
  def with_params type, context
283
340
  return type unless type.to_s.include?('$')
@@ -291,13 +348,14 @@ module Solargraph
291
348
  end
292
349
 
293
350
  # @param api_map [ApiMap]
294
- # @param context [ComplexType]
351
+ # @param context [ComplexType, ComplexType::UniqueType]
295
352
  # @param block_parameter_types [::Array<ComplexType>]
296
353
  # @param locals [::Array<Pin::LocalVariable>]
297
354
  # @return [ComplexType, nil]
298
- def block_symbol_call_type(api_map, context, block_parameter_types, locals)
355
+ def block_symbol_call_type api_map, context, block_parameter_types, locals
299
356
  # Ruby's shorthand for sending the passed in method name
300
357
  # to the first yield parameter with no arguments
358
+ # @sg-ignore Need to add nil check here
301
359
  block_symbol_name = block.links.first.word
302
360
  block_symbol_call_path = "#{block_parameter_types.first}##{block_symbol_name}"
303
361
  callee = api_map.get_path_pins(block_symbol_call_path).first
@@ -305,31 +363,43 @@ module Solargraph
305
363
  # @todo: Figure out why we get unresolved generics at
306
364
  # this point and need to assume method return types
307
365
  # based on the generic type
366
+ # @sg-ignore Need to add nil check here
308
367
  return_type ||= api_map.get_path_pins("#{context.subtypes.first}##{block.links.first.word}").first&.return_type
309
368
  return_type || ComplexType::UNDEFINED
310
369
  end
311
370
 
312
371
  # @param api_map [ApiMap]
313
372
  # @return [Pin::Block, nil]
314
- def find_block_pin(api_map)
373
+ def find_block_pin api_map
374
+ # @sg-ignore Need to add nil check here
315
375
  node_location = Solargraph::Location.from_node(block.node)
316
- return if node_location.nil?
376
+ return if node_location.nil?
317
377
  block_pins = api_map.get_block_pins
378
+ # @sg-ignore Need to add nil check here
318
379
  block_pins.find { |pin| pin.location.contain?(node_location) }
319
380
  end
320
381
 
321
382
  # @param api_map [ApiMap]
322
383
  # @param name_pin [Pin::Base]
323
- # @param block_parameter_types [::Array<ComplexType>]
324
384
  # @param locals [::Array<Pin::LocalVariable>]
325
385
  # @return [ComplexType, nil]
326
- def block_call_type(api_map, name_pin, locals)
386
+ def block_call_type api_map, name_pin, locals
327
387
  return nil unless with_block?
328
388
 
329
- block_context_pin = name_pin
330
389
  block_pin = find_block_pin(api_map)
331
- block_context_pin = block_pin.closure if block_pin
332
- block.infer(api_map, block_context_pin, locals)
390
+ # We use the block pin as the closure, as the parameters
391
+ # here will only be defined inside the block itself and we
392
+ # need to be able to see them
393
+ # @sg-ignore Need to add nil check here
394
+ block.infer(api_map, block_pin, locals)
395
+ end
396
+
397
+ protected
398
+
399
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
400
+ def equality_fields
401
+ # @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
402
+ super + [arguments, block]
333
403
  end
334
404
  end
335
405
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class ClassVariable < Link
7
7
  def resolve api_map, name_pin, locals
8
- api_map.get_class_variable_pins(name_pin.context.namespace).select{|p| p.name == word}
8
+ api_map.get_class_variable_pins(name_pin.context.namespace).select { |p| p.name == word }
9
9
  end
10
10
  end
11
11
  end
@@ -6,18 +6,22 @@ module Solargraph
6
6
  class Constant < Link
7
7
  def initialize word
8
8
  @word = word
9
+
10
+ super
9
11
  end
10
12
 
11
13
  def resolve api_map, name_pin, locals
12
14
  return [Pin::ROOT_PIN] if word.empty?
13
15
  if word.start_with?('::')
14
- base = word[2..-1]
16
+ base = word[2..]
15
17
  gates = ['']
16
18
  else
17
19
  base = word
18
20
  gates = name_pin.gates
19
21
  end
22
+ # @sg-ignore Need to add nil check here
20
23
  fqns = api_map.resolve(base, gates)
24
+ # @sg-ignore Need to add nil check here
21
25
  api_map.get_path_pins(fqns)
22
26
  end
23
27
  end
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Chain
6
6
  class GlobalVariable < Link
7
7
  def resolve api_map, name_pin, locals
8
- api_map.get_global_variable_pins.select{|p| p.name == word}
8
+ api_map.get_global_variable_pins.select { |p| p.name == word }
9
9
  end
10
10
  end
11
11
  end
@@ -12,11 +12,6 @@ module Solargraph
12
12
  @splatted = splatted
13
13
  end
14
14
 
15
- # @sg-ignore Fix "Not enough arguments to Module#protected"
16
- protected def equality_fields
17
- super + [@splatted]
18
- end
19
-
20
15
  def word
21
16
  @word ||= "<#{@type}>"
22
17
  end
@@ -28,6 +23,14 @@ module Solargraph
28
23
  def splatted?
29
24
  @splatted
30
25
  end
26
+
27
+ protected
28
+
29
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
30
+ def equality_fields
31
+ # @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
32
+ super + [@splatted]
33
+ end
31
34
  end
32
35
  end
33
36
  end
@@ -1,19 +1,19 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class Source
5
- class Chain
6
- # Chain::Head is a link for ambiguous words, e.g.; `String` can refer to
7
- # either a class (`String`) or a function (`Kernel#String`).
8
- #
9
- # @note Chain::Head is only intended to handle `self` and `super`.
10
- class Head < Link
11
- def resolve api_map, name_pin, locals
12
- return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
13
- # return super_pins(api_map, name_pin) if word == 'super'
14
- []
15
- end
16
- end
17
- end
18
- end
19
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ # Chain::Head is a link for ambiguous words, e.g.; `String` can refer to
7
+ # either a class (`String`) or a function (`Kernel#String`).
8
+ #
9
+ # @note Chain::Head is only intended to handle `self` and `super`.
10
+ class Head < Link
11
+ def resolve api_map, name_pin, locals
12
+ return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
13
+ # return super_pins(api_map, name_pin) if word == 'super'
14
+ []
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,23 +4,25 @@ module Solargraph
4
4
  class Source
5
5
  class Chain
6
6
  class If < Link
7
- def word
8
- '<if>'
9
- end
10
-
11
7
  # @param links [::Array<Chain>]
12
8
  def initialize links
13
- @links = links
14
- end
9
+ super('<if>')
15
10
 
16
- # @sg-ignore Fix "Not enough arguments to Module#protected"
17
- protected def equality_fields
18
- super + [@links]
11
+ @links = links
19
12
  end
20
13
 
21
14
  def resolve api_map, name_pin, locals
22
15
  types = @links.map { |link| link.infer(api_map, name_pin, locals) }
23
- [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')), source: :chain)]
16
+ [Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')),
17
+ source: :chain)]
18
+ end
19
+
20
+ protected
21
+
22
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
23
+ def equality_fields
24
+ # @sg-ignore literal arrays in this module turn into ::Solargraph::Source::Chain::Array
25
+ super + [@links]
24
26
  end
25
27
  end
26
28
  end
@@ -4,9 +4,27 @@ module Solargraph
4
4
  class Source
5
5
  class Chain
6
6
  class InstanceVariable < Link
7
+ # @param word [String]
8
+ # @param node [Parser::AST::Node, nil] The node representing the variable
9
+ # @param location [Location, nil] The location of the variable reference in the source
10
+ def initialize word, node, location
11
+ super(word)
12
+ @node = node
13
+ @location = location
14
+ end
15
+
7
16
  def resolve api_map, name_pin, locals
8
- api_map.get_instance_variable_pins(name_pin.binder.namespace, name_pin.binder.scope).select{|p| p.name == word}
17
+ ivars = api_map.get_instance_variable_pins(name_pin.context.namespace, name_pin.context.scope).select do |p|
18
+ p.name == word
19
+ end
20
+ out = api_map.var_at_location(ivars, word, name_pin, location)
21
+ [out].compact
9
22
  end
23
+
24
+ private
25
+
26
+ # @return [Location, nil]
27
+ attr_reader :location
10
28
  end
11
29
  end
12
30
  end
@@ -17,17 +17,6 @@ module Solargraph
17
17
  @word = word
18
18
  end
19
19
 
20
- # @sg-ignore two problems - Declared return type
21
- # ::Solargraph::Source::Chain::Array does not match inferred
22
- # type ::Array(::Class<::Solargraph::Source::Chain::Link>,
23
- # ::String) for
24
- # Solargraph::Source::Chain::Link#equality_fields
25
- # and
26
- # Not enough arguments to Module#protected
27
- protected def equality_fields
28
- [self.class, word]
29
- end
30
-
31
20
  def undefined?
32
21
  word == '<undefined>'
33
22
  end
@@ -44,18 +33,12 @@ module Solargraph
44
33
  []
45
34
  end
46
35
 
47
- # debugging description of contents; not for machine use
48
- # @return [String]
49
- def desc
50
- word
51
- end
52
-
53
36
  def to_s
54
37
  desc
55
38
  end
56
39
 
57
40
  def inspect
58
- "#<#{self.class} - `#{self.desc}`>"
41
+ "#<#{self.class} - `#{desc}`>"
59
42
  end
60
43
 
61
44
  def head?
@@ -87,14 +70,21 @@ module Solargraph
87
70
  word
88
71
  end
89
72
 
90
- def inspect
91
- "#<#{self.class} - `#{self.desc}`>"
92
- end
93
-
94
73
  include Logging
95
74
 
96
75
  protected
97
76
 
77
+ # @sg-ignore two problems - Declared return type
78
+ # ::Solargraph::Source::Chain::Array does not match inferred
79
+ # type ::Array(::Class<::Solargraph::Source::Chain::Link>,
80
+ # ::String) for
81
+ # Solargraph::Source::Chain::Link#equality_fields
82
+ # and
83
+ # Not enough arguments to Module#protected
84
+ def equality_fields
85
+ [self.class, word]
86
+ end
87
+
98
88
  # Mark whether this link is the head of a chain
99
89
  #
100
90
  # @param bool [Boolean]