solargraph 0.56.0 → 0.58.2

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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +6 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +92 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +110 -109
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +193 -175
  20. data/lib/solargraph/api_map/source_to_yard.rb +97 -88
  21. data/lib/solargraph/api_map/store.rb +384 -266
  22. data/lib/solargraph/api_map.rb +945 -973
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +228 -222
  25. data/lib/solargraph/complex_type/unique_type.rb +482 -475
  26. data/lib/solargraph/complex_type.rb +444 -423
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -60
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -100
  35. data/lib/solargraph/convention/struct_definition.rb +164 -101
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/require_not_found.rb +53 -53
  38. data/lib/solargraph/diagnostics/rubocop.rb +118 -113
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +68 -66
  40. data/lib/solargraph/diagnostics/type_check.rb +55 -55
  41. data/lib/solargraph/doc_map.rb +439 -405
  42. data/lib/solargraph/environ.rb +9 -2
  43. data/lib/solargraph/equality.rb +34 -33
  44. data/lib/solargraph/gem_pins.rb +98 -88
  45. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  46. data/lib/solargraph/language_server/host/dispatch.rb +130 -128
  47. data/lib/solargraph/language_server/host/message_worker.rb +112 -109
  48. data/lib/solargraph/language_server/host/sources.rb +99 -99
  49. data/lib/solargraph/language_server/host.rb +878 -871
  50. data/lib/solargraph/language_server/message/base.rb +2 -1
  51. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +114 -114
  52. data/lib/solargraph/language_server/message/extended/document.rb +23 -23
  53. data/lib/solargraph/language_server/message/text_document/completion.rb +56 -56
  54. data/lib/solargraph/language_server/message/text_document/definition.rb +40 -38
  55. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +26 -26
  56. data/lib/solargraph/language_server/message/text_document/formatting.rb +148 -131
  57. data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
  58. data/lib/solargraph/language_server/message/text_document/signature_help.rb +24 -24
  59. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -24
  60. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  61. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
  62. data/lib/solargraph/language_server/progress.rb +8 -0
  63. data/lib/solargraph/language_server/request.rb +4 -1
  64. data/lib/solargraph/library.rb +683 -666
  65. data/lib/solargraph/location.rb +82 -79
  66. data/lib/solargraph/logging.rb +37 -28
  67. data/lib/solargraph/page.rb +3 -0
  68. data/lib/solargraph/parser/comment_ripper.rb +69 -62
  69. data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -227
  70. data/lib/solargraph/parser/node_processor/base.rb +92 -87
  71. data/lib/solargraph/parser/node_processor.rb +62 -46
  72. data/lib/solargraph/parser/parser_gem/class_methods.rb +149 -159
  73. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_chainer.rb +166 -164
  75. data/lib/solargraph/parser/parser_gem/node_methods.rb +486 -497
  76. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -21
  77. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +59 -59
  78. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +15 -15
  79. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -45
  80. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  81. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +53 -53
  82. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -21
  83. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +40 -40
  84. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +29 -29
  85. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +59 -53
  86. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  87. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -41
  88. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -16
  89. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +38 -37
  90. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +52 -43
  91. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +291 -271
  92. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -29
  94. data/lib/solargraph/parser/parser_gem/node_processors.rb +70 -66
  95. data/lib/solargraph/parser/region.rb +69 -66
  96. data/lib/solargraph/parser/snippet.rb +17 -15
  97. data/lib/solargraph/pin/base.rb +729 -651
  98. data/lib/solargraph/pin/base_variable.rb +126 -125
  99. data/lib/solargraph/pin/block.rb +104 -103
  100. data/lib/solargraph/pin/breakable.rb +9 -9
  101. data/lib/solargraph/pin/callable.rb +231 -218
  102. data/lib/solargraph/pin/closure.rb +72 -74
  103. data/lib/solargraph/pin/common.rb +79 -75
  104. data/lib/solargraph/pin/constant.rb +2 -0
  105. data/lib/solargraph/pin/conversions.rb +123 -123
  106. data/lib/solargraph/pin/delegated_method.rb +120 -120
  107. data/lib/solargraph/pin/documenting.rb +114 -114
  108. data/lib/solargraph/pin/instance_variable.rb +34 -34
  109. data/lib/solargraph/pin/keyword.rb +20 -20
  110. data/lib/solargraph/pin/local_variable.rb +75 -76
  111. data/lib/solargraph/pin/method.rb +672 -651
  112. data/lib/solargraph/pin/method_alias.rb +34 -31
  113. data/lib/solargraph/pin/namespace.rb +115 -115
  114. data/lib/solargraph/pin/parameter.rb +275 -261
  115. data/lib/solargraph/pin/proxy_type.rb +39 -35
  116. data/lib/solargraph/pin/reference/override.rb +47 -33
  117. data/lib/solargraph/pin/reference/superclass.rb +15 -10
  118. data/lib/solargraph/pin/reference.rb +39 -22
  119. data/lib/solargraph/pin/search.rb +61 -56
  120. data/lib/solargraph/pin/signature.rb +61 -59
  121. data/lib/solargraph/pin/symbol.rb +53 -48
  122. data/lib/solargraph/pin/until.rb +18 -18
  123. data/lib/solargraph/pin/while.rb +18 -18
  124. data/lib/solargraph/pin.rb +44 -44
  125. data/lib/solargraph/pin_cache.rb +245 -185
  126. data/lib/solargraph/position.rb +132 -116
  127. data/lib/solargraph/range.rb +112 -107
  128. data/lib/solargraph/rbs_map/conversions.rb +823 -773
  129. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  130. data/lib/solargraph/rbs_map/core_map.rb +58 -51
  131. data/lib/solargraph/rbs_map/stdlib_map.rb +43 -43
  132. data/lib/solargraph/rbs_map.rb +163 -150
  133. data/lib/solargraph/shell.rb +352 -268
  134. data/lib/solargraph/source/chain/call.rb +337 -333
  135. data/lib/solargraph/source/chain/constant.rb +26 -89
  136. data/lib/solargraph/source/chain/hash.rb +34 -34
  137. data/lib/solargraph/source/chain/if.rb +28 -28
  138. data/lib/solargraph/source/chain/instance_variable.rb +13 -13
  139. data/lib/solargraph/source/chain/link.rb +11 -2
  140. data/lib/solargraph/source/chain/literal.rb +48 -48
  141. data/lib/solargraph/source/chain/or.rb +23 -23
  142. data/lib/solargraph/source/chain.rb +291 -282
  143. data/lib/solargraph/source/change.rb +82 -82
  144. data/lib/solargraph/source/cursor.rb +166 -167
  145. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  146. data/lib/solargraph/source/source_chainer.rb +194 -194
  147. data/lib/solargraph/source/updater.rb +55 -55
  148. data/lib/solargraph/source.rb +498 -495
  149. data/lib/solargraph/source_map/clip.rb +226 -234
  150. data/lib/solargraph/source_map/data.rb +34 -30
  151. data/lib/solargraph/source_map/mapper.rb +259 -259
  152. data/lib/solargraph/source_map.rb +212 -200
  153. data/lib/solargraph/type_checker/checks.rb +124 -124
  154. data/lib/solargraph/type_checker/param_def.rb +37 -35
  155. data/lib/solargraph/type_checker/problem.rb +32 -32
  156. data/lib/solargraph/type_checker/rules.rb +84 -62
  157. data/lib/solargraph/type_checker.rb +814 -699
  158. data/lib/solargraph/version.rb +5 -5
  159. data/lib/solargraph/workspace/config.rb +255 -239
  160. data/lib/solargraph/workspace/require_paths.rb +97 -0
  161. data/lib/solargraph/workspace.rb +220 -249
  162. data/lib/solargraph/yard_map/helpers.rb +44 -16
  163. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  164. data/lib/solargraph/yard_map/mapper/to_method.rb +130 -134
  165. data/lib/solargraph/yard_map/mapper/to_namespace.rb +31 -30
  166. data/lib/solargraph/yard_map/mapper.rb +79 -79
  167. data/lib/solargraph/yard_map/to_method.rb +89 -88
  168. data/lib/solargraph/yardoc.rb +87 -49
  169. data/lib/solargraph.rb +105 -90
  170. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  171. data/rbs/fills/open3/0/open3.rbs +172 -0
  172. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  173. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  174. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  175. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  176. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  177. data/rbs/shims/ast/0/node.rbs +5 -0
  178. data/rbs/shims/ast/2.4/.rbs_meta.yaml +9 -0
  179. data/rbs/shims/ast/2.4/ast.rbs +73 -0
  180. data/rbs/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  181. data/rbs/shims/parser/3.2.0.1/manifest.yaml +7 -0
  182. data/rbs/shims/parser/3.2.0.1/parser.rbs +201 -0
  183. data/rbs/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  184. data/rbs/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  185. data/rbs/shims/thor/1.2.0.1/manifest.yaml +7 -0
  186. data/rbs/shims/thor/1.2.0.1/thor.rbs +17 -0
  187. data/rbs_collection.yaml +4 -4
  188. data/solargraph.gemspec +26 -5
  189. metadata +187 -15
  190. data/lib/.rubocop.yml +0 -22
  191. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -1,249 +1,220 @@
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
-
14
- # @return [String]
15
- attr_reader :directory
16
-
17
- # The require paths associated with the workspace.
18
- #
19
- # @return [Array<String>]
20
- attr_reader :require_paths
21
-
22
- # @return [Array<String>]
23
- attr_reader :gemnames
24
- alias source_gems gemnames
25
-
26
- # @param directory [String]
27
- # @param config [Config, nil]
28
- # @param server [Hash]
29
- def initialize directory = '', config = nil, server = {}
30
- @directory = directory
31
- @config = config
32
- @server = server
33
- load_sources
34
- @gemnames = []
35
- @require_paths = generate_require_paths
36
- require_plugins
37
- end
38
-
39
- # @return [Solargraph::Workspace::Config]
40
- def config
41
- @config ||= Solargraph::Workspace::Config.new(directory)
42
- end
43
-
44
- # Merge the source. A merge will update the existing source for the file
45
- # or add it to the sources if the workspace is configured to include it.
46
- # The source is ignored if the configuration excludes it.
47
- #
48
- # @param sources [Array<Solargraph::Source>]
49
- # @return [Boolean] True if the source was added to the workspace
50
- def merge *sources
51
- unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
52
- # Reload the config to determine if a new source should be included
53
- @config = Solargraph::Workspace::Config.new(directory)
54
- end
55
-
56
- includes_any = false
57
- sources.each do |source|
58
- if directory == "*" || config.calculated.include?(source.filename)
59
- source_hash[source.filename] = source
60
- includes_any = true
61
- end
62
- end
63
-
64
- includes_any
65
- end
66
-
67
- # Remove a source from the workspace. The source will not be removed if
68
- # its file exists and the workspace is configured to include it.
69
- #
70
- # @param filename [String]
71
- # @return [Boolean] True if the source was removed from the workspace
72
- def remove filename
73
- return false unless source_hash.key?(filename)
74
- source_hash.delete filename
75
- true
76
- end
77
-
78
- # @return [Array<String>]
79
- def filenames
80
- source_hash.keys
81
- end
82
-
83
- # @return [Array<Solargraph::Source>]
84
- def sources
85
- source_hash.values
86
- end
87
-
88
- # @param filename [String]
89
- # @return [Boolean]
90
- def has_file? filename
91
- source_hash.key?(filename)
92
- end
93
-
94
- # Get a source by its filename.
95
- #
96
- # @param filename [String]
97
- # @return [Solargraph::Source]
98
- def source filename
99
- source_hash[filename]
100
- end
101
-
102
- # True if the path resolves to a file in the workspace's require paths.
103
- #
104
- # @param path [String]
105
- # @return [Boolean]
106
- def would_require? path
107
- require_paths.each do |rp|
108
- full = File.join rp, path
109
- return true if File.file?(full) || File.file?(full << ".rb")
110
- end
111
- false
112
- end
113
-
114
- # True if the workspace contains at least one gemspec file.
115
- #
116
- # @return [Boolean]
117
- def gemspec?
118
- !gemspecs.empty?
119
- end
120
-
121
- # Get an array of all gemspec files in the workspace.
122
- #
123
- # @return [Array<String>]
124
- def gemspecs
125
- return [] if directory.empty? || directory == '*'
126
- @gemspecs ||= Dir[File.join(directory, '**/*.gemspec')].select do |gs|
127
- config.allow? gs
128
- end
129
- end
130
-
131
- # @return [String, nil]
132
- def rbs_collection_path
133
- @gem_rbs_collection ||= read_rbs_collection_path
134
- end
135
-
136
- def rbs_collection_config_path
137
- @rbs_collection_config_path ||= begin
138
- 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
- end
144
-
145
- # Synchronize the workspace from the provided updater.
146
- #
147
- # @param updater [Source::Updater]
148
- # @return [void]
149
- def synchronize! updater
150
- source_hash[updater.filename] = source_hash[updater.filename].synchronize(updater)
151
- end
152
-
153
- # @return [String]
154
- def command_path
155
- server['commandPath'] || 'solargraph'
156
- end
157
-
158
- private
159
-
160
- # The language server configuration (or an empty hash if the workspace was
161
- # not initialized from a server).
162
- #
163
- # @return [Hash]
164
- attr_reader :server
165
-
166
- # @return [Hash{String => Solargraph::Source}]
167
- def source_hash
168
- @source_hash ||= {}
169
- end
170
-
171
- # @return [void]
172
- def load_sources
173
- source_hash.clear
174
- unless directory.empty? || directory == '*'
175
- size = config.calculated.length
176
- 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
177
- config.calculated.each do |filename|
178
- begin
179
- source_hash[filename] = Solargraph::Source.load(filename)
180
- rescue Errno::ENOENT => e
181
- Solargraph.logger.warn("Error loading #{filename}: [#{e.class}] #{e.message}")
182
- end
183
- end
184
- end
185
- end
186
-
187
- # Generate require paths from gemspecs if they exist or assume the default
188
- # lib directory.
189
- #
190
- # @return [Array<String>]
191
- def generate_require_paths
192
- return configured_require_paths unless gemspec?
193
- result = []
194
- gemspecs.each do |file|
195
- base = File.dirname(file)
196
- # HACK: Evaluating gemspec files violates the goal of not running
197
- # workspace code, but this is how Gem::Specification.load does it
198
- # anyway.
199
- 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)"]
200
- o, e, s = Open3.capture3(*cmd)
201
- if s.success?
202
- begin
203
- hash = o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
204
- next if hash.empty?
205
- @gemnames.push hash['name']
206
- result.concat(hash['paths'].map { |path| File.join(base, path) })
207
- rescue StandardError => e
208
- Solargraph.logger.warn "Error reading #{file}: [#{e.class}] #{e.message}"
209
- end
210
- else
211
- Solargraph.logger.warn "Error reading #{file}"
212
- Solargraph.logger.warn e
213
- end
214
- end
215
- result.concat(config.require_paths.map { |p| File.join(directory, p) })
216
- result.push File.join(directory, 'lib') if result.empty?
217
- result
218
- end
219
-
220
- # Get additional require paths defined in the configuration.
221
- #
222
- # @return [Array<String>]
223
- def configured_require_paths
224
- return ['lib'] if directory.empty?
225
- return [File.join(directory, 'lib')] if config.require_paths.empty?
226
- config.require_paths.map { |p| File.join(directory, p) }
227
- end
228
-
229
- # @return [void]
230
- def require_plugins
231
- config.plugins.each do |plugin|
232
- begin
233
- require plugin
234
- rescue LoadError
235
- Solargraph.logger.warn "Failed to load plugin '#{plugin}'"
236
- end
237
- end
238
- end
239
-
240
- # @return [String, nil]
241
- def read_rbs_collection_path
242
- return unless rbs_collection_config_path
243
-
244
- path = YAML.load_file(rbs_collection_config_path)&.fetch('path')
245
- # make fully qualified
246
- File.expand_path(path, directory)
247
- end
248
- end
249
- 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 :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,16 +1,44 @@
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
- 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
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
@@ -7,12 +7,12 @@ module Solargraph
7
7
  extend YardMap::Helpers
8
8
 
9
9
  # @param code_object [YARD::CodeObjects::Base]
10
+ # @param closure [Pin::Closure, nil]
11
+ # @param spec [Gem::Specification, nil]
12
+ # @return [Pin::Constant]
10
13
  def self.make code_object, closure = nil, spec = nil
11
- closure ||= Solargraph::Pin::Namespace.new(
12
- name: code_object.namespace.to_s,
13
- gates: [code_object.namespace.to_s],
14
- source: :yardoc,
15
- )
14
+ closure ||= create_closure_namespace_for(code_object, spec)
15
+
16
16
  Pin::Constant.new(
17
17
  location: object_location(code_object, spec),
18
18
  closure: closure,