solargraph 0.58.0 → 0.59.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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.gitattributes +2 -0
  4. data/.github/workflows/linting.yml +6 -5
  5. data/.github/workflows/plugins.yml +48 -35
  6. data/.github/workflows/rspec.yml +15 -28
  7. data/.github/workflows/typecheck.yml +3 -2
  8. data/.gitignore +1 -0
  9. data/.rubocop.yml +38 -6
  10. data/.rubocop_todo.yml +53 -966
  11. data/CHANGELOG.md +24 -0
  12. data/Gemfile +3 -1
  13. data/README.md +3 -3
  14. data/Rakefile +26 -23
  15. data/bin/solargraph +9 -8
  16. data/lib/solargraph/api_map/cache.rb +110 -110
  17. data/lib/solargraph/api_map/constants.rb +288 -279
  18. data/lib/solargraph/api_map/index.rb +204 -193
  19. data/lib/solargraph/api_map/source_to_yard.rb +110 -97
  20. data/lib/solargraph/api_map/store.rb +395 -384
  21. data/lib/solargraph/api_map.rb +1029 -945
  22. data/lib/solargraph/bench.rb +44 -45
  23. data/lib/solargraph/complex_type/conformance.rb +176 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +240 -228
  25. data/lib/solargraph/complex_type/unique_type.rb +641 -482
  26. data/lib/solargraph/complex_type.rb +557 -444
  27. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  28. data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
  29. data/lib/solargraph/convention/data_definition.rb +108 -105
  30. data/lib/solargraph/convention/gemfile.rb +15 -15
  31. data/lib/solargraph/convention/gemspec.rb +23 -23
  32. data/lib/solargraph/convention/rakefile.rb +17 -17
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
  35. data/lib/solargraph/convention/struct_definition.rb +168 -164
  36. data/lib/solargraph/convention.rb +78 -78
  37. data/lib/solargraph/converters/dd.rb +19 -17
  38. data/lib/solargraph/converters/dl.rb +17 -15
  39. data/lib/solargraph/converters/dt.rb +17 -15
  40. data/lib/solargraph/converters/misc.rb +3 -1
  41. data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
  42. data/lib/solargraph/diagnostics/rubocop.rb +119 -118
  43. data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
  44. data/lib/solargraph/diagnostics/type_check.rb +56 -55
  45. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  46. data/lib/solargraph/doc_map.rb +438 -439
  47. data/lib/solargraph/equality.rb +34 -34
  48. data/lib/solargraph/gem_pins.rb +98 -98
  49. data/lib/solargraph/language_server/error_codes.rb +20 -20
  50. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  51. data/lib/solargraph/language_server/host/dispatch.rb +130 -130
  52. data/lib/solargraph/language_server/host/message_worker.rb +113 -112
  53. data/lib/solargraph/language_server/host/sources.rb +100 -99
  54. data/lib/solargraph/language_server/host.rb +886 -878
  55. data/lib/solargraph/language_server/message/base.rb +97 -97
  56. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  57. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  58. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +108 -114
  59. data/lib/solargraph/language_server/message/extended/document.rb +24 -23
  60. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  61. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  62. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  63. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  64. data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
  65. data/lib/solargraph/language_server/message/text_document/definition.rb +49 -40
  66. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  67. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +36 -26
  68. data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
  69. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  70. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  71. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  72. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  73. data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
  74. data/lib/solargraph/language_server/message/text_document/type_definition.rb +33 -25
  75. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  76. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  77. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  78. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +33 -23
  79. data/lib/solargraph/language_server/message.rb +94 -94
  80. data/lib/solargraph/language_server/request.rb +29 -27
  81. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  82. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  83. data/lib/solargraph/library.rb +702 -683
  84. data/lib/solargraph/location.rb +85 -82
  85. data/lib/solargraph/logging.rb +55 -37
  86. data/lib/solargraph/page.rb +92 -92
  87. data/lib/solargraph/parser/comment_ripper.rb +84 -69
  88. data/lib/solargraph/parser/flow_sensitive_typing.rb +471 -255
  89. data/lib/solargraph/parser/node_processor/base.rb +122 -92
  90. data/lib/solargraph/parser/node_processor.rb +63 -62
  91. data/lib/solargraph/parser/parser_gem/class_methods.rb +165 -149
  92. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  93. data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
  94. data/lib/solargraph/parser/parser_gem/node_methods.rb +507 -486
  95. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
  96. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
  97. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
  98. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +45 -46
  99. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
  100. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  101. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
  102. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +42 -40
  103. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
  104. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
  105. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
  106. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  107. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
  108. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
  109. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +51 -52
  110. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +302 -291
  111. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  112. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  113. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
  114. data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
  115. data/lib/solargraph/parser/parser_gem.rb +14 -12
  116. data/lib/solargraph/parser/region.rb +75 -69
  117. data/lib/solargraph/parser/snippet.rb +19 -17
  118. data/lib/solargraph/parser.rb +25 -23
  119. data/lib/solargraph/pin/base.rb +773 -729
  120. data/lib/solargraph/pin/base_variable.rb +375 -126
  121. data/lib/solargraph/pin/block.rb +127 -104
  122. data/lib/solargraph/pin/breakable.rb +15 -9
  123. data/lib/solargraph/pin/callable.rb +275 -231
  124. data/lib/solargraph/pin/closure.rb +69 -72
  125. data/lib/solargraph/pin/common.rb +97 -79
  126. data/lib/solargraph/pin/compound_statement.rb +55 -0
  127. data/lib/solargraph/pin/constant.rb +43 -45
  128. data/lib/solargraph/pin/conversions.rb +129 -123
  129. data/lib/solargraph/pin/delegated_method.rb +131 -120
  130. data/lib/solargraph/pin/documenting.rb +116 -114
  131. data/lib/solargraph/pin/instance_variable.rb +38 -34
  132. data/lib/solargraph/pin/keyword.rb +16 -20
  133. data/lib/solargraph/pin/local_variable.rb +31 -75
  134. data/lib/solargraph/pin/method.rb +724 -672
  135. data/lib/solargraph/pin/method_alias.rb +42 -34
  136. data/lib/solargraph/pin/namespace.rb +122 -115
  137. data/lib/solargraph/pin/parameter.rb +339 -275
  138. data/lib/solargraph/pin/proxy_type.rb +42 -39
  139. data/lib/solargraph/pin/reference/override.rb +47 -47
  140. data/lib/solargraph/pin/reference/superclass.rb +17 -15
  141. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  142. data/lib/solargraph/pin/reference.rb +59 -39
  143. data/lib/solargraph/pin/search.rb +62 -61
  144. data/lib/solargraph/pin/signature.rb +64 -61
  145. data/lib/solargraph/pin/symbol.rb +54 -53
  146. data/lib/solargraph/pin/until.rb +16 -18
  147. data/lib/solargraph/pin/while.rb +16 -18
  148. data/lib/solargraph/pin.rb +46 -44
  149. data/lib/solargraph/pin_cache.rb +248 -245
  150. data/lib/solargraph/position.rb +139 -119
  151. data/lib/solargraph/range.rb +113 -112
  152. data/lib/solargraph/rbs_map/conversions.rb +952 -823
  153. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  154. data/lib/solargraph/rbs_map/core_map.rb +65 -58
  155. data/lib/solargraph/rbs_map/stdlib_map.rb +71 -43
  156. data/lib/solargraph/rbs_map.rb +207 -163
  157. data/lib/solargraph/server_methods.rb +16 -16
  158. data/lib/solargraph/shell.rb +555 -352
  159. data/lib/solargraph/source/chain/array.rb +39 -37
  160. data/lib/solargraph/source/chain/call.rb +377 -337
  161. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  162. data/lib/solargraph/source/chain/constant.rb +30 -26
  163. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  164. data/lib/solargraph/source/chain/hash.rb +37 -34
  165. data/lib/solargraph/source/chain/if.rb +30 -28
  166. data/lib/solargraph/source/chain/instance_variable.rb +36 -13
  167. data/lib/solargraph/source/chain/link.rb +99 -109
  168. data/lib/solargraph/source/chain/literal.rb +51 -48
  169. data/lib/solargraph/source/chain/or.rb +29 -23
  170. data/lib/solargraph/source/chain/q_call.rb +13 -11
  171. data/lib/solargraph/source/chain/variable.rb +15 -13
  172. data/lib/solargraph/source/chain/z_super.rb +28 -30
  173. data/lib/solargraph/source/chain.rb +304 -291
  174. data/lib/solargraph/source/change.rb +89 -82
  175. data/lib/solargraph/source/cursor.rb +172 -166
  176. data/lib/solargraph/source/encoding_fixes.rb +22 -23
  177. data/lib/solargraph/source/source_chainer.rb +218 -194
  178. data/lib/solargraph/source/updater.rb +59 -55
  179. data/lib/solargraph/source.rb +522 -498
  180. data/lib/solargraph/source_map/clip.rb +245 -226
  181. data/lib/solargraph/source_map/data.rb +37 -34
  182. data/lib/solargraph/source_map/mapper.rb +286 -259
  183. data/lib/solargraph/source_map.rb +224 -212
  184. data/lib/solargraph/type_checker/problem.rb +34 -32
  185. data/lib/solargraph/type_checker/rules.rb +157 -84
  186. data/lib/solargraph/type_checker.rb +888 -814
  187. data/lib/solargraph/version.rb +5 -5
  188. data/lib/solargraph/workspace/config.rb +258 -255
  189. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  190. data/lib/solargraph/workspace/require_paths.rb +98 -97
  191. data/lib/solargraph/workspace.rb +242 -220
  192. data/lib/solargraph/yard_map/helpers.rb +49 -44
  193. data/lib/solargraph/yard_map/mapper/to_method.rb +136 -130
  194. data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
  195. data/lib/solargraph/yard_map/mapper.rb +84 -79
  196. data/lib/solargraph/yard_map.rb +17 -18
  197. data/lib/solargraph/yard_tags.rb +20 -20
  198. data/lib/solargraph/yardoc.rb +90 -87
  199. data/lib/solargraph.rb +128 -105
  200. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  201. data/rbs/fills/tuple/tuple.rbs +28 -0
  202. data/rbs/shims/ast/0/node.rbs +5 -0
  203. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  204. data/rbs_collection.yaml +1 -1
  205. data/solargraph.gemspec +37 -35
  206. metadata +52 -51
  207. data/lib/solargraph/type_checker/checks.rb +0 -124
  208. data/lib/solargraph/type_checker/param_def.rb +0 -37
  209. data/lib/solargraph/yard_map/to_method.rb +0 -89
  210. data/sig/shims/ast/0/node.rbs +0 -5
  211. /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
  212. /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
  213. /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
  214. /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
  215. /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
  216. /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
  217. /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
  218. /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
  219. /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
@@ -1,220 +1,242 @@
1
- # frozen_string_literal: true
2
-
3
- require 'open3'
4
- require 'json'
5
-
6
- module Solargraph
7
- # A workspace consists of the files in a project's directory and the
8
- # project's configuration. It provides a Source for each file to be used
9
- # in an associated Library or ApiMap.
10
- #
11
- class Workspace
12
- autoload :Config, 'solargraph/workspace/config'
13
- autoload :RequirePaths, 'solargraph/workspace/require_paths'
14
-
15
- # @return [String]
16
- attr_reader :directory
17
-
18
- # @return [Array<String>]
19
- attr_reader :gemnames
20
- alias source_gems gemnames
21
-
22
- # @param directory [String] TODO: Remove '' and '*' special cases
23
- # @param config [Config, nil]
24
- # @param server [Hash]
25
- def initialize directory = '', config = nil, server = {}
26
- raise ArgumentError, 'directory must be a String' unless directory.is_a?(String)
27
-
28
- @directory = if ['*', ''].include?(directory)
29
- directory
30
- else
31
- File.absolute_path(directory)
32
- end
33
- @config = config
34
- @server = server
35
- load_sources
36
- @gemnames = []
37
- require_plugins
38
- end
39
-
40
- # The require paths associated with the workspace.
41
- #
42
- # @return [Array<String>]
43
- def require_paths
44
- # @todo are the semantics of '*' the same as '', meaning 'don't send back any require paths'?
45
- @require_paths ||= RequirePaths.new(directory_or_nil, config).generate
46
- end
47
-
48
- # @return [Solargraph::Workspace::Config]
49
- def config
50
- @config ||= Solargraph::Workspace::Config.new(directory)
51
- end
52
-
53
- # @param level [Symbol]
54
- # @return [TypeChecker::Rules]
55
- def rules(level)
56
- @rules ||= TypeChecker::Rules.new(level, config.type_checker_rules)
57
- end
58
-
59
- # Merge the source. A merge will update the existing source for the file
60
- # or add it to the sources if the workspace is configured to include it.
61
- # The source is ignored if the configuration excludes it.
62
- #
63
- # @param sources [Array<Solargraph::Source>]
64
- # @return [Boolean] True if the source was added to the workspace
65
- def merge *sources
66
- unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
67
- # Reload the config to determine if a new source should be included
68
- @config = Solargraph::Workspace::Config.new(directory)
69
- end
70
-
71
- includes_any = false
72
- sources.each do |source|
73
- if directory == "*" || config.calculated.include?(source.filename)
74
- source_hash[source.filename] = source
75
- includes_any = true
76
- end
77
- end
78
-
79
- includes_any
80
- end
81
-
82
- # Remove a source from the workspace. The source will not be removed if
83
- # its file exists and the workspace is configured to include it.
84
- #
85
- # @param filename [String]
86
- # @return [Boolean] True if the source was removed from the workspace
87
- def remove filename
88
- return false unless source_hash.key?(filename)
89
- source_hash.delete filename
90
- true
91
- end
92
-
93
- # @return [Array<String>]
94
- def filenames
95
- source_hash.keys
96
- end
97
-
98
- # @return [Array<Solargraph::Source>]
99
- def sources
100
- source_hash.values
101
- end
102
-
103
- # @param filename [String]
104
- # @return [Boolean]
105
- def has_file? filename
106
- source_hash.key?(filename)
107
- end
108
-
109
- # Get a source by its filename.
110
- #
111
- # @param filename [String]
112
- # @return [Solargraph::Source]
113
- def source filename
114
- source_hash[filename]
115
- end
116
-
117
- # True if the path resolves to a file in the workspace's require paths.
118
- #
119
- # @param path [String]
120
- # @return [Boolean]
121
- def would_require? path
122
- require_paths.each do |rp|
123
- full = File.join rp, path
124
- return true if File.file?(full) || File.file?(full << ".rb")
125
- end
126
- false
127
- end
128
-
129
- # @return [String, nil]
130
- def rbs_collection_path
131
- @gem_rbs_collection ||= read_rbs_collection_path
132
- end
133
-
134
- # @return [String, nil]
135
- def rbs_collection_config_path
136
- @rbs_collection_config_path ||= begin
137
- unless directory.empty? || directory == '*'
138
- yaml_file = File.join(directory, 'rbs_collection.yaml')
139
- yaml_file if File.file?(yaml_file)
140
- end
141
- end
142
- end
143
-
144
- # Synchronize the workspace from the provided updater.
145
- #
146
- # @param updater [Source::Updater]
147
- # @return [void]
148
- def synchronize! updater
149
- source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
150
- end
151
-
152
- # @return [String]
153
- def command_path
154
- server['commandPath'] || 'solargraph'
155
- end
156
-
157
- # @return [String, nil]
158
- def directory_or_nil
159
- return nil if directory.empty? || directory == '*'
160
- directory
161
- end
162
-
163
- # True if the workspace has a root Gemfile.
164
- #
165
- # @todo Handle projects with custom Bundler/Gemfile setups (see DocMap#gemspecs_required_from_bundler)
166
- #
167
- def gemfile?
168
- directory && File.file?(File.join(directory, 'Gemfile'))
169
- end
170
-
171
- private
172
-
173
- # The language server configuration (or an empty hash if the workspace was
174
- # not initialized from a server).
175
- #
176
- # @return [Hash]
177
- attr_reader :server
178
-
179
- # @return [Hash{String => Solargraph::Source}]
180
- def source_hash
181
- @source_hash ||= {}
182
- end
183
-
184
- # @return [void]
185
- def load_sources
186
- source_hash.clear
187
- unless directory.empty? || directory == '*'
188
- size = config.calculated.length
189
- 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
190
- config.calculated.each do |filename|
191
- begin
192
- source_hash[filename] = Solargraph::Source.load(filename)
193
- rescue Errno::ENOENT => e
194
- Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
195
- end
196
- end
197
- end
198
- end
199
-
200
- # @return [void]
201
- def require_plugins
202
- config.plugins.each do |plugin|
203
- begin
204
- require plugin
205
- rescue LoadError
206
- Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
207
- end
208
- end
209
- end
210
-
211
- # @return [String, nil]
212
- def read_rbs_collection_path
213
- return unless rbs_collection_config_path
214
-
215
- path = YAML.load_file(rbs_collection_config_path)&.fetch('path')
216
- # make fully qualified
217
- File.expand_path(path, directory)
218
- end
219
- end
220
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'json'
5
+
6
+ module Solargraph
7
+ # A workspace consists of the files in a project's directory and the
8
+ # project's configuration. It provides a Source for each file to be used
9
+ # in an associated Library or ApiMap.
10
+ #
11
+ class Workspace
12
+ autoload :Config, 'solargraph/workspace/config'
13
+ autoload :Gemspecs, 'solargraph/workspace/gemspecs'
14
+ autoload :RequirePaths, 'solargraph/workspace/require_paths'
15
+
16
+ # @return [String]
17
+ attr_reader :directory
18
+
19
+ # @return [Array<String>]
20
+ attr_reader :gemnames
21
+ alias source_gems gemnames
22
+
23
+ # @param directory [String] TODO: Remove '' and '*' special cases
24
+ # @param config [Config, nil]
25
+ # @param server [Hash]
26
+ def initialize directory = '', config = nil, server = {}
27
+ raise ArgumentError, 'directory must be a String' unless directory.is_a?(String)
28
+
29
+ @directory = if ['*', ''].include?(directory)
30
+ directory
31
+ else
32
+ File.absolute_path(directory)
33
+ end
34
+ @config = config
35
+ @server = server
36
+ load_sources
37
+ @gemnames = []
38
+ require_plugins
39
+ end
40
+
41
+ # The require paths associated with the workspace.
42
+ #
43
+ # @return [Array<String>]
44
+ def require_paths
45
+ # @todo are the semantics of '*' the same as '', meaning 'don't send back any require paths'?
46
+ @require_paths ||= RequirePaths.new(directory_or_nil, config).generate
47
+ end
48
+
49
+ # @return [Solargraph::Workspace::Config]
50
+ def config
51
+ @config ||= Solargraph::Workspace::Config.new(directory)
52
+ end
53
+
54
+ # @param level [Symbol]
55
+ # @return [TypeChecker::Rules]
56
+ def rules level
57
+ @rules ||= TypeChecker::Rules.new(level, config.type_checker_rules)
58
+ end
59
+
60
+ # Merge the source. A merge will update the existing source for the file
61
+ # or add it to the sources if the workspace is configured to include it.
62
+ # The source is ignored if the configuration excludes it.
63
+ #
64
+ # @param sources [Array<Solargraph::Source>]
65
+ # @return [Boolean] True if the source was added to the workspace
66
+ def merge *sources
67
+ unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
68
+ # Reload the config to determine if a new source should be included
69
+ @config = Solargraph::Workspace::Config.new(directory)
70
+ end
71
+
72
+ includes_any = false
73
+ sources.each do |source|
74
+ next unless directory == '*' || config.calculated.include?(source.filename)
75
+
76
+ # @sg-ignore Wrong argument type for Hash#[]=: arg0 expected String, received String, nil
77
+ source_hash[source.filename] = source
78
+ includes_any = true
79
+ end
80
+
81
+ includes_any
82
+ end
83
+
84
+ # Remove a source from the workspace. The source will not be removed if
85
+ # its file exists and the workspace is configured to include it.
86
+ #
87
+ # @param filename [String]
88
+ # @return [Boolean] True if the source was removed from the workspace
89
+ def remove filename
90
+ return false unless source_hash.key?(filename)
91
+ source_hash.delete filename
92
+ true
93
+ end
94
+
95
+ # @return [Array<String>]
96
+ def filenames
97
+ source_hash.keys
98
+ end
99
+
100
+ # @return [Array<Solargraph::Source>]
101
+ def sources
102
+ source_hash.values
103
+ end
104
+
105
+ # @param filename [String]
106
+ # @return [Boolean]
107
+ def has_file? filename
108
+ source_hash.key?(filename)
109
+ end
110
+
111
+ # Get a source by its filename.
112
+ #
113
+ # @param filename [String]
114
+ # @return [Solargraph::Source]
115
+ def source filename
116
+ source_hash[filename]
117
+ end
118
+
119
+ # True if the path resolves to a file in the workspace's require paths.
120
+ #
121
+ # @param path [String]
122
+ # @return [Boolean]
123
+ def would_require? path
124
+ require_paths.each do |rp|
125
+ full = File.join rp, path
126
+ return true if File.file?(full) || File.file?(full << '.rb')
127
+ end
128
+ false
129
+ end
130
+
131
+ # @return [String, nil]
132
+ def rbs_collection_path
133
+ @rbs_collection_path ||= read_rbs_collection_path
134
+ end
135
+
136
+ # @return [String, nil]
137
+ def rbs_collection_config_path
138
+ @rbs_collection_config_path ||= unless directory.empty? || directory == '*'
139
+ yaml_file = File.join(directory, 'rbs_collection.yaml')
140
+ yaml_file if File.file?(yaml_file)
141
+ end
142
+ end
143
+
144
+ # @param name [String]
145
+ # @param version [String, nil]
146
+ # @param out [IO, nil]
147
+ #
148
+ # @return [Gem::Specification, nil]
149
+ def find_gem name, version = nil, out: nil
150
+ Gem::Specification.find_by_name(name, version)
151
+ end
152
+
153
+ # Synchronize the workspace from the provided updater.
154
+ #
155
+ # @param updater [Source::Updater]
156
+ # @return [void]
157
+ def synchronize! updater
158
+ source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
159
+ end
160
+
161
+ # @sg-ignore return type could not be inferred
162
+ # @return [String]
163
+ def command_path
164
+ server['commandPath'] || 'solargraph'
165
+ end
166
+
167
+ # @return [String, nil]
168
+ def directory_or_nil
169
+ return nil if directory.empty? || directory == '*'
170
+ directory
171
+ end
172
+
173
+ # True if the workspace has a root Gemfile.
174
+ #
175
+ # @todo Handle projects with custom Bundler/Gemfile setups (see DocMap#gemspecs_required_from_bundler)
176
+ #
177
+ def gemfile?
178
+ directory && File.file?(File.join(directory, 'Gemfile'))
179
+ end
180
+
181
+ # True if the workspace contains at least one gemspec file.
182
+ #
183
+ # @return [Boolean]
184
+ def gemspec?
185
+ !gemspec_files.empty?
186
+ end
187
+
188
+ # Get an array of all gemspec files in the workspace.
189
+ #
190
+ # @return [Array<String>]
191
+ def gemspec_files
192
+ return [] if directory.empty? || directory == '*'
193
+ @gemspec_files ||= Dir[File.join(directory, '**/*.gemspec')].select do |gs|
194
+ config.allow? gs
195
+ end
196
+ end
197
+
198
+ private
199
+
200
+ # The language server configuration (or an empty hash if the workspace was
201
+ # not initialized from a server).
202
+ #
203
+ # @return [Hash]
204
+ attr_reader :server
205
+
206
+ # @return [Hash{String => Solargraph::Source}]
207
+ def source_hash
208
+ @source_hash ||= {}
209
+ end
210
+
211
+ # @return [void]
212
+ def load_sources
213
+ source_hash.clear
214
+ return if directory.empty? || directory == '*'
215
+ size = config.calculated.length
216
+ raise WorkspaceTooLargeError, "The workspace is too large to index (#{size} files, #{config.max_files} max)" if config.max_files.positive? && size > config.max_files
217
+ config.calculated.each do |filename|
218
+ source_hash[filename] = Solargraph::Source.load(filename)
219
+ rescue Errno::ENOENT => e
220
+ Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
221
+ end
222
+ end
223
+
224
+ # @return [void]
225
+ def require_plugins
226
+ config.plugins.each do |plugin|
227
+ require plugin
228
+ rescue LoadError
229
+ Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
230
+ end
231
+ end
232
+
233
+ # @return [String, nil]
234
+ def read_rbs_collection_path
235
+ return unless rbs_collection_config_path
236
+
237
+ path = YAML.load_file(rbs_collection_config_path)&.fetch('path')
238
+ # make fully qualified
239
+ File.expand_path(path, directory)
240
+ end
241
+ end
242
+ end
@@ -1,44 +1,49 @@
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, nil]
8
- # @return [Solargraph::Location, nil]
9
- def object_location code_object, spec
10
- if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
11
- if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
12
- # If the code object is a namespace, use the namespace's location
13
- return object_location(code_object.namespace, spec)
14
- end
15
- return Solargraph::Location.new(__FILE__, Solargraph::Range.from_to(__LINE__ - 1, 0, __LINE__ - 1, 0))
16
- end
17
- file = File.join(spec.full_gem_path, code_object.file)
18
- Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
19
- end
20
-
21
- # @param code_object [YARD::CodeObjects::Base]
22
- # @param spec [Gem::Specification, nil]
23
- # @return [Solargraph::Pin::Namespace]
24
- def create_closure_namespace_for(code_object, spec)
25
- code_object_for_location = code_object
26
- # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new")
27
- code_object_for_location = code_object.namespace if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
28
- namespace_location = object_location(code_object_for_location, spec)
29
- ns_name = code_object.namespace.to_s
30
- if ns_name.empty?
31
- Solargraph::Pin::ROOT_PIN
32
- else
33
- Solargraph::Pin::Namespace.new(
34
- name: ns_name,
35
- closure: Pin::ROOT_PIN,
36
- gates: [code_object.namespace.to_s],
37
- source: :yardoc,
38
- location: namespace_location
39
- )
40
- end
41
- end
42
- end
43
- end
44
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class YardMap
5
+ module Helpers
6
+ module_function
7
+
8
+ # @param code_object [YARD::CodeObjects::Base]
9
+ # @param spec [Gem::Specification, nil]
10
+ # @return [Solargraph::Location]
11
+ def object_location code_object, spec
12
+ if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
13
+ if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
14
+ # If the code object is a namespace, use the namespace's location
15
+ return object_location(code_object.namespace, spec)
16
+ end
17
+ return Solargraph::Location.new(__FILE__, Solargraph::Range.from_to(__LINE__ - 1, 0, __LINE__ - 1, 0))
18
+ end
19
+ # @sg-ignore flow sensitive typing should be able to identify more blocks that always return
20
+ file = File.join(spec.full_gem_path, code_object.file)
21
+ Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
22
+ end
23
+
24
+ # @param code_object [YARD::CodeObjects::Base]
25
+ # @param spec [Gem::Specification, nil]
26
+ # @return [Solargraph::Pin::Namespace]
27
+ def create_closure_namespace_for code_object, spec
28
+ code_object_for_location = code_object
29
+ # code_object.namespace is sometimes a YARD proxy object pointing to a method path ("Object#new")
30
+ if code_object.namespace.is_a?(YARD::CodeObjects::NamespaceObject)
31
+ code_object_for_location = code_object.namespace
32
+ end
33
+ namespace_location = object_location(code_object_for_location, spec)
34
+ ns_name = code_object.namespace.to_s
35
+ if ns_name.empty?
36
+ Solargraph::Pin::ROOT_PIN
37
+ else
38
+ Solargraph::Pin::Namespace.new(
39
+ name: ns_name,
40
+ closure: Pin::ROOT_PIN,
41
+ gates: [code_object.namespace.to_s],
42
+ source: :yardoc,
43
+ location: namespace_location
44
+ )
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end