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,75 +1,386 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- class ComplexType
5
- # An individual type signature. A complex type can consist of multiple
6
- # unique types.
7
- #
8
- class UniqueType
9
- include TypeMethods
10
-
11
- # Create a UniqueType with the specified name and an optional substring.
12
- # The substring is the parameter section of a parametrized type, e.g.,
13
- # for the type `Array<String>`, the name is `Array` and the substring is
14
- # `<String>`.
15
- #
16
- # @param name [String] The name of the type
17
- # @param substring [String] The substring of the type
18
- def initialize name, substring = ''
19
- if name.start_with?('::')
20
- @name = name[2..-1]
21
- @rooted = true
22
- else
23
- @name = name
24
- @rooted = false
25
- end
26
- @substring = substring
27
- @tag = @name + substring
28
- @key_types = []
29
- @subtypes = []
30
- return unless parameters?
31
- if @substring.start_with?('<(') && @substring.end_with?(')>')
32
- subs = ComplexType.parse(substring[2..-3], partial: true)
33
- else
34
- subs = ComplexType.parse(substring[1..-2], partial: true)
35
- end
36
- if hash_parameters?
37
- raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
38
- @key_types.concat subs[0].map { |u| ComplexType.new([u]) }
39
- @subtypes.concat subs[1].map { |u| ComplexType.new([u]) }
40
- else
41
- @subtypes.concat subs
42
- end
43
- end
44
-
45
- def to_s
46
- tag
47
- end
48
-
49
- def self_to dst
50
- return self unless selfy?
51
- new_name = (@name == 'self' ? dst : @name)
52
- new_key_types = @key_types.map { |t| t.self_to dst }
53
- new_subtypes = @subtypes.map { |t| t.self_to dst }
54
- if hash_parameters?
55
- UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
56
- elsif parameters?
57
- if @substring.start_with?'<('
58
- UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
59
- else
60
- UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
61
- end
62
- else
63
- UniqueType.new(new_name)
64
- end
65
- end
66
-
67
- def selfy?
68
- @name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
69
- end
70
-
71
- UNDEFINED = UniqueType.new('undefined')
72
- BOOLEAN = UniqueType.new('Boolean')
73
- end
74
- end
75
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class ComplexType
5
+ # An individual type signature. A complex type can consist of multiple
6
+ # unique types.
7
+ #
8
+ class UniqueType
9
+ include TypeMethods
10
+ include Equality
11
+
12
+ attr_reader :all_params, :subtypes, :key_types
13
+
14
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
15
+ protected def equality_fields
16
+ [@name, @all_params, @subtypes, @key_types]
17
+ end
18
+
19
+ # Create a UniqueType with the specified name and an optional substring.
20
+ # The substring is the parameter section of a parametrized type, e.g.,
21
+ # for the type `Array<String>`, the name is `Array` and the substring is
22
+ # `<String>`.
23
+ #
24
+ # @param name [String] The name of the type
25
+ # @param substring [String] The substring of the type
26
+ # @param make_rooted [Boolean, nil]
27
+ # @return [UniqueType]
28
+ def self.parse name, substring = '', make_rooted: nil
29
+ if name.start_with?(':::')
30
+ raise "Illegal prefix: #{name}"
31
+ end
32
+ if name.start_with?('::')
33
+ name = name[2..-1]
34
+ rooted = true
35
+ elsif !can_root_name?(name)
36
+ rooted = true
37
+ else
38
+ rooted = false
39
+ end
40
+ rooted = make_rooted unless make_rooted.nil?
41
+
42
+ # @type [Array<ComplexType>]
43
+ key_types = []
44
+ # @type [Array<ComplexType>]
45
+ subtypes = []
46
+ parameters_type = nil
47
+ unless substring.empty?
48
+ subs = ComplexType.parse(substring[1..-2], partial: true)
49
+ parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0])
50
+ if parameters_type == :hash
51
+ raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
52
+ # @todo should be able to resolve map; both types have it
53
+ # with same return type
54
+ # @sg-ignore
55
+ key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
56
+ # @sg-ignore
57
+ subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
58
+ else
59
+ subtypes.concat subs
60
+ end
61
+ end
62
+ new(name, key_types, subtypes, rooted: rooted, parameters_type: parameters_type)
63
+ end
64
+
65
+ # @param name [String]
66
+ # @param key_types [Array<ComplexType>]
67
+ # @param subtypes [Array<ComplexType>]
68
+ # @param rooted [Boolean]
69
+ # @param parameters_type [Symbol, nil]
70
+ def initialize(name, key_types = [], subtypes = [], rooted:, parameters_type: nil)
71
+ if parameters_type.nil?
72
+ raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
73
+ end
74
+ raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
75
+ @name = name
76
+ @key_types = key_types
77
+ @subtypes = subtypes
78
+ @rooted = rooted
79
+ @all_params = []
80
+ @all_params.concat key_types
81
+ @all_params.concat subtypes
82
+ @parameters_type = parameters_type
83
+ end
84
+
85
+ def to_s
86
+ tag
87
+ end
88
+
89
+ def eql?(other)
90
+ self.class == other.class &&
91
+ @name == other.name &&
92
+ @key_types == other.key_types &&
93
+ @subtypes == other.subtypes &&
94
+ @rooted == other.rooted? &&
95
+ @all_params == other.all_params &&
96
+ @parameters_type == other.parameters_type
97
+ end
98
+
99
+ def ==(other)
100
+ eql?(other)
101
+ end
102
+
103
+ def hash
104
+ [self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
105
+ end
106
+
107
+ # @return [Array<UniqueType>]
108
+ def items
109
+ [self]
110
+ end
111
+
112
+ # @return [String]
113
+ def rbs_name
114
+ if name == 'undefined'
115
+ 'untyped'
116
+ else
117
+ rooted_name
118
+ end
119
+ end
120
+
121
+ def desc
122
+ rooted_tags
123
+ end
124
+
125
+ # @return [String]
126
+ def to_rbs
127
+ if duck_type?
128
+ 'untyped'
129
+ elsif name == 'Boolean'
130
+ 'bool'
131
+ elsif name.downcase == 'nil'
132
+ 'nil'
133
+ elsif name == GENERIC_TAG_NAME
134
+ all_params.first.name
135
+ elsif ['Class', 'Module'].include?(name)
136
+ rbs_name
137
+ elsif ['Tuple', 'Array'].include?(name) && fixed_parameters?
138
+ # tuples don't have a name; they're just [foo, bar, baz].
139
+ if substring == '()'
140
+ # but there are no zero element tuples, so we go with an array
141
+ if rooted?
142
+ '::Array[]'
143
+ else
144
+ 'Array[]'
145
+ end
146
+ else
147
+ # already generated surrounded by []
148
+ parameters_as_rbs
149
+ end
150
+ else
151
+ "#{rbs_name}#{parameters_as_rbs}"
152
+ end
153
+ end
154
+
155
+ # @return [Boolean]
156
+ def parameters?
157
+ !all_params.empty?
158
+ end
159
+
160
+ # @param types [Array<UniqueType, ComplexType>]
161
+ # @return [String]
162
+ def rbs_union(types)
163
+ if types.length == 1
164
+ types.first.to_rbs
165
+ else
166
+ "(#{types.map(&:to_rbs).join(' | ')})"
167
+ end
168
+ end
169
+
170
+ # @return [String]
171
+ def parameters_as_rbs
172
+ return '' unless parameters?
173
+
174
+ return "[#{all_params.map(&:to_rbs).join(', ')}]" if key_types.empty?
175
+
176
+ # handle, e.g., Hash[K, V] case
177
+ key_types_str = rbs_union(key_types)
178
+ subtypes_str = rbs_union(subtypes)
179
+ "[#{key_types_str}, #{subtypes_str}]"
180
+ end
181
+
182
+ def generic?
183
+ name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
184
+ end
185
+
186
+ # @param generics_to_resolve [Enumerable<String>]
187
+ # @param context_type [UniqueType, nil]
188
+ # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
189
+ # @return [UniqueType, ComplexType]
190
+ def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
191
+ if name == ComplexType::GENERIC_TAG_NAME
192
+ type_param = subtypes.first&.name
193
+ return self unless generics_to_resolve.include? type_param
194
+ unless context_type.nil? || !resolved_generic_values[type_param].nil?
195
+ new_binding = true
196
+ resolved_generic_values[type_param] = context_type
197
+ end
198
+ if new_binding
199
+ resolved_generic_values.transform_values! do |complex_type|
200
+ complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values)
201
+ end
202
+ end
203
+ return resolved_generic_values[type_param] || self
204
+ end
205
+
206
+ # @todo typechecking should complain when the method being called has no @yieldparam tag
207
+ new_key_types = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:key_types)
208
+ new_subtypes = resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values, &:subtypes)
209
+ recreate(new_key_types: new_key_types, new_subtypes: new_subtypes)
210
+ end
211
+
212
+ # @param generics_to_resolve [Enumerable<String>]
213
+ # @param context_type [UniqueType]
214
+ # @param resolved_generic_values [Hash{String => ComplexType}]
215
+ # @yieldreturn [Array<ComplexType>]
216
+ # @return [Array<ComplexType>]
217
+ def resolve_param_generics_from_context(generics_to_resolve, context_type, resolved_generic_values)
218
+ types = yield self
219
+ types.each_with_index.flat_map do |ct, i|
220
+ ct.items.flat_map do |ut|
221
+ context_params = yield context_type if context_type
222
+ if context_params && context_params[i]
223
+ type_arg = context_params[i]
224
+ type_arg.map do |new_unique_context_type|
225
+ ut.resolve_generics_from_context generics_to_resolve, new_unique_context_type, resolved_generic_values: resolved_generic_values
226
+ end
227
+ else
228
+ ut.resolve_generics_from_context generics_to_resolve, nil, resolved_generic_values: resolved_generic_values
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ # Probe the concrete type for each of the generic type
235
+ # parameters used in this type, and return a new type if
236
+ # possible.
237
+ #
238
+ # @param definitions [Pin::Namespace, Pin::Method] The module/class/method which uses generic types
239
+ # @param context_type [ComplexType] The receiver type
240
+ # @return [UniqueType, ComplexType]
241
+ def resolve_generics definitions, context_type
242
+ return self if definitions.nil? || definitions.generics.empty?
243
+
244
+ transform(name) do |t|
245
+ if t.name == GENERIC_TAG_NAME
246
+ idx = definitions.generics.index(t.subtypes.first&.name)
247
+ next t if idx.nil?
248
+ if context_type.parameters_type == :hash
249
+ if idx == 0
250
+ next ComplexType.new(context_type.key_types)
251
+ elsif idx == 1
252
+ next ComplexType.new(context_type.subtypes)
253
+ else
254
+ next ComplexType::UNDEFINED
255
+ end
256
+ else
257
+ context_type.all_params[idx] || ComplexType::UNDEFINED
258
+ end
259
+ else
260
+ t
261
+ end
262
+ end
263
+ end
264
+
265
+ # @yieldparam t [self]
266
+ # @yieldreturn [self]
267
+ # @return [Array<self>]
268
+ def map &block
269
+ [block.yield(self)]
270
+ end
271
+
272
+ # @return [Array<UniqueType>]
273
+ def to_a
274
+ [self]
275
+ end
276
+
277
+ # @param new_name [String, nil]
278
+ # @param make_rooted [Boolean, nil]
279
+ # @param new_key_types [Array<UniqueType>, nil]
280
+ # @param rooted [Boolean, nil]
281
+ # @param new_subtypes [Array<UniqueType>, nil]
282
+ # @return [self]
283
+ def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
284
+ raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
285
+
286
+ new_name ||= name
287
+ new_key_types ||= @key_types
288
+ new_subtypes ||= @subtypes
289
+ make_rooted = @rooted if make_rooted.nil?
290
+ UniqueType.new(new_name, new_key_types, new_subtypes, rooted: make_rooted, parameters_type: parameters_type)
291
+ end
292
+
293
+ # @return [String]
294
+ def rooted_tags
295
+ rooted_tag
296
+ end
297
+
298
+ # @return [String]
299
+ def tags
300
+ tag
301
+ end
302
+
303
+ # @return [self]
304
+ def force_rooted
305
+ transform do |t|
306
+ t.recreate(make_rooted: true)
307
+ end
308
+ end
309
+
310
+ # Apply the given transformation to each subtype and then finally to this type
311
+ #
312
+ # @param new_name [String, nil]
313
+ # @yieldparam t [UniqueType]
314
+ # @yieldreturn [self]
315
+ # @return [self]
316
+ def transform(new_name = nil, &transform_type)
317
+ raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
318
+ if name == ComplexType::GENERIC_TAG_NAME
319
+ # doesn't make sense to manipulate the name of the generic
320
+ new_key_types = @key_types
321
+ new_subtypes = @subtypes
322
+ else
323
+ new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
324
+ new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
325
+ end
326
+ new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted)
327
+ yield new_type
328
+ end
329
+
330
+ # Generate a ComplexType that fully qualifies this type's namespaces.
331
+ #
332
+ # @param api_map [ApiMap] The ApiMap that performs qualification
333
+ # @param context [String] The namespace from which to resolve names
334
+ # @return [self, ComplexType, UniqueType] The generated ComplexType
335
+ def qualify api_map, context = ''
336
+ transform do |t|
337
+ next t if t.name == GENERIC_TAG_NAME
338
+ next t if t.duck_type? || t.void? || t.undefined?
339
+ recon = (t.rooted? ? '' : context)
340
+ fqns = api_map.qualify(t.name, recon)
341
+ if fqns.nil?
342
+ next UniqueType::BOOLEAN if t.tag == 'Boolean'
343
+ next UniqueType::UNDEFINED
344
+ end
345
+ t.recreate(new_name: fqns, make_rooted: true)
346
+ end
347
+ end
348
+
349
+ def selfy?
350
+ @name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
351
+ end
352
+
353
+ # @param dst [ComplexType]
354
+ # @return [self]
355
+ def self_to_type dst
356
+ object_type_dst = dst.reduce_class_type
357
+ transform do |t|
358
+ next t if t.name != 'self'
359
+ object_type_dst
360
+ end
361
+ end
362
+
363
+ def all_rooted?
364
+ return true if name == GENERIC_TAG_NAME
365
+ rooted? && all_params.all?(&:rooted?)
366
+ end
367
+
368
+ def rooted?
369
+ !can_root_name? || @rooted
370
+ end
371
+
372
+ def can_root_name?(name_to_check = name)
373
+ self.class.can_root_name?(name_to_check)
374
+ end
375
+
376
+ # @param name [String]
377
+ def self.can_root_name?(name)
378
+ # name is not lowercase
379
+ !name.empty? && name != name.downcase
380
+ end
381
+
382
+ UNDEFINED = UniqueType.new('undefined', rooted: false)
383
+ BOOLEAN = UniqueType.new('Boolean', rooted: true)
384
+ end
385
+ end
386
+ end