solargraph 0.53.4 → 0.54.1
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 +41 -0
- data/lib/solargraph/api_map/cache.rb +2 -12
- data/lib/solargraph/api_map/store.rb +14 -5
- data/lib/solargraph/api_map.rb +67 -24
- data/lib/solargraph/complex_type/type_methods.rb +70 -39
- data/lib/solargraph/complex_type/unique_type.rb +187 -73
- data/lib/solargraph/complex_type.rb +105 -40
- data/lib/solargraph/doc_map.rb +19 -3
- data/lib/solargraph/gem_pins.rb +9 -1
- data/lib/solargraph/language_server/host/dispatch.rb +8 -1
- data/lib/solargraph/language_server/host/message_worker.rb +29 -3
- data/lib/solargraph/language_server/host/sources.rb +1 -61
- data/lib/solargraph/language_server/host.rb +21 -68
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +14 -0
- 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 +1 -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 +135 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +144 -113
- data/lib/solargraph/location.rb +14 -1
- data/lib/solargraph/parser/node_processor/base.rb +3 -2
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -7
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
- data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -5
- 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 +53 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +6 -4
- data/lib/solargraph/parser/parser_gem/node_processors.rb +2 -0
- data/lib/solargraph/parser.rb +2 -5
- data/lib/solargraph/pin/base.rb +15 -1
- data/lib/solargraph/pin/base_variable.rb +35 -6
- data/lib/solargraph/pin/block.rb +48 -11
- 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/delegated_method.rb +5 -1
- data/lib/solargraph/pin/documenting.rb +2 -0
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/method.rb +54 -32
- data/lib/solargraph/pin/namespace.rb +4 -4
- data/lib/solargraph/pin/parameter.rb +14 -39
- 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 +79 -42
- data/lib/solargraph/rbs_map/core_fills.rb +6 -6
- data/lib/solargraph/rbs_map.rb +11 -3
- data/lib/solargraph/shell.rb +35 -15
- 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 +78 -50
- data/lib/solargraph/source/chain/link.rb +9 -0
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +60 -16
- data/lib/solargraph/source/cursor.rb +13 -2
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +102 -129
- data/lib/solargraph/source_map/clip.rb +4 -4
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map/mapper.rb +3 -2
- data/lib/solargraph/source_map.rb +37 -15
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +50 -25
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +2 -1
- data/lib/solargraph/workspace.rb +13 -0
- metadata +6 -3
- data/lib/solargraph/language_server/host/cataloger.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6619265fc1ba2cab9154e70c5f4a6626999b685d58e26a805ec606d6804f17b
|
4
|
+
data.tar.gz: cfac32a13734ba9b392d27fcb8da7c76b180f0bf64189d17698b2246ce6e3773
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d1d40bf5d19b37f6a2ee8cce73e36027140ae402d27326c15e39a961217153e8b269722503ca0a8a3b592bee50cb6227fffcd812f62a1ec8a1bf94219270eea
|
7
|
+
data.tar.gz: 627df7fb0bd23b641f0b1a40434a6384def8f32bf318b4f92d243266ee0c3145059adc29ea487dcdc30c914045e5737bca92bff6bd67fd06527f97c2e4690fb8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
## 0.54.1 - April 26, 2025
|
2
|
+
- Retire more RubyVM-specific code (#797)
|
3
|
+
- Add additional docs for key classes, modules and methods (#802)
|
4
|
+
- Populate location information from RBS files (#768)
|
5
|
+
- Consolidate parameter handling into Pin::Callable (#844)
|
6
|
+
- Adjust local variable presence to start after assignment, not before (#864)
|
7
|
+
- Resolve params from ref tags (#872)
|
8
|
+
- Reduce use of ComplexType.parse() to preserve rooted? information (#870)
|
9
|
+
- Ensure yield return types are qualified (#886)
|
10
|
+
- Understand type of 'def foo; @foo ||= bar; end' reader methods (#888)
|
11
|
+
- Improvements to #inspect output on pins and chains (#895)
|
12
|
+
- Block method resolution improvements (#885)
|
13
|
+
- Understand mass assignment into instance variables (#893)
|
14
|
+
- Library sync and cache invalidation (#903)
|
15
|
+
- Handle super and yield scenarios from blocks (#891)
|
16
|
+
- Allow core and stdlib documentation to be uncached (#899)
|
17
|
+
- Surface variable names in LSP, e.g., textDocument/hover (#910)
|
18
|
+
- Keep idle progress notifications alive (#911)
|
19
|
+
|
20
|
+
## 0.54.0 - April 14, 2025
|
21
|
+
- Add support for simple block argument destructuring (#821)
|
22
|
+
- Benchmark the typecheck command (#852)
|
23
|
+
- Send Gem Caching Progress Notifications to LSP Clients (#855)
|
24
|
+
- [breaking] Fix more complex_type_spec.rb cases (#813)
|
25
|
+
- Mass assignment support - e.g., a, b = ['1', '2'] (#843)
|
26
|
+
- Memoize result of Chain#infer (#857)
|
27
|
+
- Ignore malformed mixins and overloads (#862)
|
28
|
+
- Drop Parser::ParserGem::ClassMethods#returns_from_node (#866)
|
29
|
+
- Refactor TypeChecker#argument_problems_for for type safety (#867)
|
30
|
+
- Specify more type behavior for variable reassignment (#863)
|
31
|
+
- One-step source synchronization (#871)
|
32
|
+
- Show cache progress in shell commands (#874)
|
33
|
+
- Fix miscellaneous scan errors (#875)
|
34
|
+
- Synchronous libraries (#876)
|
35
|
+
- Fix parsing of Set#classify method signature from RBS (#878)
|
36
|
+
- Sync Library#diagnose (#882)
|
37
|
+
- Doesn't false-alarm over splatted non-final args in typechecking (#883)
|
38
|
+
- Remove accidental inclusion of Module's methods in objects (#884)
|
39
|
+
- Remove another splat-related false alarm in strict typechecking (#889)
|
40
|
+
- Change require path `warn` to `debug` (#897)
|
41
|
+
|
1
42
|
## 0.53.4 - March 30, 2025
|
2
43
|
- [regression] Restore 'Unresolved call' typecheck for stdlib objects (#849)
|
3
44
|
- Lazy dynamic rebinding (#851)
|
@@ -78,20 +78,10 @@ module Solargraph
|
|
78
78
|
@receiver_definitions[path] = pin
|
79
79
|
end
|
80
80
|
|
81
|
-
# @param cursor [Source::Cursor]
|
82
|
-
# @return [SourceMap::Clip, nil]
|
83
|
-
def get_clip(cursor)
|
84
|
-
@clips["#{cursor.filename}|#{cursor.range.inspect}|#{cursor.node&.to_sexp}"]
|
85
|
-
end
|
86
|
-
|
87
|
-
# @param cursor [Source::Cursor]
|
88
|
-
# @param clip [SourceMap::Clip]
|
89
|
-
def set_clip(cursor, clip)
|
90
|
-
@clips["#{cursor.filename}|#{cursor.range.inspect}|#{cursor.node&.to_sexp}"] = clip
|
91
|
-
end
|
92
|
-
|
93
81
|
# @return [void]
|
94
82
|
def clear
|
83
|
+
return if empty?
|
84
|
+
|
95
85
|
all_caches.each(&:clear)
|
96
86
|
end
|
97
87
|
|
@@ -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'
|
@@ -65,6 +69,10 @@ module Solargraph
|
|
65
69
|
path_pin_hash[path] || []
|
66
70
|
end
|
67
71
|
|
72
|
+
def cacheable_pins
|
73
|
+
@cacheable_pins ||= pins_by_class(Pin::Namespace) + pins_by_class(Pin::Constant) + pins_by_class(Pin::Method) + pins_by_class(Pin::Reference)
|
74
|
+
end
|
75
|
+
|
68
76
|
# @param fqns [String]
|
69
77
|
# @param scope [Symbol] :class or :instance
|
70
78
|
# @return [Enumerable<Solargraph::Pin::Base>]
|
@@ -140,8 +148,9 @@ module Solargraph
|
|
140
148
|
to_s
|
141
149
|
end
|
142
150
|
|
143
|
-
# @
|
144
|
-
# @
|
151
|
+
# @generic T
|
152
|
+
# @param klass [Class<T>]
|
153
|
+
# @return [Set<T>]
|
145
154
|
def pins_by_class klass
|
146
155
|
# @type [Set<Solargraph::Pin::Base>]
|
147
156
|
s = Set.new
|
@@ -165,7 +174,7 @@ module Solargraph
|
|
165
174
|
|
166
175
|
private
|
167
176
|
|
168
|
-
# @return [Hash{Array(String, String) => Array<Pin::Namespace>}]
|
177
|
+
# @return [Hash{::Array(String, String) => ::Array<Pin::Namespace>}]
|
169
178
|
def fqns_pins_map
|
170
179
|
@fqns_pins_map ||= Hash.new do |h, (base, name)|
|
171
180
|
value = namespace_children(base).select { |pin| pin.name == name && pin.is_a?(Pin::Namespace) }
|
@@ -178,7 +187,7 @@ module Solargraph
|
|
178
187
|
pins_by_class(Pin::Symbol)
|
179
188
|
end
|
180
189
|
|
181
|
-
# @return [Hash{String =>
|
190
|
+
# @return [Hash{String => Array<String>}]
|
182
191
|
def superclass_references
|
183
192
|
@superclass_references ||= {}
|
184
193
|
end
|
@@ -243,7 +252,7 @@ module Solargraph
|
|
243
252
|
def index
|
244
253
|
set = pins.to_set
|
245
254
|
@pin_class_hash = set.classify(&:class).transform_values(&:to_a)
|
246
|
-
# @type [Hash{Class =>
|
255
|
+
# @type [Hash{Class => ::Array<Solargraph::Pin::Base>}]
|
247
256
|
@pin_select_cache = {}
|
248
257
|
@namespace_map = set.classify(&:namespace)
|
249
258
|
@path_pin_hash = set.classify(&:path)
|
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
|
@@ -29,6 +29,25 @@ module Solargraph
|
|
29
29
|
index pins
|
30
30
|
end
|
31
31
|
|
32
|
+
#
|
33
|
+
# This is a mutable object, which is cached in the Chain class -
|
34
|
+
# if you add any fields which change the results of calls (not
|
35
|
+
# just caches), please also change `equality_fields` below.
|
36
|
+
#
|
37
|
+
|
38
|
+
def eql?(other)
|
39
|
+
self.class == other.class &&
|
40
|
+
equality_fields == other.equality_fields
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
self.eql?(other)
|
45
|
+
end
|
46
|
+
|
47
|
+
def hash
|
48
|
+
equality_fields.hash
|
49
|
+
end
|
50
|
+
|
32
51
|
# @param pins [Array<Pin::Base>]
|
33
52
|
# @return [self]
|
34
53
|
def index pins
|
@@ -56,21 +75,31 @@ module Solargraph
|
|
56
75
|
# @param bench [Bench]
|
57
76
|
# @return [self]
|
58
77
|
def catalog bench
|
59
|
-
|
60
|
-
|
78
|
+
old_api_hash = @source_map_hash&.values&.map(&:api_hash)
|
79
|
+
need_to_uncache = (old_api_hash != bench.source_maps.map(&:api_hash))
|
61
80
|
@source_map_hash = bench.source_maps.map { |s| [s.filename, s] }.to_h
|
62
|
-
pins = bench.source_maps.
|
81
|
+
pins = bench.source_maps.flat_map(&:pins).flatten
|
82
|
+
implicit.clear
|
63
83
|
source_map_hash.each_value do |map|
|
64
84
|
implicit.merge map.environ
|
65
85
|
end
|
66
|
-
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).uniq
|
67
|
-
@
|
86
|
+
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).to_a.compact.uniq
|
87
|
+
if @unresolved_requires != unresolved_requires || @doc_map&.uncached_gemspecs&.any?
|
88
|
+
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace.rbs_collection_path) # @todo Implement gem preferences
|
89
|
+
@unresolved_requires = unresolved_requires
|
90
|
+
need_to_uncache = true
|
91
|
+
end
|
68
92
|
@store = Store.new(@@core_map.pins + @doc_map.pins + implicit.pins + pins)
|
69
|
-
@
|
93
|
+
@cache.clear if need_to_uncache
|
94
|
+
|
70
95
|
@missing_docs = [] # @todo Implement missing docs
|
71
96
|
self
|
72
97
|
end
|
73
98
|
|
99
|
+
protected def equality_fields
|
100
|
+
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires, @missing_docs]
|
101
|
+
end
|
102
|
+
|
74
103
|
# @return [::Array<Gem::Specification>]
|
75
104
|
def uncached_gemspecs
|
76
105
|
@doc_map&.uncached_gemspecs || []
|
@@ -133,14 +162,19 @@ module Solargraph
|
|
133
162
|
# Create an ApiMap with a workspace in the specified directory and cache
|
134
163
|
# any missing gems.
|
135
164
|
#
|
165
|
+
#
|
166
|
+
# @todo IO::NULL is incorrectly inferred to be a String.
|
167
|
+
# @sg-ignore
|
168
|
+
#
|
136
169
|
# @param directory [String]
|
170
|
+
# @param out [IO] The output stream for messages
|
137
171
|
# @return [ApiMap]
|
138
|
-
def self.load_with_cache directory
|
172
|
+
def self.load_with_cache directory, out = IO::NULL
|
139
173
|
api_map = load(directory)
|
140
174
|
return api_map if api_map.uncached_gemspecs.empty?
|
141
175
|
|
142
176
|
api_map.uncached_gemspecs.each do |gemspec|
|
143
|
-
|
177
|
+
out.puts "Caching gem #{gemspec.name} #{gemspec.version}"
|
144
178
|
pins = GemPins.build(gemspec)
|
145
179
|
Solargraph::Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
146
180
|
end
|
@@ -216,15 +250,22 @@ module Solargraph
|
|
216
250
|
# @param tag [String, nil] The namespace to
|
217
251
|
# match, complete with generic parameters set to appropriate
|
218
252
|
# values if available
|
219
|
-
# @param context_tag [String] The context in which
|
220
|
-
# referenced; start from here to resolve the name
|
253
|
+
# @param context_tag [String] The fully qualified context in which
|
254
|
+
# the tag was referenced; start from here to resolve the name.
|
255
|
+
# Should not be prefixed with '::'.
|
221
256
|
# @return [String, nil] fully qualified tag
|
222
257
|
def qualify tag, context_tag = ''
|
223
258
|
return tag if ['self', nil].include?(tag)
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
259
|
+
|
260
|
+
context_type = ComplexType.parse(context_tag).force_rooted
|
261
|
+
return unless context_type
|
262
|
+
|
263
|
+
type = ComplexType.try_parse(tag)
|
264
|
+
return unless type
|
265
|
+
|
266
|
+
fqns = qualify_namespace(type.rooted_namespace, context_type.namespace)
|
267
|
+
return unless fqns
|
268
|
+
|
228
269
|
fqns + type.substring
|
229
270
|
end
|
230
271
|
|
@@ -287,6 +328,11 @@ module Solargraph
|
|
287
328
|
store.pins_by_class(Pin::GlobalVariable)
|
288
329
|
end
|
289
330
|
|
331
|
+
# @return [Enumerable<Solargraph::Pin::Block>]
|
332
|
+
def get_block_pins
|
333
|
+
store.pins_by_class(Pin::Block)
|
334
|
+
end
|
335
|
+
|
290
336
|
# Get an array of methods available in a particular context.
|
291
337
|
#
|
292
338
|
# @param rooted_tag [String] The fully qualified namespace to search for methods
|
@@ -332,7 +378,7 @@ module Solargraph
|
|
332
378
|
end
|
333
379
|
end
|
334
380
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
335
|
-
result.concat inner_get_methods('Module', scope, visibility, deep, skip)
|
381
|
+
result.concat inner_get_methods('Module', scope, visibility, deep, skip) if scope == :module
|
336
382
|
end
|
337
383
|
resolved = resolve_method_aliases(result, visibility)
|
338
384
|
cache.set_methods(rooted_tag, scope, visibility, deep, resolved)
|
@@ -466,9 +512,6 @@ module Solargraph
|
|
466
512
|
def clip cursor
|
467
513
|
raise FileNotFoundError, "ApiMap did not catalog #{cursor.filename}" unless source_map_hash.key?(cursor.filename)
|
468
514
|
|
469
|
-
# @todo Clip caches are disabled pending resolution of a stale cache bug
|
470
|
-
# cache.get_clip(cursor) ||
|
471
|
-
# SourceMap::Clip.new(self, cursor).tap { |clip| cache.set_clip(cursor, clip) }
|
472
515
|
SourceMap::Clip.new(self, cursor)
|
473
516
|
end
|
474
517
|
|
@@ -555,7 +598,7 @@ module Solargraph
|
|
555
598
|
# @param no_core [Boolean] Skip core classes if true
|
556
599
|
# @return [Array<Pin::Base>]
|
557
600
|
def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
|
558
|
-
rooted_type = ComplexType.parse(rooted_tag)
|
601
|
+
rooted_type = ComplexType.parse(rooted_tag).force_rooted
|
559
602
|
fqns = rooted_type.namespace
|
560
603
|
fqns_generic_params = rooted_type.all_params
|
561
604
|
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
|
@@ -573,8 +616,8 @@ module Solargraph
|
|
573
616
|
# namespaces; resolving the generics in the method pins is this
|
574
617
|
# class' responsibility
|
575
618
|
raw_methods = store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
|
576
|
-
namespace_pin = store.get_path_pins(fqns).select{|p| p.is_a?(Pin::Namespace)}.first
|
577
|
-
methods = if rooted_tag != fqns
|
619
|
+
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
620
|
+
methods = if namespace_pin && rooted_tag != fqns
|
578
621
|
methods = raw_methods.map do |method_pin|
|
579
622
|
method_pin.resolve_generics(namespace_pin, rooted_type)
|
580
623
|
end
|
@@ -593,7 +636,7 @@ module Solargraph
|
|
593
636
|
# @todo perform the same translation in the other areas
|
594
637
|
# here after adding a spec and handling things correctly
|
595
638
|
# in ApiMap::Store and RbsMap::Conversions
|
596
|
-
resolved_include_type = ComplexType.parse(rooted_include_tag).resolve_generics(namespace_pin, rooted_type)
|
639
|
+
resolved_include_type = ComplexType.parse(rooted_include_tag).force_rooted.resolve_generics(namespace_pin, rooted_type)
|
597
640
|
methods = inner_get_methods(resolved_include_type.tag, scope, visibility, deep, skip, true)
|
598
641
|
result.concat methods
|
599
642
|
end
|
@@ -654,7 +697,7 @@ module Solargraph
|
|
654
697
|
|
655
698
|
# @param namespace [String]
|
656
699
|
# @param context [String]
|
657
|
-
# @return [String]
|
700
|
+
# @return [String, nil]
|
658
701
|
def qualify_lower namespace, context
|
659
702
|
qualify namespace, context.split('::')[0..-2].join('::')
|
660
703
|
end
|
@@ -12,24 +12,36 @@ 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
|
24
32
|
|
25
|
-
# @return [
|
26
|
-
attr_reader :
|
33
|
+
# @return [Array<ComplexType>]
|
34
|
+
attr_reader :subtypes
|
27
35
|
|
28
36
|
# @return [String]
|
29
|
-
|
37
|
+
def tag
|
38
|
+
@tag ||= "#{name}#{substring}"
|
39
|
+
end
|
30
40
|
|
31
|
-
# @return [
|
32
|
-
|
41
|
+
# @return [String]
|
42
|
+
def rooted_tag
|
43
|
+
@rooted_tag ||= rooted_name + rooted_substring
|
44
|
+
end
|
33
45
|
|
34
46
|
# @return [Boolean]
|
35
47
|
def duck_type?
|
@@ -41,9 +53,8 @@ module Solargraph
|
|
41
53
|
@nil_type ||= (name.casecmp('nil') == 0)
|
42
54
|
end
|
43
55
|
|
44
|
-
|
45
|
-
|
46
|
-
!substring.empty?
|
56
|
+
def tuple?
|
57
|
+
@tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
|
47
58
|
end
|
48
59
|
|
49
60
|
def void?
|
@@ -74,19 +85,28 @@ module Solargraph
|
|
74
85
|
end
|
75
86
|
end
|
76
87
|
|
88
|
+
# @return [Symbol, nil]
|
89
|
+
attr_reader :parameters_type
|
90
|
+
|
91
|
+
PARAMETERS_TYPE_BY_STARTING_TAG = {
|
92
|
+
'{' => :hash,
|
93
|
+
'(' => :fixed,
|
94
|
+
'<' => :list
|
95
|
+
}.freeze
|
96
|
+
|
77
97
|
# @return [Boolean]
|
78
98
|
def list_parameters?
|
79
|
-
|
99
|
+
parameters_type == :list
|
80
100
|
end
|
81
101
|
|
82
102
|
# @return [Boolean]
|
83
103
|
def fixed_parameters?
|
84
|
-
|
104
|
+
parameters_type == :fixed
|
85
105
|
end
|
86
106
|
|
87
107
|
# @return [Boolean]
|
88
108
|
def hash_parameters?
|
89
|
-
|
109
|
+
parameters_type == :hash
|
90
110
|
end
|
91
111
|
|
92
112
|
# @return [Array<ComplexType>]
|
@@ -111,16 +131,43 @@ module Solargraph
|
|
111
131
|
|
112
132
|
# @return [String]
|
113
133
|
def rooted_namespace
|
114
|
-
return namespace unless rooted?
|
134
|
+
return namespace unless rooted? && can_root_name?(namespace)
|
115
135
|
"::#{namespace}"
|
116
136
|
end
|
117
137
|
|
118
138
|
# @return [String]
|
119
139
|
def rooted_name
|
120
|
-
return name unless rooted?
|
140
|
+
return name unless @rooted && can_root_name?
|
121
141
|
"::#{name}"
|
122
142
|
end
|
123
143
|
|
144
|
+
# @return [String]
|
145
|
+
def substring
|
146
|
+
@substring ||= generate_substring_from(&:tags)
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [String]
|
150
|
+
def rooted_substring
|
151
|
+
@rooted_substring = generate_substring_from(&:rooted_tags)
|
152
|
+
end
|
153
|
+
|
154
|
+
# @return [String]
|
155
|
+
def generate_substring_from(&to_str)
|
156
|
+
key_types_str = key_types.map(&to_str).join(', ')
|
157
|
+
subtypes_str = subtypes.map(&to_str).join(', ')
|
158
|
+
if key_types.none?(&:defined?) && subtypes.none?(&:defined?)
|
159
|
+
''
|
160
|
+
elsif key_types.empty? && subtypes.empty?
|
161
|
+
''
|
162
|
+
elsif hash_parameters?
|
163
|
+
"{#{key_types_str} => #{subtypes_str}}"
|
164
|
+
elsif fixed_parameters?
|
165
|
+
"(#{subtypes_str})"
|
166
|
+
else
|
167
|
+
"<#{subtypes_str}>"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
124
171
|
# @return [::Symbol] :class or :instance
|
125
172
|
def scope
|
126
173
|
@scope ||= :instance if duck_type? || nil_type?
|
@@ -133,38 +180,22 @@ module Solargraph
|
|
133
180
|
tag == other.tag
|
134
181
|
end
|
135
182
|
|
136
|
-
def rooted?
|
137
|
-
@rooted
|
138
|
-
end
|
139
|
-
|
140
183
|
# Generate a ComplexType that fully qualifies this type's namespaces.
|
141
184
|
#
|
142
185
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
143
186
|
# @param context [String] The namespace from which to resolve names
|
144
187
|
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
145
188
|
def qualify api_map, context = ''
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
all_rtypes = value_types.map { |t| t.qualify api_map, context }
|
157
|
-
if list_parameters?
|
158
|
-
rtypes = all_rtypes.uniq
|
159
|
-
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
|
160
|
-
elsif fixed_parameters?
|
161
|
-
Solargraph::ComplexType.parse("#{fqns}(#{all_rtypes.map(&:tag).join(', ')})")
|
162
|
-
elsif hash_parameters?
|
163
|
-
ltypes = all_ltypes.uniq
|
164
|
-
rtypes = all_rtypes.uniq
|
165
|
-
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}")
|
166
|
-
else
|
167
|
-
Solargraph::ComplexType.parse(fqns)
|
189
|
+
transform do |t|
|
190
|
+
next t if t.name == GENERIC_TAG_NAME
|
191
|
+
next t if t.duck_type? || t.void? || t.undefined?
|
192
|
+
recon = (t.rooted? ? '' : context)
|
193
|
+
fqns = api_map.qualify(t.name, recon)
|
194
|
+
if fqns.nil?
|
195
|
+
next UniqueType::BOOLEAN if t.tag == 'Boolean'
|
196
|
+
next UniqueType::UNDEFINED
|
197
|
+
end
|
198
|
+
t.recreate(new_name: fqns, make_rooted: true)
|
168
199
|
end
|
169
200
|
end
|
170
201
|
|