solargraph 0.54.0 → 0.54.5
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/CHANGELOG.md +45 -0
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +167 -0
- data/lib/solargraph/api_map/store.rb +72 -121
- data/lib/solargraph/api_map.rb +94 -36
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +17 -11
- data/lib/solargraph/complex_type/unique_type.rb +93 -10
- data/lib/solargraph/complex_type.rb +68 -18
- data/lib/solargraph/convention.rb +1 -0
- data/lib/solargraph/doc_map.rb +1 -0
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/language_server/host/message_worker.rb +48 -5
- data/lib/solargraph/language_server/host.rb +12 -11
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +19 -2
- data/lib/solargraph/library.rb +31 -41
- data/lib/solargraph/location.rb +21 -1
- data/lib/solargraph/parser/node_methods.rb +1 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +2 -6
- data/lib/solargraph/parser/parser_gem/node_methods.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
- data/lib/solargraph/parser.rb +2 -5
- data/lib/solargraph/pin/base.rb +41 -17
- data/lib/solargraph/pin/base_variable.rb +4 -3
- data/lib/solargraph/pin/block.rb +6 -26
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +8 -3
- data/lib/solargraph/pin/common.rb +2 -6
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/method.rb +57 -31
- data/lib/solargraph/pin/namespace.rb +5 -5
- data/lib/solargraph/pin/parameter.rb +11 -12
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin/signature.rb +3 -129
- data/lib/solargraph/pin.rb +4 -1
- data/lib/solargraph/position.rb +7 -0
- data/lib/solargraph/range.rb +9 -4
- data/lib/solargraph/rbs_map/conversions.rb +77 -38
- data/lib/solargraph/rbs_map/core_fills.rb +6 -6
- data/lib/solargraph/rbs_map.rb +1 -0
- data/lib/solargraph/shell.rb +19 -2
- data/lib/solargraph/source/chain/array.rb +7 -6
- 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 +90 -55
- data/lib/solargraph/source/chain/hash.rb +5 -0
- data/lib/solargraph/source/chain/if.rb +5 -0
- data/lib/solargraph/source/chain/link.rb +26 -5
- data/lib/solargraph/source/chain/literal.rb +5 -0
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +68 -30
- data/lib/solargraph/source/cursor.rb +3 -2
- data/lib/solargraph/source.rb +104 -86
- data/lib/solargraph/source_map/clip.rb +5 -5
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +15 -15
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +7 -3
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +1 -0
- data/lib/solargraph/yardoc.rb +1 -1
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +5 -5
- metadata +29 -25
data/lib/solargraph/api_map.rb
CHANGED
@@ -5,13 +5,14 @@ require 'yard'
|
|
5
5
|
require 'solargraph/yard_tags'
|
6
6
|
|
7
7
|
module Solargraph
|
8
|
-
# An aggregate provider for information about
|
8
|
+
# An aggregate provider for information about Workspaces, Sources, gems, and
|
9
9
|
# the Ruby core.
|
10
10
|
#
|
11
11
|
class ApiMap
|
12
12
|
autoload :Cache, 'solargraph/api_map/cache'
|
13
13
|
autoload :SourceToYard, 'solargraph/api_map/source_to_yard'
|
14
14
|
autoload :Store, 'solargraph/api_map/store'
|
15
|
+
autoload :Index, 'solargraph/api_map/index'
|
15
16
|
|
16
17
|
# @return [Array<String>]
|
17
18
|
attr_reader :unresolved_requires
|
@@ -48,6 +49,15 @@ module Solargraph
|
|
48
49
|
equality_fields.hash
|
49
50
|
end
|
50
51
|
|
52
|
+
def to_s
|
53
|
+
self.class.to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
# avoid enormous dump
|
57
|
+
def inspect
|
58
|
+
to_s
|
59
|
+
end
|
60
|
+
|
51
61
|
# @param pins [Array<Pin::Base>]
|
52
62
|
# @return [self]
|
53
63
|
def index pins
|
@@ -56,7 +66,7 @@ module Solargraph
|
|
56
66
|
@source_map_hash = {}
|
57
67
|
implicit.clear
|
58
68
|
cache.clear
|
59
|
-
|
69
|
+
store.update @@core_map.pins, pins
|
60
70
|
self
|
61
71
|
end
|
62
72
|
|
@@ -75,10 +85,9 @@ module Solargraph
|
|
75
85
|
# @param bench [Bench]
|
76
86
|
# @return [self]
|
77
87
|
def catalog bench
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
pins = bench.source_maps.flat_map(&:pins).flatten
|
88
|
+
@source_map_hash = bench.source_map_hash
|
89
|
+
iced_pins = bench.icebox.flat_map(&:pins)
|
90
|
+
live_pins = bench.live_map&.pins || []
|
82
91
|
implicit.clear
|
83
92
|
source_map_hash.each_value do |map|
|
84
93
|
implicit.merge map.environ
|
@@ -87,17 +96,17 @@ module Solargraph
|
|
87
96
|
if @unresolved_requires != unresolved_requires || @doc_map&.uncached_gemspecs&.any?
|
88
97
|
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace.rbs_collection_path) # @todo Implement gem preferences
|
89
98
|
@unresolved_requires = unresolved_requires
|
90
|
-
need_to_uncache = true
|
91
99
|
end
|
92
|
-
@
|
93
|
-
@cache.clear if need_to_uncache
|
94
|
-
|
100
|
+
@cache.clear if store.update(@@core_map.pins, @doc_map.pins, implicit.pins, iced_pins, live_pins)
|
95
101
|
@missing_docs = [] # @todo Implement missing docs
|
96
102
|
self
|
97
103
|
end
|
98
104
|
|
105
|
+
# @todo need to model type def statement in chains as a symbol so
|
106
|
+
# that this overload of 'protected' will typecheck @sg-ignore
|
107
|
+
# @sg-ignore
|
99
108
|
protected def equality_fields
|
100
|
-
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires
|
109
|
+
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires]
|
101
110
|
end
|
102
111
|
|
103
112
|
# @return [::Array<Gem::Specification>]
|
@@ -183,7 +192,7 @@ module Solargraph
|
|
183
192
|
|
184
193
|
# @return [Array<Solargraph::Pin::Base>]
|
185
194
|
def pins
|
186
|
-
store.pins
|
195
|
+
store.pins.clone.freeze
|
187
196
|
end
|
188
197
|
|
189
198
|
# An array of pins based on Ruby keywords (`if`, `end`, etc.).
|
@@ -250,18 +259,20 @@ module Solargraph
|
|
250
259
|
# @param tag [String, nil] The namespace to
|
251
260
|
# match, complete with generic parameters set to appropriate
|
252
261
|
# values if available
|
253
|
-
# @param context_tag [String] The context in which
|
254
|
-
# referenced; start from here to resolve the name
|
262
|
+
# @param context_tag [String] The fully qualified context in which
|
263
|
+
# the tag was referenced; start from here to resolve the name.
|
264
|
+
# Should not be prefixed with '::'.
|
255
265
|
# @return [String, nil] fully qualified tag
|
256
266
|
def qualify tag, context_tag = ''
|
257
267
|
return tag if ['self', nil].include?(tag)
|
258
|
-
|
268
|
+
|
269
|
+
context_type = ComplexType.parse(context_tag).force_rooted
|
259
270
|
return unless context_type
|
260
271
|
|
261
272
|
type = ComplexType.try_parse(tag)
|
262
273
|
return unless type
|
263
274
|
|
264
|
-
fqns = qualify_namespace(type.rooted_namespace, context_type.
|
275
|
+
fqns = qualify_namespace(type.rooted_namespace, context_type.namespace)
|
265
276
|
return unless fqns
|
266
277
|
|
267
278
|
fqns + type.substring
|
@@ -326,6 +337,11 @@ module Solargraph
|
|
326
337
|
store.pins_by_class(Pin::GlobalVariable)
|
327
338
|
end
|
328
339
|
|
340
|
+
# @return [Enumerable<Solargraph::Pin::Block>]
|
341
|
+
def get_block_pins
|
342
|
+
store.pins_by_class(Pin::Block)
|
343
|
+
end
|
344
|
+
|
329
345
|
# Get an array of methods available in a particular context.
|
330
346
|
#
|
331
347
|
# @param rooted_tag [String] The fully qualified namespace to search for methods
|
@@ -334,8 +350,12 @@ module Solargraph
|
|
334
350
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
335
351
|
# @return [Array<Solargraph::Pin::Method>]
|
336
352
|
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
353
|
+
rooted_type = ComplexType.try_parse(rooted_tag)
|
354
|
+
fqns = rooted_type.namespace
|
355
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
337
356
|
cached = cache.get_methods(rooted_tag, scope, visibility, deep)
|
338
357
|
return cached.clone unless cached.nil?
|
358
|
+
# @type [Array<Solargraph::Pin::Method>]
|
339
359
|
result = []
|
340
360
|
skip = Set.new
|
341
361
|
if rooted_tag == ''
|
@@ -373,9 +393,12 @@ module Solargraph
|
|
373
393
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
374
394
|
result.concat inner_get_methods('Module', scope, visibility, deep, skip) if scope == :module
|
375
395
|
end
|
376
|
-
|
377
|
-
|
378
|
-
|
396
|
+
result = resolve_method_aliases(result, visibility)
|
397
|
+
if namespace_pin && rooted_tag != rooted_type.name
|
398
|
+
result = result.map { |method_pin| method_pin.resolve_generics(namespace_pin, rooted_type) }
|
399
|
+
end
|
400
|
+
cache.set_methods(rooted_tag, scope, visibility, deep, result)
|
401
|
+
result
|
379
402
|
end
|
380
403
|
|
381
404
|
# Get an array of method pins for a complex type.
|
@@ -431,8 +454,13 @@ module Solargraph
|
|
431
454
|
# @param name [String] Method name to look up
|
432
455
|
# @param scope [Symbol] :instance or :class
|
433
456
|
# @return [Array<Solargraph::Pin::Method>]
|
434
|
-
def get_method_stack rooted_tag, name, scope: :instance
|
435
|
-
|
457
|
+
def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], preserve_generics: false
|
458
|
+
rooted_type = ComplexType.parse(rooted_tag)
|
459
|
+
fqns = rooted_type.namespace
|
460
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
461
|
+
methods = get_methods(rooted_tag, scope: scope, visibility: visibility).select { |p| p.name == name }
|
462
|
+
methods = erase_generics(namespace_pin, rooted_type, methods) unless preserve_generics
|
463
|
+
methods
|
436
464
|
end
|
437
465
|
|
438
466
|
# Get an array of all suggestions that match the specified path.
|
@@ -591,9 +619,10 @@ module Solargraph
|
|
591
619
|
# @param no_core [Boolean] Skip core classes if true
|
592
620
|
# @return [Array<Pin::Base>]
|
593
621
|
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
594
|
-
rooted_type = ComplexType.parse(rooted_tag)
|
622
|
+
rooted_type = ComplexType.parse(rooted_tag).force_rooted
|
595
623
|
fqns = rooted_type.namespace
|
596
624
|
fqns_generic_params = rooted_type.all_params
|
625
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
597
626
|
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
598
627
|
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
|
599
628
|
return [] if skip.include?(reqstr)
|
@@ -608,15 +637,7 @@ module Solargraph
|
|
608
637
|
# Store#get_methods doesn't know about full tags, just
|
609
638
|
# namespaces; resolving the generics in the method pins is this
|
610
639
|
# class' responsibility
|
611
|
-
|
612
|
-
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
613
|
-
methods = if namespace_pin && rooted_tag != fqns
|
614
|
-
methods = raw_methods.map do |method_pin|
|
615
|
-
method_pin.resolve_generics(namespace_pin, rooted_type)
|
616
|
-
end
|
617
|
-
else
|
618
|
-
raw_methods
|
619
|
-
end
|
640
|
+
methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
620
641
|
result.concat methods
|
621
642
|
if deep
|
622
643
|
if scope == :instance
|
@@ -629,7 +650,7 @@ module Solargraph
|
|
629
650
|
# @todo perform the same translation in the other areas
|
630
651
|
# here after adding a spec and handling things correctly
|
631
652
|
# in ApiMap::Store and RbsMap::Conversions
|
632
|
-
resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
|
653
|
+
resolved_include_type = ComplexType.parse(rooted_include_tag).force_rooted.resolve_generics(namespace_pin, rooted_type)
|
633
654
|
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
634
655
|
result.concat methods
|
635
656
|
end
|
@@ -690,7 +711,7 @@ module Solargraph
|
|
690
711
|
|
691
712
|
# @param namespace [String]
|
692
713
|
# @param context [String]
|
693
|
-
# @return [String]
|
714
|
+
# @return [String, nil]
|
694
715
|
def qualify_lower namespace, context
|
695
716
|
qualify namespace, context.split('::')[0..-2].join('::')
|
696
717
|
end
|
@@ -761,8 +782,8 @@ module Solargraph
|
|
761
782
|
|
762
783
|
# Sort an array of pins to put nil or undefined variables last.
|
763
784
|
#
|
764
|
-
# @param pins [Enumerable<
|
765
|
-
# @return [Enumerable<
|
785
|
+
# @param pins [Enumerable<Pin::BaseVariable>]
|
786
|
+
# @return [Enumerable<Pin::BaseVariable>]
|
766
787
|
def prefer_non_nil_variables pins
|
767
788
|
result = []
|
768
789
|
nil_pins = []
|
@@ -802,11 +823,48 @@ module Solargraph
|
|
802
823
|
name: pin.name,
|
803
824
|
comments: origin.comments,
|
804
825
|
scope: origin.scope,
|
826
|
+
# context: pin.context,
|
805
827
|
visibility: origin.visibility,
|
806
828
|
signatures: origin.signatures,
|
807
|
-
attribute: origin.attribute
|
829
|
+
attribute: origin.attribute?,
|
830
|
+
generics: origin.generics,
|
831
|
+
return_type: origin.return_type,
|
808
832
|
}
|
809
833
|
Pin::Method.new **args
|
810
834
|
end
|
835
|
+
|
836
|
+
include Logging
|
837
|
+
|
838
|
+
private
|
839
|
+
|
840
|
+
# @param namespace_pin [Pin::Namespace]
|
841
|
+
# @param rooted_type [ComplexType]
|
842
|
+
# @param pins [Enumerable<Pin::Base>]
|
843
|
+
# @return [Array<Pin::Base>]
|
844
|
+
def erase_generics(namespace_pin, rooted_type, pins)
|
845
|
+
return pins unless should_erase_generics_when_done?(namespace_pin, rooted_type)
|
846
|
+
|
847
|
+
logger.debug("Erasing generics on namespace_pin=#{namespace_pin} / rooted_type=#{rooted_type}")
|
848
|
+
pins.map do |method_pin|
|
849
|
+
method_pin.erase_generics(namespace_pin.generics)
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
# @param namespace_pin [Pin::Namespace]
|
854
|
+
# @param rooted_type [ComplexType]
|
855
|
+
def should_erase_generics_when_done?(namespace_pin, rooted_type)
|
856
|
+
has_generics?(namespace_pin) && !can_resolve_generics?(namespace_pin, rooted_type)
|
857
|
+
end
|
858
|
+
|
859
|
+
# @param namespace_pin [Pin::Namespace]
|
860
|
+
def has_generics?(namespace_pin)
|
861
|
+
namespace_pin && !namespace_pin.generics.empty?
|
862
|
+
end
|
863
|
+
|
864
|
+
# @param namespace_pin [Pin::Namespace]
|
865
|
+
# @param rooted_type [ComplexType]
|
866
|
+
def can_resolve_generics?(namespace_pin, rooted_type)
|
867
|
+
has_generics?(namespace_pin) && !rooted_type.all_params.empty?
|
868
|
+
end
|
811
869
|
end
|
812
870
|
end
|
data/lib/solargraph/bench.rb
CHANGED
@@ -11,18 +11,34 @@ module Solargraph
|
|
11
11
|
# @return [Workspace]
|
12
12
|
attr_reader :workspace
|
13
13
|
|
14
|
+
# @return [SourceMap]
|
15
|
+
attr_reader :live_map
|
16
|
+
|
14
17
|
# @return [Set<String>]
|
15
18
|
attr_reader :external_requires
|
16
19
|
|
17
20
|
# @param source_maps [Array<SourceMap>, Set<SourceMap>]
|
18
21
|
# @param workspace [Workspace]
|
22
|
+
# @param live_map [SourceMap, nil]
|
19
23
|
# @param external_requires [Array<String>, Set<String>]
|
20
|
-
def initialize source_maps: [], workspace: Workspace.new, external_requires: []
|
24
|
+
def initialize source_maps: [], workspace: Workspace.new, live_map: nil, external_requires: []
|
21
25
|
@source_maps = source_maps.to_set
|
22
26
|
@workspace = workspace
|
27
|
+
@live_map = live_map
|
23
28
|
@external_requires = external_requires.reject { |path| workspace.would_require?(path) }
|
24
29
|
.compact
|
25
30
|
.to_set
|
26
31
|
end
|
32
|
+
|
33
|
+
# @return [Hash{String => SourceMap}]
|
34
|
+
def source_map_hash
|
35
|
+
# @todo Work around #to_h bug in current Ruby head (3.5) with #map#to_h
|
36
|
+
@source_map_hash ||= source_maps.map { |s| [s.filename, s] }
|
37
|
+
.to_h
|
38
|
+
end
|
39
|
+
|
40
|
+
def icebox
|
41
|
+
@icebox ||= (source_maps - [live_map])
|
42
|
+
end
|
27
43
|
end
|
28
44
|
end
|
@@ -12,12 +12,20 @@ module Solargraph
|
|
12
12
|
# @rooted: boolish
|
13
13
|
# methods:
|
14
14
|
# transform()
|
15
|
+
# all_params()
|
16
|
+
# rooted?()
|
17
|
+
# can_root_name?()
|
15
18
|
module TypeMethods
|
16
19
|
# @!method transform(new_name = nil, &transform_type)
|
17
20
|
# @param new_name [String, nil]
|
18
21
|
# @yieldparam t [UniqueType]
|
19
22
|
# @yieldreturn [UniqueType]
|
20
23
|
# @return [UniqueType, nil]
|
24
|
+
# @!method all_params
|
25
|
+
# @return [Array<ComplexType>]
|
26
|
+
# @!method rooted?
|
27
|
+
# @!method can_root_name?(name_to_check = nil)
|
28
|
+
# @param name_to_check [String, nil]
|
21
29
|
|
22
30
|
# @return [String]
|
23
31
|
attr_reader :name
|
@@ -45,11 +53,6 @@ module Solargraph
|
|
45
53
|
@nil_type ||= (name.casecmp('nil') == 0)
|
46
54
|
end
|
47
55
|
|
48
|
-
# @return [Boolean]
|
49
|
-
def parameters?
|
50
|
-
!substring.empty?
|
51
|
-
end
|
52
|
-
|
53
56
|
def tuple?
|
54
57
|
@tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
|
55
58
|
end
|
@@ -126,15 +129,22 @@ module Solargraph
|
|
126
129
|
end.call
|
127
130
|
end
|
128
131
|
|
132
|
+
def namespace_type
|
133
|
+
return ComplexType.parse('::Object') if duck_type?
|
134
|
+
return ComplexType.parse('::NilClass') if nil_type?
|
135
|
+
return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty?
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
129
139
|
# @return [String]
|
130
140
|
def rooted_namespace
|
131
|
-
return namespace unless rooted?
|
141
|
+
return namespace unless rooted? && can_root_name?(namespace)
|
132
142
|
"::#{namespace}"
|
133
143
|
end
|
134
144
|
|
135
145
|
# @return [String]
|
136
146
|
def rooted_name
|
137
|
-
return name unless rooted?
|
147
|
+
return name unless @rooted && can_root_name?
|
138
148
|
"::#{name}"
|
139
149
|
end
|
140
150
|
|
@@ -177,10 +187,6 @@ module Solargraph
|
|
177
187
|
tag == other.tag
|
178
188
|
end
|
179
189
|
|
180
|
-
def rooted?
|
181
|
-
@rooted
|
182
|
-
end
|
183
|
-
|
184
190
|
# Generate a ComplexType that fully qualifies this type's namespaces.
|
185
191
|
#
|
186
192
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
@@ -7,9 +7,15 @@ module Solargraph
|
|
7
7
|
#
|
8
8
|
class UniqueType
|
9
9
|
include TypeMethods
|
10
|
+
include Equality
|
10
11
|
|
11
12
|
attr_reader :all_params, :subtypes, :key_types
|
12
13
|
|
14
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
15
|
+
protected def equality_fields
|
16
|
+
[@name, @all_params, @subtypes, @key_types]
|
17
|
+
end
|
18
|
+
|
13
19
|
# Create a UniqueType with the specified name and an optional substring.
|
14
20
|
# The substring is the parameter section of a parametrized type, e.g.,
|
15
21
|
# for the type `Array<String>`, the name is `Array` and the substring is
|
@@ -26,6 +32,8 @@ module Solargraph
|
|
26
32
|
if name.start_with?('::')
|
27
33
|
name = name[2..-1]
|
28
34
|
rooted = true
|
35
|
+
elsif !can_root_name?(name)
|
36
|
+
rooted = true
|
29
37
|
else
|
30
38
|
rooted = false
|
31
39
|
end
|
@@ -63,7 +71,7 @@ module Solargraph
|
|
63
71
|
if parameters_type.nil?
|
64
72
|
raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
|
65
73
|
end
|
66
|
-
raise "Please remove leading :: and set rooted instead - #{name}" if name.start_with?('::')
|
74
|
+
raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
|
67
75
|
@name = name
|
68
76
|
@key_types = key_types
|
69
77
|
@subtypes = subtypes
|
@@ -78,6 +86,24 @@ module Solargraph
|
|
78
86
|
tag
|
79
87
|
end
|
80
88
|
|
89
|
+
def eql?(other)
|
90
|
+
self.class == other.class &&
|
91
|
+
@name == other.name &&
|
92
|
+
@key_types == other.key_types &&
|
93
|
+
@subtypes == other.subtypes &&
|
94
|
+
@rooted == other.rooted? &&
|
95
|
+
@all_params == other.all_params &&
|
96
|
+
@parameters_type == other.parameters_type
|
97
|
+
end
|
98
|
+
|
99
|
+
def ==(other)
|
100
|
+
eql?(other)
|
101
|
+
end
|
102
|
+
|
103
|
+
def hash
|
104
|
+
[self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
|
105
|
+
end
|
106
|
+
|
81
107
|
# @return [Array<UniqueType>]
|
82
108
|
def items
|
83
109
|
[self]
|
@@ -92,6 +118,10 @@ module Solargraph
|
|
92
118
|
end
|
93
119
|
end
|
94
120
|
|
121
|
+
def desc
|
122
|
+
rooted_tags
|
123
|
+
end
|
124
|
+
|
95
125
|
# @return [String]
|
96
126
|
def to_rbs
|
97
127
|
if duck_type?
|
@@ -108,7 +138,11 @@ module Solargraph
|
|
108
138
|
# tuples don't have a name; they're just [foo, bar, baz].
|
109
139
|
if substring == '()'
|
110
140
|
# but there are no zero element tuples, so we go with an array
|
111
|
-
|
141
|
+
if rooted?
|
142
|
+
'::Array[]'
|
143
|
+
else
|
144
|
+
'Array[]'
|
145
|
+
end
|
112
146
|
else
|
113
147
|
# already generated surrounded by []
|
114
148
|
parameters_as_rbs
|
@@ -211,7 +245,17 @@ module Solargraph
|
|
211
245
|
if t.name == GENERIC_TAG_NAME
|
212
246
|
idx = definitions.generics.index(t.subtypes.first&.name)
|
213
247
|
next t if idx.nil?
|
214
|
-
context_type.
|
248
|
+
if context_type.parameters_type == :hash
|
249
|
+
if idx == 0
|
250
|
+
next ComplexType.new(context_type.key_types)
|
251
|
+
elsif idx == 1
|
252
|
+
next ComplexType.new(context_type.subtypes)
|
253
|
+
else
|
254
|
+
next ComplexType::UNDEFINED
|
255
|
+
end
|
256
|
+
else
|
257
|
+
context_type.all_params[idx] || ComplexType::UNDEFINED
|
258
|
+
end
|
215
259
|
else
|
216
260
|
t
|
217
261
|
end
|
@@ -238,6 +282,7 @@ module Solargraph
|
|
238
282
|
# @return [self]
|
239
283
|
def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
|
240
284
|
raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
|
285
|
+
|
241
286
|
new_name ||= name
|
242
287
|
new_key_types ||= @key_types
|
243
288
|
new_subtypes ||= @subtypes
|
@@ -278,17 +323,26 @@ module Solargraph
|
|
278
323
|
new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
279
324
|
new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
280
325
|
end
|
281
|
-
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes)
|
326
|
+
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted)
|
282
327
|
yield new_type
|
283
328
|
end
|
284
329
|
|
285
|
-
#
|
286
|
-
#
|
287
|
-
# @
|
288
|
-
|
330
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
331
|
+
#
|
332
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
333
|
+
# @param context [String] The namespace from which to resolve names
|
334
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
335
|
+
def qualify api_map, context = ''
|
289
336
|
transform do |t|
|
290
|
-
next t if t.name
|
291
|
-
t.
|
337
|
+
next t if t.name == GENERIC_TAG_NAME
|
338
|
+
next t if t.duck_type? || t.void? || t.undefined?
|
339
|
+
recon = (t.rooted? ? '' : context)
|
340
|
+
fqns = api_map.qualify(t.name, recon)
|
341
|
+
if fqns.nil?
|
342
|
+
next UniqueType::BOOLEAN if t.tag == 'Boolean'
|
343
|
+
next UniqueType::UNDEFINED
|
344
|
+
end
|
345
|
+
t.recreate(new_name: fqns, make_rooted: true)
|
292
346
|
end
|
293
347
|
end
|
294
348
|
|
@@ -296,6 +350,35 @@ module Solargraph
|
|
296
350
|
@name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
|
297
351
|
end
|
298
352
|
|
353
|
+
# @param dst [ComplexType]
|
354
|
+
# @return [self]
|
355
|
+
def self_to_type dst
|
356
|
+
object_type_dst = dst.reduce_class_type
|
357
|
+
transform do |t|
|
358
|
+
next t if t.name != 'self'
|
359
|
+
object_type_dst
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
def all_rooted?
|
364
|
+
return true if name == GENERIC_TAG_NAME
|
365
|
+
rooted? && all_params.all?(&:rooted?)
|
366
|
+
end
|
367
|
+
|
368
|
+
def rooted?
|
369
|
+
!can_root_name? || @rooted
|
370
|
+
end
|
371
|
+
|
372
|
+
def can_root_name?(name_to_check = name)
|
373
|
+
self.class.can_root_name?(name_to_check)
|
374
|
+
end
|
375
|
+
|
376
|
+
# @param name [String]
|
377
|
+
def self.can_root_name?(name)
|
378
|
+
# name is not lowercase
|
379
|
+
!name.empty? && name != name.downcase
|
380
|
+
end
|
381
|
+
|
299
382
|
UNDEFINED = UniqueType.new('undefined', rooted: false)
|
300
383
|
BOOLEAN = UniqueType.new('Boolean', rooted: true)
|
301
384
|
end
|