solargraph 0.58.2 → 0.59.0.dev.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.
- checksums.yaml +4 -4
- data/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +41 -34
- data/.github/workflows/rspec.yml +44 -23
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop.yml +32 -5
- data/.rubocop_todo.yml +50 -966
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +13 -3
- data/lib/solargraph/api_map/index.rb +23 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +33 -28
- data/lib/solargraph/api_map.rb +150 -82
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +28 -17
- data/lib/solargraph/complex_type/unique_type.rb +218 -57
- data/lib/solargraph/complex_type.rb +170 -57
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
- data/lib/solargraph/convention/data_definition.rb +5 -2
- data/lib/solargraph/convention/gemfile.rb +15 -15
- data/lib/solargraph/convention/gemspec.rb +23 -23
- data/lib/solargraph/convention/rakefile.rb +17 -17
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
- data/lib/solargraph/convention/struct_definition.rb +8 -4
- data/lib/solargraph/convention.rb +78 -78
- data/lib/solargraph/converters/dd.rb +19 -17
- data/lib/solargraph/converters/dl.rb +17 -15
- data/lib/solargraph/converters/dt.rb +17 -15
- data/lib/solargraph/converters/misc.rb +3 -1
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +11 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/diagnostics/type_check.rb +11 -10
- data/lib/solargraph/diagnostics/update_errors.rb +37 -41
- data/lib/solargraph/doc_map.rb +133 -373
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +21 -20
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +3 -3
- data/lib/solargraph/language_server/host/message_worker.rb +4 -3
- data/lib/solargraph/language_server/host/sources.rb +2 -1
- data/lib/solargraph/language_server/host.rb +30 -22
- data/lib/solargraph/language_server/message/base.rb +97 -97
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/initialize.rb +197 -191
- data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
- data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +94 -94
- data/lib/solargraph/language_server/request.rb +29 -27
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/library.rb +85 -44
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +24 -4
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
- data/lib/solargraph/parser/node_processor/base.rb +34 -4
- data/lib/solargraph/parser/node_processor.rb +8 -7
- data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/parser_gem.rb +14 -12
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +126 -80
- data/lib/solargraph/pin/base_variable.rb +273 -24
- data/lib/solargraph/pin/block.rb +29 -6
- data/lib/solargraph/pin/breakable.rb +7 -1
- data/lib/solargraph/pin/callable.rb +65 -21
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +24 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +43 -45
- data/lib/solargraph/pin/conversions.rb +10 -4
- data/lib/solargraph/pin/delegated_method.rb +19 -8
- data/lib/solargraph/pin/documenting.rb +4 -2
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +15 -59
- data/lib/solargraph/pin/method.rb +153 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +100 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference.rb +19 -0
- data/lib/solargraph/pin/search.rb +3 -2
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/symbol.rb +2 -1
- data/lib/solargraph/pin/until.rb +2 -4
- data/lib/solargraph/pin/while.rb +2 -4
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +490 -73
- data/lib/solargraph/position.rb +14 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +343 -214
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
- data/lib/solargraph/rbs_map.rb +77 -32
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +128 -73
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/if.rb +12 -10
- data/lib/solargraph/source/chain/instance_variable.rb +24 -1
- data/lib/solargraph/source/chain/link.rb +99 -109
- data/lib/solargraph/source/chain/literal.rb +9 -6
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +13 -11
- data/lib/solargraph/source/chain/variable.rb +15 -13
- data/lib/solargraph/source/chain/z_super.rb +28 -30
- data/lib/solargraph/source/chain.rb +49 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +23 -17
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +56 -32
- data/lib/solargraph/source/updater.rb +5 -1
- data/lib/solargraph/source.rb +59 -35
- data/lib/solargraph/source_map/clip.rb +48 -29
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +71 -42
- data/lib/solargraph/source_map.rb +21 -9
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +81 -8
- data/lib/solargraph/type_checker.rb +195 -120
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +13 -10
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +149 -30
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +13 -8
- data/lib/solargraph/yard_tags.rb +20 -20
- data/lib/solargraph/yardoc.rb +33 -23
- data/lib/solargraph.rb +29 -8
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +36 -34
- metadata +38 -33
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
data/lib/solargraph/library.rb
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'rubygems'
|
|
3
4
|
require 'pathname'
|
|
4
5
|
require 'observer'
|
|
5
6
|
require 'open3'
|
|
6
7
|
|
|
8
|
+
# @!parse
|
|
9
|
+
# class ::Gem::Specification
|
|
10
|
+
# # @return [String]
|
|
11
|
+
# def name; end
|
|
12
|
+
# end
|
|
13
|
+
|
|
7
14
|
module Solargraph
|
|
8
15
|
# A Library handles coordination between a Workspace and an ApiMap.
|
|
9
16
|
#
|
|
@@ -33,6 +40,7 @@ module Solargraph
|
|
|
33
40
|
# @type [Source, nil]
|
|
34
41
|
@current = nil
|
|
35
42
|
@sync_count = 0
|
|
43
|
+
@cache_progress = nil
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def inspect
|
|
@@ -57,8 +65,11 @@ module Solargraph
|
|
|
57
65
|
# @param source [Source, nil]
|
|
58
66
|
# @return [void]
|
|
59
67
|
def attach source
|
|
68
|
+
# @sg-ignore Need to add nil check here
|
|
60
69
|
if @current && (!source || @current.filename != source.filename) && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
|
|
70
|
+
# @sg-ignore Need to add nil check here
|
|
61
71
|
source_map_hash.delete @current.filename
|
|
72
|
+
# @sg-ignore Need to add nil check here
|
|
62
73
|
source_map_external_require_hash.delete @current.filename
|
|
63
74
|
@external_requires = nil
|
|
64
75
|
end
|
|
@@ -116,8 +127,8 @@ module Solargraph
|
|
|
116
127
|
# @return [Boolean] True if at least one file was added to the workspace.
|
|
117
128
|
def create_from_disk *filenames
|
|
118
129
|
sources = filenames
|
|
119
|
-
|
|
120
|
-
|
|
130
|
+
.reject { |filename| File.directory?(filename) || !File.exist?(filename) }
|
|
131
|
+
.map { |filename| Solargraph::Source.load_string(File.read(filename), filename) }
|
|
121
132
|
result = workspace.merge(*sources)
|
|
122
133
|
sources.each { |source| maybe_map source }
|
|
123
134
|
result
|
|
@@ -182,9 +193,14 @@ module Solargraph
|
|
|
182
193
|
if cursor.comment?
|
|
183
194
|
source = read(filename)
|
|
184
195
|
offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
# @sg-ignore Need to add nil check here
|
|
197
|
+
# @type [MatchData, nil]
|
|
198
|
+
lft = source.code[0..(offset - 1)].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
|
|
199
|
+
# @sg-ignore Need to add nil check here
|
|
200
|
+
# @type [MatchData, nil]
|
|
201
|
+
rgt = source.code[offset..].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
|
|
187
202
|
if lft && rgt
|
|
203
|
+
# @sg-ignore Need to add nil check here
|
|
188
204
|
tag = (lft[1] + rgt[1]).sub(/:+$/, '')
|
|
189
205
|
clip = mutex.synchronize { api_map.clip(cursor) }
|
|
190
206
|
clip.translate tag
|
|
@@ -248,22 +264,26 @@ module Solargraph
|
|
|
248
264
|
return [] unless pin
|
|
249
265
|
result = []
|
|
250
266
|
files = if only
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
267
|
+
[api_map.source_map(filename)]
|
|
268
|
+
else
|
|
269
|
+
(workspace.sources + (@current ? [@current] : []))
|
|
270
|
+
end
|
|
255
271
|
files.uniq(&:filename).each do |source|
|
|
256
272
|
found = source.references(pin.name)
|
|
257
273
|
found.select! do |loc|
|
|
274
|
+
# @sg-ignore Need to add nil check here
|
|
275
|
+
# @type [Solargraph::Pin::Base, nil]
|
|
258
276
|
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
|
|
259
277
|
referenced&.path == pin.path
|
|
260
278
|
end
|
|
261
279
|
if pin.path == 'Class#new'
|
|
280
|
+
# @todo flow sensitive typing should allow shadowing of Kernel#caller
|
|
262
281
|
caller = cursor.chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
263
282
|
if caller.defined?
|
|
264
283
|
found.select! do |loc|
|
|
265
284
|
clip = api_map.clip_at(loc.filename, loc.range.start)
|
|
266
285
|
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
286
|
+
# @todo flow sensitive typing should allow shadowing of Kernel#caller
|
|
267
287
|
caller == other
|
|
268
288
|
end
|
|
269
289
|
else
|
|
@@ -271,14 +291,15 @@ module Solargraph
|
|
|
271
291
|
end
|
|
272
292
|
end
|
|
273
293
|
# HACK: for language clients that exclude special characters from the start of variable names
|
|
274
|
-
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
|
294
|
+
if strip && (match = cursor.word.match(/^[^a-z0-9_]+/i))
|
|
275
295
|
found.map! do |loc|
|
|
276
|
-
Solargraph::Location.new(loc.filename,
|
|
296
|
+
Solargraph::Location.new(loc.filename,
|
|
297
|
+
# @sg-ignore flow sensitive typing needs to handle if foo = bar
|
|
298
|
+
Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line,
|
|
299
|
+
loc.range.ending.column))
|
|
277
300
|
end
|
|
278
301
|
end
|
|
279
|
-
result.concat(found.sort
|
|
280
|
-
a.range.start.line <=> b.range.start.line
|
|
281
|
-
end)
|
|
302
|
+
result.concat(found.sort { |a, b| a.range.start.line <=> b.range.start.line })
|
|
282
303
|
end
|
|
283
304
|
result.uniq
|
|
284
305
|
end
|
|
@@ -299,18 +320,17 @@ module Solargraph
|
|
|
299
320
|
def locate_ref location
|
|
300
321
|
map = source_map_hash[location.filename]
|
|
301
322
|
return if map.nil?
|
|
323
|
+
# @sg-ignore Need to add nil check here
|
|
302
324
|
pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
|
|
303
325
|
return nil if pin.nil?
|
|
304
326
|
# @param full [String]
|
|
305
327
|
return_if_match = proc do |full|
|
|
306
|
-
if source_map_hash.key?(full)
|
|
307
|
-
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
|
|
308
|
-
end
|
|
328
|
+
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0)) if source_map_hash.key?(full)
|
|
309
329
|
end
|
|
310
330
|
workspace.require_paths.each do |path|
|
|
311
331
|
full = File.join path, pin.name
|
|
312
|
-
return_if_match.(full)
|
|
313
|
-
return_if_match.(full <<
|
|
332
|
+
return_if_match.call(full)
|
|
333
|
+
return_if_match.call(full << '.rb')
|
|
314
334
|
end
|
|
315
335
|
nil
|
|
316
336
|
rescue FileNotFoundError
|
|
@@ -403,6 +423,7 @@ module Solargraph
|
|
|
403
423
|
workspace.config.reporters.each do |line|
|
|
404
424
|
if line == 'all!'
|
|
405
425
|
Diagnostics.reporters.each do |reporter_name|
|
|
426
|
+
# @sg-ignore Need to add nil check here
|
|
406
427
|
repargs[Diagnostics.reporter(reporter_name)] ||= []
|
|
407
428
|
end
|
|
408
429
|
else
|
|
@@ -410,7 +431,9 @@ module Solargraph
|
|
|
410
431
|
name = args.shift
|
|
411
432
|
reporter = Diagnostics.reporter(name)
|
|
412
433
|
raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
|
|
434
|
+
# @sg-ignore flow sensitive typing needs to handle 'raise if'
|
|
413
435
|
repargs[reporter] ||= []
|
|
436
|
+
# @sg-ignore flow sensitive typing needs to handle 'raise if'
|
|
414
437
|
repargs[reporter].concat args
|
|
415
438
|
end
|
|
416
439
|
end
|
|
@@ -433,6 +456,7 @@ module Solargraph
|
|
|
433
456
|
source_maps: source_map_hash.values,
|
|
434
457
|
workspace: workspace,
|
|
435
458
|
external_requires: external_requires,
|
|
459
|
+
# @sg-ignore Need to add nil check here
|
|
436
460
|
live_map: @current ? source_map_hash[@current.filename] : nil
|
|
437
461
|
)
|
|
438
462
|
end
|
|
@@ -469,10 +493,13 @@ module Solargraph
|
|
|
469
493
|
# @return [SourceMap, Boolean]
|
|
470
494
|
def next_map
|
|
471
495
|
return false if mapped?
|
|
496
|
+
# @sg-ignore Need to add nil check here
|
|
472
497
|
src = workspace.sources.find { |s| !source_map_hash.key?(s.filename) }
|
|
473
498
|
if src
|
|
474
499
|
Logging.logger.debug "Mapping #{src.filename}"
|
|
500
|
+
# @sg-ignore Need to add nil check here
|
|
475
501
|
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
|
502
|
+
# @sg-ignore Need to add nil check here
|
|
476
503
|
source_map_hash[src.filename]
|
|
477
504
|
else
|
|
478
505
|
false
|
|
@@ -482,7 +509,9 @@ module Solargraph
|
|
|
482
509
|
# @return [self]
|
|
483
510
|
def map!
|
|
484
511
|
workspace.sources.each do |src|
|
|
512
|
+
# @sg-ignore Need to add nil check here
|
|
485
513
|
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
|
514
|
+
# @sg-ignore Need to add nil check here
|
|
486
515
|
find_external_requires source_map_hash[src.filename]
|
|
487
516
|
end
|
|
488
517
|
self
|
|
@@ -500,6 +529,11 @@ module Solargraph
|
|
|
500
529
|
|
|
501
530
|
private
|
|
502
531
|
|
|
532
|
+
# @return [PinCache]
|
|
533
|
+
def pin_cache
|
|
534
|
+
workspace.pin_cache
|
|
535
|
+
end
|
|
536
|
+
|
|
503
537
|
# @return [Hash{String => Array<String>}]
|
|
504
538
|
def source_map_external_require_hash
|
|
505
539
|
@source_map_external_require_hash ||= {}
|
|
@@ -509,14 +543,15 @@ module Solargraph
|
|
|
509
543
|
# @return [void]
|
|
510
544
|
def find_external_requires source_map
|
|
511
545
|
# @type [Set<String>]
|
|
512
|
-
new_set = source_map.requires.
|
|
546
|
+
new_set = source_map.requires.to_set(&:name)
|
|
513
547
|
# return if new_set == source_map_external_require_hash[source_map.filename]
|
|
514
548
|
_filenames = nil
|
|
515
|
-
filenames = ->{ _filenames ||= workspace.filenames.to_set }
|
|
549
|
+
filenames = -> { _filenames ||= workspace.filenames.to_set }
|
|
550
|
+
# @sg-ignore Need to add nil check here
|
|
516
551
|
source_map_external_require_hash[source_map.filename] = new_set.reject do |path|
|
|
517
552
|
workspace.require_paths.any? do |base|
|
|
518
553
|
full = File.join(base, path)
|
|
519
|
-
filenames[].include?(full) or filenames[].include?(full <<
|
|
554
|
+
filenames[].include?(full) or filenames[].include?(full << '.rb')
|
|
520
555
|
end
|
|
521
556
|
end
|
|
522
557
|
@external_requires = nil
|
|
@@ -550,23 +585,24 @@ module Solargraph
|
|
|
550
585
|
# @param error [FileNotFoundError]
|
|
551
586
|
# @return [nil]
|
|
552
587
|
def handle_file_not_found filename, error
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
else
|
|
557
|
-
raise error
|
|
558
|
-
end
|
|
588
|
+
raise error unless workspace.source(filename)
|
|
589
|
+
Solargraph.logger.debug "#{filename} is not cataloged in the ApiMap"
|
|
590
|
+
nil
|
|
559
591
|
end
|
|
560
592
|
|
|
561
593
|
# @param source [Source, nil]
|
|
562
594
|
# @return [void]
|
|
563
595
|
def maybe_map source
|
|
564
596
|
return unless source
|
|
597
|
+
# @sg-ignore Need to add nil check here
|
|
565
598
|
return unless @current == source || workspace.has_file?(source.filename)
|
|
599
|
+
# @sg-ignore Need to add nil check here
|
|
566
600
|
if source_map_hash.key?(source.filename)
|
|
567
601
|
new_map = Solargraph::SourceMap.map(source)
|
|
602
|
+
# @sg-ignore Need to add nil check here
|
|
568
603
|
source_map_hash[source.filename] = new_map
|
|
569
604
|
else
|
|
605
|
+
# @sg-ignore Need to add nil check here
|
|
570
606
|
source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
|
|
571
607
|
end
|
|
572
608
|
end
|
|
@@ -585,7 +621,7 @@ module Solargraph
|
|
|
585
621
|
|
|
586
622
|
pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
|
|
587
623
|
|
|
588
|
-
if
|
|
624
|
+
if pin_cache.yardoc_processing?(spec)
|
|
589
625
|
logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
|
|
590
626
|
queued_gemspec_cache.push(spec)
|
|
591
627
|
return if pending - queued_gemspec_cache.length < 1
|
|
@@ -596,7 +632,10 @@ module Solargraph
|
|
|
596
632
|
logger.info "Caching #{spec.name} #{spec.version}"
|
|
597
633
|
Thread.new do
|
|
598
634
|
report_cache_progress spec.name, pending
|
|
599
|
-
|
|
635
|
+
kwargs = {}
|
|
636
|
+
kwargs[:chdir] = workspace.directory.to_s if workspace.directory && !workspace.directory.empty?
|
|
637
|
+
_o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s,
|
|
638
|
+
**kwargs)
|
|
600
639
|
if s.success?
|
|
601
640
|
logger.info "Cached #{spec.name} #{spec.version}"
|
|
602
641
|
else
|
|
@@ -613,8 +652,7 @@ module Solargraph
|
|
|
613
652
|
|
|
614
653
|
# @return [Array<Gem::Specification>]
|
|
615
654
|
def cacheable_specs
|
|
616
|
-
cacheable = api_map.
|
|
617
|
-
api_map.uncached_rbs_collection_gemspecs -
|
|
655
|
+
cacheable = api_map.uncached_gemspecs +
|
|
618
656
|
queued_gemspec_cache -
|
|
619
657
|
cache_errors.to_a
|
|
620
658
|
return cacheable unless cacheable.empty?
|
|
@@ -632,26 +670,30 @@ module Solargraph
|
|
|
632
670
|
# @return [void]
|
|
633
671
|
def report_cache_progress gem_name, pending
|
|
634
672
|
@total ||= pending
|
|
673
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
635
674
|
@total = pending if pending > @total
|
|
675
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
636
676
|
finished = @total - pending
|
|
677
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
637
678
|
pct = if @total.zero?
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
679
|
+
0
|
|
680
|
+
else
|
|
681
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
682
|
+
((finished.to_f / @total) * 100).to_i
|
|
683
|
+
end
|
|
684
|
+
message = "#{gem_name}#{" (+#{pending})" if pending.positive?}"
|
|
643
685
|
# "
|
|
644
|
-
|
|
645
|
-
@cache_progress.report(message, pct)
|
|
646
|
-
else
|
|
686
|
+
unless @cache_progress
|
|
647
687
|
@cache_progress = LanguageServer::Progress.new('Caching gem')
|
|
648
688
|
# If we don't send both a begin and a report, the progress notification
|
|
649
689
|
# might get stuck in the status bar forever
|
|
690
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
650
691
|
@cache_progress.begin(message, pct)
|
|
651
692
|
changed
|
|
652
693
|
notify_observers @cache_progress
|
|
653
|
-
@cache_progress.report(message, pct)
|
|
654
694
|
end
|
|
695
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
696
|
+
@cache_progress.report(message, pct)
|
|
655
697
|
changed
|
|
656
698
|
notify_observers @cache_progress
|
|
657
699
|
end
|
|
@@ -666,15 +708,14 @@ module Solargraph
|
|
|
666
708
|
|
|
667
709
|
# @return [void]
|
|
668
710
|
def sync_catalog
|
|
669
|
-
return if @sync_count
|
|
711
|
+
return if @sync_count.zero?
|
|
670
712
|
|
|
671
713
|
mutex.synchronize do
|
|
672
714
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
|
673
|
-
source_map_hash.
|
|
715
|
+
source_map_hash.each_value { |map| find_external_requires(map) }
|
|
674
716
|
api_map.catalog bench
|
|
675
717
|
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
|
|
676
|
-
logger.info "#{api_map.
|
|
677
|
-
logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
|
|
718
|
+
logger.info "#{api_map.uncached_gemspecs.length} uncached gemspecs"
|
|
678
719
|
cache_next_gemspec
|
|
679
720
|
@sync_count = 0
|
|
680
721
|
end
|
data/lib/solargraph/location.rb
CHANGED
|
@@ -6,6 +6,7 @@ module Solargraph
|
|
|
6
6
|
#
|
|
7
7
|
class Location
|
|
8
8
|
include Equality
|
|
9
|
+
include Comparable
|
|
9
10
|
|
|
10
11
|
# @return [String]
|
|
11
12
|
attr_reader :filename
|
|
@@ -13,20 +14,17 @@ module Solargraph
|
|
|
13
14
|
# @return [Solargraph::Range]
|
|
14
15
|
attr_reader :range
|
|
15
16
|
|
|
16
|
-
# @param filename [String]
|
|
17
|
+
# @param filename [String, nil]
|
|
17
18
|
# @param range [Solargraph::Range]
|
|
18
19
|
def initialize filename, range
|
|
20
|
+
raise 'Use nil to represent no-file' if filename&.empty?
|
|
21
|
+
|
|
19
22
|
@filename = filename
|
|
20
23
|
@range = range
|
|
21
24
|
end
|
|
22
25
|
|
|
23
|
-
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
24
|
-
protected def equality_fields
|
|
25
|
-
[filename, range]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
26
|
# @param other [self]
|
|
29
|
-
def <=>
|
|
27
|
+
def <=> other
|
|
30
28
|
return nil unless other.is_a?(Location)
|
|
31
29
|
if filename == other.filename
|
|
32
30
|
range <=> other.range
|
|
@@ -44,10 +42,6 @@ module Solargraph
|
|
|
44
42
|
range.contain?(location.range.start) && range.contain?(location.range.ending) && filename == location.filename
|
|
45
43
|
end
|
|
46
44
|
|
|
47
|
-
def inspect
|
|
48
|
-
"<#{self.class.name}: filename=#{filename}, range=#{range.inspect}>"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
45
|
def to_s
|
|
52
46
|
inspect
|
|
53
47
|
end
|
|
@@ -62,21 +56,30 @@ module Solargraph
|
|
|
62
56
|
|
|
63
57
|
# @param node [Parser::AST::Node, nil]
|
|
64
58
|
# @return [Location, nil]
|
|
65
|
-
def self.from_node
|
|
59
|
+
def self.from_node node
|
|
66
60
|
return nil if node.nil? || node.loc.nil?
|
|
61
|
+
filename = node.loc.expression.source_buffer.name
|
|
62
|
+
# @sg-ignore flow sensitive typing needs to create separate ranges for postfix if
|
|
63
|
+
filename = nil if filename.empty?
|
|
67
64
|
range = Range.from_node(node)
|
|
68
|
-
|
|
65
|
+
# @sg-ignore Need to add nil check here
|
|
66
|
+
new(filename, range)
|
|
69
67
|
end
|
|
70
68
|
|
|
71
69
|
# @param other [BasicObject]
|
|
72
70
|
def == other
|
|
73
71
|
return false unless other.is_a?(Location)
|
|
74
|
-
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
75
72
|
filename == other.filename and range == other.range
|
|
76
73
|
end
|
|
77
74
|
|
|
78
75
|
def inspect
|
|
79
76
|
"#<#{self.class} #{filename}, #{range.inspect}>"
|
|
80
77
|
end
|
|
78
|
+
|
|
79
|
+
protected
|
|
80
|
+
|
|
81
|
+
def equality_fields
|
|
82
|
+
[filename, range]
|
|
83
|
+
end
|
|
81
84
|
end
|
|
82
85
|
end
|
data/lib/solargraph/logging.rb
CHANGED
|
@@ -10,7 +10,7 @@ module Solargraph
|
|
|
10
10
|
'warn' => Logger::WARN,
|
|
11
11
|
'info' => Logger::INFO,
|
|
12
12
|
'debug' => Logger::DEBUG
|
|
13
|
-
}
|
|
13
|
+
}.freeze
|
|
14
14
|
configured_level = ENV.fetch('SOLARGRAPH_LOG', nil)
|
|
15
15
|
level = if LOG_LEVELS.keys.include?(configured_level)
|
|
16
16
|
LOG_LEVELS.fetch(configured_level)
|
|
@@ -21,17 +21,37 @@ module Solargraph
|
|
|
21
21
|
end
|
|
22
22
|
DEFAULT_LOG_LEVEL
|
|
23
23
|
end
|
|
24
|
-
@@logger = Logger.new(
|
|
24
|
+
@@logger = Logger.new($stderr, level: level)
|
|
25
25
|
# @sg-ignore Fix cvar issue
|
|
26
|
-
@@logger.formatter = proc do |severity,
|
|
26
|
+
@@logger.formatter = proc do |severity, _datetime, _progname, msg|
|
|
27
27
|
"[#{severity}] #{msg}\n"
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
module_function
|
|
31
31
|
|
|
32
|
+
# override this in your class to temporarily set a custom
|
|
33
|
+
# filtering log level for the class (e.g., suppress any debug
|
|
34
|
+
# message by setting it to :info even if it is set elsewhere, or
|
|
35
|
+
# show existing debug messages by setting to :debug).
|
|
36
|
+
#
|
|
37
|
+
# @return [Symbol]
|
|
38
|
+
def log_level
|
|
39
|
+
:warn
|
|
40
|
+
end
|
|
41
|
+
|
|
32
42
|
# @return [Logger]
|
|
33
43
|
def logger
|
|
34
|
-
|
|
44
|
+
if LOG_LEVELS[log_level.to_s] == DEFAULT_LOG_LEVEL
|
|
45
|
+
@@logger
|
|
46
|
+
else
|
|
47
|
+
new_log_level = LOG_LEVELS[log_level.to_s]
|
|
48
|
+
logger = Logger.new($stderr, level: new_log_level)
|
|
49
|
+
|
|
50
|
+
# @sg-ignore Wrong argument type for Logger#formatter=: arg_0
|
|
51
|
+
# expected nil, received Logger::_Formatter, nil
|
|
52
|
+
logger.formatter = @@logger.formatter
|
|
53
|
+
logger
|
|
54
|
+
end
|
|
35
55
|
end
|
|
36
56
|
end
|
|
37
57
|
end
|
data/lib/solargraph/page.rb
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'ostruct'
|
|
4
|
-
require 'tilt'
|
|
5
|
-
require 'yard'
|
|
6
|
-
require 'cgi'
|
|
7
|
-
|
|
8
|
-
module Solargraph
|
|
9
|
-
class Page
|
|
10
|
-
# @todo This method directive is necessary because OpenStruct.new confuses
|
|
11
|
-
# the typechecker.
|
|
12
|
-
# @!method self.new(locals, render_method)
|
|
13
|
-
# @param locals[Hash]
|
|
14
|
-
# @param render_method [Proc]
|
|
15
|
-
# @return [Binder]
|
|
16
|
-
class Binder < OpenStruct
|
|
17
|
-
# @param locals [Hash]
|
|
18
|
-
# @param render_method [Proc]
|
|
19
|
-
def initialize locals, render_method
|
|
20
|
-
super(locals)
|
|
21
|
-
define_singleton_method :render do |template, layout: false, locals: {}|
|
|
22
|
-
render_method.call(template, layout: layout, locals: locals)
|
|
23
|
-
end
|
|
24
|
-
define_singleton_method :erb do |template, layout: false, locals: {}|
|
|
25
|
-
render_method.call(template, layout: layout, locals: locals)
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# @param text [String]
|
|
30
|
-
# @return [String]
|
|
31
|
-
def htmlify text
|
|
32
|
-
# @type [String]
|
|
33
|
-
YARD::Templates::Helpers::Markup::RDocMarkup.new(text).to_html
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# @param text [String]
|
|
37
|
-
# @return [String]
|
|
38
|
-
def escape text
|
|
39
|
-
CGI.escapeHTML(text)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# @param code [String]
|
|
43
|
-
# @return [String]
|
|
44
|
-
def ruby_to_html code
|
|
45
|
-
code
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
private_constant :Binder
|
|
49
|
-
|
|
50
|
-
# @param directory [String]
|
|
51
|
-
def initialize directory = VIEWS_PATH
|
|
52
|
-
directory = VIEWS_PATH if directory.nil?
|
|
53
|
-
directories = [directory]
|
|
54
|
-
directories.push VIEWS_PATH if directory != VIEWS_PATH
|
|
55
|
-
# @type [Proc]
|
|
56
|
-
# @param template [String]
|
|
57
|
-
# @param layout [Boolean]
|
|
58
|
-
# @param locals [Hash]
|
|
59
|
-
@render_method = proc { |template, layout: false, locals: {}|
|
|
60
|
-
binder = Binder.new(locals, @render_method)
|
|
61
|
-
if layout
|
|
62
|
-
Tilt::ERBTemplate.new(Page.select_template(directories, 'layout')).render(binder) do
|
|
63
|
-
Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
|
|
64
|
-
end
|
|
65
|
-
else
|
|
66
|
-
Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
|
|
67
|
-
end
|
|
68
|
-
}
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# @param template [String]
|
|
72
|
-
# @param layout [Boolean]
|
|
73
|
-
# @param locals [Hash]
|
|
74
|
-
# @sg-ignore
|
|
75
|
-
# @return [String]
|
|
76
|
-
def render template, layout: true, locals: {}
|
|
77
|
-
# @type [String]
|
|
78
|
-
@render_method.call(template, layout: layout, locals: locals)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
# @param directories [Array<String>]
|
|
82
|
-
# @param name [String]
|
|
83
|
-
# @return [String]
|
|
84
|
-
def self.select_template directories, name
|
|
85
|
-
directories.each do |dir|
|
|
86
|
-
path = File.join(dir, "#{name}.erb")
|
|
87
|
-
return path if File.file?(path)
|
|
88
|
-
end
|
|
89
|
-
raise FileNotFoundError, "Template not found: #{name}"
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
require 'tilt'
|
|
5
|
+
require 'yard'
|
|
6
|
+
require 'cgi'
|
|
7
|
+
|
|
8
|
+
module Solargraph
|
|
9
|
+
class Page
|
|
10
|
+
# @todo This method directive is necessary because OpenStruct.new confuses
|
|
11
|
+
# the typechecker.
|
|
12
|
+
# @!method self.new(locals, render_method)
|
|
13
|
+
# @param locals[Hash]
|
|
14
|
+
# @param render_method [Proc]
|
|
15
|
+
# @return [Binder]
|
|
16
|
+
class Binder < OpenStruct
|
|
17
|
+
# @param locals [Hash]
|
|
18
|
+
# @param render_method [Proc]
|
|
19
|
+
def initialize locals, render_method
|
|
20
|
+
super(locals)
|
|
21
|
+
define_singleton_method :render do |template, layout: false, locals: {}|
|
|
22
|
+
render_method.call(template, layout: layout, locals: locals)
|
|
23
|
+
end
|
|
24
|
+
define_singleton_method :erb do |template, layout: false, locals: {}|
|
|
25
|
+
render_method.call(template, layout: layout, locals: locals)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param text [String]
|
|
30
|
+
# @return [String]
|
|
31
|
+
def htmlify text
|
|
32
|
+
# @type [String]
|
|
33
|
+
YARD::Templates::Helpers::Markup::RDocMarkup.new(text).to_html
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @param text [String]
|
|
37
|
+
# @return [String]
|
|
38
|
+
def escape text
|
|
39
|
+
CGI.escapeHTML(text)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param code [String]
|
|
43
|
+
# @return [String]
|
|
44
|
+
def ruby_to_html code
|
|
45
|
+
code
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
private_constant :Binder
|
|
49
|
+
|
|
50
|
+
# @param directory [String]
|
|
51
|
+
def initialize directory = VIEWS_PATH
|
|
52
|
+
directory = VIEWS_PATH if directory.nil? || !File.directory?(directory)
|
|
53
|
+
directories = [directory]
|
|
54
|
+
directories.push VIEWS_PATH if directory != VIEWS_PATH
|
|
55
|
+
# @type [Proc]
|
|
56
|
+
# @param template [String]
|
|
57
|
+
# @param layout [Boolean]
|
|
58
|
+
# @param locals [Hash]
|
|
59
|
+
@render_method = proc { |template, layout: false, locals: {}|
|
|
60
|
+
binder = Binder.new(locals, @render_method)
|
|
61
|
+
if layout
|
|
62
|
+
Tilt::ERBTemplate.new(Page.select_template(directories, 'layout')).render(binder) do
|
|
63
|
+
Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
Tilt::ERBTemplate.new(Page.select_template(directories, template)).render(binder)
|
|
67
|
+
end
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @param template [String]
|
|
72
|
+
# @param layout [Boolean]
|
|
73
|
+
# @param locals [Hash]
|
|
74
|
+
# @sg-ignore
|
|
75
|
+
# @return [String]
|
|
76
|
+
def render template, layout: true, locals: {}
|
|
77
|
+
# @type [String]
|
|
78
|
+
@render_method.call(template, layout: layout, locals: locals)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @param directories [Array<String>]
|
|
82
|
+
# @param name [String]
|
|
83
|
+
# @return [String]
|
|
84
|
+
def self.select_template directories, name
|
|
85
|
+
directories.each do |dir|
|
|
86
|
+
path = File.join(dir, "#{name}.erb")
|
|
87
|
+
return path if File.file?(path)
|
|
88
|
+
end
|
|
89
|
+
raise FileNotFoundError, "Template not found: #{name}"
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|