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,299 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ # The base class for map pins.
6
+ #
7
+ class Base
8
+ include Common
9
+ include Conversions
10
+ include Documenting
11
+
12
+ # @return [YARD::CodeObjects::Base]
13
+ attr_reader :code_object
14
+
15
+ # @return [Solargraph::Location]
16
+ attr_reader :location
17
+
18
+ # @return [String]
19
+ attr_reader :name
20
+
21
+ # @return [String]
22
+ attr_reader :path
23
+
24
+ # @return [::Symbol]
25
+ attr_accessor :source
26
+
27
+ # @param location [Solargraph::Location, nil]
28
+ # @param kind [Integer]
29
+ # @param closure [Solargraph::Pin::Closure, nil]
30
+ # @param name [String]
31
+ # @param comments [String]
32
+ def initialize location: nil, closure: nil, name: '', comments: ''
33
+ @location = location
34
+ @closure = closure
35
+ @name = name
36
+ @comments = comments
37
+ end
38
+
39
+ # @return [String]
40
+ def comments
41
+ @comments ||= ''
42
+ end
43
+
44
+ # @return [String, nil]
45
+ def filename
46
+ return nil if location.nil?
47
+ location.filename
48
+ end
49
+
50
+ # @return [Integer]
51
+ def completion_item_kind
52
+ LanguageServer::CompletionItemKinds::KEYWORD
53
+ end
54
+
55
+ # @return [Integer, nil]
56
+ def symbol_kind
57
+ nil
58
+ end
59
+
60
+ def to_s
61
+ name.to_s
62
+ end
63
+
64
+ # @return [Boolean]
65
+ def variable?
66
+ false
67
+ end
68
+
69
+ # Pin equality is determined using the #nearly? method and also
70
+ # requiring both pins to have the same location.
71
+ #
72
+ def == other
73
+ return false unless nearly? other
74
+ comments == other.comments and location == other.location
75
+ end
76
+
77
+ # True if the specified pin is a near match to this one. A near match
78
+ # indicates that the pins contain mostly the same data. Any differences
79
+ # between them should not have an impact on the API surface.
80
+ #
81
+ # @param other [Solargraph::Pin::Base, Object]
82
+ # @return [Boolean]
83
+ def nearly? other
84
+ self.class == other.class &&
85
+ name == other.name &&
86
+ (closure == other.closure || (closure && closure.nearly?(other.closure))) &&
87
+ (comments == other.comments ||
88
+ (((maybe_directives? == false && other.maybe_directives? == false) || compare_directives(directives, other.directives)) &&
89
+ compare_docstring_tags(docstring, other.docstring))
90
+ )
91
+ end
92
+
93
+ # The pin's return type.
94
+ #
95
+ # @return [ComplexType]
96
+ def return_type
97
+ @return_type ||= ComplexType::UNDEFINED
98
+ end
99
+
100
+ # @return [YARD::Docstring]
101
+ def docstring
102
+ parse_comments unless defined?(@docstring)
103
+ @docstring ||= Solargraph::Source.parse_docstring('').to_docstring
104
+ end
105
+
106
+ # @return [Array<YARD::Tags::Directive>]
107
+ def directives
108
+ parse_comments unless defined?(@directives)
109
+ @directives
110
+ end
111
+
112
+ # @return [Array<YARD::Tags::MacroDirective>]
113
+ def macros
114
+ @macros ||= collect_macros
115
+ end
116
+
117
+ # Perform a quick check to see if this pin possibly includes YARD
118
+ # directives. This method does not require parsing the comments.
119
+ #
120
+ # After the comments have been parsed, this method will return false if
121
+ # no directives were found, regardless of whether it previously appeared
122
+ # possible.
123
+ #
124
+ # @return [Boolean]
125
+ def maybe_directives?
126
+ return !@directives.empty? if defined?(@directives)
127
+ @maybe_directives ||= comments.include?('@!')
128
+ end
129
+
130
+ # @return [Boolean]
131
+ def deprecated?
132
+ @deprecated ||= docstring.has_tag?('deprecated')
133
+ end
134
+
135
+ # Get a fully qualified type from the pin's return type.
136
+ #
137
+ # The relative type is determined from YARD documentation (@return,
138
+ # @param, @type, etc.) and its namespaces are fully qualified using the
139
+ # provided ApiMap.
140
+ #
141
+ # @param api_map [ApiMap]
142
+ # @return [ComplexType]
143
+ def typify api_map
144
+ return_type.qualify(api_map, namespace)
145
+ end
146
+
147
+ # Infer the pin's return type via static code analysis.
148
+ #
149
+ # @param api_map [ApiMap]
150
+ # @return [ComplexType]
151
+ def probe api_map
152
+ typify api_map
153
+ end
154
+
155
+ # @deprecated Use #typify and/or #probe instead
156
+ # @param api_map [ApiMap]
157
+ # @return [ComplexType]
158
+ def infer api_map
159
+ Solargraph::Logging.logger.warn "WARNING: Pin #infer methods are deprecated. Use #typify or #probe instead."
160
+ type = typify(api_map)
161
+ return type unless type.undefined?
162
+ probe api_map
163
+ end
164
+
165
+ # Try to merge data from another pin. Merges are only possible if the
166
+ # pins are near matches (see the #nearly? method). The changes should
167
+ # not have any side effects on the API surface.
168
+ #
169
+ # @param pin [Pin::Base] The pin to merge into this one
170
+ # @return [Boolean] True if the pins were merged
171
+ def try_merge! pin
172
+ return false unless nearly?(pin)
173
+ @location = pin.location
174
+ @closure = pin.closure
175
+ return true if comments == pin.comments
176
+ @comments = pin.comments
177
+ @docstring = pin.docstring
178
+ @return_type = pin.return_type
179
+ @documentation = nil
180
+ @deprecated = nil
181
+ reset_conversions
182
+ true
183
+ end
184
+
185
+ def proxied?
186
+ @proxied ||= false
187
+ end
188
+
189
+ def probed?
190
+ @probed ||= false
191
+ end
192
+
193
+ # @param api_map [ApiMap]
194
+ # @return [self]
195
+ def realize api_map
196
+ return self if return_type.defined?
197
+ type = typify(api_map)
198
+ return proxy(type) if type.defined?
199
+ type = probe(api_map)
200
+ return self if type.undefined?
201
+ result = proxy(type)
202
+ result.probed = true
203
+ result
204
+ end
205
+
206
+ # Return a proxy for this pin with the specified return type. Other than
207
+ # the return type and the #proxied? setting, the proxy should be a clone
208
+ # of the original.
209
+ #
210
+ # @param return_type [ComplexType]
211
+ # @return [self]
212
+ def proxy return_type
213
+ result = dup
214
+ result.return_type = return_type
215
+ result.proxied = true
216
+ result
217
+ end
218
+
219
+ def identity
220
+ @identity ||= "#{closure.context.namespace}|#{name}"
221
+ end
222
+
223
+ def inspect
224
+ "#<#{self.class} `#{self.path}` at #{self.location.inspect}>"
225
+ end
226
+
227
+ protected
228
+
229
+ # @return [Boolean]
230
+ attr_writer :probed
231
+
232
+ # @return [Boolean]
233
+ attr_writer :proxied
234
+
235
+ # @return [ComplexType]
236
+ attr_writer :return_type
237
+
238
+ private
239
+
240
+ # @return [void]
241
+ def parse_comments
242
+ # HACK: Avoid a NoMethodError on nil with empty overload tags
243
+ if comments.nil? || comments.empty? || comments.strip.end_with?('@overload')
244
+ @docstring = nil
245
+ @directives = []
246
+ else
247
+ # HACK: Pass a dummy code object to the parser for plugins that
248
+ # expect it not to be nil
249
+ parse = Solargraph::Source.parse_docstring(comments)
250
+ @docstring = parse.to_docstring
251
+ @directives = parse.directives
252
+ end
253
+ end
254
+
255
+ # True if two docstrings have the same tags, regardless of any other
256
+ # differences.
257
+ #
258
+ # @param d1 [YARD::Docstring]
259
+ # @param d2 [YARD::Docstring]
260
+ # @return [Boolean]
261
+ def compare_docstring_tags d1, d2
262
+ return false if d1.tags.length != d2.tags.length
263
+ d1.tags.each_index do |i|
264
+ return false unless compare_tags(d1.tags[i], d2.tags[i])
265
+ end
266
+ true
267
+ end
268
+
269
+ # @param dir1 [Array<YARD::Tags::Directive>]
270
+ # @param dir2 [Array<YARD::Tags::Directive>]
271
+ # @return [Boolean]
272
+ def compare_directives dir1, dir2
273
+ return false if dir1.length != dir2.length
274
+ dir1.each_index do |i|
275
+ return false unless compare_tags(dir1[i].tag, dir2[i].tag)
276
+ end
277
+ true
278
+ end
279
+
280
+ # @param tag1 [YARD::Tags::Tag]
281
+ # @param tag2 [YARD::Tags::Tag]
282
+ # @return [Boolean]
283
+ def compare_tags tag1, tag2
284
+ tag1.class == tag2.class &&
285
+ tag1.tag_name == tag2.tag_name &&
286
+ tag1.text == tag2.text &&
287
+ tag1.name == tag2.name &&
288
+ tag1.types == tag2.types
289
+ end
290
+
291
+ # @return [Array<YARD::Tags::Handlers::Directive>]
292
+ def collect_macros
293
+ return [] unless maybe_directives?
294
+ parse = Solargraph::Source.parse_docstring(comments)
295
+ parse.directives.select{ |d| d.tag.tag_name == 'macro' }
296
+ end
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class BaseVariable < Base
6
+ include Solargraph::Parser::NodeMethods
7
+ # include Solargraph::Source::NodeMethods
8
+
9
+ # @return [Parser::AST::Node, nil]
10
+ attr_reader :assignment
11
+
12
+ # @param assignment [Parser::AST::Node, nil]
13
+ def initialize assignment: nil, **splat
14
+ super(**splat)
15
+ @assignment = assignment
16
+ end
17
+
18
+ def completion_item_kind
19
+ Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
20
+ end
21
+
22
+ # @return [Integer]
23
+ def symbol_kind
24
+ Solargraph::LanguageServer::SymbolKinds::VARIABLE
25
+ end
26
+
27
+ def return_type
28
+ @return_type ||= generate_complex_type
29
+ end
30
+
31
+ def nil_assignment?
32
+ return_type.nil?
33
+ end
34
+
35
+ def variable?
36
+ true
37
+ end
38
+
39
+ def probe api_map
40
+ return ComplexType::UNDEFINED if @assignment.nil?
41
+ types = []
42
+ returns_from(@assignment).each do |node|
43
+ # Nil nodes may not have a location
44
+ if node.nil? || node.type == :NIL || node.type == :nil
45
+ types.push ComplexType::NIL
46
+ else
47
+ rng = Range.from_node(node)
48
+ next if rng.nil?
49
+ pos = rng.ending
50
+ clip = api_map.clip_at(location.filename, pos)
51
+ # Use the return node for inference. The clip might infer from the
52
+ # first node in a method call instead of the entire call.
53
+ chain = Parser.chain(node, nil, clip.in_block?)
54
+ result = chain.infer(api_map, closure, clip.locals)
55
+ types.push result unless result.undefined?
56
+ end
57
+ end
58
+ return ComplexType::UNDEFINED if types.empty?
59
+ ComplexType.try_parse(*types.map(&:tag))
60
+ end
61
+
62
+ def == other
63
+ return false unless super
64
+ assignment == other.assignment
65
+ end
66
+
67
+ def try_merge! pin
68
+ return false unless super
69
+ @assignment = pin.assignment
70
+ @return_type = pin.return_type
71
+ true
72
+ end
73
+
74
+ private
75
+
76
+ # @return [ComplexType]
77
+ def generate_complex_type
78
+ tag = docstring.tag(:type)
79
+ return ComplexType.try_parse(*tag.types) unless tag.nil? || tag.types.nil? || tag.types.empty?
80
+ ComplexType.new
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Block < Closure
6
+ # The signature of the method that receives this block.
7
+ #
8
+ # @return [Parser::AST::Node]
9
+ attr_reader :receiver
10
+
11
+ # @param args [Array<Parameter>]
12
+ def initialize receiver: nil, args: [], context: nil, **splat
13
+ super(**splat)
14
+ @receiver = receiver
15
+ @context = context
16
+ @parameters = args
17
+ end
18
+
19
+ # @param api_map [ApiMap]
20
+ # @return [void]
21
+ def rebind api_map
22
+ @binder ||= binder_or_nil(api_map)
23
+ end
24
+
25
+ def binder
26
+ @binder || closure.binder
27
+ end
28
+
29
+ # @return [Array<Parameter>]
30
+ def parameters
31
+ @parameters ||= []
32
+ end
33
+
34
+ # @return [Array<String>]
35
+ def parameter_names
36
+ @parameter_names ||= parameters.map(&:name)
37
+ end
38
+
39
+ private
40
+
41
+ # @param api_map [ApiMap]
42
+ # @return [ComplexType, nil]
43
+ def binder_or_nil api_map
44
+ return nil unless receiver
45
+ word = receiver.children.find { |c| c.is_a?(::Symbol) }.to_s
46
+ return nil unless api_map.rebindable_method_names.include?(word)
47
+ chain = Parser.chain(receiver, location.filename)
48
+ locals = api_map.source_map(location.filename).locals_at(location)
49
+ links_last_word = chain.links.last.word
50
+ if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
51
+ return chain.base.infer(api_map, self, locals)
52
+ end
53
+ if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
54
+ if chain.links.size > 1 # Class.define_method
55
+ ty = chain.base.infer(api_map, self, locals)
56
+ return Solargraph::ComplexType.parse(ty.namespace)
57
+ else # define_method without self
58
+ return Solargraph::ComplexType.parse(closure.binder.namespace)
59
+ end
60
+ end
61
+ # other case without early return, read block yieldself tags
62
+ receiver_pin = chain.define(api_map, self, locals).first
63
+ if receiver_pin && receiver_pin.docstring
64
+ ys = receiver_pin.docstring.tag(:yieldself)
65
+ if ys && ys.types && !ys.types.empty?
66
+ return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
67
+ end
68
+ end
69
+ nil
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class ClassVariable < BaseVariable
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Closure < Base
6
+ # @return [::Symbol] :class or :instance
7
+ attr_reader :scope
8
+
9
+ def initialize scope: :class, **splat
10
+ super(**splat)
11
+ @scope = scope
12
+ end
13
+
14
+ def context
15
+ @context ||= begin
16
+ result = super
17
+ if scope == :instance
18
+ Solargraph::ComplexType.parse(result.namespace)
19
+ else
20
+ result
21
+ end
22
+ end
23
+ end
24
+
25
+ def binder
26
+ @binder || context
27
+ end
28
+
29
+ # @return [Array<String>]
30
+ def gates
31
+ # @todo This check might not be necessary. There should always be a
32
+ # root pin
33
+ closure ? closure.gates : ['']
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ module Common
6
+ # @return [Location]
7
+ attr_reader :location
8
+
9
+ # @return [Pin::Base, nil]
10
+ attr_reader :closure
11
+
12
+ # @return [String]
13
+ def name
14
+ @name ||= ''
15
+ end
16
+
17
+ # @return [ComplexType]
18
+ def return_type
19
+ @return_type ||= ComplexType::UNDEFINED
20
+ end
21
+
22
+ # @return [ComplexType]
23
+ def context
24
+ # Get the static context from the nearest namespace
25
+ @context ||= find_context
26
+ end
27
+ alias full_context context
28
+
29
+ # @return [String]
30
+ def namespace
31
+ context.namespace.to_s
32
+ end
33
+
34
+ # @return [ComplexType]
35
+ def binder
36
+ @binder || context
37
+ end
38
+
39
+ # @return [String]
40
+ def comments
41
+ @comments ||= ''
42
+ end
43
+
44
+ # @return [String]
45
+ def path
46
+ @path ||= name.empty? ? context.namespace : "#{context.namespace}::#{name}"
47
+ end
48
+
49
+ private
50
+
51
+ # @return [ComplexType]
52
+ def find_context
53
+ here = closure
54
+ until here.nil?
55
+ if here.is_a?(Pin::Namespace)
56
+ return here.return_type
57
+ elsif here.is_a?(Pin::Method)
58
+ if here.scope == :instance
59
+ return ComplexType.try_parse(here.context.namespace)
60
+ else
61
+ return here.context
62
+ end
63
+ end
64
+ here = here.closure
65
+ end
66
+ ComplexType::ROOT
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Constant < BaseVariable
6
+ attr_reader :visibility
7
+
8
+ def initialize visibility: :public, **splat
9
+ super(**splat)
10
+ @visibility = visibility
11
+ end
12
+
13
+ def return_type
14
+ @return_type ||= generate_complex_type
15
+ end
16
+
17
+ def completion_item_kind
18
+ Solargraph::LanguageServer::CompletionItemKinds::CONSTANT
19
+ end
20
+
21
+ # @return [Integer]
22
+ def symbol_kind
23
+ LanguageServer::SymbolKinds::CONSTANT
24
+ end
25
+
26
+ def path
27
+ @path ||= context.namespace.to_s.empty? ? name : "#{context.namespace}::#{name}"
28
+ end
29
+
30
+ private
31
+
32
+ # @return [ComplexType]
33
+ def generate_complex_type
34
+ tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
35
+ if tags.empty?
36
+ tags = docstring.tags(:type).map(&:types).flatten.reject(&:nil?)
37
+ end
38
+ return ComplexType::UNDEFINED if tags.empty?
39
+ ComplexType.try_parse *tags
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module Solargraph
6
+ module Pin
7
+ # @todo Move this stuff. It should be the responsibility of the language server.
8
+ module Conversions
9
+ # @return [Hash]
10
+ def completion_item
11
+ @completion_item ||= {
12
+ label: name,
13
+ kind: completion_item_kind,
14
+ detail: detail,
15
+ data: {
16
+ path: path,
17
+ return_type: return_type.tag,
18
+ location: (location ? location.to_hash : nil),
19
+ deprecated: deprecated?
20
+ }
21
+ }
22
+ end
23
+
24
+ # @return [Hash]
25
+ def resolve_completion_item
26
+ @resolve_completion_item ||= begin
27
+ extra = {}
28
+ alldoc = ''
29
+ # alldoc += link_documentation unless link_documentation.nil?
30
+ # alldoc += "\n\n" unless alldoc.empty?
31
+ alldoc += documentation unless documentation.nil?
32
+ extra[:documentation] = alldoc unless alldoc.empty?
33
+ completion_item.merge(extra)
34
+ end
35
+ end
36
+
37
+ # @return [Array<Hash>]
38
+ def signature_help
39
+ []
40
+ end
41
+
42
+ # @return [String]
43
+ def detail
44
+ # This property is not cached in an instance variable because it can
45
+ # change when pins get proxied.
46
+ detail = String.new
47
+ detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
48
+ detail.strip!
49
+ return nil if detail.empty?
50
+ detail
51
+ end
52
+
53
+ # Get a markdown-flavored link to a documentation page.
54
+ #
55
+ # @return [String]
56
+ def link_documentation
57
+ @link_documentation ||= generate_link
58
+ end
59
+
60
+ def text_documentation
61
+ this_path = path || return_type.tag
62
+ return nil if this_path == 'undefined'
63
+ escape_brackets this_path
64
+ end
65
+
66
+ def reset_conversions
67
+ @completion_item = nil
68
+ @resolve_completion_item = nil
69
+ @signature_help = nil
70
+ @detail = nil
71
+ @link_documentation = nil
72
+ end
73
+
74
+ private
75
+
76
+ # @return [String]
77
+ def generate_link
78
+ this_path = path || return_type.tag
79
+ return nil if this_path == 'undefined'
80
+ return nil if this_path.nil? || this_path == 'undefined'
81
+ "[#{escape_brackets(this_path).gsub('_', '\\\\_')}](solargraph:/document?query=#{CGI.escape(this_path)})"
82
+ end
83
+
84
+ # @param text [String]
85
+ # @return [String]
86
+ def escape_brackets text
87
+ # text.gsub(/(\<|\>)/, "\\#{$1}")
88
+ text.gsub("<", '\<').gsub(">", '\>')
89
+ end
90
+ end
91
+ end
92
+ end