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,221 +1,394 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- # A container for type data based on YARD type tags.
5
- #
6
- class ComplexType
7
- # @!parse
8
- # include TypeMethods
9
-
10
- autoload :TypeMethods, 'solargraph/complex_type/type_methods'
11
- autoload :UniqueType, 'solargraph/complex_type/unique_type'
12
-
13
- # @param types [Array<UniqueType>]
14
- def initialize types = [UniqueType::UNDEFINED]
15
- @items = types.uniq(&:to_s)
16
- end
17
-
18
- # @param api_map [ApiMap]
19
- # @param context [String]
20
- # @return [ComplexType]
21
- def qualify api_map, context = ''
22
- types = @items.map do |t|
23
- next t if ['Boolean', 'nil', 'void', 'undefined'].include?(t.name)
24
- t.qualify api_map, context
25
- end
26
- ComplexType.new(types)
27
- end
28
-
29
- def first
30
- @items.first
31
- end
32
-
33
- def map &block
34
- @items.map &block
35
- end
36
-
37
- # @yieldparam [UniqueType]
38
- # @return [Array]
39
- def each &block
40
- @items.each &block
41
- end
42
-
43
- def length
44
- @items.length
45
- end
46
-
47
- def [](index)
48
- @items[index]
49
- end
50
-
51
- def select &block
52
- @items.select &block
53
- end
54
- def namespace
55
- # cache this attr for high frequency call
56
- @namespace ||= method_missing(:namespace).to_s
57
- end
58
-
59
- def method_missing name, *args, &block
60
- return if @items.first.nil?
61
- return @items.first.send(name, *args, &block) if respond_to_missing?(name)
62
- super
63
- end
64
-
65
- def respond_to_missing?(name, include_private = false)
66
- TypeMethods.public_instance_methods.include?(name) || super
67
- end
68
-
69
- def to_s
70
- map(&:tag).join(', ')
71
- end
72
-
73
- def all? &block
74
- @items.all? &block
75
- end
76
-
77
- def selfy?
78
- @items.any?(&:selfy?)
79
- end
80
-
81
- # @param dst [String]
82
- # @return [ComplexType]
83
- def self_to dst
84
- return self unless selfy?
85
- red = reduce_class(dst)
86
- result = @items.map { |i| i.self_to red }
87
- ComplexType.parse(*result.map(&:tag))
88
- end
89
-
90
- def nullable?
91
- @items.any?(&:nil_type?)
92
- end
93
-
94
- private
95
-
96
- # @todo This is a quick and dirty hack that forces `self` keywords
97
- # to reference an instance of their class and never the class itself.
98
- # This behavior may change depending on which result is expected
99
- # from YARD conventions. See https://github.com/lsegal/yard/issues/1257
100
- # @param dst [String]
101
- # @return [String]
102
- def reduce_class dst
103
- while dst =~ /^(Class|Module)\<(.*?)\>$/
104
- dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
105
- end
106
- dst
107
- end
108
-
109
- class << self
110
- # Parse type strings into a ComplexType.
111
- #
112
- # @example
113
- # ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
114
- #
115
- # @note
116
- # The `partial` parameter is used to indicate that the method is
117
- # receiving a string that will be used inside another ComplexType.
118
- # It returns arrays of ComplexTypes instead of a single cohesive one.
119
- # Consumers should not need to use this parameter; it should only be
120
- # used internally.
121
- #
122
- # @param *strings [Array<String>] The type definitions to parse
123
- # @param partial [Boolean] True if the string is part of a another type
124
- # @return [ComplexType, Array, nil]
125
- def parse *strings, partial: false
126
- @cache ||= {}
127
- unless partial
128
- cached = @cache[strings]
129
- return cached unless cached.nil?
130
- end
131
- types = []
132
- key_types = nil
133
- strings.each do |type_string|
134
- point_stack = 0
135
- curly_stack = 0
136
- paren_stack = 0
137
- base = String.new
138
- subtype_string = String.new
139
- type_string.each_char do |char|
140
- if char == '='
141
- #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
142
- elsif char == '<'
143
- point_stack += 1
144
- elsif char == '>'
145
- if subtype_string.end_with?('=') && curly_stack > 0
146
- subtype_string += char
147
- elsif base.end_with?('=')
148
- raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
149
- # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
150
- types.push UniqueType.new(base[0..-2].strip)
151
- key_types = types
152
- types = []
153
- base.clear
154
- subtype_string.clear
155
- next
156
- else
157
- point_stack -= 1
158
- subtype_string += char if point_stack == 0
159
- raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack < 0
160
- end
161
- next
162
- elsif char == '{'
163
- curly_stack += 1
164
- elsif char == '}'
165
- curly_stack -= 1
166
- subtype_string += char
167
- raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
168
- next
169
- elsif char == '('
170
- paren_stack += 1
171
- elsif char == ')'
172
- paren_stack -= 1
173
- subtype_string += char if paren_stack == 0
174
- raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
175
- next
176
- elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
177
- # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
178
- types.push UniqueType.new(base.strip, subtype_string.strip)
179
- base.clear
180
- subtype_string.clear
181
- next
182
- end
183
- if point_stack == 0 && curly_stack == 0 && paren_stack == 0
184
- base.concat char
185
- else
186
- subtype_string.concat char
187
- end
188
- end
189
- raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
190
- # types.push ComplexType.new([UniqueType.new(base, subtype_string)])
191
- types.push UniqueType.new(base.strip, subtype_string.strip)
192
- end
193
- unless key_types.nil?
194
- raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
195
- return key_types if types.empty?
196
- return [key_types, types]
197
- end
198
- result = partial ? types : ComplexType.new(types)
199
- @cache[strings] = result unless partial
200
- result
201
- end
202
-
203
- # @param strings [Array<String>]
204
- # @return [ComplexType]
205
- def try_parse *strings
206
- parse *strings
207
- rescue ComplexTypeError => e
208
- Solargraph.logger.info "Error parsing complex type: #{e.message}"
209
- ComplexType::UNDEFINED
210
- end
211
- end
212
-
213
- VOID = ComplexType.parse('void')
214
- UNDEFINED = ComplexType.parse('undefined')
215
- SYMBOL = ComplexType.parse('Symbol')
216
- ROOT = ComplexType.parse('Class<>')
217
- NIL = ComplexType.parse('nil')
218
- SELF = ComplexType.parse('self')
219
- BOOLEAN = ComplexType.parse('Boolean')
220
- end
221
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ # A container for type data based on YARD type tags.
5
+ #
6
+ class ComplexType
7
+ GENERIC_TAG_NAME = 'generic'.freeze
8
+ # @!parse
9
+ # include TypeMethods
10
+ include Equality
11
+
12
+ autoload :TypeMethods, 'solargraph/complex_type/type_methods'
13
+ autoload :UniqueType, 'solargraph/complex_type/unique_type'
14
+
15
+ # @param types [Array<UniqueType, ComplexType>]
16
+ def initialize types = [UniqueType::UNDEFINED]
17
+ # @todo @items here should not need an annotation
18
+ # @type [Array<UniqueType>]
19
+ @items = types.flat_map(&:items).uniq(&:to_s)
20
+ end
21
+
22
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
23
+ protected def equality_fields
24
+ [self.class, items]
25
+ end
26
+
27
+ # @param api_map [ApiMap]
28
+ # @param context [String]
29
+ # @return [ComplexType]
30
+ def qualify api_map, context = ''
31
+ red = reduce_object
32
+ types = red.items.map do |t|
33
+ next t if ['nil', 'void', 'undefined'].include?(t.name)
34
+ next t if ['::Boolean'].include?(t.rooted_name)
35
+ t.qualify api_map, context
36
+ end
37
+ ComplexType.new(types).reduce_object
38
+ end
39
+
40
+ # @param generics_to_resolve [Enumerable<String>]]
41
+ # @param context_type [UniqueType, nil]
42
+ # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
43
+ # @return [self]
44
+ def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
45
+ return self unless generic?
46
+
47
+ ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
48
+ end
49
+
50
+ # @return [UniqueType]
51
+ def first
52
+ @items.first
53
+ end
54
+
55
+ # @return [String]
56
+ def to_rbs
57
+ ((@items.length > 1 ? '(' : '') +
58
+ @items.map(&:to_rbs).join(' | ') +
59
+ (@items.length > 1 ? ')' : ''))
60
+ end
61
+
62
+ # @param dst [ComplexType]
63
+ # @return [ComplexType]
64
+ def self_to_type dst
65
+ object_type_dst = dst.reduce_class_type
66
+ transform do |t|
67
+ next t if t.name != 'self'
68
+ object_type_dst
69
+ end
70
+ end
71
+
72
+ # @yieldparam [UniqueType]
73
+ # @return [Array]
74
+ def map &block
75
+ @items.map &block
76
+ end
77
+
78
+ # @yieldparam [UniqueType]
79
+ # @return [Enumerable<UniqueType>]
80
+ def each &block
81
+ @items.each &block
82
+ end
83
+
84
+ # @yieldparam [UniqueType]
85
+ # @return [void]
86
+ # @overload each_unique_type()
87
+ # @return [Enumerator<UniqueType>]
88
+ def each_unique_type &block
89
+ return enum_for(__method__) unless block_given?
90
+
91
+ @items.each do |item|
92
+ item.each_unique_type &block
93
+ end
94
+ end
95
+
96
+ # @return [Integer]
97
+ def length
98
+ @items.length
99
+ end
100
+
101
+ # @return [Array<UniqueType>]
102
+ def to_a
103
+ @items
104
+ end
105
+
106
+ def tags
107
+ @items.map(&:tag).join(', ')
108
+ end
109
+
110
+ # @param index [Integer]
111
+ # @return [UniqueType]
112
+ def [](index)
113
+ @items[index]
114
+ end
115
+
116
+ # @return [Array<UniqueType>]
117
+ def select &block
118
+ @items.select &block
119
+ end
120
+
121
+ # @return [String]
122
+ def namespace
123
+ # cache this attr for high frequency call
124
+ @namespace ||= method_missing(:namespace).to_s
125
+ end
126
+
127
+ # @return [Array<String>]
128
+ def namespaces
129
+ @items.map(&:namespace)
130
+ end
131
+
132
+ # @param name [Symbol]
133
+ # @return [Object, nil]
134
+ def method_missing name, *args, &block
135
+ return if @items.first.nil?
136
+ return @items.first.send(name, *args, &block) if respond_to_missing?(name)
137
+ super
138
+ end
139
+
140
+ # @param name [Symbol]
141
+ # @param include_private [Boolean]
142
+ def respond_to_missing?(name, include_private = false)
143
+ TypeMethods.public_instance_methods.include?(name) || super
144
+ end
145
+
146
+ def to_s
147
+ map(&:tag).join(', ')
148
+ end
149
+
150
+ def desc
151
+ rooted_tags
152
+ end
153
+
154
+ def rooted_tags
155
+ map(&:rooted_tag).join(', ')
156
+ end
157
+
158
+ # @yieldparam [UniqueType]
159
+ def all? &block
160
+ @items.all? &block
161
+ end
162
+
163
+ # @yieldparam [UniqueType]
164
+ # @yieldreturn [Boolean]
165
+ # @return [Boolean]
166
+ def any? &block
167
+ @items.compact.any? &block
168
+ end
169
+
170
+ def selfy?
171
+ @items.any?(&:selfy?)
172
+ end
173
+
174
+ def generic?
175
+ any?(&:generic?)
176
+ end
177
+
178
+ # @param new_name [String, nil]
179
+ # @yieldparam t [UniqueType]
180
+ # @yieldreturn [UniqueType]
181
+ # @return [ComplexType]
182
+ def transform(new_name = nil, &transform_type)
183
+ raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
184
+ ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
185
+ end
186
+
187
+ # @return [self]
188
+ def force_rooted
189
+ transform do |t|
190
+ t.recreate(make_rooted: true)
191
+ end
192
+ end
193
+
194
+ # @param definitions [Pin::Namespace, Pin::Method]
195
+ # @param context_type [ComplexType]
196
+ # @return [ComplexType]
197
+ def resolve_generics definitions, context_type
198
+ result = @items.map { |i| i.resolve_generics(definitions, context_type) }
199
+ ComplexType.new(result)
200
+ end
201
+
202
+ def nullable?
203
+ @items.any?(&:nil_type?)
204
+ end
205
+
206
+ # @return [Array<ComplexType>]
207
+ def all_params
208
+ @items.first.all_params || []
209
+ end
210
+
211
+ # @return [ComplexType]
212
+ def reduce_class_type
213
+ new_items = items.flat_map do |type|
214
+ next type unless ['Module', 'Class'].include?(type.name)
215
+
216
+ type.all_params
217
+ end
218
+ ComplexType.new(new_items)
219
+ end
220
+
221
+ # every type and subtype in this union have been resolved to be
222
+ # fully qualified
223
+ def all_rooted?
224
+ all?(&:all_rooted?)
225
+ end
226
+
227
+ # every top-level type has resolved to be fully qualified; see
228
+ # #all_rooted? to check their subtypes as well
229
+ def rooted?
230
+ all?(&:rooted?)
231
+ end
232
+
233
+ attr_reader :items
234
+
235
+ def rooted?
236
+ @items.all?(&:rooted?)
237
+ end
238
+
239
+ protected
240
+
241
+ # @return [ComplexType]
242
+ def reduce_object
243
+ new_items = items.flat_map do |ut|
244
+ next [ut] if ut.name != 'Object' || ut.subtypes.empty?
245
+ ut.subtypes
246
+ end
247
+ ComplexType.new(new_items)
248
+ end
249
+
250
+ def bottom?
251
+ @items.all?(&:bot?)
252
+ end
253
+
254
+ class << self
255
+ # Parse type strings into a ComplexType.
256
+ #
257
+ # @example
258
+ # ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
259
+ #
260
+ # @note
261
+ # The `partial` parameter is used to indicate that the method is
262
+ # receiving a string that will be used inside another ComplexType.
263
+ # It returns arrays of ComplexTypes instead of a single cohesive one.
264
+ # Consumers should not need to use this parameter; it should only be
265
+ # used internally.
266
+ #
267
+ # @param strings [Array<String>] The type definitions to parse
268
+ # @return [ComplexType]
269
+ # # @overload parse(*strings, partial: false)
270
+ # # @todo Need ability to use a literal true as a type below
271
+ # # @param partial [Boolean] True if the string is part of a another type
272
+ # # @return [Array<UniqueType>]
273
+ # @sg-ignore
274
+ # @todo To be able to select the right signature above,
275
+ # Chain::Call needs to know the decl type (:arg, :optarg,
276
+ # :kwarg, etc) of the arguments given, instead of just having
277
+ # an array of Chains as the arguments.
278
+ def parse *strings, partial: false
279
+ # @type [Hash{Array<String> => ComplexType}]
280
+ @cache ||= {}
281
+ unless partial
282
+ cached = @cache[strings]
283
+ return cached unless cached.nil?
284
+ end
285
+ types = []
286
+ key_types = nil
287
+ strings.each do |type_string|
288
+ point_stack = 0
289
+ curly_stack = 0
290
+ paren_stack = 0
291
+ base = String.new
292
+ subtype_string = String.new
293
+ type_string&.each_char do |char|
294
+ if char == '='
295
+ #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
296
+ elsif char == '<'
297
+ point_stack += 1
298
+ elsif char == '>'
299
+ if subtype_string.end_with?('=') && curly_stack > 0
300
+ subtype_string += char
301
+ elsif base.end_with?('=')
302
+ raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
303
+ # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
304
+ types.push UniqueType.parse(base[0..-2].strip, subtype_string)
305
+ # @todo this should either expand key_type's type
306
+ # automatically or complain about not being
307
+ # compatible with key_type's type in type checking
308
+ key_types = types
309
+ types = []
310
+ base.clear
311
+ subtype_string.clear
312
+ next
313
+ else
314
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0
315
+ point_stack -= 1
316
+ subtype_string += char
317
+ end
318
+ next
319
+ elsif char == '{'
320
+ curly_stack += 1
321
+ elsif char == '}'
322
+ curly_stack -= 1
323
+ subtype_string += char
324
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack < 0
325
+ next
326
+ elsif char == '('
327
+ paren_stack += 1
328
+ elsif char == ')'
329
+ paren_stack -= 1
330
+ subtype_string += char
331
+ raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
332
+ next
333
+ elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
334
+ # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
335
+ types.push UniqueType.parse(base.strip, subtype_string.strip)
336
+ base.clear
337
+ subtype_string.clear
338
+ next
339
+ end
340
+ if point_stack == 0 && curly_stack == 0 && paren_stack == 0
341
+ base.concat char
342
+ else
343
+ subtype_string.concat char
344
+ end
345
+ end
346
+ raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
347
+ # types.push ComplexType.new([UniqueType.new(base, subtype_string)])
348
+ types.push UniqueType.parse(base.strip, subtype_string.strip)
349
+ end
350
+ unless key_types.nil?
351
+ raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
352
+ return key_types if types.empty?
353
+ return [key_types, types]
354
+ end
355
+ result = partial ? types : ComplexType.new(types)
356
+ @cache[strings] = result unless partial
357
+ result
358
+ end
359
+
360
+ # @param strings [Array<String>]
361
+ # @return [ComplexType]
362
+ def try_parse *strings
363
+ parse *strings
364
+ rescue ComplexTypeError => e
365
+ Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
366
+ ComplexType::UNDEFINED
367
+ end
368
+ end
369
+
370
+ VOID = ComplexType.parse('void')
371
+ UNDEFINED = ComplexType.parse('undefined')
372
+ SYMBOL = ComplexType.parse('::Symbol')
373
+ ROOT = ComplexType.parse('::Class<>')
374
+ NIL = ComplexType.parse('nil')
375
+ SELF = ComplexType.parse('self')
376
+ BOOLEAN = ComplexType.parse('::Boolean')
377
+ BOT = ComplexType.parse('bot')
378
+
379
+ private
380
+
381
+ # @todo This is a quick and dirty hack that forces `self` keywords
382
+ # to reference an instance of their class and never the class itself.
383
+ # This behavior may change depending on which result is expected
384
+ # from YARD conventions. See https://github.com/lsegal/yard/issues/1257
385
+ # @param dst [String]
386
+ # @return [String]
387
+ def reduce_class dst
388
+ while dst =~ /^(Class|Module)\<(.*?)\>$/
389
+ dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
390
+ end
391
+ dst
392
+ end
393
+ end
394
+ end