solargraph 0.54.0 → 0.54.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/CHANGELOG.md +27 -0
- data/lib/solargraph/api_map/store.rb +8 -4
- data/lib/solargraph/api_map.rb +74 -23
- data/lib/solargraph/complex_type/type_methods.rb +17 -11
- data/lib/solargraph/complex_type/unique_type.rb +72 -9
- data/lib/solargraph/complex_type.rb +66 -17
- data/lib/solargraph/language_server/host/message_worker.rb +45 -5
- data/lib/solargraph/language_server/host.rb +10 -10
- data/lib/solargraph/language_server/message/base.rb +18 -11
- 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/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 +29 -39
- data/lib/solargraph/location.rb +14 -1
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
- data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -2
- 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 +16 -3
- data/lib/solargraph/pin/base_variable.rb +1 -1
- 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 +51 -31
- data/lib/solargraph/pin/namespace.rb +4 -4
- data/lib/solargraph/pin/parameter.rb +9 -11
- 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/range.rb +2 -4
- data/lib/solargraph/rbs_map/conversions.rb +76 -37
- data/lib/solargraph/rbs_map/core_fills.rb +6 -6
- data/lib/solargraph/shell.rb +17 -2
- data/lib/solargraph/source/chain/array.rb +6 -5
- 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 +81 -51
- data/lib/solargraph/source/chain/link.rb +9 -0
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +41 -17
- data/lib/solargraph/source/cursor.rb +14 -2
- data/lib/solargraph/source.rb +102 -85
- data/lib/solargraph/source_map/clip.rb +4 -4
- 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 +7 -7
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/solargraph.gemspec +4 -4
- metadata +20 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17844968917df55d45751cbe82fa1f59e72f4dbfe7ecce04f73dbccbc1ec2aeb
|
4
|
+
data.tar.gz: 1b86c653e3b5c145f1b0aa9c614f136bd6d75c305aeac680f0cfe992ca4ff3dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44d428aa78d2d82bcfb97b650acd72aaf904666702a59e13a87f1a4c4c8bb2fa171afe6f502fb7327a67f12854a3953fccee1fde95f75fc5cf4b4f8742683e8e
|
7
|
+
data.tar.gz: ce37d473c9e3b8decd9c97c868fb66ef8441e27aeb10b557abf345bba1ad9c96c8dc5657127ea9680dfa60f59da7663f25ccffed412d5683b272ea3dbf823f76
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,30 @@
|
|
1
|
+
## 0.54.2 - April 28, 2025
|
2
|
+
- Resolve generics correctly on mixin inclusion (#898)
|
3
|
+
- Pick correct String#split overload (#905)
|
4
|
+
- Fix type sent into YARD method (#912)
|
5
|
+
- Early CancelRequest handling (#914)
|
6
|
+
- Destructure partial yield types (#915)
|
7
|
+
- Dependency versions (#916)
|
8
|
+
|
9
|
+
## 0.54.1 - April 26, 2025
|
10
|
+
- Retire more RubyVM-specific code (#797)
|
11
|
+
- Add additional docs for key classes, modules and methods (#802)
|
12
|
+
- Populate location information from RBS files (#768)
|
13
|
+
- Consolidate parameter handling into Pin::Callable (#844)
|
14
|
+
- Adjust local variable presence to start after assignment, not before (#864)
|
15
|
+
- Resolve params from ref tags (#872)
|
16
|
+
- Reduce use of ComplexType.parse() to preserve rooted? information (#870)
|
17
|
+
- Ensure yield return types are qualified (#886)
|
18
|
+
- Understand type of 'def foo; @foo ||= bar; end' reader methods (#888)
|
19
|
+
- Improvements to #inspect output on pins and chains (#895)
|
20
|
+
- Block method resolution improvements (#885)
|
21
|
+
- Understand mass assignment into instance variables (#893)
|
22
|
+
- Library sync and cache invalidation (#903)
|
23
|
+
- Handle super and yield scenarios from blocks (#891)
|
24
|
+
- Allow core and stdlib documentation to be uncached (#899)
|
25
|
+
- Surface variable names in LSP, e.g., textDocument/hover (#910)
|
26
|
+
- Keep idle progress notifications alive (#911)
|
27
|
+
|
1
28
|
## 0.54.0 - April 14, 2025
|
2
29
|
- Add support for simple block argument destructuring (#821)
|
3
30
|
- Benchmark the typecheck command (#852)
|
@@ -3,6 +3,9 @@
|
|
3
3
|
|
4
4
|
module Solargraph
|
5
5
|
class ApiMap
|
6
|
+
# Queryable collection of Pins representing a Workspace, gems and the Ruby
|
7
|
+
# core.
|
8
|
+
#
|
6
9
|
class Store
|
7
10
|
# @return [Array<Solargraph::Pin::Base>]
|
8
11
|
attr_reader :pins
|
@@ -35,6 +38,7 @@ module Solargraph
|
|
35
38
|
# @param fqns [String]
|
36
39
|
# @return [String, nil]
|
37
40
|
def get_superclass fqns
|
41
|
+
raise "Do not prefix fully qualified namespaces with '::' - #{fqns.inspect}" if fqns.start_with?('::')
|
38
42
|
return superclass_references[fqns].first if superclass_references.key?(fqns)
|
39
43
|
return 'Object' if fqns != 'BasicObject' && namespace_exists?(fqns)
|
40
44
|
return 'Object' if fqns == 'Boolean'
|
@@ -100,7 +104,7 @@ module Solargraph
|
|
100
104
|
@namespaces ||= Set.new
|
101
105
|
end
|
102
106
|
|
103
|
-
# @return [
|
107
|
+
# @return [Enumerable<Solargraph::Pin::Base>]
|
104
108
|
def namespace_pins
|
105
109
|
pins_by_class(Solargraph::Pin::Namespace)
|
106
110
|
end
|
@@ -146,7 +150,7 @@ module Solargraph
|
|
146
150
|
|
147
151
|
# @generic T
|
148
152
|
# @param klass [Class<T>]
|
149
|
-
# @return [
|
153
|
+
# @return [Set<T>]
|
150
154
|
def pins_by_class klass
|
151
155
|
# @type [Set<Solargraph::Pin::Base>]
|
152
156
|
s = Set.new
|
@@ -280,8 +284,8 @@ module Solargraph
|
|
280
284
|
get_path_pins(pin.path.sub(/#initialize/, '.new')).first
|
281
285
|
end
|
282
286
|
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
283
|
-
pin.docstring.delete_tags tag
|
284
|
-
new_pin.docstring.delete_tags tag
|
287
|
+
pin.docstring.delete_tags tag
|
288
|
+
new_pin.docstring.delete_tags tag if new_pin
|
285
289
|
end
|
286
290
|
ovr.tags.each do |tag|
|
287
291
|
pin.docstring.add_tag(tag)
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -5,7 +5,7 @@ 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
|
@@ -96,6 +96,9 @@ module Solargraph
|
|
96
96
|
self
|
97
97
|
end
|
98
98
|
|
99
|
+
# @todo need to model type def statement in chains as a symbol so
|
100
|
+
# that this overload of 'protected' will typecheck @sg-ignore
|
101
|
+
# @sg-ignore
|
99
102
|
protected def equality_fields
|
100
103
|
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires, @missing_docs]
|
101
104
|
end
|
@@ -250,18 +253,20 @@ module Solargraph
|
|
250
253
|
# @param tag [String, nil] The namespace to
|
251
254
|
# match, complete with generic parameters set to appropriate
|
252
255
|
# values if available
|
253
|
-
# @param context_tag [String] The context in which
|
254
|
-
# referenced; start from here to resolve the name
|
256
|
+
# @param context_tag [String] The fully qualified context in which
|
257
|
+
# the tag was referenced; start from here to resolve the name.
|
258
|
+
# Should not be prefixed with '::'.
|
255
259
|
# @return [String, nil] fully qualified tag
|
256
260
|
def qualify tag, context_tag = ''
|
257
261
|
return tag if ['self', nil].include?(tag)
|
258
|
-
|
262
|
+
|
263
|
+
context_type = ComplexType.parse(context_tag).force_rooted
|
259
264
|
return unless context_type
|
260
265
|
|
261
266
|
type = ComplexType.try_parse(tag)
|
262
267
|
return unless type
|
263
268
|
|
264
|
-
fqns = qualify_namespace(type.rooted_namespace, context_type.
|
269
|
+
fqns = qualify_namespace(type.rooted_namespace, context_type.namespace)
|
265
270
|
return unless fqns
|
266
271
|
|
267
272
|
fqns + type.substring
|
@@ -326,6 +331,11 @@ module Solargraph
|
|
326
331
|
store.pins_by_class(Pin::GlobalVariable)
|
327
332
|
end
|
328
333
|
|
334
|
+
# @return [Enumerable<Solargraph::Pin::Block>]
|
335
|
+
def get_block_pins
|
336
|
+
store.pins_by_class(Pin::Block)
|
337
|
+
end
|
338
|
+
|
329
339
|
# Get an array of methods available in a particular context.
|
330
340
|
#
|
331
341
|
# @param rooted_tag [String] The fully qualified namespace to search for methods
|
@@ -334,6 +344,9 @@ module Solargraph
|
|
334
344
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
335
345
|
# @return [Array<Solargraph::Pin::Method>]
|
336
346
|
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
347
|
+
rooted_type = ComplexType.try_parse(rooted_tag)
|
348
|
+
fqns = rooted_type.namespace
|
349
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
337
350
|
cached = cache.get_methods(rooted_tag, scope, visibility, deep)
|
338
351
|
return cached.clone unless cached.nil?
|
339
352
|
result = []
|
@@ -373,9 +386,12 @@ module Solargraph
|
|
373
386
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
374
387
|
result.concat inner_get_methods('Module', scope, visibility, deep, skip) if scope == :module
|
375
388
|
end
|
376
|
-
|
377
|
-
|
378
|
-
|
389
|
+
result = resolve_method_aliases(result, visibility)
|
390
|
+
if namespace_pin && rooted_tag != rooted_type.name
|
391
|
+
result = result.map { |method_pin| method_pin.resolve_generics(namespace_pin, rooted_type) }
|
392
|
+
end
|
393
|
+
cache.set_methods(rooted_tag, scope, visibility, deep, result)
|
394
|
+
result
|
379
395
|
end
|
380
396
|
|
381
397
|
# Get an array of method pins for a complex type.
|
@@ -431,8 +447,13 @@ module Solargraph
|
|
431
447
|
# @param name [String] Method name to look up
|
432
448
|
# @param scope [Symbol] :instance or :class
|
433
449
|
# @return [Array<Solargraph::Pin::Method>]
|
434
|
-
def get_method_stack rooted_tag, name, scope: :instance
|
435
|
-
|
450
|
+
def get_method_stack rooted_tag, name, scope: :instance, visibility: [:private, :protected, :public], preserve_generics: false
|
451
|
+
rooted_type = ComplexType.parse(rooted_tag)
|
452
|
+
fqns = rooted_type.namespace
|
453
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
454
|
+
methods = get_methods(rooted_tag, scope: scope, visibility: visibility).select { |p| p.name == name }
|
455
|
+
methods = erase_generics(namespace_pin, rooted_type, methods) unless preserve_generics
|
456
|
+
methods
|
436
457
|
end
|
437
458
|
|
438
459
|
# Get an array of all suggestions that match the specified path.
|
@@ -591,9 +612,10 @@ module Solargraph
|
|
591
612
|
# @param no_core [Boolean] Skip core classes if true
|
592
613
|
# @return [Array<Pin::Base>]
|
593
614
|
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
594
|
-
rooted_type = ComplexType.parse(rooted_tag)
|
615
|
+
rooted_type = ComplexType.parse(rooted_tag).force_rooted
|
595
616
|
fqns = rooted_type.namespace
|
596
617
|
fqns_generic_params = rooted_type.all_params
|
618
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
597
619
|
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
598
620
|
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
|
599
621
|
return [] if skip.include?(reqstr)
|
@@ -608,15 +630,7 @@ module Solargraph
|
|
608
630
|
# Store#get_methods doesn't know about full tags, just
|
609
631
|
# namespaces; resolving the generics in the method pins is this
|
610
632
|
# 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
|
633
|
+
methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
620
634
|
result.concat methods
|
621
635
|
if deep
|
622
636
|
if scope == :instance
|
@@ -629,7 +643,7 @@ module Solargraph
|
|
629
643
|
# @todo perform the same translation in the other areas
|
630
644
|
# here after adding a spec and handling things correctly
|
631
645
|
# in ApiMap::Store and RbsMap::Conversions
|
632
|
-
resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
|
646
|
+
resolved_include_type = ComplexType.parse(rooted_include_tag).force_rooted.resolve_generics(namespace_pin, rooted_type)
|
633
647
|
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
634
648
|
result.concat methods
|
635
649
|
end
|
@@ -690,7 +704,7 @@ module Solargraph
|
|
690
704
|
|
691
705
|
# @param namespace [String]
|
692
706
|
# @param context [String]
|
693
|
-
# @return [String]
|
707
|
+
# @return [String, nil]
|
694
708
|
def qualify_lower namespace, context
|
695
709
|
qualify namespace, context.split('::')[0..-2].join('::')
|
696
710
|
end
|
@@ -802,11 +816,48 @@ module Solargraph
|
|
802
816
|
name: pin.name,
|
803
817
|
comments: origin.comments,
|
804
818
|
scope: origin.scope,
|
819
|
+
# context: pin.context,
|
805
820
|
visibility: origin.visibility,
|
806
821
|
signatures: origin.signatures,
|
807
|
-
attribute: origin.attribute
|
822
|
+
attribute: origin.attribute?,
|
823
|
+
generics: origin.generics,
|
824
|
+
return_type: origin.return_type,
|
808
825
|
}
|
809
826
|
Pin::Method.new **args
|
810
827
|
end
|
828
|
+
|
829
|
+
include Logging
|
830
|
+
|
831
|
+
private
|
832
|
+
|
833
|
+
# @param namespace_pin [Pin::Namespace]
|
834
|
+
# @param rooted_type [ComplexType]
|
835
|
+
# @param pins [Enumerable<Pin::Base>]
|
836
|
+
# @return [Array<Pin::Base>]
|
837
|
+
def erase_generics(namespace_pin, rooted_type, pins)
|
838
|
+
return pins unless should_erase_generics_when_done?(namespace_pin, rooted_type)
|
839
|
+
|
840
|
+
logger.debug("Erasing generics on namespace_pin=#{namespace_pin} / rooted_type=#{rooted_type}")
|
841
|
+
pins.map do |method_pin|
|
842
|
+
method_pin.erase_generics(namespace_pin.generics)
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
# @param namespace_pin [Pin::Namespace]
|
847
|
+
# @param rooted_type [ComplexType]
|
848
|
+
def should_erase_generics_when_done?(namespace_pin, rooted_type)
|
849
|
+
has_generics?(namespace_pin) && !can_resolve_generics?(namespace_pin, rooted_type)
|
850
|
+
end
|
851
|
+
|
852
|
+
# @param namespace_pin [Pin::Namespace]
|
853
|
+
def has_generics?(namespace_pin)
|
854
|
+
namespace_pin && !namespace_pin.generics.empty?
|
855
|
+
end
|
856
|
+
|
857
|
+
# @param namespace_pin [Pin::Namespace]
|
858
|
+
# @param rooted_type [ComplexType]
|
859
|
+
def can_resolve_generics?(namespace_pin, rooted_type)
|
860
|
+
has_generics?(namespace_pin) && !rooted_type.all_params.empty?
|
861
|
+
end
|
811
862
|
end
|
812
863
|
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
|
@@ -26,6 +26,8 @@ module Solargraph
|
|
26
26
|
if name.start_with?('::')
|
27
27
|
name = name[2..-1]
|
28
28
|
rooted = true
|
29
|
+
elsif !can_root_name?(name)
|
30
|
+
rooted = true
|
29
31
|
else
|
30
32
|
rooted = false
|
31
33
|
end
|
@@ -63,7 +65,7 @@ module Solargraph
|
|
63
65
|
if parameters_type.nil?
|
64
66
|
raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
|
65
67
|
end
|
66
|
-
raise "Please remove leading :: and set rooted instead - #{name}" if name.start_with?('::')
|
68
|
+
raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
|
67
69
|
@name = name
|
68
70
|
@key_types = key_types
|
69
71
|
@subtypes = subtypes
|
@@ -78,6 +80,24 @@ module Solargraph
|
|
78
80
|
tag
|
79
81
|
end
|
80
82
|
|
83
|
+
def eql?(other)
|
84
|
+
self.class == other.class &&
|
85
|
+
@name == other.name &&
|
86
|
+
@key_types == other.key_types &&
|
87
|
+
@subtypes == other.subtypes &&
|
88
|
+
@rooted == other.rooted? &&
|
89
|
+
@all_params == other.all_params &&
|
90
|
+
@parameters_type == other.parameters_type
|
91
|
+
end
|
92
|
+
|
93
|
+
def ==(other)
|
94
|
+
eql?(other)
|
95
|
+
end
|
96
|
+
|
97
|
+
def hash
|
98
|
+
[self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
|
99
|
+
end
|
100
|
+
|
81
101
|
# @return [Array<UniqueType>]
|
82
102
|
def items
|
83
103
|
[self]
|
@@ -108,7 +128,11 @@ module Solargraph
|
|
108
128
|
# tuples don't have a name; they're just [foo, bar, baz].
|
109
129
|
if substring == '()'
|
110
130
|
# but there are no zero element tuples, so we go with an array
|
111
|
-
|
131
|
+
if rooted?
|
132
|
+
'::Array[]'
|
133
|
+
else
|
134
|
+
'Array[]'
|
135
|
+
end
|
112
136
|
else
|
113
137
|
# already generated surrounded by []
|
114
138
|
parameters_as_rbs
|
@@ -238,6 +262,7 @@ module Solargraph
|
|
238
262
|
# @return [self]
|
239
263
|
def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
|
240
264
|
raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
|
265
|
+
|
241
266
|
new_name ||= name
|
242
267
|
new_key_types ||= @key_types
|
243
268
|
new_subtypes ||= @subtypes
|
@@ -278,17 +303,26 @@ module Solargraph
|
|
278
303
|
new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
279
304
|
new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
280
305
|
end
|
281
|
-
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes)
|
306
|
+
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted)
|
282
307
|
yield new_type
|
283
308
|
end
|
284
309
|
|
285
|
-
#
|
286
|
-
#
|
287
|
-
# @
|
288
|
-
|
310
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
311
|
+
#
|
312
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
313
|
+
# @param context [String] The namespace from which to resolve names
|
314
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
315
|
+
def qualify api_map, context = ''
|
289
316
|
transform do |t|
|
290
|
-
next t if t.name
|
291
|
-
t.
|
317
|
+
next t if t.name == GENERIC_TAG_NAME
|
318
|
+
next t if t.duck_type? || t.void? || t.undefined?
|
319
|
+
recon = (t.rooted? ? '' : context)
|
320
|
+
fqns = api_map.qualify(t.name, recon)
|
321
|
+
if fqns.nil?
|
322
|
+
next UniqueType::BOOLEAN if t.tag == 'Boolean'
|
323
|
+
next UniqueType::UNDEFINED
|
324
|
+
end
|
325
|
+
t.recreate(new_name: fqns, make_rooted: true)
|
292
326
|
end
|
293
327
|
end
|
294
328
|
|
@@ -296,6 +330,35 @@ module Solargraph
|
|
296
330
|
@name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
|
297
331
|
end
|
298
332
|
|
333
|
+
# @param dst [ComplexType]
|
334
|
+
# @return [self]
|
335
|
+
def self_to_type dst
|
336
|
+
object_type_dst = dst.reduce_class_type
|
337
|
+
transform do |t|
|
338
|
+
next t if t.name != 'self'
|
339
|
+
object_type_dst
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def all_rooted?
|
344
|
+
return true if name == GENERIC_TAG_NAME
|
345
|
+
rooted? && all_params.all?(&:rooted?)
|
346
|
+
end
|
347
|
+
|
348
|
+
def rooted?
|
349
|
+
!can_root_name? || @rooted
|
350
|
+
end
|
351
|
+
|
352
|
+
def can_root_name?(name_to_check = name)
|
353
|
+
self.class.can_root_name?(name_to_check)
|
354
|
+
end
|
355
|
+
|
356
|
+
# @param name [String]
|
357
|
+
def self.can_root_name?(name)
|
358
|
+
# name is not lowercase
|
359
|
+
!name.empty? && name != name.downcase
|
360
|
+
end
|
361
|
+
|
299
362
|
UNDEFINED = UniqueType.new('undefined', rooted: false)
|
300
363
|
BOOLEAN = UniqueType.new('Boolean', rooted: true)
|
301
364
|
end
|
@@ -18,13 +18,27 @@ module Solargraph
|
|
18
18
|
@items = types.flat_map(&:items).uniq(&:to_s)
|
19
19
|
end
|
20
20
|
|
21
|
+
def eql?(other)
|
22
|
+
self.class == other.class &&
|
23
|
+
@items == other.items
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other)
|
27
|
+
self.eql?(other)
|
28
|
+
end
|
29
|
+
|
30
|
+
def hash
|
31
|
+
[self.class, @items].hash
|
32
|
+
end
|
33
|
+
|
21
34
|
# @param api_map [ApiMap]
|
22
35
|
# @param context [String]
|
23
36
|
# @return [ComplexType]
|
24
37
|
def qualify api_map, context = ''
|
25
38
|
red = reduce_object
|
26
39
|
types = red.items.map do |t|
|
27
|
-
next t if ['
|
40
|
+
next t if ['nil', 'void', 'undefined'].include?(t.name)
|
41
|
+
next t if ['::Boolean'].include?(t.rooted_name)
|
28
42
|
t.qualify api_map, context
|
29
43
|
end
|
30
44
|
ComplexType.new(types).reduce_object
|
@@ -52,6 +66,16 @@ module Solargraph
|
|
52
66
|
(@items.length > 1 ? ')' : ''))
|
53
67
|
end
|
54
68
|
|
69
|
+
# @param dst [ComplexType]
|
70
|
+
# @return [ComplexType]
|
71
|
+
def self_to_type dst
|
72
|
+
object_type_dst = dst.reduce_class_type
|
73
|
+
transform do |t|
|
74
|
+
next t if t.name != 'self'
|
75
|
+
object_type_dst
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
55
79
|
# @yieldparam [UniqueType]
|
56
80
|
# @return [Array]
|
57
81
|
def map &block
|
@@ -171,16 +195,7 @@ module Solargraph
|
|
171
195
|
# @return [ComplexType]
|
172
196
|
def resolve_generics definitions, context_type
|
173
197
|
result = @items.map { |i| i.resolve_generics(definitions, context_type) }
|
174
|
-
ComplexType.
|
175
|
-
end
|
176
|
-
|
177
|
-
# @param dst [String]
|
178
|
-
# @return [ComplexType]
|
179
|
-
def self_to dst
|
180
|
-
return self unless selfy?
|
181
|
-
red = reduce_class(dst)
|
182
|
-
result = @items.map { |i| i.self_to red }
|
183
|
-
ComplexType.try_parse(*result.map(&:tag))
|
198
|
+
ComplexType.new(result)
|
184
199
|
end
|
185
200
|
|
186
201
|
def nullable?
|
@@ -192,14 +207,43 @@ module Solargraph
|
|
192
207
|
@items.first.all_params || []
|
193
208
|
end
|
194
209
|
|
210
|
+
# @return [ComplexType]
|
211
|
+
def reduce_class_type
|
212
|
+
new_items = items.flat_map do |type|
|
213
|
+
next type unless ['Module', 'Class'].include?(type.name)
|
214
|
+
|
215
|
+
type.all_params
|
216
|
+
end
|
217
|
+
ComplexType.new(new_items)
|
218
|
+
end
|
219
|
+
|
220
|
+
# every type and subtype in this union have been resolved to be
|
221
|
+
# fully qualified
|
222
|
+
def all_rooted?
|
223
|
+
all?(&:all_rooted?)
|
224
|
+
end
|
225
|
+
|
226
|
+
# every top-level type has resolved to be fully qualified; see
|
227
|
+
# #all_rooted? to check their subtypes as well
|
228
|
+
def rooted?
|
229
|
+
all?(&:rooted?)
|
230
|
+
end
|
231
|
+
|
195
232
|
attr_reader :items
|
196
233
|
|
234
|
+
def rooted?
|
235
|
+
@items.all?(&:rooted?)
|
236
|
+
end
|
237
|
+
|
197
238
|
protected
|
198
239
|
|
199
240
|
# @return [ComplexType]
|
200
241
|
def reduce_object
|
201
|
-
|
202
|
-
|
242
|
+
new_items = items.flat_map do |ut|
|
243
|
+
next [ut] if ut.name != 'Object' || ut.subtypes.empty?
|
244
|
+
ut.subtypes
|
245
|
+
end
|
246
|
+
ComplexType.new(new_items)
|
203
247
|
end
|
204
248
|
|
205
249
|
def bottom?
|
@@ -221,10 +265,15 @@ module Solargraph
|
|
221
265
|
#
|
222
266
|
# @param *strings [Array<String>] The type definitions to parse
|
223
267
|
# @return [ComplexType]
|
224
|
-
# @overload parse(*strings, partial: false)
|
225
|
-
# @todo Need ability to use a literal true as a type below
|
226
|
-
# @param partial [Boolean] True if the string is part of a another type
|
227
|
-
# @return [Array<UniqueType>]
|
268
|
+
# # @overload parse(*strings, partial: false)
|
269
|
+
# # @todo Need ability to use a literal true as a type below
|
270
|
+
# # @param partial [Boolean] True if the string is part of a another type
|
271
|
+
# # @return [Array<UniqueType>]
|
272
|
+
# @sg-ignore
|
273
|
+
# @todo To be able to select the right signature above,
|
274
|
+
# Chain::Call needs to know the decl type (:arg, :optarg,
|
275
|
+
# :kwarg, etc) of the arguments given, instead of just having
|
276
|
+
# an array of Chains as the arguments.
|
228
277
|
def parse *strings, partial: false
|
229
278
|
# @type [Hash{Array<String> => ComplexType}]
|
230
279
|
@cache ||= {}
|
@@ -3,10 +3,15 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module LanguageServer
|
5
5
|
class Host
|
6
|
-
# A serial worker Thread to handle
|
6
|
+
# A serial worker Thread to handle incoming messages.
|
7
7
|
#
|
8
|
-
# this make check pending message possible, and maybe cancelled to speedup process
|
9
8
|
class MessageWorker
|
9
|
+
UPDATE_METHODS = [
|
10
|
+
'textDocument/didOpen',
|
11
|
+
'textDocument/didChange',
|
12
|
+
'workspace/didChangeWatchedFiles'
|
13
|
+
].freeze
|
14
|
+
|
10
15
|
# @param host [Host]
|
11
16
|
def initialize(host)
|
12
17
|
@host = host
|
@@ -30,7 +35,7 @@ module Solargraph
|
|
30
35
|
@stopped = true
|
31
36
|
end
|
32
37
|
|
33
|
-
# @param message [Hash] The message
|
38
|
+
# @param message [Hash] The message to handle. Will be forwarded to Host#receive
|
34
39
|
# @return [void]
|
35
40
|
def queue(message)
|
36
41
|
@mutex.synchronize do
|
@@ -52,10 +57,45 @@ module Solargraph
|
|
52
57
|
def tick
|
53
58
|
message = @mutex.synchronize do
|
54
59
|
@resource.wait(@mutex) if messages.empty?
|
55
|
-
|
60
|
+
next_message
|
56
61
|
end
|
57
62
|
handler = @host.receive(message)
|
58
|
-
handler
|
63
|
+
handler&.send_response
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def next_message
|
69
|
+
cancel_message || next_priority
|
70
|
+
end
|
71
|
+
|
72
|
+
def cancel_message
|
73
|
+
# Handle cancellations first
|
74
|
+
idx = messages.find_index { |msg| msg['method'] == '$/cancelRequest' }
|
75
|
+
return unless idx
|
76
|
+
|
77
|
+
msg = messages[idx]
|
78
|
+
messages.delete_at idx
|
79
|
+
msg
|
80
|
+
end
|
81
|
+
|
82
|
+
def next_priority
|
83
|
+
# Prioritize updates and version-dependent messages for performance
|
84
|
+
idx = messages.find_index do |msg|
|
85
|
+
UPDATE_METHODS.include?(msg['method']) || version_dependent?(msg)
|
86
|
+
end
|
87
|
+
return messages.shift unless idx
|
88
|
+
|
89
|
+
msg = messages[idx]
|
90
|
+
messages.delete_at idx
|
91
|
+
msg
|
92
|
+
end
|
93
|
+
|
94
|
+
# True if the message requires a previous update to have executed in
|
95
|
+
# order to work correctly.
|
96
|
+
#
|
97
|
+
def version_dependent? msg
|
98
|
+
msg['textDocument'] && msg['position']
|
59
99
|
end
|
60
100
|
end
|
61
101
|
end
|