solargraph 0.44.2 → 0.46.0

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 (246) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rspec.yml +41 -0
  3. data/.gitignore +9 -9
  4. data/.rspec +2 -2
  5. data/.travis.yml +19 -19
  6. data/CHANGELOG.md +1115 -1088
  7. data/Gemfile +0 -0
  8. data/LICENSE +0 -0
  9. data/README.md +128 -120
  10. data/Rakefile +0 -0
  11. data/SPONSORS.md +18 -15
  12. data/bin/solargraph +0 -0
  13. data/lib/solargraph/api_map/bundler_methods.rb +22 -22
  14. data/lib/solargraph/api_map/cache.rb +70 -70
  15. data/lib/solargraph/api_map/source_to_yard.rb +81 -81
  16. data/lib/solargraph/api_map/store.rb +256 -256
  17. data/lib/solargraph/api_map.rb +686 -681
  18. data/lib/solargraph/bench.rb +27 -27
  19. data/lib/solargraph/compat.rb +37 -37
  20. data/lib/solargraph/complex_type/type_methods.rb +130 -130
  21. data/lib/solargraph/complex_type/unique_type.rb +75 -75
  22. data/lib/solargraph/complex_type.rb +221 -221
  23. data/lib/solargraph/convention/base.rb +33 -33
  24. data/lib/solargraph/convention/gemfile.rb +15 -15
  25. data/lib/solargraph/convention/gemspec.rb +22 -22
  26. data/lib/solargraph/convention/rspec.rb +30 -21
  27. data/lib/solargraph/convention.rb +47 -47
  28. data/lib/solargraph/converters/dd.rb +12 -12
  29. data/lib/solargraph/converters/dl.rb +12 -12
  30. data/lib/solargraph/converters/dt.rb +12 -12
  31. data/lib/solargraph/converters/misc.rb +1 -1
  32. data/lib/solargraph/diagnostics/base.rb +29 -29
  33. data/lib/solargraph/diagnostics/require_not_found.rb +53 -37
  34. data/lib/solargraph/diagnostics/rubocop.rb +98 -98
  35. data/lib/solargraph/diagnostics/rubocop_helpers.rb +63 -63
  36. data/lib/solargraph/diagnostics/severities.rb +15 -15
  37. data/lib/solargraph/diagnostics/type_check.rb +54 -54
  38. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  39. data/lib/solargraph/diagnostics.rb +55 -55
  40. data/lib/solargraph/documentor.rb +76 -76
  41. data/lib/solargraph/environ.rb +45 -45
  42. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -35
  43. data/lib/solargraph/language_server/error_codes.rb +20 -20
  44. data/lib/solargraph/language_server/host/cataloger.rb +56 -56
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +111 -111
  47. data/lib/solargraph/language_server/host/message_worker.rb +59 -59
  48. data/lib/solargraph/language_server/host/sources.rb +156 -156
  49. data/lib/solargraph/language_server/host.rb +865 -865
  50. data/lib/solargraph/language_server/message/base.rb +89 -89
  51. data/lib/solargraph/language_server/message/cancel_request.rb +13 -13
  52. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  53. data/lib/solargraph/language_server/message/client.rb +11 -11
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -58
  55. data/lib/solargraph/language_server/message/completion_item.rb +11 -11
  56. data/lib/solargraph/language_server/message/exit_notification.rb +13 -13
  57. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -100
  58. data/lib/solargraph/language_server/message/extended/document.rb +20 -20
  59. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  60. data/lib/solargraph/language_server/message/extended/download_core.rb +23 -23
  61. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/extended.rb +21 -21
  64. data/lib/solargraph/language_server/message/initialize.rb +162 -162
  65. data/lib/solargraph/language_server/message/initialized.rb +27 -27
  66. data/lib/solargraph/language_server/message/method_not_found.rb +16 -16
  67. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -14
  68. data/lib/solargraph/language_server/message/shutdown.rb +13 -13
  69. data/lib/solargraph/language_server/message/text_document/base.rb +19 -19
  70. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -17
  71. data/lib/solargraph/language_server/message/text_document/completion.rb +59 -59
  72. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -38
  73. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -15
  74. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -15
  75. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -15
  76. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -17
  77. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  78. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -23
  79. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -26
  80. data/lib/solargraph/language_server/message/text_document/formatting.rb +126 -126
  81. data/lib/solargraph/language_server/message/text_document/hover.rb +54 -44
  82. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -34
  83. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  84. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  85. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  86. data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -29
  87. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  88. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +30 -30
  89. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -33
  90. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
  91. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  92. data/lib/solargraph/language_server/message/workspace.rb +14 -14
  93. data/lib/solargraph/language_server/message.rb +93 -93
  94. data/lib/solargraph/language_server/message_types.rb +14 -14
  95. data/lib/solargraph/language_server/request.rb +24 -24
  96. data/lib/solargraph/language_server/symbol_kinds.rb +36 -36
  97. data/lib/solargraph/language_server/transport/adapter.rb +53 -53
  98. data/lib/solargraph/language_server/transport/data_reader.rb +72 -72
  99. data/lib/solargraph/language_server/transport.rb +13 -13
  100. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  101. data/lib/solargraph/language_server.rb +19 -19
  102. data/lib/solargraph/library.rb +546 -546
  103. data/lib/solargraph/location.rb +37 -37
  104. data/lib/solargraph/logging.rb +27 -27
  105. data/lib/solargraph/page.rb +83 -83
  106. data/lib/solargraph/parser/comment_ripper.rb +52 -52
  107. data/lib/solargraph/parser/legacy/class_methods.rb +135 -140
  108. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -16
  109. data/lib/solargraph/parser/legacy/node_chainer.rb +148 -148
  110. data/lib/solargraph/parser/legacy/node_methods.rb +325 -325
  111. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -23
  112. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -35
  113. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -15
  114. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +42 -42
  115. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -25
  116. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -23
  117. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -63
  118. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -36
  119. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -23
  120. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -38
  121. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -28
  122. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -39
  123. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -16
  124. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -36
  125. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -21
  126. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -257
  127. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -18
  128. data/lib/solargraph/parser/legacy/node_processors.rb +54 -54
  129. data/lib/solargraph/parser/legacy.rb +12 -12
  130. data/lib/solargraph/parser/node_methods.rb +43 -43
  131. data/lib/solargraph/parser/node_processor/base.rb +77 -77
  132. data/lib/solargraph/parser/node_processor.rb +43 -43
  133. data/lib/solargraph/parser/region.rb +66 -66
  134. data/lib/solargraph/parser/rubyvm/class_methods.rb +144 -155
  135. data/lib/solargraph/parser/rubyvm/node_chainer.rb +160 -160
  136. data/lib/solargraph/parser/rubyvm/node_methods.rb +315 -315
  137. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -23
  138. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +85 -85
  139. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -15
  140. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +42 -42
  141. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -22
  142. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -23
  143. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +63 -64
  144. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -57
  145. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -23
  146. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -38
  147. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -39
  148. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -20
  149. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -27
  150. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -39
  151. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -26
  152. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -15
  153. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -45
  154. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -21
  155. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -15
  156. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +277 -277
  157. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -18
  158. data/lib/solargraph/parser/rubyvm/node_processors.rb +63 -62
  159. data/lib/solargraph/parser/rubyvm.rb +40 -40
  160. data/lib/solargraph/parser/snippet.rb +13 -13
  161. data/lib/solargraph/parser.rb +26 -26
  162. data/lib/solargraph/pin/base.rb +296 -296
  163. data/lib/solargraph/pin/base_variable.rb +84 -84
  164. data/lib/solargraph/pin/block.rb +72 -72
  165. data/lib/solargraph/pin/class_variable.rb +8 -8
  166. data/lib/solargraph/pin/closure.rb +37 -37
  167. data/lib/solargraph/pin/common.rb +70 -70
  168. data/lib/solargraph/pin/constant.rb +43 -43
  169. data/lib/solargraph/pin/conversions.rb +96 -96
  170. data/lib/solargraph/pin/documenting.rb +105 -105
  171. data/lib/solargraph/pin/duck_method.rb +16 -16
  172. data/lib/solargraph/pin/global_variable.rb +8 -8
  173. data/lib/solargraph/pin/instance_variable.rb +30 -30
  174. data/lib/solargraph/pin/keyword.rb +15 -15
  175. data/lib/solargraph/pin/keyword_param.rb +8 -8
  176. data/lib/solargraph/pin/local_variable.rb +55 -55
  177. data/lib/solargraph/pin/method.rb +245 -245
  178. data/lib/solargraph/pin/method_alias.rb +31 -31
  179. data/lib/solargraph/pin/namespace.rb +91 -91
  180. data/lib/solargraph/pin/parameter.rb +201 -206
  181. data/lib/solargraph/pin/proxy_type.rb +29 -29
  182. data/lib/solargraph/pin/reference/extend.rb +10 -10
  183. data/lib/solargraph/pin/reference/include.rb +10 -10
  184. data/lib/solargraph/pin/reference/override.rb +29 -29
  185. data/lib/solargraph/pin/reference/prepend.rb +10 -10
  186. data/lib/solargraph/pin/reference/require.rb +14 -14
  187. data/lib/solargraph/pin/reference/superclass.rb +10 -10
  188. data/lib/solargraph/pin/reference.rb +14 -14
  189. data/lib/solargraph/pin/search.rb +56 -0
  190. data/lib/solargraph/pin/singleton.rb +11 -11
  191. data/lib/solargraph/pin/symbol.rb +47 -47
  192. data/lib/solargraph/pin.rb +37 -36
  193. data/lib/solargraph/position.rb +100 -100
  194. data/lib/solargraph/range.rb +95 -95
  195. data/lib/solargraph/server_methods.rb +16 -16
  196. data/lib/solargraph/shell.rb +226 -226
  197. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  198. data/lib/solargraph/source/chain/call.rb +204 -204
  199. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  200. data/lib/solargraph/source/chain/constant.rb +75 -75
  201. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  202. data/lib/solargraph/source/chain/hash.rb +28 -28
  203. data/lib/solargraph/source/chain/head.rb +19 -19
  204. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  205. data/lib/solargraph/source/chain/link.rb +71 -71
  206. data/lib/solargraph/source/chain/literal.rb +23 -23
  207. data/lib/solargraph/source/chain/or.rb +23 -23
  208. data/lib/solargraph/source/chain/q_call.rb +11 -11
  209. data/lib/solargraph/source/chain/variable.rb +13 -13
  210. data/lib/solargraph/source/chain/z_super.rb +30 -30
  211. data/lib/solargraph/source/chain.rb +164 -164
  212. data/lib/solargraph/source/change.rb +79 -79
  213. data/lib/solargraph/source/cursor.rb +164 -164
  214. data/lib/solargraph/source/source_chainer.rb +191 -191
  215. data/lib/solargraph/source/updater.rb +54 -54
  216. data/lib/solargraph/source.rb +522 -522
  217. data/lib/solargraph/source_map/clip.rb +224 -224
  218. data/lib/solargraph/source_map/completion.rb +23 -23
  219. data/lib/solargraph/source_map/mapper.rb +212 -212
  220. data/lib/solargraph/source_map.rb +180 -189
  221. data/lib/solargraph/type_checker/checks.rb +99 -99
  222. data/lib/solargraph/type_checker/param_def.rb +35 -35
  223. data/lib/solargraph/type_checker/problem.rb +32 -32
  224. data/lib/solargraph/type_checker/rules.rb +57 -57
  225. data/lib/solargraph/type_checker.rb +543 -510
  226. data/lib/solargraph/version.rb +5 -5
  227. data/lib/solargraph/views/environment.erb +58 -58
  228. data/lib/solargraph/workspace/config.rb +231 -231
  229. data/lib/solargraph/workspace.rb +215 -214
  230. data/lib/solargraph/yard_map/cache.rb +19 -19
  231. data/lib/solargraph/yard_map/core_docs.rb +170 -170
  232. data/lib/solargraph/yard_map/core_fills.rb +208 -203
  233. data/lib/solargraph/yard_map/core_gen.rb +76 -76
  234. data/lib/solargraph/yard_map/helpers.rb +16 -16
  235. data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -25
  236. data/lib/solargraph/yard_map/mapper/to_method.rb +78 -78
  237. data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -27
  238. data/lib/solargraph/yard_map/mapper.rb +77 -77
  239. data/lib/solargraph/yard_map/rdoc_to_yard.rb +140 -140
  240. data/lib/solargraph/yard_map/stdlib_fills.rb +43 -43
  241. data/lib/solargraph/yard_map/to_method.rb +79 -79
  242. data/lib/solargraph/yard_map.rb +460 -443
  243. data/lib/solargraph.rb +69 -69
  244. data/lib/yard-solargraph.rb +33 -33
  245. data/solargraph.gemspec +0 -0
  246. metadata +14 -12
@@ -1,315 +1,315 @@
1
- module Solargraph
2
- module Parser
3
- module Rubyvm
4
- module NodeMethods
5
- module_function
6
-
7
- # @param node [RubyVM::AbstractSyntaxTree::Node]
8
- # @return [String]
9
- def unpack_name node
10
- pack_name(node).join('::')
11
- end
12
-
13
- # @param node [RubyVM::AbstractSyntaxTree::Node]
14
- # @return [Array<String>]
15
- def pack_name(node)
16
- parts = []
17
- if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
18
- parts.push '' if node.type == :COLON3
19
- node.children.each { |n|
20
- if n.is_a?(RubyVM::AbstractSyntaxTree::Node)
21
- parts += pack_name(n)
22
- else
23
- parts.push n unless n.nil?
24
- end
25
- }
26
- end
27
- parts
28
- end
29
-
30
- # @param node [RubyVM::AbstractSyntaxTree::Node]
31
- # @return [String, nil]
32
- def infer_literal_node_type node
33
- return nil unless Parser.is_ast_node?(node)
34
- case node.type
35
- when :LIT, :STR
36
- "::#{node.children.first.class.to_s}"
37
- when :DSTR
38
- "::String"
39
- when :ARRAY, :ZARRAY, :LIST, :ZLIST
40
- '::Array'
41
- when :HASH
42
- '::Hash'
43
- when :DOT2, :DOT3
44
- '::Range'
45
- when :TRUE, :FALSE
46
- '::Boolean'
47
- when :SCOPE
48
- infer_literal_node_type(node.children[2])
49
- end
50
- end
51
-
52
- def returns_from node
53
- return [] unless Parser.is_ast_node?(node)
54
- if node.type == :SCOPE
55
- # node.children.select { |n| n.is_a?(RubyVM::AbstractSyntaxTree::Node) }.map { |n| DeepInference.get_return_nodes(n) }.flatten
56
- DeepInference.get_return_nodes(node.children[2])
57
- else
58
- DeepInference.get_return_nodes(node)
59
- end
60
- end
61
-
62
- def const_nodes_from node
63
- return [] unless Parser.is_ast_node?(node)
64
- result = []
65
- if [:CONST, :COLON2, :COLON3].include?(node.type)
66
- result.push node
67
- else
68
- node.children.each { |child| result.concat const_nodes_from(child) }
69
- end
70
- result
71
- end
72
-
73
- def call_nodes_from node
74
- return [] unless Parser.is_ast_node?(node)
75
- result = []
76
- if node.type == :ITER
77
- result.push node.children[0]
78
- node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
79
- elsif node.type == :MASGN
80
- # @todo We're treating a mass assignment as a call node, but the
81
- # type checker still needs the logic to handle it.
82
- result.push node
83
- elsif [:CALL, :VCALL, :FCALL, :ATTRASGN, :OPCALL].include?(node.type)
84
- result.push node
85
- node.children.each { |child| result.concat call_nodes_from(child) }
86
- else
87
- node.children.each { |child| result.concat call_nodes_from(child) }
88
- end
89
- result
90
- end
91
-
92
- def convert_hash node
93
- return {} unless node?(node) && node.type == :HASH
94
- return convert_hash(node.children[0].children[1]) if splatted_hash?(node)
95
- return {} unless node?(node.children[0])
96
- result = {}
97
- index = 0
98
- until index > node.children[0].children.length - 2
99
- k = node.children[0].children[index]
100
- return {} unless node?(k)
101
- v = node.children[0].children[index + 1]
102
- result[k.children[0]] = Solargraph::Parser.chain(v)
103
- index += 2
104
- end
105
- result
106
- end
107
-
108
- def splatted_hash? node
109
- splatted_node?(node) && node.children[0].children[1].type == :HASH
110
- end
111
-
112
- def splatted_node? node
113
- node?(node.children[0]) &&
114
- [:ARRAY, :LIST].include?(node.children[0].type) &&
115
- node.children[0].children[0].nil? &&
116
- node?(node.children[0].children[1])
117
- end
118
-
119
- def splatted_call? node
120
- return false unless Parser.is_ast_node?(node)
121
- splatted_node?(node) && node.children[0].children[1].type != :HASH
122
- end
123
-
124
- def any_splatted_call?(nodes)
125
- nodes.any? { |n| splatted_call?(n) }
126
- end
127
-
128
- def node? node
129
- node.is_a?(RubyVM::AbstractSyntaxTree::Node)
130
- end
131
-
132
- # @param cursor [Solargraph::Source::Cursor]
133
- def find_recipient_node cursor
134
- if cursor.source.synchronized?
135
- NodeMethods.synchronized_find_recipient_node cursor
136
- else
137
- NodeMethods.unsynchronized_find_recipient_node cursor
138
- end
139
- end
140
-
141
- class << self
142
- protected
143
-
144
- # @param cursor [Source::Cursor]
145
- # @return [RubyVM::AbstractSyntaxTree::Node, nil]
146
- def synchronized_find_recipient_node cursor
147
- cursor = maybe_adjust_cursor(cursor)
148
- source = cursor.source
149
- position = cursor.position
150
- offset = cursor.offset
151
- tree = source.tree_at(position.line, position.column)
152
- .select { |n| [:FCALL, :VCALL, :CALL].include?(n.type) }
153
- unless source.repaired?
154
- tree.shift while tree.first && !source.code_for(tree.first).strip.end_with?(')')
155
- end
156
- return tree.first if source.repaired? || source.code[0..offset-1] =~ /\(\s*$/
157
- tree.each do |node|
158
- args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
159
- if args
160
- match = source.code[0..offset-1].match(/,[^\)]*\z/)
161
- rng = Solargraph::Range.from_node(args)
162
- if match
163
- rng = Solargraph::Range.new(rng.start, position)
164
- end
165
- return node if rng.contain?(position)
166
- end
167
- end
168
- nil
169
- end
170
-
171
- # @param cursor [Source::Cursor]
172
- # @return [Source::Cursor]
173
- def maybe_adjust_cursor cursor
174
- return cursor unless (cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(') || [',', ' '].include?(cursor.source.code[cursor.offset - 1])
175
- cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
176
- end
177
-
178
- def unsynchronized_find_recipient_node cursor
179
- source = cursor.source
180
- position = cursor.position
181
- offset = cursor.offset
182
- if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/
183
- tree = source.tree_at(position.line, position.column - 1)
184
- if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
185
- return tree.first
186
- else
187
- return nil
188
- end
189
- else
190
- match = source.code[0..offset-1].match(/[\(,][A-Zaz0-9_\s]*\z/)
191
- if match
192
- moved = Position.from_offset(source.code, offset - match[0].length)
193
- tree = source.tree_at(moved.line, moved.column)
194
- tree.shift if match[0].start_with?(',')
195
- tree.shift while tree.first && ![:FCALL, :VCALL, :CALL].include?(tree.first.type)
196
- if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
197
- return tree.first
198
- end
199
- end
200
- return nil
201
- end
202
- end
203
- end
204
-
205
- module DeepInference
206
- class << self
207
- CONDITIONAL = [:IF, :UNLESS]
208
- REDUCEABLE = [:BLOCK]
209
- SKIPPABLE = [:DEFN, :DEFS, :CLASS, :SCLASS, :MODULE]
210
-
211
- # @param node [Parser::AST::Node]
212
- # @return [Array<Parser::AST::Node>]
213
- def get_return_nodes node
214
- return [] unless node.is_a?(RubyVM::AbstractSyntaxTree::Node)
215
- result = []
216
- if REDUCEABLE.include?(node.type)
217
- result.concat get_return_nodes_from_children(node)
218
- elsif CONDITIONAL.include?(node.type)
219
- result.concat reduce_to_value_nodes(node.children[1..-1])
220
- elsif node.type == :RESCUE
221
- result.concat reduce_to_value_nodes([node.children[0]])
222
- result.concat reduce_to_value_nodes(node.children[1..-2])
223
- elsif node.type == :OR
224
- result.concat reduce_to_value_nodes(node.children)
225
- elsif node.type == :RETURN
226
- result.concat reduce_to_value_nodes([node.children[0]])
227
- elsif node.type == :ITER
228
- result.push node
229
- result.concat get_return_nodes_only(node.children[1])
230
- elsif node.type == :CASE
231
- node.children[1..-1].each do |cc|
232
- result.concat reduce_to_value_nodes(cc.children[1..-1])
233
- end
234
- else
235
- result.push node
236
- end
237
- result
238
- end
239
-
240
- private
241
-
242
- def get_return_nodes_from_children parent
243
- result = []
244
- nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
245
- nodes.each_with_index do |node, idx|
246
- if node.type == :BLOCK
247
- result.concat get_return_nodes_only(node.children[2])
248
- elsif SKIPPABLE.include?(node.type)
249
- next
250
- elsif CONDITIONAL.include?(node.type)
251
- result.concat get_return_nodes_only(node)
252
- elsif node.type == :RETURN
253
- result.concat reduce_to_value_nodes([node.children[0]])
254
- # Return the result here because the rest of the code is
255
- # unreachable
256
- return result
257
- else
258
- result.concat get_return_nodes_only(node)
259
- end
260
- result.concat reduce_to_value_nodes([nodes.last]) if idx == nodes.length - 1
261
- end
262
- result
263
- end
264
-
265
- def get_return_nodes_only parent
266
- return [] unless parent.is_a?(RubyVM::AbstractSyntaxTree::Node)
267
- result = []
268
- nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
269
- nodes.each do |node|
270
- next if SKIPPABLE.include?(node.type)
271
- if node.type == :RETURN
272
- result.concat reduce_to_value_nodes([node.children[0]])
273
- # Return the result here because the rest of the code is
274
- # unreachable
275
- return result
276
- else
277
- result.concat get_return_nodes_only(node)
278
- end
279
- end
280
- result
281
- end
282
-
283
- def reduce_to_value_nodes nodes
284
- result = []
285
- nodes.each do |node|
286
- if !node.is_a?(RubyVM::AbstractSyntaxTree::Node)
287
- result.push nil
288
- elsif REDUCEABLE.include?(node.type)
289
- result.concat get_return_nodes_from_children(node)
290
- elsif CONDITIONAL.include?(node.type)
291
- result.concat reduce_to_value_nodes(node.children[1..-1])
292
- elsif node.type == :RETURN
293
- if node.children[0].nil?
294
- result.push nil
295
- else
296
- result.concat get_return_nodes(node.children[0])
297
- end
298
- elsif node.type == :OR
299
- result.concat reduce_to_value_nodes(node.children)
300
- elsif node.type == :BLOCK
301
- result.concat get_return_nodes_only(node.children[2])
302
- elsif node.type == :RESBODY
303
- result.concat reduce_to_value_nodes([node.children[1]])
304
- else
305
- result.push node
306
- end
307
- end
308
- result
309
- end
310
- end
311
- end
312
- end
313
- end
314
- end
315
- end
1
+ module Solargraph
2
+ module Parser
3
+ module Rubyvm
4
+ module NodeMethods
5
+ module_function
6
+
7
+ # @param node [RubyVM::AbstractSyntaxTree::Node]
8
+ # @return [String]
9
+ def unpack_name node
10
+ pack_name(node).join('::')
11
+ end
12
+
13
+ # @param node [RubyVM::AbstractSyntaxTree::Node]
14
+ # @return [Array<String>]
15
+ def pack_name(node)
16
+ parts = []
17
+ if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
18
+ parts.push '' if node.type == :COLON3
19
+ node.children.each { |n|
20
+ if n.is_a?(RubyVM::AbstractSyntaxTree::Node)
21
+ parts += pack_name(n)
22
+ else
23
+ parts.push n unless n.nil?
24
+ end
25
+ }
26
+ end
27
+ parts
28
+ end
29
+
30
+ # @param node [RubyVM::AbstractSyntaxTree::Node]
31
+ # @return [String, nil]
32
+ def infer_literal_node_type node
33
+ return nil unless Parser.is_ast_node?(node)
34
+ case node.type
35
+ when :LIT, :STR
36
+ "::#{node.children.first.class.to_s}"
37
+ when :DSTR
38
+ "::String"
39
+ when :ARRAY, :ZARRAY, :LIST, :ZLIST
40
+ '::Array'
41
+ when :HASH
42
+ '::Hash'
43
+ when :DOT2, :DOT3
44
+ '::Range'
45
+ when :TRUE, :FALSE
46
+ '::Boolean'
47
+ when :SCOPE
48
+ infer_literal_node_type(node.children[2])
49
+ end
50
+ end
51
+
52
+ def returns_from node
53
+ return [] unless Parser.is_ast_node?(node)
54
+ if node.type == :SCOPE
55
+ # node.children.select { |n| n.is_a?(RubyVM::AbstractSyntaxTree::Node) }.map { |n| DeepInference.get_return_nodes(n) }.flatten
56
+ DeepInference.get_return_nodes(node.children[2])
57
+ else
58
+ DeepInference.get_return_nodes(node)
59
+ end
60
+ end
61
+
62
+ def const_nodes_from node
63
+ return [] unless Parser.is_ast_node?(node)
64
+ result = []
65
+ if [:CONST, :COLON2, :COLON3].include?(node.type)
66
+ result.push node
67
+ else
68
+ node.children.each { |child| result.concat const_nodes_from(child) }
69
+ end
70
+ result
71
+ end
72
+
73
+ def call_nodes_from node
74
+ return [] unless Parser.is_ast_node?(node)
75
+ result = []
76
+ if node.type == :ITER
77
+ result.push node.children[0]
78
+ node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
79
+ elsif node.type == :MASGN
80
+ # @todo We're treating a mass assignment as a call node, but the
81
+ # type checker still needs the logic to handle it.
82
+ result.push node
83
+ elsif [:CALL, :VCALL, :FCALL, :ATTRASGN, :OPCALL].include?(node.type)
84
+ result.push node
85
+ node.children.each { |child| result.concat call_nodes_from(child) }
86
+ else
87
+ node.children.each { |child| result.concat call_nodes_from(child) }
88
+ end
89
+ result
90
+ end
91
+
92
+ def convert_hash node
93
+ return {} unless node?(node) && node.type == :HASH
94
+ return convert_hash(node.children[0].children[1]) if splatted_hash?(node)
95
+ return {} unless node?(node.children[0])
96
+ result = {}
97
+ index = 0
98
+ until index > node.children[0].children.length - 2
99
+ k = node.children[0].children[index]
100
+ return {} unless node?(k)
101
+ v = node.children[0].children[index + 1]
102
+ result[k.children[0]] = Solargraph::Parser.chain(v)
103
+ index += 2
104
+ end
105
+ result
106
+ end
107
+
108
+ def splatted_hash? node
109
+ splatted_node?(node) && node.children[0].children[1].type == :HASH
110
+ end
111
+
112
+ def splatted_node? node
113
+ node?(node.children[0]) &&
114
+ [:ARRAY, :LIST].include?(node.children[0].type) &&
115
+ node.children[0].children[0].nil? &&
116
+ node?(node.children[0].children[1])
117
+ end
118
+
119
+ def splatted_call? node
120
+ return false unless Parser.is_ast_node?(node)
121
+ splatted_node?(node) && node.children[0].children[1].type != :HASH
122
+ end
123
+
124
+ def any_splatted_call?(nodes)
125
+ nodes.any? { |n| splatted_call?(n) }
126
+ end
127
+
128
+ def node? node
129
+ node.is_a?(RubyVM::AbstractSyntaxTree::Node)
130
+ end
131
+
132
+ # @param cursor [Solargraph::Source::Cursor]
133
+ def find_recipient_node cursor
134
+ if cursor.source.synchronized?
135
+ NodeMethods.synchronized_find_recipient_node cursor
136
+ else
137
+ NodeMethods.unsynchronized_find_recipient_node cursor
138
+ end
139
+ end
140
+
141
+ class << self
142
+ protected
143
+
144
+ # @param cursor [Source::Cursor]
145
+ # @return [RubyVM::AbstractSyntaxTree::Node, nil]
146
+ def synchronized_find_recipient_node cursor
147
+ cursor = maybe_adjust_cursor(cursor)
148
+ source = cursor.source
149
+ position = cursor.position
150
+ offset = cursor.offset
151
+ tree = source.tree_at(position.line, position.column)
152
+ .select { |n| [:FCALL, :VCALL, :CALL].include?(n.type) }
153
+ unless source.repaired?
154
+ tree.shift while tree.first && !source.code_for(tree.first).strip.end_with?(')')
155
+ end
156
+ return tree.first if source.repaired? || source.code[0..offset-1] =~ /\(\s*$/
157
+ tree.each do |node|
158
+ args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
159
+ if args
160
+ match = source.code[0..offset-1].match(/,[^\)]*\z/)
161
+ rng = Solargraph::Range.from_node(args)
162
+ if match
163
+ rng = Solargraph::Range.new(rng.start, position)
164
+ end
165
+ return node if rng.contain?(position)
166
+ end
167
+ end
168
+ nil
169
+ end
170
+
171
+ # @param cursor [Source::Cursor]
172
+ # @return [Source::Cursor]
173
+ def maybe_adjust_cursor cursor
174
+ return cursor unless (cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(') || [',', ' '].include?(cursor.source.code[cursor.offset - 1])
175
+ cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
176
+ end
177
+
178
+ def unsynchronized_find_recipient_node cursor
179
+ source = cursor.source
180
+ position = cursor.position
181
+ offset = cursor.offset
182
+ if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/
183
+ tree = source.tree_at(position.line, position.column - 1)
184
+ if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
185
+ return tree.first
186
+ else
187
+ return nil
188
+ end
189
+ else
190
+ match = source.code[0..offset-1].match(/[\(,][A-Zaz0-9_\s]*\z/)
191
+ if match
192
+ moved = Position.from_offset(source.code, offset - match[0].length)
193
+ tree = source.tree_at(moved.line, moved.column)
194
+ tree.shift if match[0].start_with?(',')
195
+ tree.shift while tree.first && ![:FCALL, :VCALL, :CALL].include?(tree.first.type)
196
+ if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
197
+ return tree.first
198
+ end
199
+ end
200
+ return nil
201
+ end
202
+ end
203
+ end
204
+
205
+ module DeepInference
206
+ class << self
207
+ CONDITIONAL = [:IF, :UNLESS]
208
+ REDUCEABLE = [:BLOCK]
209
+ SKIPPABLE = [:DEFN, :DEFS, :CLASS, :SCLASS, :MODULE]
210
+
211
+ # @param node [Parser::AST::Node]
212
+ # @return [Array<Parser::AST::Node>]
213
+ def get_return_nodes node
214
+ return [] unless node.is_a?(RubyVM::AbstractSyntaxTree::Node)
215
+ result = []
216
+ if REDUCEABLE.include?(node.type)
217
+ result.concat get_return_nodes_from_children(node)
218
+ elsif CONDITIONAL.include?(node.type)
219
+ result.concat reduce_to_value_nodes(node.children[1..-1])
220
+ elsif node.type == :RESCUE
221
+ result.concat reduce_to_value_nodes([node.children[0]])
222
+ result.concat reduce_to_value_nodes(node.children[1..-2])
223
+ elsif node.type == :OR
224
+ result.concat reduce_to_value_nodes(node.children)
225
+ elsif node.type == :RETURN
226
+ result.concat reduce_to_value_nodes([node.children[0]])
227
+ elsif node.type == :ITER
228
+ result.push node
229
+ result.concat get_return_nodes_only(node.children[1])
230
+ elsif node.type == :CASE
231
+ node.children[1..-1].each do |cc|
232
+ result.concat reduce_to_value_nodes(cc.children[1..-1])
233
+ end
234
+ else
235
+ result.push node
236
+ end
237
+ result
238
+ end
239
+
240
+ private
241
+
242
+ def get_return_nodes_from_children parent
243
+ result = []
244
+ nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
245
+ nodes.each_with_index do |node, idx|
246
+ if node.type == :BLOCK
247
+ result.concat get_return_nodes_only(node.children[2])
248
+ elsif SKIPPABLE.include?(node.type)
249
+ next
250
+ elsif CONDITIONAL.include?(node.type)
251
+ result.concat get_return_nodes_only(node)
252
+ elsif node.type == :RETURN
253
+ result.concat reduce_to_value_nodes([node.children[0]])
254
+ # Return the result here because the rest of the code is
255
+ # unreachable
256
+ return result
257
+ else
258
+ result.concat get_return_nodes_only(node)
259
+ end
260
+ result.concat reduce_to_value_nodes([nodes.last]) if idx == nodes.length - 1
261
+ end
262
+ result
263
+ end
264
+
265
+ def get_return_nodes_only parent
266
+ return [] unless parent.is_a?(RubyVM::AbstractSyntaxTree::Node)
267
+ result = []
268
+ nodes = parent.children.select{|n| n.is_a?(RubyVM::AbstractSyntaxTree::Node)}
269
+ nodes.each do |node|
270
+ next if SKIPPABLE.include?(node.type)
271
+ if node.type == :RETURN
272
+ result.concat reduce_to_value_nodes([node.children[0]])
273
+ # Return the result here because the rest of the code is
274
+ # unreachable
275
+ return result
276
+ else
277
+ result.concat get_return_nodes_only(node)
278
+ end
279
+ end
280
+ result
281
+ end
282
+
283
+ def reduce_to_value_nodes nodes
284
+ result = []
285
+ nodes.each do |node|
286
+ if !node.is_a?(RubyVM::AbstractSyntaxTree::Node)
287
+ result.push nil
288
+ elsif REDUCEABLE.include?(node.type)
289
+ result.concat get_return_nodes_from_children(node)
290
+ elsif CONDITIONAL.include?(node.type)
291
+ result.concat reduce_to_value_nodes(node.children[1..-1])
292
+ elsif node.type == :RETURN
293
+ if node.children[0].nil?
294
+ result.push nil
295
+ else
296
+ result.concat get_return_nodes(node.children[0])
297
+ end
298
+ elsif node.type == :OR
299
+ result.concat reduce_to_value_nodes(node.children)
300
+ elsif node.type == :BLOCK
301
+ result.concat get_return_nodes_only(node.children[2])
302
+ elsif node.type == :RESBODY
303
+ result.concat reduce_to_value_nodes([node.children[1]])
304
+ else
305
+ result.push node
306
+ end
307
+ end
308
+ result
309
+ end
310
+ end
311
+ end
312
+ end
313
+ end
314
+ end
315
+ end