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,180 +1,217 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yard'
4
- require 'yard-solargraph'
5
- require 'set'
6
-
7
- module Solargraph
8
- # An index of pins and other ApiMap-related data for a Source.
9
- #
10
- class SourceMap
11
- autoload :Mapper, 'solargraph/source_map/mapper'
12
- autoload :Clip, 'solargraph/source_map/clip'
13
- autoload :Completion, 'solargraph/source_map/completion'
14
-
15
- # @return [Source]
16
- attr_reader :source
17
-
18
- # @return [Array<Pin::Base>]
19
- attr_reader :pins
20
-
21
- # @return [Array<Pin::Base>]
22
- attr_reader :locals
23
-
24
- # @param source [Source]
25
- # @param pins [Array<Pin::Base>]
26
- # @param locals [Array<Pin::Base>]
27
- def initialize source, pins, locals
28
- # HACK: Keep the library from changing this
29
- @source = source.dup
30
- @pins = pins
31
- @locals = locals
32
- environ.merge Convention.for_local(self) unless filename.nil?
33
- @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
34
- @pin_select_cache = {}
35
- end
36
-
37
- def pins_by_class klass
38
- @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
39
- end
40
-
41
- def rebindable_method_names
42
- @rebindable_method_names ||= pins_by_class(Pin::Method)
43
- .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
44
- .map(&:name)
45
- .to_set
46
- end
47
-
48
- # @return [String]
49
- def filename
50
- source.filename
51
- end
52
-
53
- # @return [String]
54
- def code
55
- source.code
56
- end
57
-
58
- # @return [Array<Pin::Reference::Require>]
59
- def requires
60
- pins_by_class(Pin::Reference::Require)
61
- end
62
-
63
- # @return [Environ]
64
- def environ
65
- @environ ||= Environ.new
66
- end
67
-
68
- # @return [Array<Pin::Base>]
69
- def document_symbols
70
- @document_symbols ||= pins.select { |pin|
71
- pin.path && !pin.path.empty?
72
- }
73
- end
74
-
75
- # @param query [String]
76
- # @return [Array<Pin::Base>]
77
- def query_symbols query
78
- Pin::Search.new(document_symbols, query).results
79
- end
80
-
81
- # @param position [Position]
82
- # @return [Source::Cursor]
83
- def cursor_at position
84
- Source::Cursor.new(source, position)
85
- end
86
-
87
- # @param path [String]
88
- # @return [Pin::Base]
89
- def first_pin path
90
- pins.select { |p| p.path == path }.first
91
- end
92
-
93
- # @param location [Solargraph::Location]
94
- # @return [Array<Solargraph::Pin::Base>]
95
- def locate_pins location
96
- # return nil unless location.start_with?("#{filename}:")
97
- (pins + locals).select { |pin| pin.location == location }
98
- end
99
-
100
- def locate_named_path_pin line, character
101
- _locate_pin line, character, Pin::Namespace, Pin::Method
102
- end
103
-
104
- def locate_block_pin line, character
105
- _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
106
- end
107
-
108
- # @param other_map [SourceMap]
109
- # @return [Boolean]
110
- def try_merge! other_map
111
- return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
112
- pins.each_index do |i|
113
- return false unless pins[i].try_merge!(other_map.pins[i])
114
- end
115
- locals.each_index do |i|
116
- return false unless locals[i].try_merge!(other_map.locals[i])
117
- end
118
- @source = other_map.source
119
- true
120
- end
121
-
122
- # @param name [String]
123
- # @return [Array<Location>]
124
- def references name
125
- source.references name
126
- end
127
-
128
- # @param location [Location]
129
- # @return [Array<Pin::LocalVariable>]
130
- def locals_at(location)
131
- return [] if location.filename != filename
132
- closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
133
- locals.select { |pin| pin.visible_at?(closure, location) }
134
- end
135
-
136
- class << self
137
- # @param filename [String]
138
- # @return [SourceMap]
139
- def load filename
140
- source = Solargraph::Source.load(filename)
141
- SourceMap.map(source)
142
- end
143
-
144
- # @param code [String]
145
- # @param filename [String, nil]
146
- # @return [SourceMap]
147
- def load_string code, filename = nil
148
- source = Solargraph::Source.load_string(code, filename)
149
- SourceMap.map(source)
150
- end
151
-
152
- # @param source [Source]
153
- # @return [SourceMap]
154
- def map source
155
- result = SourceMap::Mapper.map(source)
156
- new(source, *result)
157
- end
158
- end
159
-
160
- private
161
-
162
- # @param line [Integer]
163
- # @param character [Integer]
164
- # @param klasses [Array<Class>]
165
- # @return [Pin::Base]
166
- def _locate_pin line, character, *klasses
167
- position = Position.new(line, character)
168
- found = nil
169
- pins.each do |pin|
170
- # @todo Attribute pins should not be treated like closures, but
171
- # there's probably a better way to handle it
172
- next if pin.is_a?(Pin::Method) && pin.attribute?
173
- found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
174
- break if pin.location.range.start.line > line
175
- end
176
- # Assuming the root pin is always valid
177
- found || pins.first
178
- end
179
- end
180
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'yard'
4
+ require 'solargraph/yard_tags'
5
+
6
+ module Solargraph
7
+ # An index of Pins and other ApiMap-related data for a single Source
8
+ # that can be queried.
9
+ #
10
+ class SourceMap
11
+ autoload :Mapper, 'solargraph/source_map/mapper'
12
+ autoload :Clip, 'solargraph/source_map/clip'
13
+ autoload :Completion, 'solargraph/source_map/completion'
14
+ autoload :Data, 'solargraph/source_map/data'
15
+
16
+ # @return [Source]
17
+ attr_reader :source
18
+
19
+ # @return [Array<Pin::Base>]
20
+ def pins
21
+ data.pins
22
+ end
23
+
24
+ # @return [Array<Pin::LocalVariable>]
25
+ def locals
26
+ data.locals
27
+ end
28
+
29
+ # @param source [Source]
30
+ def initialize source
31
+ @source = source
32
+
33
+ environ.merge Convention.for_local(self) unless filename.nil?
34
+ self.convention_pins = environ.pins
35
+ @pin_select_cache = {}
36
+ end
37
+
38
+ # @param klass [Class]
39
+ # @return [Array<Pin::Base>]
40
+ def pins_by_class klass
41
+ @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
42
+ end
43
+
44
+ # A hash representing the state of the source map's API.
45
+ #
46
+ # ApiMap#catalog uses this value to determine whether it needs to clear its
47
+ # cache.
48
+ #
49
+ # @return [Integer]
50
+ def api_hash
51
+ @api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
52
+ end
53
+
54
+ # @return [String]
55
+ def filename
56
+ source.filename
57
+ end
58
+
59
+ # @return [String]
60
+ def code
61
+ source.code
62
+ end
63
+
64
+ # @return [Array<Pin::Reference::Require>]
65
+ def requires
66
+ pins_by_class(Pin::Reference::Require)
67
+ end
68
+
69
+ # @return [Environ]
70
+ def environ
71
+ @environ ||= Environ.new
72
+ end
73
+
74
+ # all pins except Solargraph::Pin::Reference::Reference
75
+ # @return [Array<Pin::Base>]
76
+ def document_symbols
77
+ @document_symbols ||= (pins + convention_pins).select do |pin|
78
+ pin.path && !pin.path.empty?
79
+ end
80
+ end
81
+
82
+ # @param query [String]
83
+ # @return [Array<Pin::Base>]
84
+ def query_symbols query
85
+ Pin::Search.new(document_symbols, query).results
86
+ end
87
+
88
+ # @param position [Position]
89
+ # @return [Source::Cursor]
90
+ def cursor_at position
91
+ Source::Cursor.new(source, position)
92
+ end
93
+
94
+ # @param path [String]
95
+ # @return [Pin::Base]
96
+ def first_pin path
97
+ pins.select { |p| p.path == path }.first
98
+ end
99
+
100
+ # @param location [Solargraph::Location]
101
+ # @return [Array<Solargraph::Pin::Base>]
102
+ def locate_pins location
103
+ # return nil unless location.start_with?("#{filename}:")
104
+ (pins + locals).select { |pin| pin.location == location }
105
+ end
106
+
107
+ # @param line [Integer]
108
+ # @param character [Integer]
109
+ # @return [Pin::Method,Pin::Namespace]
110
+ def locate_named_path_pin line, character
111
+ _locate_pin line, character, Pin::Namespace, Pin::Method
112
+ end
113
+
114
+ # @param line [Integer]
115
+ # @param character [Integer]
116
+ # @return [Pin::Namespace,Pin::Method,Pin::Block]
117
+ def locate_block_pin line, character
118
+ _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
119
+ end
120
+
121
+ # @todo Candidate for deprecation
122
+ #
123
+ # @param other_map [SourceMap]
124
+ # @return [Boolean]
125
+ def try_merge! other_map
126
+ return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
127
+
128
+ pins.each_index do |i|
129
+ return false unless pins[i].try_merge!(other_map.pins[i])
130
+ end
131
+ locals.each_index do |i|
132
+ return false unless locals[i].try_merge!(other_map.locals[i])
133
+ end
134
+ @source = other_map.source
135
+ true
136
+ end
137
+
138
+ # @param name [String]
139
+ # @return [Array<Location>]
140
+ def references name
141
+ source.references name
142
+ end
143
+
144
+ # @param location [Location]
145
+ # @return [Array<Pin::LocalVariable>]
146
+ def locals_at(location)
147
+ return [] if location.filename != filename
148
+ closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
149
+ locals.select { |pin| pin.visible_at?(closure, location) }
150
+ end
151
+
152
+ class << self
153
+ # @param filename [String]
154
+ # @return [SourceMap]
155
+ def load filename
156
+ source = Solargraph::Source.load(filename)
157
+ SourceMap.map(source)
158
+ end
159
+
160
+ # @param code [String]
161
+ # @param filename [String, nil]
162
+ # @return [SourceMap]
163
+ def load_string code, filename = nil
164
+ source = Solargraph::Source.load_string(code, filename)
165
+ SourceMap.map(source)
166
+ end
167
+
168
+ # @deprecated
169
+ # @param source [Source]
170
+ # @return [SourceMap]
171
+ def map source
172
+ new(source)
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ def pin_class_hash
179
+ @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
180
+ end
181
+
182
+ def data
183
+ @data ||= Data.new(source)
184
+ end
185
+
186
+ # @return [Array<Pin::Base>]
187
+ def convention_pins
188
+ @convention_pins || []
189
+ end
190
+
191
+ # @param pins [Array<Pin::Base>]
192
+ # @return [Array<Pin::Base>]
193
+ def convention_pins=(pins)
194
+ # unmemoizing the document_symbols in case it was called from any of conventions
195
+ @document_symbols = nil
196
+ @convention_pins = pins
197
+ end
198
+
199
+ # @param line [Integer]
200
+ # @param character [Integer]
201
+ # @param klasses [Array<Class>]
202
+ # @return [Pin::Base, nil]
203
+ def _locate_pin line, character, *klasses
204
+ position = Position.new(line, character)
205
+ found = nil
206
+ pins.each do |pin|
207
+ # @todo Attribute pins should not be treated like closures, but
208
+ # there's probably a better way to handle it
209
+ next if pin.is_a?(Pin::Method) && pin.attribute?
210
+ found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
211
+ break if pin.location.range.start.line > line
212
+ end
213
+ # Assuming the root pin is always valid
214
+ found || pins.first
215
+ end
216
+ end
217
+ end
@@ -1,99 +1,120 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class TypeChecker
5
- # Helper methods for performing type checks
6
- #
7
- module Checks
8
- module_function
9
-
10
- # Compare an expected type with an inferred type. Common usage is to
11
- # check if the type declared in a method's @return tag matches the type
12
- # inferred from static analysis of the code.
13
- #
14
- # @param api_map [ApiMap]
15
- # @param expected [ComplexType]
16
- # @param inferred [ComplexType]
17
- # @return [Boolean]
18
- def types_match? api_map, expected, inferred
19
- return true if expected.to_s == inferred.to_s
20
- matches = []
21
- expected.each do |exp|
22
- found = false
23
- inferred.each do |inf|
24
- # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
25
- if either_way?(api_map, inf, exp)
26
- found = true
27
- matches.push inf
28
- break
29
- end
30
- end
31
- return false unless found
32
- end
33
- inferred.each do |inf|
34
- next if matches.include?(inf)
35
- found = false
36
- expected.each do |exp|
37
- # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
38
- if either_way?(api_map, inf, exp)
39
- found = true
40
- break
41
- end
42
- end
43
- return false unless found
44
- end
45
- true
46
- end
47
-
48
- # @param api_map [ApiMap]
49
- # @param expected [ComplexType]
50
- # @param inferred [ComplexType]
51
- # @return [Boolean]
52
- def any_types_match? api_map, expected, inferred
53
- return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
54
- expected.each do |exp|
55
- next if exp.duck_type?
56
- inferred.each do |inf|
57
- # return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))
58
- return true if exp == inf || either_way?(api_map, inf, exp)
59
- end
60
- end
61
- false
62
- end
63
-
64
- # @param api_map [ApiMap]
65
- # @param expected [ComplexType]
66
- # @param inferred [ComplexType]
67
- # @return [Boolean]
68
- def duck_types_match? api_map, expected, inferred
69
- raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
70
- expected.each do |exp|
71
- next unless exp.duck_type?
72
- quack = exp.to_s[1..-1]
73
- return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
74
- end
75
- true
76
- end
77
-
78
- # @param type [ComplexType::UniqueType]
79
- # @return [String]
80
- def fuzz type
81
- if type.parameters?
82
- type.name
83
- else
84
- type.tag
85
- end
86
- end
87
-
88
- # @param api_map [ApiMap]
89
- # @param cls1 [ComplexType::UniqueType]
90
- # @param cls2 [ComplexType::UniqueType]
91
- # @return [Boolean]
92
- def either_way?(api_map, cls1, cls2)
93
- f1 = fuzz(cls1)
94
- f2 = fuzz(cls2)
95
- api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
96
- end
97
- end
98
- end
99
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class TypeChecker
5
+ # Helper methods for performing type checks
6
+ #
7
+ module Checks
8
+ module_function
9
+
10
+ # Compare an expected type with an inferred type. Common usage is to
11
+ # check if the type declared in a method's @return tag matches the type
12
+ # inferred from static analysis of the code.
13
+ #
14
+ # @param api_map [ApiMap]
15
+ # @param expected [ComplexType]
16
+ # @param inferred [ComplexType]
17
+ # @return [Boolean]
18
+ def types_match? api_map, expected, inferred
19
+ return true if expected.to_s == inferred.to_s
20
+ matches = []
21
+ expected.each do |exp|
22
+ found = false
23
+ inferred.each do |inf|
24
+ # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
25
+ if either_way?(api_map, inf, exp)
26
+ found = true
27
+ matches.push inf
28
+ break
29
+ end
30
+ end
31
+ return false unless found
32
+ end
33
+ inferred.each do |inf|
34
+ next if matches.include?(inf)
35
+ found = false
36
+ expected.each do |exp|
37
+ # if api_map.super_and_sub?(fuzz(inf), fuzz(exp))
38
+ if either_way?(api_map, inf, exp)
39
+ found = true
40
+ break
41
+ end
42
+ end
43
+ return false unless found
44
+ end
45
+ true
46
+ end
47
+
48
+ # @param api_map [ApiMap]
49
+ # @param expected [ComplexType]
50
+ # @param inferred [ComplexType]
51
+ # @return [Boolean]
52
+ def any_types_match? api_map, expected, inferred
53
+ return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
54
+ # walk through the union expected type and see if any members
55
+ # of the union match the inferred type
56
+ expected.each do |exp|
57
+ next if exp.duck_type?
58
+ # @todo: there should be a level of typechecking where all
59
+ # unique types in the inferred must match one of the
60
+ # expected unique types
61
+ inferred.each do |inf|
62
+ # return true if exp == inf || api_map.super_and_sub?(fuzz(inf), fuzz(exp))
63
+ return true if exp == inf || either_way?(api_map, inf, exp)
64
+ end
65
+ end
66
+ false
67
+ end
68
+
69
+ # @param api_map [ApiMap]
70
+ # @param inferred [ComplexType]
71
+ # @param expected [ComplexType]
72
+ # @return [Boolean]
73
+ def all_types_match? api_map, inferred, expected
74
+ return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
75
+ inferred.each do |inf|
76
+ next if inf.duck_type?
77
+ return false unless expected.any? { |exp| exp == inf || either_way?(api_map, inf, exp) }
78
+ end
79
+ true
80
+ end
81
+
82
+ # @param api_map [ApiMap]
83
+ # @param expected [ComplexType]
84
+ # @param inferred [ComplexType]
85
+ # @return [Boolean]
86
+ def duck_types_match? api_map, expected, inferred
87
+ raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
88
+ expected.each do |exp|
89
+ next unless exp.duck_type?
90
+ quack = exp.to_s[1..-1]
91
+ return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
92
+ end
93
+ true
94
+ end
95
+
96
+ # @param type [ComplexType::UniqueType]
97
+ # @return [String]
98
+ def fuzz type
99
+ if type.parameters?
100
+ type.name
101
+ else
102
+ type.tag
103
+ end
104
+ end
105
+
106
+ # @param api_map [ApiMap]
107
+ # @param cls1 [ComplexType::UniqueType]
108
+ # @param cls2 [ComplexType::UniqueType]
109
+ # @return [Boolean]
110
+ def either_way?(api_map, cls1, cls2)
111
+ # @todo there should be a level of typechecking which uses the
112
+ # full tag with parameters to determine compatibility
113
+ f1 = cls1.name
114
+ f2 = cls2.name
115
+ api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
116
+ # api_map.type_include?(f1, f2) || api_map.super_and_sub?(f1, f2) || api_map.super_and_sub?(f2, f1)
117
+ end
118
+ end
119
+ end
120
+ end