solargraph 0.55.1 → 0.55.4
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/.github/workflows/typecheck.yml +1 -1
- data/CHANGELOG.md +9 -0
- data/lib/solargraph/api_map/store.rb +6 -3
- data/lib/solargraph/api_map.rb +98 -31
- data/lib/solargraph/complex_type/type_methods.rb +1 -0
- data/lib/solargraph/complex_type/unique_type.rb +3 -2
- data/lib/solargraph/doc_map.rb +57 -28
- data/lib/solargraph/gem_pins.rb +2 -1
- data/lib/solargraph/language_server/host.rb +2 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -0
- data/lib/solargraph/logging.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +1 -0
- data/lib/solargraph/parser/flow_sensitive_typing.rb +5 -4
- data/lib/solargraph/parser/node_processor.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +4 -2
- 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 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/pin/base.rb +27 -4
- data/lib/solargraph/pin/callable.rb +5 -3
- data/lib/solargraph/pin/closure.rb +6 -1
- data/lib/solargraph/pin/common.rb +5 -0
- data/lib/solargraph/pin/delegated_method.rb +2 -0
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/method.rb +14 -9
- data/lib/solargraph/pin/namespace.rb +7 -2
- data/lib/solargraph/pin/parameter.rb +4 -0
- data/lib/solargraph/pin/proxy_type.rb +3 -3
- data/lib/solargraph/pin/reference/override.rb +10 -6
- data/lib/solargraph/pin/reference/require.rb +2 -2
- data/lib/solargraph/pin/signature.rb +4 -0
- data/lib/solargraph/pin/singleton.rb +1 -1
- data/lib/solargraph/pin/symbol.rb +3 -2
- data/lib/solargraph/pin.rb +1 -1
- data/lib/solargraph/rbs_map/conversions.rb +164 -48
- data/lib/solargraph/rbs_map/core_fills.rb +24 -15
- data/lib/solargraph/rbs_map/core_map.rb +3 -2
- data/lib/solargraph/shell.rb +1 -0
- data/lib/solargraph/source/chain/array.rb +7 -4
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +8 -7
- data/lib/solargraph/source/chain/hash.rb +1 -1
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +1 -1
- data/lib/solargraph/source/chain/literal.rb +2 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +2 -2
- data/lib/solargraph/source_map/mapper.rb +9 -5
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +4 -2
- data/lib/solargraph/yard_map/mapper/to_method.rb +14 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +4 -2
- data/lib/solargraph/yard_map/mapper.rb +4 -3
- data/lib/solargraph/yard_map/to_method.rb +4 -2
- data/lib/solargraph.rb +20 -0
- data/rbs/fills/tuple.rbs +150 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e00ddc5e4b665c4527099b496d2caf414a0fe5c1cdb44e71b4af16a7c5521d34
|
4
|
+
data.tar.gz: 494b003c5260150a4c66952c0e4c512374197a52b528249027100b48a3deb4c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b56ff99aecf4a656722a8a55cdcf521b9dba1066c53e22dd344840f173dfb302fb560daba2b828af01ad0789f7defab7976511509484613df13687854b90bf77
|
7
|
+
data.tar.gz: 2cc74269454a5290c0c98e89f55942bdc36f916b622bfc37a42d4aeaf30d023f497a6be585f725b4397991a5083fdc43dedf90c05526a3739bb2c4a78266daf0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.55.4 - June 27, 2025
|
2
|
+
- Flatten results of DocMap external bundle query (#981)
|
3
|
+
|
4
|
+
## 0.55.3 - June 25, 2025
|
5
|
+
- Nil guards in flow-sensitive typing (patch release) (#980)
|
6
|
+
|
7
|
+
## 0.55.2 - June 21, 2025
|
8
|
+
- Require external bundle (#972)
|
9
|
+
|
1
10
|
## 0.55.1 - June 8, 2025
|
2
11
|
- Fix inline Struct definition (#962)
|
3
12
|
- Ensure DocMap requires bundler when loading gemspecs (#963)
|
@@ -66,10 +66,13 @@ module Solargraph
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
# @param
|
69
|
+
# @param fq_tag [String]
|
70
70
|
# @return [String, nil]
|
71
|
-
def get_superclass
|
72
|
-
raise "Do not prefix fully qualified
|
71
|
+
def get_superclass fq_tag
|
72
|
+
raise "Do not prefix fully qualified tags with '::' - #{fq_tag.inspect}" if fq_tag.start_with?('::')
|
73
|
+
sub = ComplexType.parse(fq_tag)
|
74
|
+
fqns = sub.namespace
|
75
|
+
return superclass_references[fq_tag].first if superclass_references.key?(fq_tag)
|
73
76
|
return superclass_references[fqns].first if superclass_references.key?(fqns)
|
74
77
|
return 'Object' if fqns != 'BasicObject' && namespace_exists?(fqns)
|
75
78
|
return 'Object' if fqns == 'Boolean'
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -94,7 +94,7 @@ module Solargraph
|
|
94
94
|
end
|
95
95
|
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).to_a.compact.uniq
|
96
96
|
if @unresolved_requires != unresolved_requires || @doc_map&.uncached_gemspecs&.any?
|
97
|
-
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace
|
97
|
+
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace) # @todo Implement gem preferences
|
98
98
|
@unresolved_requires = unresolved_requires
|
99
99
|
end
|
100
100
|
@cache.clear if store.update(@@core_map.pins, @doc_map.pins, implicit.pins, iced_pins, live_pins)
|
@@ -359,6 +359,11 @@ module Solargraph
|
|
359
359
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
360
360
|
# @return [Array<Solargraph::Pin::Method>]
|
361
361
|
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
362
|
+
if rooted_tag.start_with? 'Array('
|
363
|
+
# Array() are really tuples - use our fill, as the RBS repo
|
364
|
+
# does not give us definitions for it
|
365
|
+
rooted_tag = "Solargraph::Fills::Tuple(#{rooted_tag[6..-2]})"
|
366
|
+
end
|
362
367
|
rooted_type = ComplexType.try_parse(rooted_tag)
|
363
368
|
fqns = rooted_type.namespace
|
364
369
|
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
@@ -386,18 +391,35 @@ module Solargraph
|
|
386
391
|
next pin unless init_pin
|
387
392
|
|
388
393
|
type = ComplexType::SELF
|
389
|
-
Pin::Method.new(
|
394
|
+
new_pin = Pin::Method.new(
|
390
395
|
name: 'new',
|
391
396
|
scope: :class,
|
392
397
|
location: init_pin.location,
|
393
|
-
parameters: init_pin.parameters,
|
394
|
-
signatures: init_pin.signatures.map { |sig| sig.proxy(type) },
|
395
398
|
return_type: type,
|
396
399
|
comments: init_pin.comments,
|
397
400
|
closure: init_pin.closure,
|
398
401
|
source: init_pin.source,
|
399
402
|
type_location: init_pin.type_location,
|
400
403
|
)
|
404
|
+
new_pin.parameters = init_pin.parameters.map do |init_param|
|
405
|
+
param = init_param.clone
|
406
|
+
param.closure = new_pin
|
407
|
+
param.reset_generated!
|
408
|
+
param
|
409
|
+
end.freeze
|
410
|
+
new_pin.signatures = init_pin.signatures.map do |init_sig|
|
411
|
+
sig = init_sig.proxy(type)
|
412
|
+
sig.parameters = init_sig.parameters.map do |param|
|
413
|
+
param = param.clone
|
414
|
+
param.closure = new_pin
|
415
|
+
param.reset_generated!
|
416
|
+
param
|
417
|
+
end.freeze
|
418
|
+
sig.closure = new_pin
|
419
|
+
sig.reset_generated!
|
420
|
+
sig
|
421
|
+
end.freeze
|
422
|
+
new_pin
|
401
423
|
end
|
402
424
|
end
|
403
425
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
@@ -436,7 +458,7 @@ module Solargraph
|
|
436
458
|
result = Set.new
|
437
459
|
complex_type.each do |type|
|
438
460
|
if type.duck_type?
|
439
|
-
result.add Pin::DuckMethod.new(name: type.to_s[1..-1])
|
461
|
+
result.add Pin::DuckMethod.new(name: type.to_s[1..-1], source: :api_map)
|
440
462
|
result.merge get_methods('Object')
|
441
463
|
else
|
442
464
|
unless type.nil? || type.name == 'void'
|
@@ -653,29 +675,20 @@ module Solargraph
|
|
653
675
|
if scope == :instance
|
654
676
|
store.get_includes(fqns).reverse.each do |include_tag|
|
655
677
|
rooted_include_tag = qualify(include_tag, rooted_tag)
|
656
|
-
|
657
|
-
# relative to the generics passed to the include. e.g.,
|
658
|
-
# Foo<String> might include Enumerable<String>
|
659
|
-
#
|
660
|
-
# @todo perform the same translation in the other areas
|
661
|
-
# here after adding a spec and handling things correctly
|
662
|
-
# in ApiMap::Store and RbsMap::Conversions
|
663
|
-
resolved_include_type = ComplexType.parse(rooted_include_tag).force_rooted.resolve_generics(namespace_pin, rooted_type)
|
664
|
-
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
665
|
-
result.concat methods
|
678
|
+
result.concat inner_get_methods_from_reference(rooted_include_tag, namespace_pin, rooted_type, scope, visibility, deep, skip, true)
|
666
679
|
end
|
667
|
-
|
668
|
-
unless
|
669
|
-
result.concat
|
680
|
+
rooted_sc_tag = qualify_superclass(rooted_tag)
|
681
|
+
unless rooted_sc_tag.nil?
|
682
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, no_core)
|
670
683
|
end
|
671
684
|
else
|
672
685
|
store.get_extends(fqns).reverse.each do |em|
|
673
686
|
fqem = qualify(em, fqns)
|
674
687
|
result.concat inner_get_methods(fqem, :instance, visibility, deep, skip, true) unless fqem.nil?
|
675
688
|
end
|
676
|
-
|
677
|
-
unless
|
678
|
-
result.concat
|
689
|
+
rooted_sc_tag = qualify_superclass(rooted_tag)
|
690
|
+
unless rooted_sc_tag.nil?
|
691
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, true)
|
679
692
|
end
|
680
693
|
unless no_core || fqns.empty?
|
681
694
|
type = get_namespace_type(fqns)
|
@@ -691,6 +704,41 @@ module Solargraph
|
|
691
704
|
result
|
692
705
|
end
|
693
706
|
|
707
|
+
# @param fq_reference_tag [String] A fully qualified whose method should be pulled in
|
708
|
+
# @param namespace_pin [Pin::Base] Namespace pin for the rooted_type
|
709
|
+
# parameter - used to pull generics information
|
710
|
+
# @param type [ComplexType] The type which is having its
|
711
|
+
# methods supplemented from fq_reference_tag
|
712
|
+
# @param scope [Symbol] :class or :instance
|
713
|
+
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
714
|
+
# @param deep [Boolean]
|
715
|
+
# @param skip [Set<String>]
|
716
|
+
# @param no_core [Boolean] Skip core classes if true
|
717
|
+
# @return [Array<Pin::Base>]
|
718
|
+
def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core)
|
719
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) starting" }
|
720
|
+
|
721
|
+
# Ensure the types returned by the methods in the referenced
|
722
|
+
# type are relative to the generic values passed in the
|
723
|
+
# reference. e.g., Foo<String> might include Enumerable<String>
|
724
|
+
#
|
725
|
+
# @todo perform the same translation in the other areas
|
726
|
+
# here after adding a spec and handling things correctly
|
727
|
+
# in ApiMap::Store and RbsMap::Conversions for each
|
728
|
+
resolved_reference_type = ComplexType.parse(fq_reference_tag).force_rooted.resolve_generics(namespace_pin, type)
|
729
|
+
# @todo Can inner_get_methods be cached? Lots of lookups of base types going on.
|
730
|
+
methods = inner_get_methods(resolved_reference_type.tag, scope, visibility, deep, skip, no_core)
|
731
|
+
if namespace_pin && !resolved_reference_type.all_params.empty?
|
732
|
+
reference_pin = store.get_path_pins(resolved_reference_type.name).select { |p| p.is_a?(Pin::Namespace) }.first
|
733
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolving generics with #{reference_pin.generics}, #{resolved_reference_type.rooted_tags}" }
|
734
|
+
methods = methods.map do |method_pin|
|
735
|
+
method_pin.resolve_generics(reference_pin, resolved_reference_type)
|
736
|
+
end
|
737
|
+
end
|
738
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolved_reference_type: #{resolved_reference_type} for type=#{type}: #{methods.map(&:name)}" }
|
739
|
+
methods
|
740
|
+
end
|
741
|
+
|
694
742
|
# @param fqns [String]
|
695
743
|
# @param visibility [Array<Symbol>]
|
696
744
|
# @param skip [Set<String>]
|
@@ -726,15 +774,19 @@ module Solargraph
|
|
726
774
|
qualify namespace, context.split('::')[0..-2].join('::')
|
727
775
|
end
|
728
776
|
|
729
|
-
# @param
|
777
|
+
# @param fq_tag [String]
|
730
778
|
# @return [String, nil]
|
731
|
-
def qualify_superclass
|
732
|
-
|
733
|
-
|
734
|
-
|
779
|
+
def qualify_superclass fq_sub_tag
|
780
|
+
fq_sub_type = ComplexType.try_parse(fq_sub_tag)
|
781
|
+
fq_sub_ns = fq_sub_type.name
|
782
|
+
sup_tag = store.get_superclass(fq_sub_tag)
|
783
|
+
sup_type = ComplexType.try_parse(sup_tag)
|
784
|
+
sup_ns = sup_type.name
|
785
|
+
return nil if sup_tag.nil?
|
786
|
+
parts = fq_sub_ns.split('::')
|
735
787
|
last = parts.pop
|
736
|
-
parts.pop if last ==
|
737
|
-
qualify(
|
788
|
+
parts.pop if last == sup_ns
|
789
|
+
qualify(sup_tag, parts.join('::'))
|
738
790
|
end
|
739
791
|
|
740
792
|
# @param name [String] Namespace to fully qualify
|
@@ -829,18 +881,33 @@ module Solargraph
|
|
829
881
|
return nil if origin.nil?
|
830
882
|
args = {
|
831
883
|
location: pin.location,
|
884
|
+
type_location: origin.type_location,
|
832
885
|
closure: pin.closure,
|
833
886
|
name: pin.name,
|
834
887
|
comments: origin.comments,
|
835
888
|
scope: origin.scope,
|
836
889
|
# context: pin.context,
|
837
890
|
visibility: origin.visibility,
|
838
|
-
signatures: origin.signatures,
|
891
|
+
signatures: origin.signatures.map(&:clone).freeze,
|
839
892
|
attribute: origin.attribute?,
|
840
|
-
generics: origin.generics,
|
893
|
+
generics: origin.generics.clone,
|
841
894
|
return_type: origin.return_type,
|
895
|
+
source: :resolve_method_alias
|
842
896
|
}
|
843
|
-
Pin::Method.new **args
|
897
|
+
out = Pin::Method.new **args
|
898
|
+
out.signatures.each do |sig|
|
899
|
+
sig.parameters = sig.parameters.map(&:clone).freeze
|
900
|
+
sig.source = :resolve_method_alias
|
901
|
+
sig.parameters.each do |param|
|
902
|
+
param.closure = out
|
903
|
+
param.source = :resolve_method_alias
|
904
|
+
param.reset_generated!
|
905
|
+
end
|
906
|
+
sig.closure = out
|
907
|
+
sig.reset_generated!
|
908
|
+
end
|
909
|
+
logger.debug { "ApiMap#resolve_method_alias(pin=#{pin}) - returning #{out} from #{origin}" }
|
910
|
+
out
|
844
911
|
end
|
845
912
|
|
846
913
|
include Logging
|
@@ -306,7 +306,8 @@ module Solargraph
|
|
306
306
|
|
307
307
|
transform(name) do |t|
|
308
308
|
if t.name == GENERIC_TAG_NAME
|
309
|
-
|
309
|
+
generic_name = t.subtypes.first&.name
|
310
|
+
idx = definitions.generics.index(generic_name)
|
310
311
|
next t if idx.nil?
|
311
312
|
if context_type.parameters_type == :hash
|
312
313
|
if idx == 0
|
@@ -323,7 +324,7 @@ module Solargraph
|
|
323
324
|
ComplexType::UNDEFINED
|
324
325
|
end
|
325
326
|
else
|
326
|
-
context_type.all_params[idx] || ComplexType::UNDEFINED
|
327
|
+
context_type.all_params[idx] || definitions.generic_defaults[generic_name] || ComplexType::UNDEFINED
|
327
328
|
end
|
328
329
|
else
|
329
330
|
t
|
data/lib/solargraph/doc_map.rb
CHANGED
@@ -18,13 +18,16 @@ module Solargraph
|
|
18
18
|
# @return [Array<Gem::Specification>]
|
19
19
|
attr_reader :uncached_gemspecs
|
20
20
|
|
21
|
+
# @return [Workspace, nil]
|
22
|
+
attr_reader :workspace
|
23
|
+
|
21
24
|
# @param requires [Array<String>]
|
22
25
|
# @param preferences [Array<Gem::Specification>]
|
23
|
-
# @param
|
24
|
-
def initialize(requires, preferences,
|
26
|
+
# @param workspace [Workspace, nil]
|
27
|
+
def initialize(requires, preferences, workspace = nil)
|
25
28
|
@requires = requires.compact
|
26
29
|
@preferences = preferences.compact
|
27
|
-
@
|
30
|
+
@workspace = workspace
|
28
31
|
generate
|
29
32
|
end
|
30
33
|
|
@@ -118,10 +121,10 @@ module Solargraph
|
|
118
121
|
|
119
122
|
# @param gemspec [Gem::Specification]
|
120
123
|
def update_from_collection gemspec, gempins
|
121
|
-
return gempins unless
|
124
|
+
return gempins unless workspace&.rbs_collection_path && File.directory?(workspace&.rbs_collection_path)
|
122
125
|
return gempins if RbsMap.new(gemspec.name, gemspec.version).resolved?
|
123
126
|
|
124
|
-
rbs_map = RbsMap.new(gemspec.name, gemspec.version, directories: [
|
127
|
+
rbs_map = RbsMap.new(gemspec.name, gemspec.version, directories: [workspace&.rbs_collection_path])
|
125
128
|
return gempins unless rbs_map.resolved?
|
126
129
|
|
127
130
|
Solargraph.logger.info "Updating #{gemspec.name} #{gemspec.version} from collection"
|
@@ -132,29 +135,7 @@ module Solargraph
|
|
132
135
|
# @return [::Array<Gem::Specification>, nil]
|
133
136
|
def resolve_path_to_gemspecs path
|
134
137
|
return nil if path.empty?
|
135
|
-
|
136
|
-
if path == 'bundler/require'
|
137
|
-
# @todo Quick fix for cases when Solargraph is running without Bundler.
|
138
|
-
# The next goal is to enable loading of external bundles, i.e.,
|
139
|
-
# finding gems that are defined in the workspace's bundle when
|
140
|
-
# Solargraph is running in a different environment.
|
141
|
-
# See https://github.com/castwide/vscode-solargraph/issues/279
|
142
|
-
require 'bundler'
|
143
|
-
|
144
|
-
# find only the gems bundler is now using
|
145
|
-
gemspecs = Bundler.definition.locked_gems.specs.flat_map do |lazy_spec|
|
146
|
-
logger.info "Handling #{lazy_spec.name}:#{lazy_spec.version} from #{path}"
|
147
|
-
[Gem::Specification.find_by_name(lazy_spec.name, lazy_spec.version)]
|
148
|
-
rescue Gem::MissingSpecError => e
|
149
|
-
logger.info("Could not find #{lazy_spec.name}:#{lazy_spec.version} with find_by_name, falling back to guess")
|
150
|
-
# can happen in local filesystem references
|
151
|
-
specs = resolve_path_to_gemspecs lazy_spec.name
|
152
|
-
logger.info "Gem #{lazy_spec.name} #{lazy_spec.version} from bundle not found: #{e}" if specs.nil?
|
153
|
-
next specs
|
154
|
-
end.compact
|
155
|
-
|
156
|
-
return gemspecs
|
157
|
-
end
|
138
|
+
return gemspecs_required_from_bundler if path == 'bundler/require'
|
158
139
|
|
159
140
|
gemspec = Gem::Specification.find_by_path(path)
|
160
141
|
if gemspec.nil?
|
@@ -215,5 +196,53 @@ module Solargraph
|
|
215
196
|
def only_runtime_dependencies gemspec
|
216
197
|
gemspec.dependencies - gemspec.development_dependencies
|
217
198
|
end
|
199
|
+
|
200
|
+
def gemspecs_required_from_bundler
|
201
|
+
if workspace&.directory && Bundler.definition&.lockfile&.to_s&.start_with?(workspace.directory)
|
202
|
+
# Find only the gems bundler is now using
|
203
|
+
Bundler.definition.locked_gems.specs.flat_map do |lazy_spec|
|
204
|
+
logger.info "Handling #{lazy_spec.name}:#{lazy_spec.version}"
|
205
|
+
[Gem::Specification.find_by_name(lazy_spec.name, lazy_spec.version)]
|
206
|
+
rescue Gem::MissingSpecError => e
|
207
|
+
logger.info("Could not find #{lazy_spec.name}:#{lazy_spec.version} with find_by_name, falling back to guess")
|
208
|
+
# can happen in local filesystem references
|
209
|
+
specs = resolve_path_to_gemspecs lazy_spec.name
|
210
|
+
logger.warn "Gem #{lazy_spec.name} #{lazy_spec.version} from bundle not found: #{e}" if specs.nil?
|
211
|
+
next specs
|
212
|
+
end.compact
|
213
|
+
else
|
214
|
+
logger.info 'Fetching gemspecs required from Bundler (bundler/require)'
|
215
|
+
gemspecs_required_from_external_bundle
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def gemspecs_required_from_external_bundle
|
220
|
+
logger.info 'Fetching gemspecs required from external bundle'
|
221
|
+
return [] unless workspace&.directory
|
222
|
+
|
223
|
+
Solargraph.with_clean_env do
|
224
|
+
cmd = [
|
225
|
+
'ruby', '-e',
|
226
|
+
"require 'bundler'; require 'json'; Dir.chdir('#{workspace&.directory}') { puts Bundler.definition.locked_gems.specs.map { |spec| [spec.name, spec.version] }.to_h.to_json }"
|
227
|
+
]
|
228
|
+
o, e, s = Open3.capture3(*cmd)
|
229
|
+
if s.success?
|
230
|
+
Solargraph.logger.debug "External bundle: #{o}"
|
231
|
+
hash = o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
|
232
|
+
hash.flat_map do |name, version|
|
233
|
+
Gem::Specification.find_by_name(name, version)
|
234
|
+
rescue Gem::MissingSpecError => e
|
235
|
+
logger.info("Could not find #{name}:#{version} with find_by_name, falling back to guess")
|
236
|
+
# can happen in local filesystem references
|
237
|
+
specs = resolve_path_to_gemspecs name
|
238
|
+
logger.warn "Gem #{name} #{version} from bundle not found: #{e}" if specs.nil?
|
239
|
+
next specs
|
240
|
+
end.compact
|
241
|
+
else
|
242
|
+
Solargraph.logger.warn e
|
243
|
+
raise BundleNotFoundError, "Failed to load gems from bundle at #{workspace&.directory}"
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
218
247
|
end
|
219
248
|
end
|
data/lib/solargraph/gem_pins.rb
CHANGED
@@ -42,7 +42,8 @@ module Solargraph
|
|
42
42
|
generics: rbs.generics,
|
43
43
|
node: yard.node,
|
44
44
|
signatures: yard.signatures,
|
45
|
-
return_type: best_return_type(rbs.return_type, yard.return_type)
|
45
|
+
return_type: best_return_type(rbs.return_type, yard.return_type),
|
46
|
+
source: :gem_pins
|
46
47
|
)
|
47
48
|
end
|
48
49
|
in_rbs = rbs_map.pins.reject { |pin| in_yard.include?(pin.path) }
|
@@ -83,6 +83,7 @@ module Solargraph
|
|
83
83
|
@fetched = true
|
84
84
|
begin
|
85
85
|
@available ||= begin
|
86
|
+
# @type [Gem::Dependency, nil]
|
86
87
|
tuple = CheckGemVersion.fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
|
87
88
|
if tuple.nil?
|
88
89
|
@error = 'An error occurred fetching the gem data'
|
data/lib/solargraph/logging.rb
CHANGED
@@ -118,7 +118,8 @@ module Solargraph
|
|
118
118
|
comments: pin.comments,
|
119
119
|
presence: presence,
|
120
120
|
return_type: ComplexType.try_parse(downcast_type_name),
|
121
|
-
presence_certain: true
|
121
|
+
presence_certain: true,
|
122
|
+
source: :flow_sensitive_typing
|
122
123
|
)
|
123
124
|
locals.push(new_pin)
|
124
125
|
end
|
@@ -152,7 +153,7 @@ module Solargraph
|
|
152
153
|
# @param isa_node [Parser::AST::Node]
|
153
154
|
# @return [Array(String, String)]
|
154
155
|
def parse_isa(isa_node)
|
155
|
-
return unless isa_node
|
156
|
+
return unless isa_node&.type == :send && isa_node.children[1] == :is_a?
|
156
157
|
# Check if conditional node follows this pattern:
|
157
158
|
# s(:send,
|
158
159
|
# s(:send, nil, :foo), :is_a?,
|
@@ -164,12 +165,12 @@ module Solargraph
|
|
164
165
|
# check if isa_receiver looks like this:
|
165
166
|
# s(:send, nil, :foo)
|
166
167
|
# and set variable_name to :foo
|
167
|
-
if isa_receiver
|
168
|
+
if isa_receiver&.type == :send && isa_receiver.children[0].nil? && isa_receiver.children[1].is_a?(Symbol)
|
168
169
|
variable_name = isa_receiver.children[1].to_s
|
169
170
|
end
|
170
171
|
# or like this:
|
171
172
|
# (lvar :repr)
|
172
|
-
variable_name = isa_receiver.children[0].to_s if isa_receiver
|
173
|
+
variable_name = isa_receiver.children[0].to_s if isa_receiver&.type == :lvar
|
173
174
|
return unless variable_name
|
174
175
|
|
175
176
|
[isa_type_name, variable_name]
|
@@ -9,6 +9,7 @@ module Solargraph
|
|
9
9
|
autoload :Base, 'solargraph/parser/node_processor/base'
|
10
10
|
|
11
11
|
class << self
|
12
|
+
# @type [Hash{Symbol => Class<NodeProcessor::Base>}]
|
12
13
|
@@processors ||= {}
|
13
14
|
|
14
15
|
# Register a processor for a node type.
|
@@ -30,7 +31,8 @@ module Solargraph
|
|
30
31
|
if pins.empty?
|
31
32
|
pins.push Pin::Namespace.new(
|
32
33
|
location: region.source.location,
|
33
|
-
name: ''
|
34
|
+
name: '',
|
35
|
+
source: :parser,
|
34
36
|
)
|
35
37
|
end
|
36
38
|
return [pins, locals] unless Parser.is_ast_node?(node)
|
@@ -12,7 +12,8 @@ module Solargraph
|
|
12
12
|
closure: region.closure,
|
13
13
|
name: node.children[0].children[0].to_s,
|
14
14
|
original: node.children[1].children[0].to_s,
|
15
|
-
scope: region.scope || :instance
|
15
|
+
scope: region.scope || :instance,
|
16
|
+
source: :parser
|
16
17
|
)
|
17
18
|
process_children
|
18
19
|
end
|
@@ -21,7 +21,8 @@ module Solargraph
|
|
21
21
|
assignment: u.children[1],
|
22
22
|
asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil,
|
23
23
|
presence: callable.location.range,
|
24
|
-
decl: get_decl(u)
|
24
|
+
decl: get_decl(u),
|
25
|
+
source: :parser
|
25
26
|
)
|
26
27
|
callable.parameters.push locals.last
|
27
28
|
end
|
@@ -40,7 +41,8 @@ module Solargraph
|
|
40
41
|
location: loc,
|
41
42
|
closure: callable,
|
42
43
|
presence: region.closure.location.range,
|
43
|
-
decl: get_decl(node)
|
44
|
+
decl: get_decl(node),
|
45
|
+
source: :parser
|
44
46
|
)
|
45
47
|
callable.parameters.push locals.last
|
46
48
|
end
|
@@ -13,7 +13,8 @@ module Solargraph
|
|
13
13
|
Solargraph::Pin::Namespace.new(
|
14
14
|
location: location,
|
15
15
|
type: :class,
|
16
|
-
name: unpack_name(node.children[0].children[0])
|
16
|
+
name: unpack_name(node.children[0].children[0]),
|
17
|
+
source: :parser,
|
17
18
|
)
|
18
19
|
else
|
19
20
|
region.closure
|
@@ -24,7 +25,8 @@ module Solargraph
|
|
24
25
|
node: node,
|
25
26
|
receiver: node.children[0],
|
26
27
|
comments: comments_for(node),
|
27
|
-
scope: region.scope || region.closure.context.scope
|
28
|
+
scope: region.scope || region.closure.context.scope,
|
29
|
+
source: :parser
|
28
30
|
)
|
29
31
|
process_children region.update(closure: pins.last)
|
30
32
|
end
|
@@ -15,7 +15,8 @@ module Solargraph
|
|
15
15
|
comments: comments_for(node),
|
16
16
|
scope: scope,
|
17
17
|
visibility: scope == :instance && name == 'initialize' ? :private : region.visibility,
|
18
|
-
node: node
|
18
|
+
node: node,
|
19
|
+
source: :parser,
|
19
20
|
)
|
20
21
|
if region.visibility == :module_function
|
21
22
|
pins.push Solargraph::Pin::Method.new(
|
@@ -26,7 +27,8 @@ module Solargraph
|
|
26
27
|
scope: :class,
|
27
28
|
visibility: :public,
|
28
29
|
parameters: methpin.parameters,
|
29
|
-
node: methpin.node
|
30
|
+
node: methpin.node,
|
31
|
+
source: :parser,
|
30
32
|
)
|
31
33
|
pins.push Solargraph::Pin::Method.new(
|
32
34
|
location: methpin.location,
|
@@ -36,7 +38,8 @@ module Solargraph
|
|
36
38
|
scope: :instance,
|
37
39
|
visibility: :private,
|
38
40
|
parameters: methpin.parameters,
|
39
|
-
node: methpin.node
|
41
|
+
node: methpin.node,
|
42
|
+
source: :parser,
|
40
43
|
)
|
41
44
|
else
|
42
45
|
pins.push methpin
|