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,58 @@
1
+ <html>
2
+ <head>
3
+ <title>Solargraph Environment</title>
4
+ </head>
5
+ <h1>
6
+ Solargraph Environment Info
7
+ </h1>
8
+ <h2>
9
+ System
10
+ </h2>
11
+ <ul>
12
+ <li>
13
+ Platform: <%= RUBY_PLATFORM %>
14
+ </li>
15
+ <li>
16
+ Shell: <%= ENV['SHELL'] %>
17
+ </li>
18
+ <li>
19
+ Ruby Version: <%= RUBY_VERSION %>
20
+ </li>
21
+ <li>
22
+ RuboCop Version: <%= RuboCop::Version::STRING %>
23
+ </li>
24
+ </ul>
25
+ <h2>
26
+ Solargraph
27
+ </h2>
28
+ <ul>
29
+ <li>
30
+ Solargraph Version: <%= Solargraph::VERSION %>
31
+ </li>
32
+ <li>
33
+ Core Documentation Version: N/A <%# @todo Fix %>
34
+ </li>
35
+ <li>
36
+ Core Cache Directory: N/A <%# @todo Fix %>
37
+ </li>
38
+ <% unless Solargraph::Parser.rubyvm? %>
39
+ <li>
40
+ Parser Target Version: <%= Solargraph::Parser.version %>
41
+ </li>
42
+ <% end %>
43
+ <li>
44
+ Using Bundler: <%= ENV.key?('BUNDLE_BIN_PATH') %>
45
+ </li>
46
+ </ul>
47
+ <h2>
48
+ Project
49
+ </h2>
50
+ <ul>
51
+ <li>
52
+ Config: <%= config %>
53
+ </li>
54
+ <li>
55
+ Workspace folders: <%= folders %>
56
+ </li>
57
+ </ul>
58
+ </html>
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Solargraph</title>
5
+ <style>
6
+ a {
7
+ color: inherit;
8
+ text-decoration: underline;
9
+ }
10
+ h2 {
11
+ font-size: 110%;
12
+ margin: 1.5em 0 1em 0;
13
+ }
14
+ big {
15
+ font-size: 110%;
16
+ }
17
+ pre {
18
+ margin: 1em;
19
+ padding: 0.5em;
20
+ overflow: auto;
21
+ border: 1px solid gray;
22
+ }
23
+ ul.doc-list {
24
+ margin: 1em 0 1em 0.5em;
25
+ padding: 0;
26
+ }
27
+ ul.doc-list li {
28
+ list-style: none;
29
+ margin: 0.25em 0 0.25em 0;
30
+ padding: 0;
31
+ }
32
+ h1 small {
33
+ font-size: 75%;
34
+ font-weight: normal;
35
+ }
36
+ .document-section {
37
+ margin: 1.5em 0 1em 0;
38
+ }
39
+ </style>
40
+ </head>
41
+ <body>
42
+ <%= yield %>
43
+ </body>
44
+ </html>
@@ -0,0 +1,11 @@
1
+ <h1>Search Results for <kbd><%= query %></kbd></h1>
2
+
3
+ <% unless results.empty? %>
4
+ <ul class="doc-list">
5
+ <% results.each do |result| %>
6
+ <li>
7
+ <a href="solargraph:/document?query=<%= CGI.escape(result) %>"><%= result %></a>
8
+ </li>
9
+ <% end %>
10
+ </ul>
11
+ <% end %>
@@ -0,0 +1,231 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module Solargraph
6
+ class Workspace
7
+ # Configuration data for a workspace.
8
+ #
9
+ class Config
10
+ # The maximum number of files that can be added to a workspace.
11
+ # The workspace's .solargraph.yml can override this value.
12
+ MAX_FILES = 5000
13
+
14
+ # @return [String]
15
+ attr_reader :directory
16
+
17
+ # @return [Hash]
18
+ attr_reader :raw_data
19
+
20
+ # @param directory [String]
21
+ def initialize directory = ''
22
+ @directory = directory
23
+ @raw_data = config_data
24
+ included
25
+ excluded
26
+ end
27
+
28
+ # An array of files included in the workspace (before calculating excluded files).
29
+ #
30
+ # @return [Array<String>]
31
+ def included
32
+ return [] if directory.empty? || directory == '*'
33
+ @included ||= process_globs(@raw_data['include'])
34
+ end
35
+
36
+ # An array of files excluded from the workspace.
37
+ #
38
+ # @return [Array<String>]
39
+ def excluded
40
+ return [] if directory.empty? || directory == '*'
41
+ @excluded ||= process_exclusions(@raw_data['exclude'])
42
+ end
43
+
44
+ def allow? filename
45
+ filename.start_with?(directory) &&
46
+ !excluded.include?(filename) &&
47
+ excluded_directories.none? { |d| filename.start_with?(d) }
48
+ end
49
+
50
+ # The calculated array of (included - excluded) files in the workspace.
51
+ #
52
+ # @return [Array<String>]
53
+ def calculated
54
+ Solargraph.logger.info "Indexing workspace files in #{directory}" unless @calculated || directory.empty? || directory == '*'
55
+ @calculated ||= included - excluded
56
+ end
57
+
58
+ # An array of domains configured for the workspace.
59
+ # A domain is a namespace that the ApiMap should include in the global
60
+ # namespace. It's typically used to identify available DSLs.
61
+ #
62
+ # @return [Array<String>]
63
+ def domains
64
+ raw_data['domains']
65
+ end
66
+
67
+ # An array of required paths to add to the workspace.
68
+ #
69
+ # @return [Array<String>]
70
+ def required
71
+ raw_data['require']
72
+ end
73
+
74
+ # An array of load paths for required paths.
75
+ #
76
+ # @return [Array<String>]
77
+ def require_paths
78
+ raw_data['require_paths'] || []
79
+ end
80
+
81
+ # An array of reporters to use for diagnostics.
82
+ #
83
+ # @return [Array<String>]
84
+ def reporters
85
+ raw_data['reporters']
86
+ end
87
+
88
+ # A hash of options supported by the formatter
89
+ #
90
+ # @return [Hash]
91
+ def formatter
92
+ raw_data['formatter']
93
+ end
94
+
95
+ # An array of plugins to require.
96
+ #
97
+ # @return [Array<String>]
98
+ def plugins
99
+ raw_data['plugins']
100
+ end
101
+
102
+ # The maximum number of files to parse from the workspace.
103
+ #
104
+ # @return [Integer]
105
+ def max_files
106
+ raw_data['max_files']
107
+ end
108
+
109
+ private
110
+
111
+ # @return [String]
112
+ def global_config_path
113
+ ENV['SOLARGRAPH_GLOBAL_CONFIG'] ||
114
+ File.join(Dir.home, '.config', 'solargraph', 'config.yml')
115
+ end
116
+
117
+ # @return [String]
118
+ def workspace_config_path
119
+ return '' if @directory.empty?
120
+ File.join(@directory, '.solargraph.yml')
121
+ end
122
+
123
+ # @return [Hash]
124
+ def config_data
125
+ workspace_config = read_config(workspace_config_path)
126
+ global_config = read_config(global_config_path)
127
+
128
+ defaults = default_config
129
+ defaults.merge({'exclude' => []}) unless workspace_config.nil?
130
+
131
+ defaults
132
+ .merge(global_config || {})
133
+ .merge(workspace_config || {})
134
+ end
135
+
136
+ # Read a .solargraph yaml config
137
+ #
138
+ # @param directory [String]
139
+ # @return [Hash, nil]
140
+ def read_config config_path = ''
141
+ return nil if config_path.empty?
142
+ return nil unless File.file?(config_path)
143
+ YAML.safe_load(File.read(config_path))
144
+ end
145
+
146
+ # @return [Hash]
147
+ def default_config
148
+ {
149
+ 'include' => ['**/*.rb'],
150
+ 'exclude' => ['spec/**/*', 'test/**/*', 'vendor/**/*', '.bundle/**/*'],
151
+ 'require' => [],
152
+ 'domains' => [],
153
+ 'reporters' => %w[rubocop require_not_found],
154
+ 'formatter' => {
155
+ 'rubocop' => {
156
+ 'cops' => 'safe',
157
+ 'except' => [],
158
+ 'only' => [],
159
+ 'extra_args' =>[]
160
+ }
161
+ },
162
+ 'require_paths' => [],
163
+ 'plugins' => [],
164
+ 'max_files' => MAX_FILES
165
+ }
166
+ end
167
+
168
+ # Get an array of files from the provided globs.
169
+ #
170
+ # @param globs [Array<String>]
171
+ # @return [Array<String>]
172
+ def process_globs globs
173
+ result = globs.flat_map do |glob|
174
+ Dir[File.join directory, glob]
175
+ .map{ |f| f.gsub(/\\/, '/') }
176
+ .select { |f| File.file?(f) }
177
+ end
178
+ result
179
+ end
180
+
181
+ # Modify the included files based on excluded directories and get an
182
+ # array of additional files to exclude.
183
+ #
184
+ # @param globs [Array<String>]
185
+ # @return [Array<String>]
186
+ def process_exclusions globs
187
+ remainder = globs.select do |glob|
188
+ if glob_is_directory?(glob)
189
+ exdir = File.join(directory, glob_to_directory(glob))
190
+ included.delete_if { |file| file.start_with?(exdir) }
191
+ false
192
+ else
193
+ true
194
+ end
195
+ end
196
+ process_globs remainder
197
+ end
198
+
199
+ # True if the glob translates to a whole directory.
200
+ #
201
+ # @example
202
+ # glob_is_directory?('path/to/dir') # => true
203
+ # glob_is_directory?('path/to/dir/**/*) # => true
204
+ # glob_is_directory?('path/to/file.txt') # => false
205
+ # glob_is_directory?('path/to/*.txt') # => false
206
+ #
207
+ # @param glob [String]
208
+ # @return [Boolean]
209
+ def glob_is_directory? glob
210
+ File.directory?(glob) || File.directory?(glob_to_directory(glob))
211
+ end
212
+
213
+ # Translate a glob to a base directory if applicable
214
+ #
215
+ # @example
216
+ # glob_to_directory('path/to/dir/**/*') # => 'path/to/dir'
217
+ #
218
+ # @param glob [String]
219
+ # @return [String]
220
+ def glob_to_directory glob
221
+ glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '')
222
+ end
223
+
224
+ def excluded_directories
225
+ @raw_data['exclude']
226
+ .select { |g| glob_is_directory?(g) }
227
+ .map { |g| File.join(directory, glob_to_directory(g)) }
228
+ end
229
+ end
230
+ end
231
+ end
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'rubygems'
5
+ require 'json'
6
+
7
+ module Solargraph
8
+ # A workspace consists of the files in a project's directory and the
9
+ # project's configuration. It provides a Source for each file to be used
10
+ # in an associated Library or ApiMap.
11
+ #
12
+ class Workspace
13
+ autoload :Config, 'solargraph/workspace/config'
14
+
15
+ # @return [String]
16
+ attr_reader :directory
17
+
18
+ # The require paths associated with the workspace.
19
+ #
20
+ # @return [Array<String>]
21
+ attr_reader :require_paths
22
+
23
+ # @return [Array<String>]
24
+ attr_reader :gemnames
25
+ alias source_gems gemnames
26
+
27
+ # @param directory [String]
28
+ # @param config [Config, nil]
29
+ def initialize directory = '', config = nil
30
+ @directory = directory
31
+ @config = config
32
+ load_sources
33
+ @gemnames = []
34
+ @require_paths = generate_require_paths
35
+ require_plugins
36
+ end
37
+
38
+ # @return [Solargraph::Workspace::Config]
39
+ def config
40
+ @config ||= Solargraph::Workspace::Config.new(directory)
41
+ end
42
+
43
+ # Merge the source. A merge will update the existing source for the file
44
+ # or add it to the sources if the workspace is configured to include it.
45
+ # The source is ignored if the configuration excludes it.
46
+ #
47
+ # @param source [Solargraph::Source]
48
+ # @return [Boolean] True if the source was added to the workspace
49
+ def merge *sources
50
+ unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
51
+ # Reload the config to determine if a new source should be included
52
+ @config = Solargraph::Workspace::Config.new(directory)
53
+ end
54
+
55
+ includes_any = false
56
+ sources.each do |source|
57
+ if directory == "*" || config.calculated.include?(source.filename)
58
+ source_hash[source.filename] = source
59
+ includes_any = true
60
+ end
61
+ end
62
+
63
+ includes_any
64
+ end
65
+
66
+ # Remove a source from the workspace. The source will not be removed if
67
+ # its file exists and the workspace is configured to include it.
68
+ #
69
+ # @param filename [String]
70
+ # @return [Boolean] True if the source was removed from the workspace
71
+ def remove filename
72
+ return false unless source_hash.key?(filename)
73
+ source_hash.delete filename
74
+ true
75
+ end
76
+
77
+ # @return [Array<String>]
78
+ def filenames
79
+ source_hash.keys
80
+ end
81
+
82
+ # @return [Array<Solargraph::Source>]
83
+ def sources
84
+ source_hash.values
85
+ end
86
+
87
+ # @param filename [String]
88
+ # @return [Boolean]
89
+ def has_file? filename
90
+ source_hash.key?(filename)
91
+ end
92
+
93
+ # Get a source by its filename.
94
+ #
95
+ # @param filename [String]
96
+ # @return [Solargraph::Source]
97
+ def source filename
98
+ source_hash[filename]
99
+ end
100
+
101
+ # True if the path resolves to a file in the workspace's require paths.
102
+ #
103
+ # @param path [String]
104
+ # @return [Boolean]
105
+ def would_require? path
106
+ require_paths.each do |rp|
107
+ return true if File.exist?(File.join(rp, "#{path}.rb"))
108
+ end
109
+ false
110
+ end
111
+
112
+ # True if the workspace contains at least one gemspec file.
113
+ #
114
+ # @return [Boolean]
115
+ def gemspec?
116
+ !gemspecs.empty?
117
+ end
118
+
119
+ # Get an array of all gemspec files in the workspace.
120
+ #
121
+ # @return [Array<String>]
122
+ def gemspecs
123
+ return [] if directory.empty? || directory == '*'
124
+ @gemspecs ||= Dir[File.join(directory, '**/*.gemspec')].select do |gs|
125
+ config.allow? gs
126
+ end
127
+ end
128
+
129
+ # Synchronize the workspace from the provided updater.
130
+ #
131
+ # @param updater [Source::Updater]
132
+ # @return [void]
133
+ def synchronize! updater
134
+ source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
135
+ end
136
+
137
+ private
138
+
139
+ # @return [Hash{String => Solargraph::Source}]
140
+ def source_hash
141
+ @source_hash ||= {}
142
+ end
143
+
144
+ # @return [void]
145
+ def load_sources
146
+ source_hash.clear
147
+ unless directory.empty? || directory == '*'
148
+ size = config.calculated.length
149
+ raise WorkspaceTooLargeError, "The workspace is too large to index (#{size} files, #{config.max_files} max)" if config.max_files > 0 and size > config.max_files
150
+ config.calculated.each do |filename|
151
+ begin
152
+ source_hash[filename] = Solargraph::Source.load(filename)
153
+ rescue Errno::ENOENT => e
154
+ Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
155
+ end
156
+ end
157
+ end
158
+ end
159
+
160
+ # Generate require paths from gemspecs if they exist or assume the default
161
+ # lib directory.
162
+ #
163
+ # @return [Array<String>]
164
+ def generate_require_paths
165
+ return configured_require_paths unless gemspec?
166
+ result = []
167
+ gemspecs.each do |file|
168
+ base = File.dirname(file)
169
+ # HACK: Evaluating gemspec files violates the goal of not running
170
+ # workspace code, but this is how Gem::Specification.load does it
171
+ # anyway.
172
+ cmd = ['ruby', '-e', "require 'rubygems'; require 'json'; spec = eval(File.read('#{file}'), TOPLEVEL_BINDING, '#{file}'); return unless Gem::Specification === spec; puts({name: spec.name, paths: spec.require_paths}.to_json)"]
173
+ o, e, s = Open3.capture3(*cmd)
174
+ if s.success?
175
+ begin
176
+ hash = o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
177
+ next if hash.empty?
178
+ @gemnames.push hash['name']
179
+ result.concat(hash['paths'].map { |path| File.join(base, path) })
180
+ rescue StandardError => e
181
+ Solargraph.logger.warn "Error reading #{file}: [#{e.class}] #{e.message}"
182
+ end
183
+ else
184
+ Solargraph.logger.warn "Error reading #{file}"
185
+ Solargraph.logger.warn e
186
+ end
187
+ end
188
+ result.concat(config.require_paths.map { |p| File.join(directory, p) })
189
+ result.push File.join(directory, 'lib') if result.empty?
190
+ result
191
+ end
192
+
193
+ # Get additional require paths defined in the configuration.
194
+ #
195
+ # @return [Array<String>]
196
+ def configured_require_paths
197
+ return ['lib'] if directory.empty?
198
+ return [File.join(directory, 'lib')] if config.require_paths.empty?
199
+ config.require_paths.map{|p| File.join(directory, p)}
200
+ end
201
+
202
+ def require_plugins
203
+ config.plugins.each do |plugin|
204
+ begin
205
+ require plugin
206
+ rescue LoadError
207
+ Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ class Cache
6
+ def initialize
7
+ @path_pins = {}
8
+ end
9
+
10
+ def set_path_pins path, pins
11
+ @path_pins[path] = pins
12
+ end
13
+
14
+ def get_path_pins path
15
+ @path_pins[path]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module Solargraph
2
+ class YardMap
3
+ module Helpers
4
+ module_function
5
+
6
+ # @param code_object [YARD::CodeObjects::Base]
7
+ # @param spec [Gem::Specification]
8
+ # @return [Solargraph::Location, nil]
9
+ def object_location code_object, spec
10
+ return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
11
+ file = File.join(spec.full_gem_path, code_object.file)
12
+ Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ class Mapper
6
+ module ToConstant
7
+ extend YardMap::Helpers
8
+
9
+ def self.make code_object, closure = nil, spec = nil
10
+ closure ||= Solargraph::Pin::Namespace.new(
11
+ name: code_object.namespace.to_s,
12
+ gates: [code_object.namespace.to_s]
13
+ )
14
+ Pin::Constant.new(
15
+ location: object_location(code_object, spec),
16
+ closure: closure,
17
+ name: code_object.name.to_s,
18
+ comments: code_object.docstring ? code_object.docstring.all.to_s : '',
19
+ visibility: code_object.visibility
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ class Mapper
6
+ module ToMethod
7
+ extend YardMap::Helpers
8
+
9
+ def self.make code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
10
+ closure ||= Solargraph::Pin::Namespace.new(
11
+ name: code_object.namespace.to_s,
12
+ gates: [code_object.namespace.to_s]
13
+ )
14
+ location = object_location(code_object, spec)
15
+ comments = code_object.docstring ? code_object.docstring.all.to_s : ''
16
+ pin = Pin::Method.new(
17
+ location: location,
18
+ closure: closure,
19
+ name: name || code_object.name.to_s,
20
+ comments: comments,
21
+ scope: scope || code_object.scope,
22
+ visibility: visibility || code_object.visibility,
23
+ # @todo Might need to convert overloads to signatures
24
+ parameters: [],
25
+ explicit: code_object.is_explicit?
26
+ )
27
+ pin.parameters.concat get_parameters(code_object, location, comments, pin)
28
+ pin
29
+ end
30
+
31
+ class << self
32
+ private
33
+
34
+ # @param code_object [YARD::CodeObjects::Base]
35
+ # @return [Array<Solargraph::Pin::Parameter>]
36
+ def get_parameters code_object, location, comments, pin
37
+ return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
38
+ # HACK: Skip `nil` and `self` parameters that are sometimes emitted
39
+ # for methods defined in C
40
+ # See https://github.com/castwide/solargraph/issues/345
41
+ code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
42
+ Solargraph::Pin::Parameter.new(
43
+ location: location,
44
+ closure: pin,
45
+ comments: comments,
46
+ name: arg_name(a),
47
+ presence: nil,
48
+ decl: arg_type(a),
49
+ asgn_code: a[1]
50
+ )
51
+ end
52
+ end
53
+
54
+ # @param a [Array]
55
+ # @return [String]
56
+ def arg_name a
57
+ a[0].gsub(/[^a-z0-9_]/i, '')
58
+ end
59
+
60
+ # @param a [Array]
61
+ # @return [::Symbol]
62
+ def arg_type a
63
+ if a[0].start_with?('**')
64
+ :kwrestarg
65
+ elsif a[0].start_with?('*')
66
+ :restarg
67
+ elsif a[0].start_with?('&')
68
+ :blockarg
69
+ elsif a[0].end_with?(':')
70
+ a[1] ? :kwoptarg : :kwarg
71
+ elsif a[1]
72
+ :optarg
73
+ else
74
+ :arg
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end