solargraph 0.39.7

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 (252) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +28 -0
  5. data/.yardopts +2 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE +21 -0
  8. data/README.md +104 -0
  9. data/Rakefile +14 -0
  10. data/SPONSORS.md +9 -0
  11. data/bin/solargraph +5 -0
  12. data/lib/.rubocop.yml +21 -0
  13. data/lib/solargraph.rb +66 -0
  14. data/lib/solargraph/api_map.rb +745 -0
  15. data/lib/solargraph/api_map/bundler_methods.rb +27 -0
  16. data/lib/solargraph/api_map/cache.rb +66 -0
  17. data/lib/solargraph/api_map/source_to_yard.rb +81 -0
  18. data/lib/solargraph/api_map/store.rb +267 -0
  19. data/lib/solargraph/bundle.rb +26 -0
  20. data/lib/solargraph/complex_type.rb +213 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +127 -0
  22. data/lib/solargraph/complex_type/unique_type.rb +75 -0
  23. data/lib/solargraph/convention.rb +38 -0
  24. data/lib/solargraph/convention/base.rb +25 -0
  25. data/lib/solargraph/convention/gemfile.rb +18 -0
  26. data/lib/solargraph/convention/gemspec.rb +25 -0
  27. data/lib/solargraph/convention/rspec.rb +24 -0
  28. data/lib/solargraph/converters/dd.rb +12 -0
  29. data/lib/solargraph/converters/dl.rb +12 -0
  30. data/lib/solargraph/converters/dt.rb +12 -0
  31. data/lib/solargraph/converters/misc.rb +1 -0
  32. data/lib/solargraph/core_fills.rb +159 -0
  33. data/lib/solargraph/diagnostics.rb +55 -0
  34. data/lib/solargraph/diagnostics/base.rb +29 -0
  35. data/lib/solargraph/diagnostics/require_not_found.rb +37 -0
  36. data/lib/solargraph/diagnostics/rubocop.rb +90 -0
  37. data/lib/solargraph/diagnostics/rubocop_helpers.rb +64 -0
  38. data/lib/solargraph/diagnostics/severities.rb +15 -0
  39. data/lib/solargraph/diagnostics/type_check.rb +54 -0
  40. data/lib/solargraph/diagnostics/update_errors.rb +41 -0
  41. data/lib/solargraph/documentor.rb +76 -0
  42. data/lib/solargraph/environ.rb +40 -0
  43. data/lib/solargraph/language_server.rb +19 -0
  44. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -0
  45. data/lib/solargraph/language_server/error_codes.rb +20 -0
  46. data/lib/solargraph/language_server/host.rb +741 -0
  47. data/lib/solargraph/language_server/host/cataloger.rb +56 -0
  48. data/lib/solargraph/language_server/host/diagnoser.rb +81 -0
  49. data/lib/solargraph/language_server/host/dispatch.rb +112 -0
  50. data/lib/solargraph/language_server/host/sources.rb +156 -0
  51. data/lib/solargraph/language_server/message.rb +92 -0
  52. data/lib/solargraph/language_server/message/base.rb +85 -0
  53. data/lib/solargraph/language_server/message/cancel_request.rb +13 -0
  54. data/lib/solargraph/language_server/message/client.rb +11 -0
  55. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -0
  56. data/lib/solargraph/language_server/message/completion_item.rb +11 -0
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +57 -0
  58. data/lib/solargraph/language_server/message/exit_notification.rb +13 -0
  59. data/lib/solargraph/language_server/message/extended.rb +21 -0
  60. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +95 -0
  61. data/lib/solargraph/language_server/message/extended/document.rb +20 -0
  62. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -0
  63. data/lib/solargraph/language_server/message/extended/download_core.rb +23 -0
  64. data/lib/solargraph/language_server/message/extended/environment.rb +25 -0
  65. data/lib/solargraph/language_server/message/extended/search.rb +20 -0
  66. data/lib/solargraph/language_server/message/initialize.rb +153 -0
  67. data/lib/solargraph/language_server/message/initialized.rb +26 -0
  68. data/lib/solargraph/language_server/message/method_not_found.rb +16 -0
  69. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -0
  70. data/lib/solargraph/language_server/message/shutdown.rb +13 -0
  71. data/lib/solargraph/language_server/message/text_document.rb +28 -0
  72. data/lib/solargraph/language_server/message/text_document/base.rb +19 -0
  73. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -0
  74. data/lib/solargraph/language_server/message/text_document/completion.rb +57 -0
  75. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
  76. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
  77. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -0
  78. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -0
  79. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -0
  80. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -0
  81. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -0
  82. data/lib/solargraph/language_server/message/text_document/formatting.rb +78 -0
  83. data/lib/solargraph/language_server/message/text_document/hover.rb +44 -0
  84. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -0
  85. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -0
  86. data/lib/solargraph/language_server/message/text_document/references.rb +16 -0
  87. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -0
  88. data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -0
  89. data/lib/solargraph/language_server/message/workspace.rb +14 -0
  90. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -0
  91. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -0
  92. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
  93. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -0
  94. data/lib/solargraph/language_server/message_types.rb +14 -0
  95. data/lib/solargraph/language_server/request.rb +24 -0
  96. data/lib/solargraph/language_server/symbol_kinds.rb +36 -0
  97. data/lib/solargraph/language_server/transport.rb +13 -0
  98. data/lib/solargraph/language_server/transport/adapter.rb +56 -0
  99. data/lib/solargraph/language_server/transport/data_reader.rb +72 -0
  100. data/lib/solargraph/language_server/uri_helpers.rb +49 -0
  101. data/lib/solargraph/library.rb +414 -0
  102. data/lib/solargraph/location.rb +37 -0
  103. data/lib/solargraph/logging.rb +27 -0
  104. data/lib/solargraph/page.rb +83 -0
  105. data/lib/solargraph/parser.rb +26 -0
  106. data/lib/solargraph/parser/comment_ripper.rb +52 -0
  107. data/lib/solargraph/parser/legacy.rb +12 -0
  108. data/lib/solargraph/parser/legacy/class_methods.rb +109 -0
  109. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
  110. data/lib/solargraph/parser/legacy/node_chainer.rb +118 -0
  111. data/lib/solargraph/parser/legacy/node_methods.rb +300 -0
  112. data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
  113. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
  114. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
  115. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
  116. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +22 -0
  117. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -0
  118. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
  119. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
  120. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
  121. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
  122. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
  123. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
  124. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
  125. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
  126. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
  127. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -0
  128. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +234 -0
  129. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
  130. data/lib/solargraph/parser/node_methods.rb +43 -0
  131. data/lib/solargraph/parser/node_processor.rb +43 -0
  132. data/lib/solargraph/parser/node_processor/base.rb +77 -0
  133. data/lib/solargraph/parser/region.rb +66 -0
  134. data/lib/solargraph/parser/rubyvm.rb +40 -0
  135. data/lib/solargraph/parser/rubyvm/class_methods.rb +150 -0
  136. data/lib/solargraph/parser/rubyvm/node_chainer.rb +135 -0
  137. data/lib/solargraph/parser/rubyvm/node_methods.rb +284 -0
  138. data/lib/solargraph/parser/rubyvm/node_processors.rb +61 -0
  139. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
  140. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +62 -0
  141. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
  142. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +22 -0
  143. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -0
  144. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
  145. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +64 -0
  146. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -0
  147. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
  148. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
  149. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -0
  150. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
  151. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
  152. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
  153. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +31 -0
  154. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
  155. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
  156. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -0
  157. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
  158. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +255 -0
  159. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
  160. data/lib/solargraph/parser/snippet.rb +13 -0
  161. data/lib/solargraph/pin.rb +39 -0
  162. data/lib/solargraph/pin/attribute.rb +49 -0
  163. data/lib/solargraph/pin/base.rb +296 -0
  164. data/lib/solargraph/pin/base_method.rb +141 -0
  165. data/lib/solargraph/pin/base_variable.rb +84 -0
  166. data/lib/solargraph/pin/block.rb +48 -0
  167. data/lib/solargraph/pin/class_variable.rb +8 -0
  168. data/lib/solargraph/pin/closure.rb +37 -0
  169. data/lib/solargraph/pin/common.rb +70 -0
  170. data/lib/solargraph/pin/constant.rb +43 -0
  171. data/lib/solargraph/pin/conversions.rb +97 -0
  172. data/lib/solargraph/pin/documenting.rb +110 -0
  173. data/lib/solargraph/pin/duck_method.rb +16 -0
  174. data/lib/solargraph/pin/global_variable.rb +8 -0
  175. data/lib/solargraph/pin/instance_variable.rb +30 -0
  176. data/lib/solargraph/pin/keyword.rb +15 -0
  177. data/lib/solargraph/pin/keyword_param.rb +8 -0
  178. data/lib/solargraph/pin/local_variable.rb +21 -0
  179. data/lib/solargraph/pin/localized.rb +43 -0
  180. data/lib/solargraph/pin/method.rb +111 -0
  181. data/lib/solargraph/pin/method_alias.rb +31 -0
  182. data/lib/solargraph/pin/namespace.rb +85 -0
  183. data/lib/solargraph/pin/parameter.rb +206 -0
  184. data/lib/solargraph/pin/proxy_type.rb +29 -0
  185. data/lib/solargraph/pin/reference.rb +14 -0
  186. data/lib/solargraph/pin/reference/extend.rb +10 -0
  187. data/lib/solargraph/pin/reference/include.rb +10 -0
  188. data/lib/solargraph/pin/reference/override.rb +29 -0
  189. data/lib/solargraph/pin/reference/prepend.rb +10 -0
  190. data/lib/solargraph/pin/reference/require.rb +14 -0
  191. data/lib/solargraph/pin/reference/superclass.rb +10 -0
  192. data/lib/solargraph/pin/singleton.rb +11 -0
  193. data/lib/solargraph/pin/symbol.rb +47 -0
  194. data/lib/solargraph/pin/yard_pin.rb +12 -0
  195. data/lib/solargraph/pin/yard_pin/constant.rb +25 -0
  196. data/lib/solargraph/pin/yard_pin/method.rb +65 -0
  197. data/lib/solargraph/pin/yard_pin/namespace.rb +27 -0
  198. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +26 -0
  199. data/lib/solargraph/position.rb +112 -0
  200. data/lib/solargraph/range.rb +95 -0
  201. data/lib/solargraph/server_methods.rb +16 -0
  202. data/lib/solargraph/shell.rb +221 -0
  203. data/lib/solargraph/source.rb +533 -0
  204. data/lib/solargraph/source/chain.rb +172 -0
  205. data/lib/solargraph/source/chain/block_variable.rb +13 -0
  206. data/lib/solargraph/source/chain/call.rb +203 -0
  207. data/lib/solargraph/source/chain/class_variable.rb +13 -0
  208. data/lib/solargraph/source/chain/constant.rb +75 -0
  209. data/lib/solargraph/source/chain/global_variable.rb +13 -0
  210. data/lib/solargraph/source/chain/head.rb +35 -0
  211. data/lib/solargraph/source/chain/instance_variable.rb +13 -0
  212. data/lib/solargraph/source/chain/link.rb +67 -0
  213. data/lib/solargraph/source/chain/literal.rb +23 -0
  214. data/lib/solargraph/source/chain/or.rb +23 -0
  215. data/lib/solargraph/source/chain/variable.rb +13 -0
  216. data/lib/solargraph/source/chain/z_super.rb +184 -0
  217. data/lib/solargraph/source/change.rb +79 -0
  218. data/lib/solargraph/source/cursor.rb +164 -0
  219. data/lib/solargraph/source/encoding_fixes.rb +23 -0
  220. data/lib/solargraph/source/source_chainer.rb +189 -0
  221. data/lib/solargraph/source/updater.rb +54 -0
  222. data/lib/solargraph/source_map.rb +170 -0
  223. data/lib/solargraph/source_map/clip.rb +190 -0
  224. data/lib/solargraph/source_map/completion.rb +23 -0
  225. data/lib/solargraph/source_map/mapper.rb +199 -0
  226. data/lib/solargraph/stdlib_fills.rb +32 -0
  227. data/lib/solargraph/type_checker.rb +498 -0
  228. data/lib/solargraph/type_checker/checks.rb +95 -0
  229. data/lib/solargraph/type_checker/param_def.rb +35 -0
  230. data/lib/solargraph/type_checker/problem.rb +32 -0
  231. data/lib/solargraph/type_checker/rules.rb +53 -0
  232. data/lib/solargraph/version.rb +5 -0
  233. data/lib/solargraph/views/_method.erb +62 -0
  234. data/lib/solargraph/views/_name_type_tag.erb +10 -0
  235. data/lib/solargraph/views/_namespace.erb +24 -0
  236. data/lib/solargraph/views/document.erb +23 -0
  237. data/lib/solargraph/views/environment.erb +58 -0
  238. data/lib/solargraph/views/layout.erb +44 -0
  239. data/lib/solargraph/views/search.erb +11 -0
  240. data/lib/solargraph/workspace.rb +209 -0
  241. data/lib/solargraph/workspace/config.rb +215 -0
  242. data/lib/solargraph/yard_map.rb +420 -0
  243. data/lib/solargraph/yard_map/cache.rb +19 -0
  244. data/lib/solargraph/yard_map/core_docs.rb +170 -0
  245. data/lib/solargraph/yard_map/core_gen.rb +76 -0
  246. data/lib/solargraph/yard_map/mapper.rb +71 -0
  247. data/lib/solargraph/yard_map/rdoc_to_yard.rb +136 -0
  248. data/lib/yard-solargraph.rb +30 -0
  249. data/solargraph.gemspec +41 -0
  250. data/travis-bundler.rb +11 -0
  251. data/yardoc/2.2.2.tar.gz +0 -0
  252. metadata +575 -0
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # HACK: Fix autoload issue
4
+ require 'solargraph/source/chain/link'
5
+
6
+ module Solargraph
7
+ class Source
8
+ # A chain of constants, variables, and method calls for inferring types of
9
+ # values.
10
+ #
11
+ class Chain
12
+ autoload :Link, 'solargraph/source/chain/link'
13
+ autoload :Call, 'solargraph/source/chain/call'
14
+ autoload :Variable, 'solargraph/source/chain/variable'
15
+ autoload :ClassVariable, 'solargraph/source/chain/class_variable'
16
+ autoload :Constant, 'solargraph/source/chain/constant'
17
+ autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
18
+ autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
19
+ autoload :Literal, 'solargraph/source/chain/literal'
20
+ autoload :Head, 'solargraph/source/chain/head'
21
+ autoload :Or, 'solargraph/source/chain/or'
22
+ autoload :BlockVariable, 'solargraph/source/chain/block_variable'
23
+ autoload :ZSuper, 'solargraph/source/chain/z_super'
24
+
25
+ @@inference_stack = []
26
+ @@inference_depth = 0
27
+
28
+ UNDEFINED_CALL = Chain::Call.new('<undefined>')
29
+ UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
30
+
31
+ # @return [Array<Source::Chain::Link>]
32
+ attr_reader :links
33
+
34
+ attr_reader :node
35
+
36
+ # @param links [Array<Chain::Link>]
37
+ def initialize links, node = nil, splat = false
38
+ @links = links.clone
39
+ @links.push UNDEFINED_CALL if @links.empty?
40
+ head = true
41
+ @links.map! do |link|
42
+ result = (head ? link.clone_head : link.clone_body)
43
+ head = false
44
+ result
45
+ end
46
+ @node = node
47
+ @splat = splat
48
+ end
49
+
50
+ # @return [Chain]
51
+ def base
52
+ @base ||= Chain.new(links[0..-2])
53
+ end
54
+
55
+ # @param api_map [ApiMap]
56
+ # @param name_pin [Pin::Base]
57
+ # @param locals [Array<Pin::Base>]
58
+ # @return [Array<Pin::Base>]
59
+ def define api_map, name_pin, locals
60
+ rebind_block name_pin, api_map, locals
61
+ return [] if undefined?
62
+ working_pin = name_pin
63
+ links[0..-2].each do |link|
64
+ pins = link.resolve(api_map, working_pin, locals)
65
+ # Locals are only used when resolving the first link
66
+ # @todo There's a problem here. Call links need to resolve arguments
67
+ # that might refer to local variables.
68
+ # locals = []
69
+ type = infer_first_defined(pins, working_pin, api_map)
70
+ return [] if type.undefined?
71
+ working_pin = Pin::ProxyType.anonymous(type)
72
+ end
73
+ links.last.last_context = working_pin
74
+ links.last.resolve(api_map, working_pin, locals)
75
+ end
76
+
77
+ # @param api_map [ApiMap]
78
+ # @param name_pin [Pin::Base]
79
+ # @param locals [Array<Pin::Base>]
80
+ # @return [ComplexType]
81
+ def infer api_map, name_pin, locals
82
+ rebind_block name_pin, api_map, locals
83
+ pins = define(api_map, name_pin, locals)
84
+ infer_first_defined(pins, links.last.last_context, api_map)
85
+ end
86
+
87
+ # @return [Boolean]
88
+ def literal?
89
+ links.last.is_a?(Chain::Literal)
90
+ end
91
+
92
+ def undefined?
93
+ links.any?(&:undefined?)
94
+ end
95
+
96
+ def defined?
97
+ !undefined?
98
+ end
99
+
100
+ # @return [Boolean]
101
+ def constant?
102
+ links.last.is_a?(Chain::Constant)
103
+ end
104
+
105
+ def splat?
106
+ @splat
107
+ end
108
+
109
+ private
110
+
111
+ # @param pins [Array<Pin::Base>]
112
+ # @param api_map [ApiMap]
113
+ # @return [ComplexType]
114
+ def infer_first_defined pins, context, api_map
115
+ type = ComplexType::UNDEFINED
116
+ pins.each do |pin|
117
+ # Avoid infinite recursion
118
+ next if @@inference_stack.include?(pin.identity)
119
+ @@inference_stack.push pin.identity
120
+ type = pin.typify(api_map)
121
+ @@inference_stack.pop
122
+ break if type.defined?
123
+ end
124
+ if type.undefined?
125
+ # Limit method inference recursion
126
+ return type if @@inference_depth >= 10 && pins.first.is_a?(Pin::BaseMethod)
127
+ @@inference_depth += 1
128
+ pins.each do |pin|
129
+ # Avoid infinite recursion
130
+ next if @@inference_stack.include?(pin.identity)
131
+ @@inference_stack.push pin.identity
132
+ type = pin.probe(api_map)
133
+ @@inference_stack.pop
134
+ break if type.defined?
135
+ end
136
+ @@inference_depth -= 1
137
+ end
138
+ return type if context.nil? || context.return_type.undefined?
139
+ type.self_to(context.return_type.namespace)
140
+ end
141
+
142
+ def skippable_block_receivers api_map
143
+ @@skippable_block_receivers ||= (
144
+ api_map.get_methods('Array', deep: false).map(&:name) +
145
+ api_map.get_methods('Enumerable', deep: false).map(&:name) +
146
+ api_map.get_methods('Hash', deep: false).map(&:name) +
147
+ ['new']
148
+ ).to_set
149
+ end
150
+
151
+ def rebind_block pin, api_map, locals
152
+ return unless pin.is_a?(Pin::Block) && pin.receiver && !pin.rebound?
153
+ # This first rebind just sets the block pin's rebound state
154
+ pin.rebind ComplexType::UNDEFINED
155
+ chain = Parser.chain(pin.receiver, pin.location.filename)
156
+ return if skippable_block_receivers(api_map).include?(chain.links.last.word)
157
+ if ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'].include?(chain.links.last.word)
158
+ type = chain.base.infer(api_map, pin, locals)
159
+ pin.rebind type
160
+ else
161
+ receiver_pin = chain.define(api_map, pin, locals).first
162
+ return if receiver_pin.nil? || receiver_pin.docstring.nil?
163
+ ys = receiver_pin.docstring.tag(:yieldself)
164
+ unless ys.nil? || ys.types.nil? || ys.types.empty?
165
+ ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
166
+ pin.rebind ysct
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class BlockVariable < Link
7
+ def resolve api_map, name_pin, locals
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('Proc'))]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Call < Link
7
+ # @return [String]
8
+ attr_reader :word
9
+
10
+ # @return [Array<Chain>]
11
+ attr_reader :arguments
12
+
13
+ # @param word [String]
14
+ # @param arguments [Array<Chain>]
15
+ # @param with_block [Boolean] True if the chain is inside a block
16
+ # @param head [Boolean] True if the call is the start of its chain
17
+ def initialize word, arguments = [], with_block = false
18
+ @word = word
19
+ @arguments = arguments
20
+ @with_block = with_block
21
+ end
22
+
23
+ def with_block?
24
+ @with_block
25
+ end
26
+
27
+ # @param api_map [ApiMap]
28
+ # @param name_pin [Pin::Base]
29
+ # @param locals [Array<Pin::Base>]
30
+ def resolve api_map, name_pin, locals
31
+ return super_pins(api_map, name_pin) if word == 'super'
32
+ found = if head?
33
+ locals.select { |p| p.name == word }
34
+ else
35
+ []
36
+ end
37
+ return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
38
+ pins = api_map.get_method_stack(name_pin.binder.namespace, word, scope: name_pin.binder.scope)
39
+ return [] if pins.empty?
40
+ inferred_pins(pins, api_map, name_pin.context, locals)
41
+ end
42
+
43
+ private
44
+
45
+ # @param pins [Array<Pin::Base>]
46
+ # @param api_map [ApiMap]
47
+ # @param context [ComplexType]
48
+ # @param locals [Pin::LocalVariable]
49
+ # @return [Array<Pin::Base>]
50
+ def inferred_pins pins, api_map, context, locals
51
+ result = pins.map do |p|
52
+ overloads = p.docstring.tags(:overload)
53
+ # next p if overloads.empty?
54
+ type = ComplexType::UNDEFINED
55
+ # @param [YARD::Tags::OverloadTag]
56
+ overloads.each do |ol|
57
+ next unless arguments_match(arguments, ol.parameters)
58
+ next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
59
+ match = true
60
+ arguments.each_with_index do |arg, idx|
61
+ achain = arguments[idx]
62
+ next if achain.nil?
63
+ param = ol.parameters[idx]
64
+ if param.nil?
65
+ match = false unless ol.parameters.last && ol.parameters.last.first.start_with?('*')
66
+ break
67
+ end
68
+ par = ol.tags(:param).select { |pp| pp.name == param.first }.first
69
+ next if par.nil? || par.types.nil? || par.types.empty?
70
+ atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
71
+ other = ComplexType.try_parse(*par.types)
72
+ # @todo Weak type comparison
73
+ unless atype.tag == other.tag || api_map.super_and_sub?(other.tag, atype.tag)
74
+ match = false
75
+ break
76
+ end
77
+ end
78
+ if match
79
+ type = extra_return_type(ol, context)
80
+ type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
81
+ type ||= ComplexType::UNDEFINED
82
+ end
83
+ break if type.defined?
84
+ end
85
+ next p.proxy(type) if type.defined?
86
+ type = extra_return_type(p.docstring, context)
87
+ if type
88
+ next Solargraph::Pin::Method.new(
89
+ location: p.location,
90
+ closure: p.closure,
91
+ name: p.name,
92
+ comments: "@return [#{context.subtypes.first.to_s}]",
93
+ scope: p.scope,
94
+ visibility: p.visibility,
95
+ parameters: p.parameters,
96
+ node: p.node
97
+ )
98
+ end
99
+ if p.is_a?(Pin::Method) && !p.macros.empty?
100
+ result = process_macro(p, api_map, context, locals)
101
+ next result unless result.return_type.undefined?
102
+ elsif !p.directives.empty?
103
+ result = process_directive(p, api_map, context, locals)
104
+ next result unless result.return_type.undefined?
105
+ end
106
+ p
107
+ end
108
+ result.map do |pin|
109
+ next pin if pin.return_type.undefined?
110
+ selfy = pin.return_type.self_to(context.tag)
111
+ selfy == pin.return_type ? pin : pin.proxy(selfy)
112
+ end
113
+ end
114
+
115
+ # @param pin [Pin::Method]
116
+ # @param api_map [ApiMap]
117
+ # @param context [ComplexType]
118
+ # @param locals [Pin::Base]
119
+ # @return [Pin::Base]
120
+ def process_macro pin, api_map, context, locals
121
+ pin.macros.each do |macro|
122
+ result = inner_process_macro(pin, macro, api_map, context, locals)
123
+ return result unless result.return_type.undefined?
124
+ end
125
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
126
+ end
127
+
128
+ # @param pin [Pin::Method]
129
+ # @param api_map [ApiMap]
130
+ # @param context [ComplexType]
131
+ # @param locals [Pin::Base]
132
+ # @return [Pin::ProxyType]
133
+ def process_directive pin, api_map, context, locals
134
+ pin.directives.each do |dir|
135
+ macro = api_map.named_macro(dir.tag.name)
136
+ next if macro.nil?
137
+ result = inner_process_macro(pin, macro, api_map, context, locals)
138
+ return result unless result.return_type.undefined?
139
+ end
140
+ Pin::ProxyType.anonymous ComplexType::UNDEFINED
141
+ end
142
+
143
+ # @param pin [Pin]
144
+ # @param macro [YARD::Tags::MacroDirective]
145
+ # @param api_map [ApiMap]
146
+ # @param context [ComplexType]
147
+ # @param locals [Array<Pin::Base>]
148
+ # @return [Pin::ProxyType]
149
+ def inner_process_macro pin, macro, api_map, context, locals
150
+ vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
151
+ txt = macro.tag.text.clone
152
+ if txt.empty? && macro.tag.name
153
+ named = api_map.named_macro(macro.tag.name)
154
+ txt = named.tag.text.clone if named
155
+ end
156
+ i = 1
157
+ vals.each do |v|
158
+ txt.gsub!(/\$#{i}/, v.context.namespace)
159
+ i += 1
160
+ end
161
+ docstring = Solargraph::Source.parse_docstring(txt).to_docstring
162
+ tag = docstring.tag(:return)
163
+ unless tag.nil? || tag.types.nil?
164
+ return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
165
+ end
166
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
167
+ end
168
+
169
+ # @param docstring [YARD::Docstring]
170
+ # @param context [ComplexType]
171
+ # @return [ComplexType]
172
+ def extra_return_type docstring, context
173
+ if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
174
+ return context.subtypes.first
175
+ elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
176
+ return context.value_types.first
177
+ end
178
+ nil
179
+ end
180
+
181
+ # @param arguments [Array<Chain>]
182
+ # @param parameters [Array<String>]
183
+ # @return [Boolean]
184
+ def arguments_match arguments, parameters
185
+ argcount = arguments.length
186
+ # argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
187
+ parcount = parameters.length
188
+ parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
189
+ return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
190
+ true
191
+ end
192
+
193
+ # @param api_map [ApiMap]
194
+ # @param name_pin [Pin::Base]
195
+ # @return [Array<Pin::Base>]
196
+ def super_pins api_map, name_pin
197
+ pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
198
+ pins.reject{|p| p.path == name_pin.path}
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class ClassVariable < Link
7
+ def resolve api_map, name_pin, locals
8
+ api_map.get_class_variable_pins(name_pin.context.namespace).select{|p| p.name == word}
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Constant < Link
7
+ def initialize word
8
+ @word = word
9
+ end
10
+
11
+ def resolve api_map, name_pin, locals
12
+ return [Pin::ROOT_PIN] if word.empty?
13
+ if word.start_with?('::')
14
+ base = word[2..-1]
15
+ gates = ['']
16
+ else
17
+ base = word
18
+ gates = crawl_gates(name_pin)
19
+ end
20
+ parts = base.split('::')
21
+ gates.each do |gate|
22
+ type = deep_constant_type(gate, api_map)
23
+ # Use deep inference to resolve root
24
+ parts[0..-2].each do |sym|
25
+ pins = api_map.get_constants('', type.namespace).select{ |pin| pin.name == sym }
26
+ type = first_pin_type(pins, api_map)
27
+ break if type.undefined?
28
+ end
29
+ next if type.undefined?
30
+ result = api_map.get_constants('', type.namespace).select { |pin| pin.name == parts.last }
31
+ return result unless result.empty?
32
+ end
33
+ []
34
+ end
35
+
36
+ private
37
+
38
+ def crawl_gates pin
39
+ clos = pin
40
+ until clos.nil?
41
+ if clos.is_a?(Pin::Namespace)
42
+ gates = clos.gates
43
+ gates.push('') if gates.empty?
44
+ return gates
45
+ end
46
+ clos = clos.closure
47
+ end
48
+ ['']
49
+ end
50
+
51
+ def first_pin_type(pins, api_map)
52
+ type = ComplexType::UNDEFINED
53
+ pins.each do |pin|
54
+ type = pin.typify(api_map)
55
+ break if type.defined?
56
+ type = pin.probe(api_map)
57
+ break if type.defined?
58
+ end
59
+ type
60
+ end
61
+
62
+ def deep_constant_type(gate, api_map)
63
+ type = ComplexType::ROOT
64
+ return type if gate == ''
65
+ gate.split('::').each do |word|
66
+ pins = api_map.get_constants('', type.namespace).select { |pin| pin.name == word }
67
+ type = first_pin_type(pins, api_map)
68
+ break if type.undefined?
69
+ end
70
+ type
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end