solargraph 0.46.0 → 0.54.5

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/plugins.yml +40 -0
  4. data/.github/workflows/rspec.yml +37 -41
  5. data/.github/workflows/typecheck.yml +34 -0
  6. data/.gitignore +9 -9
  7. data/.rspec +2 -2
  8. data/.yardopts +2 -2
  9. data/CHANGELOG.md +1338 -1115
  10. data/Gemfile +0 -0
  11. data/LICENSE +1 -1
  12. data/README.md +131 -128
  13. data/Rakefile +0 -0
  14. data/SPONSORS.md +10 -18
  15. data/bin/solargraph +0 -0
  16. data/lib/solargraph/api_map/cache.rb +109 -70
  17. data/lib/solargraph/api_map/index.rb +167 -0
  18. data/lib/solargraph/api_map/source_to_yard.rb +88 -81
  19. data/lib/solargraph/api_map/store.rb +260 -256
  20. data/lib/solargraph/api_map.rb +870 -686
  21. data/lib/solargraph/bench.rb +44 -27
  22. data/lib/solargraph/cache.rb +77 -0
  23. data/lib/solargraph/complex_type/type_methods.rb +217 -130
  24. data/lib/solargraph/complex_type/unique_type.rb +386 -75
  25. data/lib/solargraph/complex_type.rb +394 -221
  26. data/lib/solargraph/convention/base.rb +33 -33
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +22 -22
  29. data/lib/solargraph/convention/rakefile.rb +17 -0
  30. data/lib/solargraph/convention.rb +47 -47
  31. data/lib/solargraph/converters/dd.rb +17 -12
  32. data/lib/solargraph/converters/dl.rb +15 -12
  33. data/lib/solargraph/converters/dt.rb +15 -12
  34. data/lib/solargraph/converters/misc.rb +1 -1
  35. data/lib/solargraph/diagnostics/base.rb +29 -29
  36. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  37. data/lib/solargraph/diagnostics/rubocop.rb +113 -98
  38. data/lib/solargraph/diagnostics/rubocop_helpers.rb +66 -63
  39. data/lib/solargraph/diagnostics/severities.rb +15 -15
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -54
  41. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  42. data/lib/solargraph/diagnostics.rb +55 -55
  43. data/lib/solargraph/doc_map.rb +188 -0
  44. data/lib/solargraph/environ.rb +45 -45
  45. data/lib/solargraph/equality.rb +33 -0
  46. data/lib/solargraph/gem_pins.rb +72 -0
  47. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -35
  48. data/lib/solargraph/language_server/error_codes.rb +20 -20
  49. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  50. data/lib/solargraph/language_server/host/dispatch.rb +128 -111
  51. data/lib/solargraph/language_server/host/message_worker.rb +106 -59
  52. data/lib/solargraph/language_server/host/sources.rb +99 -156
  53. data/lib/solargraph/language_server/host.rb +861 -865
  54. data/lib/solargraph/language_server/message/base.rb +96 -89
  55. data/lib/solargraph/language_server/message/cancel_request.rb +13 -13
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  57. data/lib/solargraph/language_server/message/client.rb +11 -11
  58. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -58
  59. data/lib/solargraph/language_server/message/completion_item.rb +11 -11
  60. data/lib/solargraph/language_server/message/exit_notification.rb +13 -13
  61. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +112 -100
  62. data/lib/solargraph/language_server/message/extended/document.rb +20 -20
  63. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  64. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -23
  65. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  66. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  67. data/lib/solargraph/language_server/message/extended.rb +21 -21
  68. data/lib/solargraph/language_server/message/initialize.rb +191 -162
  69. data/lib/solargraph/language_server/message/initialized.rb +28 -27
  70. data/lib/solargraph/language_server/message/method_not_found.rb +16 -16
  71. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -14
  72. data/lib/solargraph/language_server/message/shutdown.rb +13 -13
  73. data/lib/solargraph/language_server/message/text_document/base.rb +19 -19
  74. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -17
  75. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -59
  76. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -38
  77. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -15
  78. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -15
  79. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -15
  80. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -17
  81. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  82. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -23
  83. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -26
  84. data/lib/solargraph/language_server/message/text_document/formatting.rb +131 -126
  85. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -54
  86. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -34
  87. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  88. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  89. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  90. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -29
  91. data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
  92. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  93. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -30
  94. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -33
  95. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
  96. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  97. data/lib/solargraph/language_server/message/workspace.rb +14 -14
  98. data/lib/solargraph/language_server/message.rb +94 -93
  99. data/lib/solargraph/language_server/message_types.rb +14 -14
  100. data/lib/solargraph/language_server/progress.rb +135 -0
  101. data/lib/solargraph/language_server/request.rb +24 -24
  102. data/lib/solargraph/language_server/symbol_kinds.rb +36 -36
  103. data/lib/solargraph/language_server/transport/adapter.rb +68 -53
  104. data/lib/solargraph/language_server/transport/data_reader.rb +74 -72
  105. data/lib/solargraph/language_server/transport.rb +13 -13
  106. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  107. data/lib/solargraph/language_server.rb +20 -19
  108. data/lib/solargraph/library.rb +663 -546
  109. data/lib/solargraph/location.rb +58 -37
  110. data/lib/solargraph/logging.rb +27 -27
  111. data/lib/solargraph/page.rb +89 -83
  112. data/lib/solargraph/parser/comment_ripper.rb +56 -52
  113. data/lib/solargraph/parser/node_methods.rb +83 -43
  114. data/lib/solargraph/parser/node_processor/base.rb +87 -77
  115. data/lib/solargraph/parser/node_processor.rb +45 -43
  116. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +153 -135
  117. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +18 -16
  118. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +164 -148
  119. data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
  120. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +23 -23
  121. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
  122. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +15 -15
  123. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +43 -42
  124. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +35 -25
  125. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +23 -23
  126. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +50 -63
  127. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +36 -36
  128. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +23 -23
  129. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +38 -38
  130. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +28 -28
  131. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
  132. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +39 -39
  133. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +16 -16
  134. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +36 -36
  135. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
  136. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +259 -257
  137. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +18 -18
  138. data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
  139. data/lib/solargraph/parser/parser_gem.rb +12 -0
  140. data/lib/solargraph/parser/region.rb +66 -66
  141. data/lib/solargraph/parser/snippet.rb +15 -13
  142. data/lib/solargraph/parser.rb +22 -26
  143. data/lib/solargraph/pin/base.rb +378 -296
  144. data/lib/solargraph/pin/base_variable.rb +118 -84
  145. data/lib/solargraph/pin/block.rb +101 -72
  146. data/lib/solargraph/pin/callable.rb +147 -0
  147. data/lib/solargraph/pin/class_variable.rb +8 -8
  148. data/lib/solargraph/pin/closure.rb +57 -37
  149. data/lib/solargraph/pin/common.rb +70 -70
  150. data/lib/solargraph/pin/constant.rb +43 -43
  151. data/lib/solargraph/pin/conversions.rb +123 -96
  152. data/lib/solargraph/pin/delegated_method.rb +101 -0
  153. data/lib/solargraph/pin/documenting.rb +98 -105
  154. data/lib/solargraph/pin/duck_method.rb +16 -16
  155. data/lib/solargraph/pin/global_variable.rb +8 -8
  156. data/lib/solargraph/pin/instance_variable.rb +34 -30
  157. data/lib/solargraph/pin/keyword.rb +15 -15
  158. data/lib/solargraph/pin/keyword_param.rb +8 -8
  159. data/lib/solargraph/pin/local_variable.rb +67 -55
  160. data/lib/solargraph/pin/method.rb +527 -245
  161. data/lib/solargraph/pin/method_alias.rb +31 -31
  162. data/lib/solargraph/pin/namespace.rb +107 -91
  163. data/lib/solargraph/pin/parameter.rb +212 -201
  164. data/lib/solargraph/pin/proxy_type.rb +29 -29
  165. data/lib/solargraph/pin/reference/extend.rb +10 -10
  166. data/lib/solargraph/pin/reference/include.rb +10 -10
  167. data/lib/solargraph/pin/reference/override.rb +29 -29
  168. data/lib/solargraph/pin/reference/prepend.rb +10 -10
  169. data/lib/solargraph/pin/reference/require.rb +14 -14
  170. data/lib/solargraph/pin/reference/superclass.rb +10 -10
  171. data/lib/solargraph/pin/reference.rb +22 -14
  172. data/lib/solargraph/pin/search.rb +56 -56
  173. data/lib/solargraph/pin/signature.rb +17 -0
  174. data/lib/solargraph/pin/singleton.rb +11 -11
  175. data/lib/solargraph/pin/symbol.rb +47 -47
  176. data/lib/solargraph/pin.rb +41 -37
  177. data/lib/solargraph/position.rb +107 -100
  178. data/lib/solargraph/range.rb +98 -95
  179. data/lib/solargraph/rbs_map/conversions.rb +646 -0
  180. data/lib/solargraph/rbs_map/core_fills.rb +50 -0
  181. data/lib/solargraph/rbs_map/core_map.rb +28 -0
  182. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
  183. data/lib/solargraph/rbs_map.rb +93 -0
  184. data/lib/solargraph/server_methods.rb +16 -16
  185. data/lib/solargraph/shell.rb +269 -226
  186. data/lib/solargraph/source/chain/array.rb +33 -0
  187. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  188. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  189. data/lib/solargraph/source/chain/call.rb +303 -204
  190. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  191. data/lib/solargraph/source/chain/constant.rb +89 -75
  192. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  193. data/lib/solargraph/source/chain/hash.rb +33 -28
  194. data/lib/solargraph/source/chain/head.rb +19 -19
  195. data/lib/solargraph/source/chain/if.rb +28 -0
  196. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  197. data/lib/solargraph/source/chain/link.rb +98 -71
  198. data/lib/solargraph/source/chain/literal.rb +28 -23
  199. data/lib/solargraph/source/chain/or.rb +23 -23
  200. data/lib/solargraph/source/chain/q_call.rb +11 -11
  201. data/lib/solargraph/source/chain/variable.rb +13 -13
  202. data/lib/solargraph/source/chain/z_super.rb +30 -30
  203. data/lib/solargraph/source/chain.rb +252 -164
  204. data/lib/solargraph/source/change.rb +82 -79
  205. data/lib/solargraph/source/cursor.rb +167 -164
  206. data/lib/solargraph/source/source_chainer.rb +194 -191
  207. data/lib/solargraph/source/updater.rb +55 -54
  208. data/lib/solargraph/source.rb +495 -522
  209. data/lib/solargraph/source_map/clip.rb +232 -224
  210. data/lib/solargraph/source_map/completion.rb +23 -23
  211. data/lib/solargraph/source_map/data.rb +30 -0
  212. data/lib/solargraph/source_map/mapper.rb +255 -212
  213. data/lib/solargraph/source_map.rb +217 -180
  214. data/lib/solargraph/type_checker/checks.rb +120 -99
  215. data/lib/solargraph/type_checker/param_def.rb +35 -35
  216. data/lib/solargraph/type_checker/problem.rb +32 -32
  217. data/lib/solargraph/type_checker/rules.rb +62 -57
  218. data/lib/solargraph/type_checker.rb +672 -543
  219. data/lib/solargraph/version.rb +5 -5
  220. data/lib/solargraph/views/environment.erb +56 -58
  221. data/lib/solargraph/workspace/config.rb +239 -231
  222. data/lib/solargraph/workspace.rb +239 -215
  223. data/lib/solargraph/yard_map/cache.rb +25 -19
  224. data/lib/solargraph/yard_map/helpers.rb +16 -16
  225. data/lib/solargraph/yard_map/mapper/to_constant.rb +26 -25
  226. data/lib/solargraph/yard_map/mapper/to_method.rb +94 -78
  227. data/lib/solargraph/yard_map/mapper/to_namespace.rb +28 -27
  228. data/lib/solargraph/yard_map/mapper.rb +78 -77
  229. data/lib/solargraph/yard_map/to_method.rb +86 -79
  230. data/lib/solargraph/yard_map.rb +18 -460
  231. data/lib/solargraph/yard_tags.rb +20 -0
  232. data/lib/solargraph/yardoc.rb +52 -0
  233. data/lib/solargraph.rb +72 -69
  234. data/solargraph.gemspec +21 -10
  235. metadata +184 -115
  236. data/.travis.yml +0 -19
  237. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  238. data/lib/solargraph/compat.rb +0 -37
  239. data/lib/solargraph/convention/rspec.rb +0 -30
  240. data/lib/solargraph/documentor.rb +0 -76
  241. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  242. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  243. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  244. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  245. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  246. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
  247. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
  248. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  249. data/lib/solargraph/parser/legacy.rb +0 -12
  250. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
  251. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  252. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  253. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  254. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  255. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
  256. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  257. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
  258. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  259. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  260. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  261. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  262. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  263. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  264. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  265. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  266. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  267. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
  268. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  269. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
  270. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
  271. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  272. data/lib/solargraph/parser/rubyvm.rb +0 -40
  273. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  274. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  275. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  276. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  277. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  278. data/lib/yard-solargraph.rb +0 -33
  279. data/yardoc/2.2.2.tar.gz +0 -0
@@ -1,245 +1,527 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- # The base class for method and attribute pins.
6
- #
7
- class Method < Closure
8
- include Solargraph::Parser::NodeMethods
9
-
10
- # @return [Array<Pin::Parameter>]
11
- attr_reader :parameters
12
-
13
- # @return [::Symbol] :public, :private, or :protected
14
- attr_reader :visibility
15
-
16
- # @return [Parser::AST::Node]
17
- attr_reader :node
18
-
19
- # @param visibility [::Symbol] :public, :protected, or :private
20
- # @param explicit [Boolean]
21
- def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, **splat
22
- super(**splat)
23
- @visibility = visibility
24
- @explicit = explicit
25
- @parameters = parameters
26
- @node = node
27
- @attribute = attribute
28
- end
29
-
30
- # @return [Array<String>]
31
- def parameter_names
32
- @parameter_names ||= parameters.map(&:name)
33
- end
34
-
35
- def completion_item_kind
36
- attribute? ? Solargraph::LanguageServer::CompletionItemKinds::PROPERTY : Solargraph::LanguageServer::CompletionItemKinds::METHOD
37
- end
38
-
39
- def symbol_kind
40
- attribute? ? Solargraph::LanguageServer::SymbolKinds::PROPERTY : LanguageServer::SymbolKinds::METHOD
41
- end
42
-
43
- def return_type
44
- @return_type ||= generate_complex_type
45
- end
46
-
47
- def path
48
- @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
49
- end
50
-
51
- def typify api_map
52
- decl = super
53
- return decl unless decl.undefined?
54
- type = see_reference(api_map) || typify_from_super(api_map)
55
- return type.qualify(api_map, namespace) unless type.nil?
56
- name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
57
- end
58
-
59
- def documentation
60
- if @documentation.nil?
61
- @documentation ||= super || ''
62
- param_tags = docstring.tags(:param)
63
- unless param_tags.nil? or param_tags.empty?
64
- @documentation += "\n\n" unless @documentation.empty?
65
- @documentation += "Params:\n"
66
- lines = []
67
- param_tags.each do |p|
68
- l = "* #{p.name}"
69
- l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
70
- l += " #{p.text}"
71
- lines.push l
72
- end
73
- @documentation += lines.join("\n")
74
- end
75
- return_tags = docstring.tags(:return)
76
- unless return_tags.empty?
77
- @documentation += "\n\n" unless @documentation.empty?
78
- @documentation += "Returns:\n"
79
- lines = []
80
- return_tags.each do |r|
81
- l = "*"
82
- l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
83
- l += " #{r.text}"
84
- lines.push l
85
- end
86
- @documentation += lines.join("\n")
87
- end
88
- @documentation += "\n\n" unless @documentation.empty?
89
- @documentation += "Visibility: #{visibility}"
90
- end
91
- @documentation.to_s
92
- end
93
-
94
- def explicit?
95
- @explicit
96
- end
97
-
98
- def attribute?
99
- @attribute
100
- end
101
-
102
- def nearly? other
103
- return false unless super
104
- parameters == other.parameters and
105
- scope == other.scope and
106
- visibility == other.visibility
107
- end
108
-
109
- def probe api_map
110
- attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
111
- end
112
-
113
- def try_merge! pin
114
- return false unless super
115
- @node = pin.node
116
- true
117
- end
118
-
119
- # @return [Array<Pin::Method>]
120
- def overloads
121
- @overloads ||= docstring.tags(:overload).map do |tag|
122
- Solargraph::Pin::Method.new(
123
- name: name,
124
- closure: self,
125
- # args: tag.parameters.map(&:first),
126
- parameters: tag.parameters.map do |src|
127
- Pin::Parameter.new(
128
- location: location,
129
- closure: self,
130
- comments: tag.docstring.all.to_s,
131
- name: src.first,
132
- presence: location ? location.range : nil,
133
- decl: :arg
134
- )
135
- end,
136
- comments: tag.docstring.all.to_s
137
- )
138
- end
139
- end
140
-
141
- private
142
-
143
- # @return [ComplexType]
144
- def generate_complex_type
145
- tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
146
- return ComplexType::UNDEFINED if tags.empty?
147
- ComplexType.try_parse *tags
148
- end
149
-
150
- # @param api_map [ApiMap]
151
- # @return [ComplexType, nil]
152
- def see_reference api_map
153
- docstring.ref_tags.each do |ref|
154
- next unless ref.tag_name == 'return' && ref.owner
155
- result = resolve_reference(ref.owner.to_s, api_map)
156
- return result unless result.nil?
157
- end
158
- match = comments.match(/^[ \t]*\(see (.*)\)/m)
159
- return nil if match.nil?
160
- resolve_reference match[1], api_map
161
- end
162
-
163
- # @param api_map [ApiMap]
164
- # @return [ComplexType, nil]
165
- def typify_from_super api_map
166
- stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
167
- return nil if stack.empty?
168
- stack.each do |pin|
169
- return pin.return_type unless pin.return_type.undefined?
170
- end
171
- nil
172
- end
173
-
174
- # @param ref [String]
175
- # @param api_map [ApiMap]
176
- # @return [ComplexType]
177
- def resolve_reference ref, api_map
178
- parts = ref.split(/[\.#]/)
179
- if parts.first.empty? || parts.one?
180
- path = "#{namespace}#{ref}"
181
- else
182
- fqns = api_map.qualify(parts.first, namespace)
183
- return ComplexType::UNDEFINED if fqns.nil?
184
- path = fqns + ref[parts.first.length] + parts.last
185
- end
186
- pins = api_map.get_path_pins(path)
187
- pins.each do |pin|
188
- type = pin.typify(api_map)
189
- return type unless type.undefined?
190
- end
191
- nil
192
- end
193
-
194
- # @return [Parser::AST::Node, nil]
195
- def method_body_node
196
- return nil if node.nil?
197
- return node.children[1].children.last if node.type == :DEFN
198
- return node.children[2].children.last if node.type == :DEFS
199
- return node.children[2] if node.type == :def || node.type == :DEFS
200
- return node.children[3] if node.type == :defs
201
- nil
202
- end
203
-
204
- # @param api_map [ApiMap]
205
- # @return [ComplexType]
206
- def infer_from_return_nodes api_map
207
- return ComplexType::UNDEFINED if node.nil?
208
- result = []
209
- has_nil = false
210
- return ComplexType::NIL if method_body_node.nil?
211
- returns_from(method_body_node).each do |n|
212
- if n.nil? || [:NIL, :nil].include?(n.type)
213
- has_nil = true
214
- next
215
- end
216
- rng = Range.from_node(n)
217
- next unless rng
218
- clip = api_map.clip_at(
219
- location.filename,
220
- rng.ending
221
- )
222
- chain = Solargraph::Parser.chain(n, location.filename)
223
- type = chain.infer(api_map, self, clip.locals)
224
- result.push type unless type.undefined?
225
- end
226
- result.push ComplexType::NIL if has_nil
227
- return ComplexType::UNDEFINED if result.empty?
228
- ComplexType.try_parse(*result.map(&:tag).uniq)
229
- end
230
-
231
- def infer_from_iv api_map
232
- types = []
233
- varname = "@#{name.gsub(/=$/, '')}"
234
- pins = api_map.get_instance_variable_pins(binder.namespace, binder.scope).select { |iv| iv.name == varname }
235
- pins.each do |pin|
236
- type = pin.typify(api_map)
237
- type = pin.probe(api_map) if type.undefined?
238
- types.push type if type.defined?
239
- end
240
- return ComplexType::UNDEFINED if types.empty?
241
- ComplexType.try_parse(*types.map(&:tag).uniq)
242
- end
243
- end
244
- end
245
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ # The base class for method and attribute pins.
6
+ #
7
+ class Method < Callable
8
+ include Solargraph::Parser::NodeMethods
9
+
10
+ # @return [::Symbol] :public, :private, or :protected
11
+ attr_reader :visibility
12
+
13
+ # @return [Parser::AST::Node]
14
+ attr_reader :node
15
+
16
+ # @param visibility [::Symbol] :public, :protected, or :private
17
+ # @param explicit [Boolean]
18
+ # @param block [Pin::Signature, nil, ::Symbol]
19
+ # @param node [Parser::AST::Node, nil]
20
+ # @param attribute [Boolean]
21
+ # @param signatures [::Array<Signature>, nil]
22
+ # @param anon_splat [Boolean]
23
+ def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
24
+ super(**splat)
25
+ @visibility = visibility
26
+ @explicit = explicit
27
+ @block = block
28
+ @node = node
29
+ @attribute = attribute
30
+ @signatures = signatures
31
+ @anon_splat = anon_splat
32
+ end
33
+
34
+ def == other
35
+ super && other.node == node
36
+ end
37
+
38
+ def transform_types(&transform)
39
+ # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
40
+ m = super(&transform)
41
+ m.signatures = m.signatures.map do |sig|
42
+ sig.transform_types(&transform)
43
+ end
44
+ m.block = block&.transform_types(&transform)
45
+ m.signature_help = nil
46
+ m.documentation = nil
47
+ m
48
+ end
49
+
50
+ def all_rooted?
51
+ super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
52
+ end
53
+
54
+ # @param signature [Pin::Signature]
55
+ # @return [Pin::Method]
56
+ def with_single_signature(signature)
57
+ m = proxy signature.return_type
58
+ m.signature_help = nil
59
+ m.documentation = nil
60
+ # @todo populating the single parameters/return_type/block
61
+ # arguments here seems to be needed for some specs to pass,
62
+ # even though we have a signature with the same information.
63
+ # Is this a problem for RBS-populated methods, which don't
64
+ # populate these three?
65
+ m.parameters = signature.parameters
66
+ m.return_type = signature.return_type
67
+ m.block = signature.block
68
+ m.signatures = [signature]
69
+ m
70
+ end
71
+
72
+ def block?
73
+ !block.nil?
74
+ end
75
+
76
+ # @return [Pin::Signature, nil]
77
+ def block
78
+ return @block unless @block == :undefined
79
+ @block = signatures.first&.block
80
+ end
81
+
82
+ def completion_item_kind
83
+ attribute? ? Solargraph::LanguageServer::CompletionItemKinds::PROPERTY : Solargraph::LanguageServer::CompletionItemKinds::METHOD
84
+ end
85
+
86
+ def symbol_kind
87
+ attribute? ? Solargraph::LanguageServer::SymbolKinds::PROPERTY : LanguageServer::SymbolKinds::METHOD
88
+ end
89
+
90
+ def return_type
91
+ @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
92
+ end
93
+
94
+ # @param parameters [::Array<Parameter>]
95
+ # @param return_type [ComplexType]
96
+ # @return [Signature]
97
+ def generate_signature(parameters, return_type)
98
+ block = nil
99
+ yieldparam_tags = docstring.tags(:yieldparam)
100
+ yieldreturn_tags = docstring.tags(:yieldreturn)
101
+ generics = docstring.tags(:generic).map(&:name)
102
+ needs_block_param_signature =
103
+ parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
104
+ if needs_block_param_signature
105
+ yield_parameters = yieldparam_tags.map do |p|
106
+ name = p.name
107
+ decl = :arg
108
+ if name
109
+ decl = select_decl(name, false)
110
+ name = clean_param(name)
111
+ end
112
+ Pin::Parameter.new(
113
+ location: location,
114
+ closure: self,
115
+ comments: p.text,
116
+ name: name,
117
+ decl: decl,
118
+ presence: location ? location.range : nil,
119
+ return_type: ComplexType.try_parse(*p.types)
120
+ )
121
+ end
122
+ yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
123
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
124
+ end
125
+ Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
126
+ end
127
+
128
+ # @return [::Array<Signature>]
129
+ def signatures
130
+ @signatures ||= begin
131
+ top_type = generate_complex_type
132
+ result = []
133
+ result.push generate_signature(parameters, top_type) if top_type.defined?
134
+ result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
135
+ result.push generate_signature(parameters, @return_type || ComplexType::UNDEFINED) if result.empty?
136
+ result
137
+ end
138
+ end
139
+
140
+ # @return [String, nil]
141
+ def detail
142
+ # This property is not cached in an instance variable because it can
143
+ # change when pins get proxied.
144
+ detail = String.new
145
+ detail += if signatures.length > 1
146
+ "(*) "
147
+ else
148
+ "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
149
+ end.to_s
150
+ detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
151
+ detail.strip!
152
+ return nil if detail.empty?
153
+ detail
154
+ end
155
+
156
+ # @return [::Array<Hash>]
157
+ def signature_help
158
+ @signature_help ||= signatures.map do |sig|
159
+ {
160
+ label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
161
+ documentation: documentation
162
+ }
163
+ end
164
+ end
165
+
166
+ def desc
167
+ # ensure the signatures line up when logged
168
+ if signatures.length > 1
169
+ "\n#{to_rbs}\n"
170
+ else
171
+ to_rbs
172
+ end
173
+ end
174
+
175
+ def to_rbs
176
+ return nil if signatures.empty?
177
+
178
+ rbs = "def #{name}: #{signatures.first.to_rbs}"
179
+ signatures[1..].each do |sig|
180
+ rbs += "\n"
181
+ rbs += (' ' * (4 + name.length))
182
+ rbs += "| #{name}: #{sig.to_rbs}"
183
+ end
184
+ rbs
185
+ end
186
+
187
+ def path
188
+ @path ||= "#{namespace}#{(scope == :instance ? '#' : '.')}#{name}"
189
+ end
190
+
191
+ def typify api_map
192
+ decl = super
193
+ return decl unless decl.undefined?
194
+ type = see_reference(api_map) || typify_from_super(api_map)
195
+ return type.qualify(api_map, namespace) unless type.nil?
196
+ name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
197
+ end
198
+
199
+ def documentation
200
+ if @documentation.nil?
201
+ @documentation ||= super || ''
202
+ param_tags = docstring.tags(:param)
203
+ unless param_tags.nil? or param_tags.empty?
204
+ @documentation += "\n\n" unless @documentation.empty?
205
+ @documentation += "Params:\n"
206
+ lines = []
207
+ param_tags.each do |p|
208
+ l = "* #{p.name}"
209
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
210
+ l += " #{p.text}"
211
+ lines.push l
212
+ end
213
+ @documentation += lines.join("\n")
214
+ end
215
+ yieldparam_tags = docstring.tags(:yieldparam)
216
+ unless yieldparam_tags.nil? or yieldparam_tags.empty?
217
+ @documentation += "\n\n" unless @documentation.empty?
218
+ @documentation += "Block Params:\n"
219
+ lines = []
220
+ yieldparam_tags.each do |p|
221
+ l = "* #{p.name}"
222
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
223
+ l += " #{p.text}"
224
+ lines.push l
225
+ end
226
+ @documentation += lines.join("\n")
227
+ end
228
+ yieldreturn_tags = docstring.tags(:yieldreturn)
229
+ unless yieldreturn_tags.empty?
230
+ @documentation += "\n\n" unless @documentation.empty?
231
+ @documentation += "Block Returns:\n"
232
+ lines = []
233
+ yieldreturn_tags.each do |r|
234
+ l = "*"
235
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
236
+ l += " #{r.text}"
237
+ lines.push l
238
+ end
239
+ @documentation += lines.join("\n")
240
+ end
241
+ return_tags = docstring.tags(:return)
242
+ unless return_tags.empty?
243
+ @documentation += "\n\n" unless @documentation.empty?
244
+ @documentation += "Returns:\n"
245
+ lines = []
246
+ return_tags.each do |r|
247
+ l = "*"
248
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
249
+ l += " #{r.text}"
250
+ lines.push l
251
+ end
252
+ @documentation += lines.join("\n")
253
+ end
254
+ @documentation += "\n\n" unless @documentation.empty?
255
+ @documentation += "Visibility: #{visibility}"
256
+ concat_example_tags
257
+ end
258
+ @documentation.to_s
259
+ end
260
+
261
+ def explicit?
262
+ @explicit
263
+ end
264
+
265
+ def attribute?
266
+ @attribute
267
+ end
268
+
269
+ # @parm other [Method]
270
+ def nearly? other
271
+ super &&
272
+ parameters == other.parameters &&
273
+ scope == other.scope &&
274
+ visibility == other.visibility
275
+ end
276
+
277
+ def probe api_map
278
+ attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
279
+ end
280
+
281
+ # @param pin [Pin::Method]
282
+ def try_merge! pin
283
+ return false unless super
284
+ @node = pin.node
285
+ @resolved_ref_tag = false
286
+ true
287
+ end
288
+
289
+ # @return [::Array<Pin::Method>]
290
+ def overloads
291
+ # Ignore overload tags with nil parameters. If it's not an array, the
292
+ # tag's source is likely malformed.
293
+ @overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
294
+ Pin::Signature.new(
295
+ generics: generics,
296
+ parameters: tag.parameters.map do |src|
297
+ name, decl = parse_overload_param(src.first)
298
+ Pin::Parameter.new(
299
+ location: location,
300
+ closure: self,
301
+ comments: tag.docstring.all.to_s,
302
+ name: name,
303
+ decl: decl,
304
+ presence: location ? location.range : nil,
305
+ return_type: param_type_from_name(tag, src.first)
306
+ )
307
+ end,
308
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
309
+ )
310
+ end
311
+ @overloads
312
+ end
313
+
314
+ def anon_splat?
315
+ @anon_splat
316
+ end
317
+
318
+ # @param [ApiMap]
319
+ # @return [self]
320
+ def resolve_ref_tag api_map
321
+ return self if @resolved_ref_tag
322
+
323
+ @resolved_ref_tag = true
324
+ return self unless docstring.ref_tags.any?
325
+ docstring.ref_tags.each do |tag|
326
+ ref = if tag.owner.to_s.start_with?(/[#\.]/)
327
+ api_map.get_methods(namespace)
328
+ .select { |pin| pin.path.end_with?(tag.owner.to_s) }
329
+ .first
330
+ else
331
+ # @todo Resolve relative namespaces
332
+ api_map.get_path_pins(tag.owner.to_s).first
333
+ end
334
+ next unless ref
335
+
336
+ docstring.add_tag(*ref.docstring.tags(:param))
337
+ end
338
+ self
339
+ end
340
+
341
+ protected
342
+
343
+ attr_writer :block
344
+
345
+ attr_writer :signatures
346
+
347
+ attr_writer :signature_help
348
+
349
+ attr_writer :documentation
350
+
351
+ private
352
+
353
+ # @param name [String]
354
+ # @param asgn [Boolean]
355
+ #
356
+ # @return [::Symbol]
357
+ def select_decl name, asgn
358
+ if name.start_with?('**')
359
+ :kwrestarg
360
+ elsif name.start_with?('*')
361
+ :restarg
362
+ elsif name.start_with?('&')
363
+ :blockarg
364
+ elsif name.end_with?(':') && asgn
365
+ :kwoptarg
366
+ elsif name.end_with?(':')
367
+ :kwarg
368
+ elsif asgn
369
+ :optarg
370
+ else
371
+ :arg
372
+ end
373
+ end
374
+
375
+ # @param name [String]
376
+ # @return [String]
377
+ def clean_param name
378
+ name.gsub(/[*&:]/, '')
379
+ end
380
+
381
+ # @param tag [YARD::Tags::OverloadTag]
382
+ # @param name [String]
383
+ #
384
+ # @return [ComplexType]
385
+ def param_type_from_name(tag, name)
386
+ param = tag.tags(:param).select { |t| t.name == name }.first
387
+ return ComplexType::UNDEFINED unless param
388
+ ComplexType.try_parse(*param.types)
389
+ end
390
+
391
+ # @return [ComplexType]
392
+ def generate_complex_type
393
+ tags = docstring.tags(:return).map(&:types).flatten.compact
394
+ return ComplexType::UNDEFINED if tags.empty?
395
+ ComplexType.try_parse *tags
396
+ end
397
+
398
+ # @param api_map [ApiMap]
399
+ # @return [ComplexType, nil]
400
+ def see_reference api_map
401
+ docstring.ref_tags.each do |ref|
402
+ next unless ref.tag_name == 'return' && ref.owner
403
+ result = resolve_reference(ref.owner.to_s, api_map)
404
+ return result unless result.nil?
405
+ end
406
+ match = comments.match(/^[ \t]*\(see (.*)\)/m)
407
+ return nil if match.nil?
408
+ resolve_reference match[1], api_map
409
+ end
410
+
411
+ # @param api_map [ApiMap]
412
+ # @return [ComplexType, nil]
413
+ def typify_from_super api_map
414
+ stack = api_map.get_method_stack(namespace, name, scope: scope).reject { |pin| pin.path == path }
415
+ return nil if stack.empty?
416
+ stack.each do |pin|
417
+ return pin.return_type unless pin.return_type.undefined?
418
+ end
419
+ nil
420
+ end
421
+
422
+ # @param ref [String]
423
+ # @param api_map [ApiMap]
424
+ # @return [ComplexType, nil]
425
+ def resolve_reference ref, api_map
426
+ parts = ref.split(/[\.#]/)
427
+ if parts.first.empty? || parts.one?
428
+ path = "#{namespace}#{ref}"
429
+ else
430
+ fqns = api_map.qualify(parts.first, namespace)
431
+ return ComplexType::UNDEFINED if fqns.nil?
432
+ path = fqns + ref[parts.first.length] + parts.last
433
+ end
434
+ pins = api_map.get_path_pins(path)
435
+ pins.each do |pin|
436
+ type = pin.typify(api_map)
437
+ return type unless type.undefined?
438
+ end
439
+ nil
440
+ end
441
+
442
+ # @return [Parser::AST::Node, nil]
443
+ def method_body_node
444
+ return nil if node.nil?
445
+ return node.children[1].children.last if node.type == :DEFN
446
+ return node.children[2].children.last if node.type == :DEFS
447
+ return node.children[2] if node.type == :def || node.type == :DEFS
448
+ return node.children[3] if node.type == :defs
449
+ nil
450
+ end
451
+
452
+ # @param api_map [ApiMap]
453
+ # @return [ComplexType]
454
+ def infer_from_return_nodes api_map
455
+ return ComplexType::UNDEFINED if node.nil?
456
+ result = []
457
+ has_nil = false
458
+ return ComplexType::NIL if method_body_node.nil?
459
+ returns_from_method_body(method_body_node).each do |n|
460
+ if n.nil? || [:NIL, :nil].include?(n.type)
461
+ has_nil = true
462
+ next
463
+ end
464
+ rng = Range.from_node(n)
465
+ next unless rng
466
+ clip = api_map.clip_at(
467
+ location.filename,
468
+ rng.ending
469
+ )
470
+ chain = Solargraph::Parser.chain(n, location.filename)
471
+ type = chain.infer(api_map, self, clip.locals)
472
+ result.push type unless type.undefined?
473
+ end
474
+ result.push ComplexType::NIL if has_nil
475
+ return ComplexType::UNDEFINED if result.empty?
476
+ ComplexType.new(result.uniq)
477
+ end
478
+
479
+ # @param [ApiMap] api_map
480
+ # @return [ComplexType]
481
+ def infer_from_iv api_map
482
+ types = []
483
+ varname = "@#{name.gsub(/=$/, '')}"
484
+ pins = api_map.get_instance_variable_pins(binder.namespace, binder.scope).select { |iv| iv.name == varname }
485
+ pins.each do |pin|
486
+ type = pin.typify(api_map)
487
+ type = pin.probe(api_map) if type.undefined?
488
+ types.push type if type.defined?
489
+ end
490
+ return ComplexType::UNDEFINED if types.empty?
491
+ ComplexType.new(types.uniq)
492
+ end
493
+
494
+ # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
495
+ #
496
+ # @param name [String]
497
+ # @return [::Array(String, ::Symbol)]
498
+ def parse_overload_param(name)
499
+ # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
500
+ if name.start_with?('**')
501
+ [name[2..-1], :kwrestarg]
502
+ elsif name.start_with?('*')
503
+ [name[1..-1], :restarg]
504
+ else
505
+ [name, :arg]
506
+ end
507
+ end
508
+
509
+ # @return [void]
510
+ def concat_example_tags
511
+ example_tags = docstring.tags(:example)
512
+ return if example_tags.empty?
513
+ @documentation += "\n\nExamples:\n\n```ruby\n"
514
+ @documentation += example_tags.map do |tag|
515
+ (tag.name && !tag.name.empty? ? "# #{tag.name}\n" : '') +
516
+ "#{tag.text}\n"
517
+ end
518
+ .join("\n")
519
+ .concat("```\n")
520
+ end
521
+
522
+ protected
523
+
524
+ attr_writer :signatures
525
+ end
526
+ end
527
+ end