cosmicgraph 0.49.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 (259) hide show
  1. checksums.yaml +7 -0
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/rspec.yml +41 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +2 -0
  6. data/.yardopts +2 -0
  7. data/CHANGELOG.md +1150 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE +21 -0
  10. data/README.md +136 -0
  11. data/Rakefile +25 -0
  12. data/SPONSORS.md +15 -0
  13. data/bin/solargraph +5 -0
  14. data/cosmicgraph.gemspec +44 -0
  15. data/lib/.rubocop.yml +22 -0
  16. data/lib/solargraph/api_map/bundler_methods.rb +22 -0
  17. data/lib/solargraph/api_map/cache.rb +70 -0
  18. data/lib/solargraph/api_map/source_to_yard.rb +81 -0
  19. data/lib/solargraph/api_map/store.rb +268 -0
  20. data/lib/solargraph/api_map.rb +704 -0
  21. data/lib/solargraph/bench.rb +27 -0
  22. data/lib/solargraph/cache.rb +51 -0
  23. data/lib/solargraph/complex_type/type_methods.rb +134 -0
  24. data/lib/solargraph/complex_type/unique_type.rb +132 -0
  25. data/lib/solargraph/complex_type.rb +254 -0
  26. data/lib/solargraph/convention/base.rb +33 -0
  27. data/lib/solargraph/convention/gemfile.rb +15 -0
  28. data/lib/solargraph/convention/gemspec.rb +22 -0
  29. data/lib/solargraph/convention/rakefile.rb +17 -0
  30. data/lib/solargraph/convention/rspec.rb +30 -0
  31. data/lib/solargraph/convention.rb +49 -0
  32. data/lib/solargraph/converters/dd.rb +12 -0
  33. data/lib/solargraph/converters/dl.rb +12 -0
  34. data/lib/solargraph/converters/dt.rb +12 -0
  35. data/lib/solargraph/converters/misc.rb +1 -0
  36. data/lib/solargraph/diagnostics/base.rb +29 -0
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -0
  38. data/lib/solargraph/diagnostics/rubocop.rb +112 -0
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +65 -0
  40. data/lib/solargraph/diagnostics/severities.rb +15 -0
  41. data/lib/solargraph/diagnostics/type_check.rb +54 -0
  42. data/lib/solargraph/diagnostics/update_errors.rb +41 -0
  43. data/lib/solargraph/diagnostics.rb +55 -0
  44. data/lib/solargraph/documentor.rb +76 -0
  45. data/lib/solargraph/environ.rb +45 -0
  46. data/lib/solargraph/language_server/completion_item_kinds.rb +35 -0
  47. data/lib/solargraph/language_server/error_codes.rb +20 -0
  48. data/lib/solargraph/language_server/host/cataloger.rb +56 -0
  49. data/lib/solargraph/language_server/host/diagnoser.rb +89 -0
  50. data/lib/solargraph/language_server/host/dispatch.rb +111 -0
  51. data/lib/solargraph/language_server/host/message_worker.rb +59 -0
  52. data/lib/solargraph/language_server/host/sources.rb +156 -0
  53. data/lib/solargraph/language_server/host.rb +869 -0
  54. data/lib/solargraph/language_server/message/base.rb +89 -0
  55. data/lib/solargraph/language_server/message/cancel_request.rb +13 -0
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -0
  57. data/lib/solargraph/language_server/message/client.rb +11 -0
  58. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -0
  59. data/lib/solargraph/language_server/message/completion_item.rb +11 -0
  60. data/lib/solargraph/language_server/message/exit_notification.rb +13 -0
  61. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -0
  62. data/lib/solargraph/language_server/message/extended/document.rb +20 -0
  63. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -0
  64. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -0
  65. data/lib/solargraph/language_server/message/extended/environment.rb +25 -0
  66. data/lib/solargraph/language_server/message/extended/search.rb +20 -0
  67. data/lib/solargraph/language_server/message/extended.rb +21 -0
  68. data/lib/solargraph/language_server/message/initialize.rb +164 -0
  69. data/lib/solargraph/language_server/message/initialized.rb +27 -0
  70. data/lib/solargraph/language_server/message/method_not_found.rb +16 -0
  71. data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -0
  72. data/lib/solargraph/language_server/message/shutdown.rb +13 -0
  73. data/lib/solargraph/language_server/message/text_document/base.rb +19 -0
  74. data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -0
  75. data/lib/solargraph/language_server/message/text_document/completion.rb +59 -0
  76. data/lib/solargraph/language_server/message/text_document/definition.rb +38 -0
  77. data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -0
  78. data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -0
  79. data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -0
  80. data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -0
  81. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -0
  82. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -0
  83. data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -0
  84. data/lib/solargraph/language_server/message/text_document/formatting.rb +126 -0
  85. data/lib/solargraph/language_server/message/text_document/hover.rb +56 -0
  86. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -0
  87. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -0
  88. data/lib/solargraph/language_server/message/text_document/references.rb +16 -0
  89. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -0
  90. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -0
  91. data/lib/solargraph/language_server/message/text_document.rb +28 -0
  92. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +30 -0
  93. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -0
  94. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
  95. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -0
  96. data/lib/solargraph/language_server/message/workspace.rb +14 -0
  97. data/lib/solargraph/language_server/message.rb +93 -0
  98. data/lib/solargraph/language_server/message_types.rb +14 -0
  99. data/lib/solargraph/language_server/request.rb +24 -0
  100. data/lib/solargraph/language_server/symbol_kinds.rb +36 -0
  101. data/lib/solargraph/language_server/transport/adapter.rb +53 -0
  102. data/lib/solargraph/language_server/transport/data_reader.rb +72 -0
  103. data/lib/solargraph/language_server/transport.rb +13 -0
  104. data/lib/solargraph/language_server/uri_helpers.rb +49 -0
  105. data/lib/solargraph/language_server.rb +19 -0
  106. data/lib/solargraph/library.rb +547 -0
  107. data/lib/solargraph/location.rb +37 -0
  108. data/lib/solargraph/logging.rb +27 -0
  109. data/lib/solargraph/page.rb +83 -0
  110. data/lib/solargraph/parser/comment_ripper.rb +52 -0
  111. data/lib/solargraph/parser/legacy/class_methods.rb +135 -0
  112. data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -0
  113. data/lib/solargraph/parser/legacy/node_chainer.rb +148 -0
  114. data/lib/solargraph/parser/legacy/node_methods.rb +325 -0
  115. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -0
  116. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -0
  117. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -0
  118. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +42 -0
  119. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +35 -0
  120. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -0
  121. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -0
  122. data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -0
  123. data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -0
  124. data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -0
  125. data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -0
  126. data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -0
  127. data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -0
  128. data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -0
  129. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +42 -0
  130. data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -0
  131. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -0
  132. data/lib/solargraph/parser/legacy/node_processors.rb +54 -0
  133. data/lib/solargraph/parser/legacy.rb +12 -0
  134. data/lib/solargraph/parser/node_methods.rb +43 -0
  135. data/lib/solargraph/parser/node_processor/base.rb +77 -0
  136. data/lib/solargraph/parser/node_processor.rb +43 -0
  137. data/lib/solargraph/parser/region.rb +66 -0
  138. data/lib/solargraph/parser/rubyvm/class_methods.rb +149 -0
  139. data/lib/solargraph/parser/rubyvm/node_chainer.rb +160 -0
  140. data/lib/solargraph/parser/rubyvm/node_methods.rb +315 -0
  141. data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -0
  142. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +85 -0
  143. data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -0
  144. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +42 -0
  145. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +33 -0
  146. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -0
  147. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +75 -0
  148. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +68 -0
  149. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -0
  150. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -0
  151. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -0
  152. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -0
  153. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -0
  154. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -0
  155. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -0
  156. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -0
  157. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -0
  158. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +32 -0
  159. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -0
  160. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +279 -0
  161. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -0
  162. data/lib/solargraph/parser/rubyvm/node_processors.rb +63 -0
  163. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  164. data/lib/solargraph/parser/rubyvm.rb +40 -0
  165. data/lib/solargraph/parser/snippet.rb +13 -0
  166. data/lib/solargraph/parser.rb +26 -0
  167. data/lib/solargraph/pin/base.rb +299 -0
  168. data/lib/solargraph/pin/base_variable.rb +84 -0
  169. data/lib/solargraph/pin/block.rb +73 -0
  170. data/lib/solargraph/pin/class_variable.rb +8 -0
  171. data/lib/solargraph/pin/closure.rb +37 -0
  172. data/lib/solargraph/pin/common.rb +70 -0
  173. data/lib/solargraph/pin/constant.rb +43 -0
  174. data/lib/solargraph/pin/conversions.rb +92 -0
  175. data/lib/solargraph/pin/documenting.rb +105 -0
  176. data/lib/solargraph/pin/duck_method.rb +16 -0
  177. data/lib/solargraph/pin/global_variable.rb +8 -0
  178. data/lib/solargraph/pin/instance_variable.rb +30 -0
  179. data/lib/solargraph/pin/keyword.rb +15 -0
  180. data/lib/solargraph/pin/keyword_param.rb +8 -0
  181. data/lib/solargraph/pin/local_variable.rb +55 -0
  182. data/lib/solargraph/pin/method.rb +335 -0
  183. data/lib/solargraph/pin/method_alias.rb +31 -0
  184. data/lib/solargraph/pin/namespace.rb +94 -0
  185. data/lib/solargraph/pin/parameter.rb +206 -0
  186. data/lib/solargraph/pin/proxy_type.rb +29 -0
  187. data/lib/solargraph/pin/reference/extend.rb +10 -0
  188. data/lib/solargraph/pin/reference/include.rb +10 -0
  189. data/lib/solargraph/pin/reference/override.rb +29 -0
  190. data/lib/solargraph/pin/reference/prepend.rb +10 -0
  191. data/lib/solargraph/pin/reference/require.rb +14 -0
  192. data/lib/solargraph/pin/reference/superclass.rb +10 -0
  193. data/lib/solargraph/pin/reference.rb +14 -0
  194. data/lib/solargraph/pin/search.rb +56 -0
  195. data/lib/solargraph/pin/signature.rb +23 -0
  196. data/lib/solargraph/pin/singleton.rb +11 -0
  197. data/lib/solargraph/pin/symbol.rb +47 -0
  198. data/lib/solargraph/pin.rb +38 -0
  199. data/lib/solargraph/position.rb +100 -0
  200. data/lib/solargraph/range.rb +95 -0
  201. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  202. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  203. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  204. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  205. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  206. data/lib/solargraph/rbs_map.rb +73 -0
  207. data/lib/solargraph/server_methods.rb +16 -0
  208. data/lib/solargraph/shell.rb +234 -0
  209. data/lib/solargraph/source/chain/block_variable.rb +13 -0
  210. data/lib/solargraph/source/chain/call.rb +215 -0
  211. data/lib/solargraph/source/chain/class_variable.rb +13 -0
  212. data/lib/solargraph/source/chain/constant.rb +75 -0
  213. data/lib/solargraph/source/chain/global_variable.rb +13 -0
  214. data/lib/solargraph/source/chain/hash.rb +28 -0
  215. data/lib/solargraph/source/chain/head.rb +19 -0
  216. data/lib/solargraph/source/chain/instance_variable.rb +13 -0
  217. data/lib/solargraph/source/chain/link.rb +71 -0
  218. data/lib/solargraph/source/chain/literal.rb +23 -0
  219. data/lib/solargraph/source/chain/or.rb +23 -0
  220. data/lib/solargraph/source/chain/q_call.rb +11 -0
  221. data/lib/solargraph/source/chain/variable.rb +13 -0
  222. data/lib/solargraph/source/chain/z_super.rb +30 -0
  223. data/lib/solargraph/source/chain.rb +179 -0
  224. data/lib/solargraph/source/change.rb +79 -0
  225. data/lib/solargraph/source/cursor.rb +164 -0
  226. data/lib/solargraph/source/encoding_fixes.rb +23 -0
  227. data/lib/solargraph/source/source_chainer.rb +191 -0
  228. data/lib/solargraph/source/updater.rb +54 -0
  229. data/lib/solargraph/source.rb +522 -0
  230. data/lib/solargraph/source_map/clip.rb +229 -0
  231. data/lib/solargraph/source_map/completion.rb +23 -0
  232. data/lib/solargraph/source_map/mapper.rb +241 -0
  233. data/lib/solargraph/source_map.rb +180 -0
  234. data/lib/solargraph/type_checker/checks.rb +112 -0
  235. data/lib/solargraph/type_checker/param_def.rb +35 -0
  236. data/lib/solargraph/type_checker/problem.rb +32 -0
  237. data/lib/solargraph/type_checker/rules.rb +57 -0
  238. data/lib/solargraph/type_checker.rb +549 -0
  239. data/lib/solargraph/version.rb +5 -0
  240. data/lib/solargraph/views/_method.erb +62 -0
  241. data/lib/solargraph/views/_name_type_tag.erb +10 -0
  242. data/lib/solargraph/views/_namespace.erb +24 -0
  243. data/lib/solargraph/views/document.erb +23 -0
  244. data/lib/solargraph/views/environment.erb +58 -0
  245. data/lib/solargraph/views/layout.erb +44 -0
  246. data/lib/solargraph/views/search.erb +11 -0
  247. data/lib/solargraph/workspace/config.rb +231 -0
  248. data/lib/solargraph/workspace.rb +212 -0
  249. data/lib/solargraph/yard_map/cache.rb +19 -0
  250. data/lib/solargraph/yard_map/helpers.rb +16 -0
  251. data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -0
  252. data/lib/solargraph/yard_map/mapper/to_method.rb +81 -0
  253. data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -0
  254. data/lib/solargraph/yard_map/mapper.rb +77 -0
  255. data/lib/solargraph/yard_map/to_method.rb +79 -0
  256. data/lib/solargraph/yard_map.rb +301 -0
  257. data/lib/solargraph.rb +69 -0
  258. data/lib/yard-solargraph.rb +33 -0
  259. metadata +587 -0
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rbs'
4
+ require 'set'
5
+
6
+ module Solargraph
7
+ class RbsMap
8
+ autoload :Conversions, 'solargraph/rbs_map/conversions'
9
+ autoload :CoreMap, 'solargraph/rbs_map/core_map'
10
+ autoload :CoreFills, 'solargraph/rbs_map/core_fills'
11
+ autoload :CoreSigns, 'solargraph/rbs_map/core_signs'
12
+ autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
13
+
14
+ include Conversions
15
+
16
+ # @type [Hash{String => RbsMap}]
17
+ @@rbs_maps_hash = {}
18
+
19
+ attr_reader :library
20
+
21
+ # @param library [String]
22
+ def initialize library
23
+ @library = library
24
+ loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
25
+ add_library loader, library
26
+ return unless resolved?
27
+ environment = RBS::Environment.from_loader(loader).resolve_type_names
28
+ environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
29
+ end
30
+
31
+ def path_pin path
32
+ pins.find { |p| p.path == path }
33
+ end
34
+
35
+ def path_pins path
36
+ pins.select { |p| p.path == path }
37
+ end
38
+
39
+ def resolved?
40
+ @resolved
41
+ end
42
+
43
+ # @param library [String]
44
+ # @return [RbsMap]
45
+ def self.load library
46
+ @@rbs_maps_hash[library] ||= RbsMap.new(library)
47
+ end
48
+
49
+ def repository
50
+ @repository ||= RBS::Repository.new(no_stdlib: true)
51
+ end
52
+
53
+ private
54
+
55
+ # @param loader [RBS::EnvironmentLoader]
56
+ # @param library [String]
57
+ # @return [Boolean] true if adding the library succeeded
58
+ def add_library loader, library
59
+ @resolved = if loader.has_library?(library: library, version: nil)
60
+ loader.add library: library
61
+ Solargraph.logger.info "#{short_name} successfully loaded library #{library}"
62
+ true
63
+ else
64
+ Solargraph.logger.info "#{short_name} failed to load library #{library}"
65
+ false
66
+ end
67
+ end
68
+
69
+ def short_name
70
+ self.class.name.split('::').last
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+
5
+ module Solargraph
6
+ module ServerMethods
7
+ # @return [Integer]
8
+ def available_port
9
+ socket = Socket.new(:INET, :STREAM, 0)
10
+ socket.bind(Addrinfo.tcp("127.0.0.1", 0))
11
+ port = socket.local_address.ip_port
12
+ socket.close
13
+ port
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Solargraph
6
+ class Shell < Thor
7
+ include Solargraph::ServerMethods
8
+
9
+ map %w[--version -v] => :version
10
+
11
+ desc "--version, -v", "Print the version"
12
+ def version
13
+ puts Solargraph::VERSION
14
+ end
15
+
16
+ desc 'socket', 'Run a Solargraph socket server'
17
+ option :host, type: :string, aliases: :h, desc: 'The server host', default: '127.0.0.1'
18
+ option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7658
19
+ def socket
20
+ require 'backport'
21
+ port = options[:port]
22
+ port = available_port if port.zero?
23
+ Backport.run do
24
+ Signal.trap("INT") do
25
+ Backport.stop
26
+ end
27
+ Signal.trap("TERM") do
28
+ Backport.stop
29
+ end
30
+ Backport.prepare_tcp_server host: options[:host], port: port, adapter: Solargraph::LanguageServer::Transport::Adapter
31
+ STDERR.puts "Solargraph is listening PORT=#{port} PID=#{Process.pid}"
32
+ end
33
+ end
34
+
35
+ desc 'stdio', 'Run a Solargraph stdio server'
36
+ def stdio
37
+ require 'backport'
38
+ Backport.run do
39
+ Signal.trap("INT") do
40
+ Backport.stop
41
+ end
42
+ Signal.trap("TERM") do
43
+ Backport.stop
44
+ end
45
+ Backport.prepare_stdio_server adapter: Solargraph::LanguageServer::Transport::Adapter
46
+ STDERR.puts "Solargraph is listening on stdio PID=#{Process.pid}"
47
+ end
48
+ end
49
+
50
+ desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
51
+ option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
52
+ def config(directory = '.')
53
+ matches = []
54
+ if options[:extensions]
55
+ Gem::Specification.each do |g|
56
+ if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/)
57
+ require g.name
58
+ matches.push g.name
59
+ end
60
+ end
61
+ end
62
+ conf = Solargraph::Workspace::Config.new.raw_data
63
+ unless matches.empty?
64
+ matches.each do |m|
65
+ conf['extensions'].push m
66
+ end
67
+ end
68
+ File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
69
+ file.puts conf.to_yaml
70
+ end
71
+ STDOUT.puts "Configuration file initialized."
72
+ end
73
+
74
+ desc 'download-core [VERSION]', 'Download core documentation [deprecated]'
75
+ long_desc %(
76
+ The `download-core` command is deprecated. Current versions of Solargraph
77
+ use RBS for core and stdlib documentation.
78
+ )
79
+ # @deprecated
80
+ def download_core _version = nil
81
+ puts 'The `download-core` command is deprecated.'
82
+ puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
83
+ end
84
+
85
+ desc 'list-cores', 'List the local documentation versions [deprecated]'
86
+ long_desc %(
87
+ The `list-cores` command is deprecated. Current versions of Solargraph use
88
+ RBS for core and stdlib documentation.
89
+ )
90
+ # @deprecated
91
+ def list_cores
92
+ puts 'The `list-cores` command is deprecated.'
93
+ puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
94
+ end
95
+
96
+ desc 'available-cores', 'List available documentation versions [deprecated]'
97
+ long_desc %(
98
+ The `available-cores` command is deprecated. Current versions of Solargraph
99
+ use RBS for core and stdlib documentation.
100
+ )
101
+ # @deprecated
102
+ def available_cores
103
+ puts 'The `available-cores` command is deprecated.'
104
+ puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
105
+ end
106
+
107
+ desc 'clear', 'Delete all cached documentation'
108
+ long_desc %(
109
+ This command will delete all core and gem documentation from the cache.
110
+ )
111
+ # @deprecated
112
+ def clear
113
+ puts "Deleting the cached documentation"
114
+ Solargraph::Cache.clear
115
+ end
116
+ map 'clear-cache' => :clear
117
+ map 'clear-cores' => :clear
118
+
119
+ desc 'uncache GEM [...GEM]', "Delete cached gem documentation"
120
+ def uncache *gems
121
+ raise ArgumentError, 'No gems specified.' if gems.empty?
122
+ gems.each do |gem|
123
+ Dir[File.join(Solargraph::YardMap::CoreDocs.cache_dir, 'gems', "#{gem}-*")].each do |dir|
124
+ puts "Deleting cache: #{dir}"
125
+ FileUtils.remove_entry_secure dir
126
+ end
127
+ end
128
+ end
129
+
130
+ desc 'reporters', 'Get a list of diagnostics reporters'
131
+ def reporters
132
+ puts Solargraph::Diagnostics.reporters
133
+ end
134
+
135
+ desc 'typecheck [FILE(s)]', 'Run the type checker'
136
+ long_desc %(
137
+ Perform type checking on one or more files in a workspace. Check the
138
+ entire workspace if no files are specified.
139
+
140
+ Type checking levels are normal, typed, strict, and strong.
141
+ )
142
+ option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
143
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
144
+ def typecheck *files
145
+ directory = File.realpath(options[:directory])
146
+ api_map = Solargraph::ApiMap.load(directory)
147
+ if files.empty?
148
+ files = api_map.source_maps.map(&:filename)
149
+ else
150
+ files.map! { |file| File.realpath(file) }
151
+ end
152
+ probcount = 0
153
+ filecount = 0
154
+ files.each do |file|
155
+ checker = TypeChecker.new(file, api_map: api_map, level: options[:level].to_sym)
156
+ problems = checker.problems
157
+ next if problems.empty?
158
+ problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
159
+ puts problems.map { |prob| "#{prob.location.filename}:#{prob.location.range.start.line + 1} - #{prob.message}" }.join("\n")
160
+ filecount += 1
161
+ probcount += problems.length
162
+ end
163
+ puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
164
+ exit 1 if probcount > 0
165
+ end
166
+
167
+ desc 'scan', 'Test the workspace for problems'
168
+ long_desc %(
169
+ A scan loads the entire workspace to make sure that the ASTs and
170
+ maps do not raise errors during analysis. It does not perform any type
171
+ checking or validation; it only confirms that the analysis itself is
172
+ error-free.
173
+ )
174
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
175
+ option :verbose, type: :boolean, aliases: :v, desc: 'Verbose output', default: false
176
+ def scan
177
+ require 'benchmark'
178
+ directory = File.realpath(options[:directory])
179
+ api_map = nil
180
+ time = Benchmark.measure {
181
+ api_map = Solargraph::ApiMap.load(directory)
182
+ api_map.pins.each do |pin|
183
+ begin
184
+ puts pin_description(pin) if options[:verbose]
185
+ pin.typify api_map
186
+ pin.probe api_map
187
+ rescue StandardError => e
188
+ STDERR.puts "Error testing #{pin_description(pin)} #{pin.location ? "at #{pin.location.filename}:#{pin.location.range.start.line + 1}" : ''}"
189
+ STDERR.puts "[#{e.class}]: #{e.message}"
190
+ STDERR.puts e.backtrace.join("\n")
191
+ exit 1
192
+ end
193
+ end
194
+ }
195
+ puts "Scanned #{directory} (#{api_map.pins.length} pins) in #{time.real} seconds."
196
+ end
197
+
198
+ desc 'bundle', 'Generate documentation for bundled gems [deprecated]'
199
+ long_desc %(
200
+ The `bundle` command is deprecated. Solargraph currently uses RBS instead.
201
+ )
202
+ option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
203
+ option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
204
+ def bundle
205
+ puts 'The `bundle` command is deprecated. Solargraph currently uses RBS instead.'
206
+ end
207
+
208
+ desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation [deprecated]'
209
+ long_desc %(
210
+ The `rdoc` command is deprecated. Solargraph currently uses RBS instead.
211
+ )
212
+ def rdoc _gem, _version = '>= 0'
213
+ puts 'The `rdoc` command is deprecated. Solargraph currently uses RBS instead.'
214
+ end
215
+
216
+ private
217
+
218
+ # @param pin [Solargraph::Pin::Base]
219
+ # @return [String]
220
+ def pin_description pin
221
+ desc = if pin.path.nil? || pin.path.empty?
222
+ if pin.closure
223
+ "#{pin.closure.path} | #{pin.name}"
224
+ else
225
+ "#{pin.context.namespace} | #{pin.name}"
226
+ end
227
+ else
228
+ pin.path
229
+ end
230
+ desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
231
+ desc
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class BlockVariable < Link
7
+ def resolve api_map, name_pin, locals
8
+ [Pin::ProxyType.anonymous(ComplexType.try_parse('Proc'))]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Call < Link
7
+ # @return [String]
8
+ attr_reader :word
9
+
10
+ # @return [Array<Chain>]
11
+ attr_reader :arguments
12
+
13
+ # @param word [String]
14
+ # @param arguments [Array<Chain>]
15
+ # @param with_block [Boolean] True if the chain is inside a block
16
+ # @param head [Boolean] True if the call is the start of its chain
17
+ def initialize word, arguments = [], with_block = false
18
+ @word = word
19
+ @arguments = arguments
20
+ @with_block = with_block
21
+ end
22
+
23
+ def with_block?
24
+ @with_block
25
+ end
26
+
27
+ # @param api_map [ApiMap]
28
+ # @param name_pin [Pin::Base]
29
+ # @param locals [Array<Pin::Base>]
30
+ def resolve api_map, name_pin, locals
31
+ return super_pins(api_map, name_pin) if word == 'super'
32
+ found = if head?
33
+ locals.select { |p| p.name == word }
34
+ else
35
+ []
36
+ end
37
+ return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
38
+ # @param [ComplexType::UniqueType]
39
+ pins = name_pin.binder.each_unique_type.flat_map do |context|
40
+ api_map.get_method_stack(context.namespace, word, scope: context.scope)
41
+ end
42
+ return [] if pins.empty?
43
+ inferred_pins(pins, api_map, name_pin.context, locals)
44
+ end
45
+
46
+ private
47
+
48
+ # @param pins [Array<Pin::Base>]
49
+ # @param api_map [ApiMap]
50
+ # @param context [ComplexType]
51
+ # @param locals [Pin::LocalVariable]
52
+ # @return [Array<Pin::Base>]
53
+ def inferred_pins pins, api_map, context, locals
54
+ result = pins.map do |p|
55
+ next p unless p.is_a?(Pin::Method)
56
+ overloads = p.signatures
57
+ # next p if overloads.empty?
58
+ type = ComplexType::UNDEFINED
59
+ overloads.each do |ol|
60
+ next unless arguments_match(arguments, ol)
61
+ # next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
62
+ match = true
63
+ arguments.each_with_index do |arg, idx|
64
+ param = ol.parameters[idx]
65
+ if param.nil?
66
+ match = false unless ol.parameters.any?(&:restarg?)
67
+ break
68
+ end
69
+ atype = arg.infer(api_map, Pin::ProxyType.anonymous(context), locals)
70
+ # @todo Weak type comparison
71
+ # unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
72
+ unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name)
73
+ match = false
74
+ break
75
+ end
76
+ end
77
+ if match
78
+ type = extra_return_type(p.docstring, context)
79
+ break if type
80
+ type = with_params(ol.return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if ol.return_type.defined?
81
+ type ||= ComplexType::UNDEFINED
82
+ end
83
+ break if type.defined?
84
+ end
85
+ next p.proxy(type) if type.defined?
86
+ type = extra_return_type(p.docstring, context)
87
+ if type
88
+ next Solargraph::Pin::Method.new(
89
+ location: p.location,
90
+ closure: p.closure,
91
+ name: p.name,
92
+ comments: "@return [#{context.subtypes.first.to_s}]",
93
+ scope: p.scope,
94
+ visibility: p.visibility,
95
+ parameters: p.parameters,
96
+ node: p.node
97
+ )
98
+ end
99
+ if p.is_a?(Pin::Method) && !p.macros.empty?
100
+ result = process_macro(p, api_map, context, locals)
101
+ next result unless result.return_type.undefined?
102
+ elsif !p.directives.empty?
103
+ result = process_directive(p, api_map, context, locals)
104
+ next result unless result.return_type.undefined?
105
+ end
106
+ p
107
+ end
108
+ result.map do |pin|
109
+ if pin.path == 'Class#new' && context.tag != 'Class'
110
+ pin.proxy(ComplexType.try_parse(context.namespace))
111
+ else
112
+ next pin if pin.return_type.undefined?
113
+ selfy = pin.return_type.self_to(context.tag)
114
+ selfy == pin.return_type ? pin : pin.proxy(selfy)
115
+ end
116
+ end
117
+ end
118
+
119
+ # @param pin [Pin::Method]
120
+ # @param api_map [ApiMap]
121
+ # @param context [ComplexType]
122
+ # @param locals [Pin::Base]
123
+ # @return [Pin::Base]
124
+ def process_macro pin, api_map, context, locals
125
+ pin.macros.each do |macro|
126
+ result = inner_process_macro(pin, macro, api_map, context, locals)
127
+ return result unless result.return_type.undefined?
128
+ end
129
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
130
+ end
131
+
132
+ # @param pin [Pin::Method]
133
+ # @param api_map [ApiMap]
134
+ # @param context [ComplexType]
135
+ # @param locals [Pin::Base]
136
+ # @return [Pin::ProxyType]
137
+ def process_directive pin, api_map, context, locals
138
+ pin.directives.each do |dir|
139
+ macro = api_map.named_macro(dir.tag.name)
140
+ next if macro.nil?
141
+ result = inner_process_macro(pin, macro, api_map, context, locals)
142
+ return result unless result.return_type.undefined?
143
+ end
144
+ Pin::ProxyType.anonymous ComplexType::UNDEFINED
145
+ end
146
+
147
+ # @param pin [Pin]
148
+ # @param macro [YARD::Tags::MacroDirective]
149
+ # @param api_map [ApiMap]
150
+ # @param context [ComplexType]
151
+ # @param locals [Array<Pin::Base>]
152
+ # @return [Pin::ProxyType]
153
+ def inner_process_macro pin, macro, api_map, context, locals
154
+ vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
155
+ txt = macro.tag.text.clone
156
+ if txt.empty? && macro.tag.name
157
+ named = api_map.named_macro(macro.tag.name)
158
+ txt = named.tag.text.clone if named
159
+ end
160
+ i = 1
161
+ vals.each do |v|
162
+ txt.gsub!(/\$#{i}/, v.context.namespace)
163
+ i += 1
164
+ end
165
+ docstring = Solargraph::Source.parse_docstring(txt).to_docstring
166
+ tag = docstring.tag(:return)
167
+ unless tag.nil? || tag.types.nil?
168
+ return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
169
+ end
170
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
171
+ end
172
+
173
+ # @param docstring [YARD::Docstring]
174
+ # @param context [ComplexType]
175
+ # @return [ComplexType]
176
+ def extra_return_type docstring, context
177
+ if docstring.has_tag?(:return_single_parameter) #&& context.subtypes.one?
178
+ return context.subtypes.first || ComplexType::UNDEFINED
179
+ elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
180
+ return context.value_types.first
181
+ end
182
+ nil
183
+ end
184
+
185
+ # @param arguments [Array<Chain>]
186
+ # @param signature [Pin::Signature]
187
+ # @return [Boolean]
188
+ def arguments_match arguments, signature
189
+ parameters = signature.parameters
190
+ argcount = arguments.length
191
+ parcount = parameters.length
192
+ parcount -= 1 if !parameters.empty? && parameters.last.block?
193
+ return false if signature.block? && !with_block?
194
+ return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
195
+ true
196
+ end
197
+
198
+ # @param api_map [ApiMap]
199
+ # @param name_pin [Pin::Base]
200
+ # @return [Array<Pin::Base>]
201
+ def super_pins api_map, name_pin
202
+ pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
203
+ pins.reject{|p| p.path == name_pin.path}
204
+ end
205
+
206
+ # @param type [ComplexType]
207
+ # @param context [ComplexType]
208
+ def with_params type, context
209
+ return type unless type.to_s.include?('$')
210
+ ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:tag).join(', ')).gsub('<>', ''))
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class ClassVariable < Link
7
+ def resolve api_map, name_pin, locals
8
+ api_map.get_class_variable_pins(name_pin.context.namespace).select{|p| p.name == word}
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Constant < Link
7
+ def initialize word
8
+ @word = word
9
+ end
10
+
11
+ def resolve api_map, name_pin, locals
12
+ return [Pin::ROOT_PIN] if word.empty?
13
+ if word.start_with?('::')
14
+ base = word[2..-1]
15
+ gates = ['']
16
+ else
17
+ base = word
18
+ gates = crawl_gates(name_pin)
19
+ end
20
+ parts = base.split('::')
21
+ gates.each do |gate|
22
+ type = deep_constant_type(gate, api_map)
23
+ # Use deep inference to resolve root
24
+ parts[0..-2].each do |sym|
25
+ pins = api_map.get_constants('', type.namespace).select{ |pin| pin.name == sym }
26
+ type = first_pin_type(pins, api_map)
27
+ break if type.undefined?
28
+ end
29
+ next if type.undefined?
30
+ result = api_map.get_constants('', type.namespace).select { |pin| pin.name == parts.last }
31
+ return result unless result.empty?
32
+ end
33
+ []
34
+ end
35
+
36
+ private
37
+
38
+ def crawl_gates pin
39
+ clos = pin
40
+ until clos.nil?
41
+ if clos.is_a?(Pin::Namespace)
42
+ gates = clos.gates
43
+ gates.push('') if gates.empty?
44
+ return gates
45
+ end
46
+ clos = clos.closure
47
+ end
48
+ ['']
49
+ end
50
+
51
+ def first_pin_type(pins, api_map)
52
+ type = ComplexType::UNDEFINED
53
+ pins.each do |pin|
54
+ type = pin.typify(api_map)
55
+ break if type.defined?
56
+ type = pin.probe(api_map)
57
+ break if type.defined?
58
+ end
59
+ type
60
+ end
61
+
62
+ def deep_constant_type(gate, api_map)
63
+ type = ComplexType::ROOT
64
+ return type if gate == ''
65
+ gate.split('::').each do |word|
66
+ pins = api_map.get_constants('', type.namespace).select { |pin| pin.name == word }
67
+ type = first_pin_type(pins, api_map)
68
+ break if type.undefined?
69
+ end
70
+ type
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class GlobalVariable < Link
7
+ def resolve api_map, name_pin, locals
8
+ api_map.get_global_variable_pins.select{|p| p.name == word}
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class Hash < Literal
7
+ # @param type [String]
8
+ # @param splatted [Boolean]
9
+ def initialize type, splatted = false
10
+ super(type)
11
+ @splatted = splatted
12
+ end
13
+
14
+ def word
15
+ @word ||= "<#{@type}>"
16
+ end
17
+
18
+ def resolve api_map, name_pin, locals
19
+ [Pin::ProxyType.anonymous(@complex_type)]
20
+ end
21
+
22
+ def splatted?
23
+ @splatted
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end