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,224 +1,232 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class SourceMap
5
- # A static analysis tool for obtaining definitions, completions,
6
- # signatures, and type inferences from a cursor.
7
- #
8
- class Clip
9
- # @param api_map [ApiMap]
10
- # @param cursor [Source::Cursor]
11
- def initialize api_map, cursor
12
- @api_map = api_map
13
- @cursor = cursor
14
- end
15
-
16
- # @return [Array<Pin::Base>]
17
- def define
18
- return [] if cursor.comment? || cursor.chain.literal?
19
- result = cursor.chain.define(api_map, block, locals)
20
- result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty?
21
- result
22
- end
23
-
24
- # @return [Completion]
25
- def complete
26
- return package_completions([]) if !source_map.source.parsed? || cursor.string?
27
- return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '<Symbol>'
28
- return Completion.new([], cursor.range) if cursor.chain.literal?
29
- if cursor.comment?
30
- tag_complete
31
- else
32
- code_complete
33
- end
34
- end
35
-
36
- # @return [Array<Pin::Base>]
37
- def signify
38
- return [] unless cursor.argument?
39
- chain = Parser.chain(cursor.recipient_node, cursor.filename)
40
- chain.define(api_map, context_pin, locals).select { |pin| pin.is_a?(Pin::Method) }
41
- end
42
-
43
- # @return [ComplexType]
44
- def infer
45
- result = cursor.chain.infer(api_map, block, locals)
46
- return result unless result.tag == 'self'
47
- ComplexType.try_parse(cursor.chain.base.infer(api_map, block, locals).namespace)
48
- end
49
-
50
- # Get an array of all the locals that are visible from the cursors's
51
- # position. Locals can be local variables, method parameters, or block
52
- # parameters. The array starts with the nearest local pin.
53
- #
54
- # @return [Array<Solargraph::Pin::Base>]
55
- def locals
56
- @locals ||= source_map.locals_at(location)
57
- end
58
-
59
- def gates
60
- block.gates
61
- end
62
-
63
- def in_block?
64
- return @in_block unless @in_block.nil?
65
- @in_block = begin
66
- tree = cursor.source.tree_at(cursor.position.line, cursor.position.column)
67
- Parser.is_ast_node?(tree[1]) && [:block, :ITER].include?(tree[1].type)
68
- end
69
- end
70
-
71
- # @param phrase [String]
72
- # @return [Array<Solargraph::Pin::Base>]
73
- def translate phrase
74
- chain = Parser.chain(Parser.parse(phrase))
75
- chain.define(api_map, block, locals)
76
- end
77
-
78
- private
79
-
80
- # @return [ApiMap]
81
- attr_reader :api_map
82
-
83
- # @return [Source::Cursor]
84
- attr_reader :cursor
85
-
86
- # @return [SourceMap]
87
- def source_map
88
- @source_map ||= api_map.source_map(cursor.filename)
89
- end
90
-
91
- def location
92
- Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
93
- end
94
-
95
- # @return [Solargraph::Pin::Base]
96
- def block
97
- @block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
98
- end
99
-
100
- # The context at the current position.
101
- #
102
- # @return [Pin::Base]
103
- def context_pin
104
- @context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
105
- end
106
-
107
- # @return [Array<Pin::Base>]
108
- def yielded_self_pins
109
- return [] unless block.is_a?(Pin::Block) && block.receiver
110
- chain = Parser.chain(block.receiver, source_map.source.filename)
111
- receiver_pin = chain.define(api_map, context_pin, locals).first
112
- return [] if receiver_pin.nil?
113
- result = []
114
- ys = receiver_pin.docstring.tag(:yieldpublic)
115
- unless ys.nil? || ys.types.empty?
116
- ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
117
- result.concat api_map.get_complex_type_methods(ysct, '', false)
118
- end
119
- result
120
- end
121
-
122
- # @return [Array<Pin::KeywordParam]
123
- def complete_keyword_parameters
124
- return [] unless cursor.argument? && cursor.chain.links.one? && cursor.word =~ /^[a-z0-9_]*:?$/
125
- pins = signify
126
- result = []
127
- done = []
128
- pins.each do |pin|
129
- pin.parameters.each do |param|
130
- next if done.include?(param.name)
131
- done.push param.name
132
- next unless param.keyword?
133
- result.push Pin::KeywordParam.new(pin.location, "#{param.name}:")
134
- end
135
- if !pin.parameters.empty? && pin.parameters.last.kwrestarg?
136
- pin.docstring.tags(:param).each do |tag|
137
- next if done.include?(tag.name)
138
- done.push tag.name
139
- result.push Pin::KeywordParam.new(pin.location, "#{tag.name}:")
140
- end
141
- end
142
- end
143
- result
144
- end
145
-
146
- # @param result [Array<Pin::Base>]
147
- # @return [Completion]
148
- def package_completions result
149
- frag_start = cursor.start_of_word.to_s.downcase
150
- filtered = result.uniq(&:name).select { |s|
151
- s.name.downcase.start_with?(frag_start) &&
152
- (!s.is_a?(Pin::Method) || s.name.match(/^[a-z0-9_]+(\!|\?|=)?$/i))
153
- }
154
- Completion.new(filtered, cursor.range)
155
- end
156
-
157
- def tag_complete
158
- result = []
159
- match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
160
- if match
161
- full = match[1]
162
- if full.include?('::')
163
- if full.end_with?('::')
164
- result.concat api_map.get_constants(full[0..-3], *gates)
165
- else
166
- result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
167
- end
168
- else
169
- result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
170
- end
171
- end
172
- package_completions(result)
173
- end
174
-
175
- def code_complete
176
- result = []
177
- result.concat complete_keyword_parameters
178
- if cursor.chain.constant? || cursor.start_of_constant?
179
- full = cursor.chain.links.first.word
180
- type = if cursor.chain.undefined?
181
- cursor.chain.base.infer(api_map, context_pin, locals)
182
- else
183
- if full.include?('::') && cursor.chain.links.length == 1
184
- ComplexType.try_parse(full.split('::')[0..-2].join('::'))
185
- elsif cursor.chain.links.length > 1
186
- ComplexType.try_parse(full)
187
- else
188
- ComplexType::UNDEFINED
189
- end
190
- end
191
- if type.undefined?
192
- if full.include?('::')
193
- result.concat api_map.get_constants(full, *gates)
194
- else
195
- result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
196
- end
197
- else
198
- result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
199
- end
200
- else
201
- type = cursor.chain.base.infer(api_map, block, locals)
202
- result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
203
- if cursor.chain.links.length == 1
204
- if cursor.word.start_with?('@@')
205
- return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
206
- elsif cursor.word.start_with?('@')
207
- return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
208
- elsif cursor.word.start_with?('$')
209
- return package_completions(api_map.get_global_variable_pins)
210
- end
211
- result.concat locals
212
- result.concat api_map.get_constants(context_pin.context.namespace, *gates)
213
- result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
214
- result.concat api_map.get_methods('Kernel')
215
- # result.concat ApiMap.keywords
216
- result.concat api_map.keyword_pins.to_a
217
- result.concat yielded_self_pins
218
- end
219
- end
220
- package_completions(result)
221
- end
222
- end
223
- end
224
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class SourceMap
5
+ # A static analysis tool for obtaining definitions, Completions,
6
+ # signatures, and type inferences from a Cursor.
7
+ #
8
+ class Clip
9
+ # @param api_map [ApiMap]
10
+ # @param cursor [Source::Cursor]
11
+ def initialize api_map, cursor
12
+ @api_map = api_map
13
+ @cursor = cursor
14
+ block.rebind(api_map) if block.is_a?(Pin::Block)
15
+ end
16
+
17
+ # @return [Array<Pin::Base>] Relevant pins for infering the type of the Cursor's position
18
+ def define
19
+ return [] if cursor.comment? || cursor.chain.literal?
20
+ result = cursor.chain.define(api_map, block, locals)
21
+ result.concat file_global_methods
22
+ result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty?
23
+ result
24
+ end
25
+
26
+ # @return [Array<Pin::Base>]
27
+ def types
28
+ infer.namespaces.map { |namespace| api_map.get_path_pins(namespace) }.flatten
29
+ end
30
+
31
+ # @return [Completion]
32
+ def complete
33
+ return package_completions([]) if !source_map.source.parsed? || cursor.string?
34
+ return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '<Symbol>'
35
+ return Completion.new([], cursor.range) if cursor.chain.literal?
36
+ if cursor.comment?
37
+ tag_complete
38
+ else
39
+ code_complete
40
+ end
41
+ end
42
+
43
+ # @return [Array<Pin::Method>]
44
+ def signify
45
+ return [] unless cursor.argument?
46
+ chain = Parser.chain(cursor.recipient_node, cursor.filename)
47
+ chain.define(api_map, context_pin, locals).select { |pin| pin.is_a?(Pin::Method) }
48
+ end
49
+
50
+ # @return [ComplexType]
51
+ def infer
52
+ result = cursor.chain.infer(api_map, block, locals)
53
+ if result.tag == 'Class'
54
+ # HACK: Exception to return BasicObject from Class#new
55
+ dfn = cursor.chain.define(api_map, block, locals).first
56
+ return ComplexType.try_parse('::BasicObject') if dfn && dfn.path == 'Class#new'
57
+ end
58
+ return result unless result.tag == 'self'
59
+ cursor.chain.base.infer(api_map, block, locals)
60
+ end
61
+
62
+ # Get an array of all the locals that are visible from the cursors's
63
+ # position. Locals can be local variables, method parameters, or block
64
+ # parameters. The array starts with the nearest local pin.
65
+ #
66
+ # @return [::Array<Solargraph::Pin::Base>]
67
+ def locals
68
+ @locals ||= source_map.locals_at(location)
69
+ end
70
+
71
+ # @return [::Array<String>]
72
+ def gates
73
+ block.gates
74
+ end
75
+
76
+ def in_block?
77
+ return @in_block unless @in_block.nil?
78
+ @in_block = begin
79
+ tree = cursor.source.tree_at(cursor.position.line, cursor.position.column)
80
+ Parser.is_ast_node?(tree[1]) && [:block, :ITER].include?(tree[1].type)
81
+ end
82
+ end
83
+
84
+ # @param phrase [String]
85
+ # @return [Array<Solargraph::Pin::Base>]
86
+ def translate phrase
87
+ chain = Parser.chain(Parser.parse(phrase))
88
+ chain.define(api_map, block, locals)
89
+ end
90
+
91
+ private
92
+
93
+ # @return [ApiMap]
94
+ attr_reader :api_map
95
+
96
+ # @return [Source::Cursor]
97
+ attr_reader :cursor
98
+
99
+ # @return [SourceMap]
100
+ def source_map
101
+ @source_map ||= api_map.source_map(cursor.filename)
102
+ end
103
+
104
+ # @return [Location]
105
+ def location
106
+ Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
107
+ end
108
+
109
+ # @return [Solargraph::Pin::Closure]
110
+ def block
111
+ @block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
112
+ end
113
+
114
+ # The context at the current position.
115
+ #
116
+ # @return [Pin::Base]
117
+ def context_pin
118
+ @context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
119
+ end
120
+
121
+ # @return [Array<Pin::KeywordParam>]
122
+ def complete_keyword_parameters
123
+ return [] unless cursor.argument? && cursor.chain.links.one? && cursor.word =~ /^[a-z0-9_]*:?$/
124
+ pins = signify
125
+ result = []
126
+ done = []
127
+ pins.each do |pin|
128
+ pin.parameters.each do |param|
129
+ next if done.include?(param.name)
130
+ done.push param.name
131
+ next unless param.keyword?
132
+ result.push Pin::KeywordParam.new(pin.location, "#{param.name}:")
133
+ end
134
+ if !pin.parameters.empty? && pin.parameters.last.kwrestarg?
135
+ pin.docstring.tags(:param).each do |tag|
136
+ next if done.include?(tag.name)
137
+ done.push tag.name
138
+ result.push Pin::KeywordParam.new(pin.location, "#{tag.name}:")
139
+ end
140
+ end
141
+ end
142
+ result
143
+ end
144
+
145
+ # @param result [Enumerable<Pin::Base>]
146
+ # @return [Completion]
147
+ def package_completions result
148
+ frag_start = cursor.start_of_word.to_s.downcase
149
+ filtered = result.uniq(&:name).select { |s|
150
+ s.name.downcase.start_with?(frag_start) &&
151
+ (!s.is_a?(Pin::Method) || s.name.match(/^[a-z0-9_]+(\!|\?|=)?$/i))
152
+ }
153
+ Completion.new(filtered, cursor.range)
154
+ end
155
+
156
+ # @return [Completion]
157
+ def tag_complete
158
+ result = []
159
+ match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
160
+ if match
161
+ full = match[1]
162
+ if full.include?('::')
163
+ if full.end_with?('::')
164
+ result.concat api_map.get_constants(full[0..-3], *gates)
165
+ else
166
+ result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
167
+ end
168
+ else
169
+ result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
170
+ end
171
+ end
172
+ package_completions(result)
173
+ end
174
+
175
+ # @return [Completion]
176
+ def code_complete
177
+ result = []
178
+ result.concat complete_keyword_parameters
179
+ if cursor.chain.constant? || cursor.start_of_constant?
180
+ full = cursor.chain.links.first.word
181
+ type = if cursor.chain.undefined?
182
+ cursor.chain.base.infer(api_map, context_pin, locals)
183
+ else
184
+ if full.include?('::') && cursor.chain.links.length == 1
185
+ ComplexType.try_parse(full.split('::')[0..-2].join('::'))
186
+ elsif cursor.chain.links.length > 1
187
+ ComplexType.try_parse(full)
188
+ else
189
+ ComplexType::UNDEFINED
190
+ end
191
+ end
192
+ if type.undefined?
193
+ if full.include?('::')
194
+ result.concat api_map.get_constants(full, *gates)
195
+ else
196
+ result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
197
+ end
198
+ else
199
+ result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
200
+ end
201
+ else
202
+ type = cursor.chain.base.infer(api_map, block, locals)
203
+ result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
204
+ if cursor.chain.links.length == 1
205
+ if cursor.word.start_with?('@@')
206
+ return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
207
+ elsif cursor.word.start_with?('@')
208
+ return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
209
+ elsif cursor.word.start_with?('$')
210
+ return package_completions(api_map.get_global_variable_pins)
211
+ end
212
+ result.concat locals
213
+ result.concat file_global_methods unless block.binder.namespace.empty?
214
+ result.concat api_map.get_constants(context_pin.context.namespace, *gates)
215
+ result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
216
+ result.concat api_map.get_methods('Kernel')
217
+ result.concat api_map.keyword_pins.to_a
218
+ end
219
+ end
220
+ package_completions(result)
221
+ end
222
+
223
+ # @return [Array<Pin::Base>]
224
+ def file_global_methods
225
+ return [] if cursor.word.empty?
226
+ source_map.pins.select do |pin|
227
+ pin.is_a?(Pin::Method) && pin.namespace == '' && pin.name.start_with?(cursor.word)
228
+ end
229
+ end
230
+ end
231
+ end
232
+ end
@@ -1,23 +1,23 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class SourceMap
5
- # The result of a completion request containing the pins that describe
6
- # completion options and the range to be replaced.
7
- #
8
- class Completion
9
- # @return [Array<Solargraph::Pin::Base>]
10
- attr_reader :pins
11
-
12
- # @return [Solargraph::Range]
13
- attr_reader :range
14
-
15
- # @param pins [Array<Solargraph::Pin::Base>]
16
- # @param range [Solargraph::Range]
17
- def initialize pins, range
18
- @pins = pins
19
- @range = range
20
- end
21
- end
22
- end
23
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class SourceMap
5
+ # The result of a completion request containing the pins that describe
6
+ # completion options and the range to be replaced.
7
+ #
8
+ class Completion
9
+ # @return [Array<Solargraph::Pin::Base>]
10
+ attr_reader :pins
11
+
12
+ # @return [Solargraph::Range]
13
+ attr_reader :range
14
+
15
+ # @param pins [Array<Solargraph::Pin::Base>]
16
+ # @param range [Solargraph::Range]
17
+ def initialize pins, range
18
+ @pins = pins
19
+ @range = range
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class SourceMap
5
+ class Data
6
+ def initialize source
7
+ @source = source
8
+ end
9
+
10
+ def pins
11
+ generate
12
+ @pins || []
13
+ end
14
+
15
+ def locals
16
+ generate
17
+ @locals || []
18
+ end
19
+
20
+ private
21
+
22
+ def generate
23
+ return if @generated
24
+
25
+ @generated = true
26
+ @pins, @locals = Mapper.map(@source)
27
+ end
28
+ end
29
+ end
30
+ end