solargraph 0.55.3 → 0.55.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/.github/workflows/plugins.yml +2 -0
- data/.github/workflows/typecheck.yml +3 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +7 -1
- data/README.md +13 -3
- data/lib/solargraph/api_map/index.rb +23 -15
- data/lib/solargraph/api_map/store.rb +8 -4
- data/lib/solargraph/api_map.rb +150 -57
- data/lib/solargraph/complex_type/type_methods.rb +6 -1
- data/lib/solargraph/complex_type/unique_type.rb +10 -2
- data/lib/solargraph/convention/base.rb +3 -3
- data/lib/solargraph/convention.rb +3 -3
- data/lib/solargraph/doc_map.rb +192 -46
- data/lib/solargraph/gem_pins.rb +53 -37
- data/lib/solargraph/language_server/host.rb +11 -2
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/library.rb +7 -4
- data/lib/solargraph/location.rb +13 -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 +2 -1
- data/lib/solargraph/parser/node_processor.rb +3 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +5 -8
- 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 +4 -3
- 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 +6 -4
- 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 +295 -28
- data/lib/solargraph/pin/base_variable.rb +9 -8
- data/lib/solargraph/pin/callable.rb +74 -3
- data/lib/solargraph/pin/closure.rb +18 -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/local_variable.rb +8 -5
- data/lib/solargraph/pin/method.rb +147 -25
- data/lib/solargraph/pin/namespace.rb +7 -2
- data/lib/solargraph/pin/parameter.rb +47 -6
- 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 +42 -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/pin_cache.rb +185 -0
- data/lib/solargraph/position.rb +9 -0
- data/lib/solargraph/range.rb +9 -0
- data/lib/solargraph/rbs_map/conversions.rb +183 -56
- data/lib/solargraph/rbs_map/core_fills.rb +24 -15
- data/lib/solargraph/rbs_map/core_map.rb +34 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +74 -17
- data/lib/solargraph/shell.rb +12 -15
- 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/source_map.rb +0 -17
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/workspace.rb +15 -5
- 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/yardoc.rb +3 -11
- data/lib/solargraph.rb +18 -1
- data/rbs/fills/tuple.rbs +150 -0
- data/rbs_collection.yaml +19 -0
- data/solargraph.gemspec +1 -0
- metadata +20 -7
- data/lib/solargraph/cache.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e015963ad868b3671d88892483ec3c06a3e7c96757f2013ba56c514af35eb0e
|
4
|
+
data.tar.gz: 22a6383d6f179ec708a930fbf8cb81bea8cbbee694de559f43208c859240a0cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd7b151efc8a584829cdc5c4424c81dd3703dd22f8287c8edfcfc32d65b8409e8be9d8354ed5369c6fa0955cc1ccd534014f6782aa71ca7b0a89c5df8a0d9b06
|
7
|
+
data.tar.gz: 818390cee111c7948e40904e1eb48dd407dd8f15045a29b96881e6bb520022438d9fca6a7ec678dbc6d793f74b3bcdaf17d4b152e86bb5b1f563f1703423a7ed
|
@@ -34,6 +34,8 @@ jobs:
|
|
34
34
|
bundle exec solargraph config
|
35
35
|
yq -yi '.plugins += ["solargraph-rails"]' .solargraph.yml
|
36
36
|
yq -yi '.plugins += ["solargraph-rspec"]' .solargraph.yml
|
37
|
+
- name: Install gem types
|
38
|
+
run: bundle exec rbs collection install
|
37
39
|
- name: Ensure typechecking still works
|
38
40
|
run: bundle exec solargraph typecheck --level typed
|
39
41
|
- name: Ensure specs still run
|
@@ -30,5 +30,7 @@ jobs:
|
|
30
30
|
bundler-cache: false
|
31
31
|
- name: Install gems
|
32
32
|
run: bundle install
|
33
|
+
- name: Install gem types
|
34
|
+
run: bundle exec rbs collection install
|
33
35
|
- name: Typecheck self
|
34
|
-
run: bundle exec solargraph typecheck --level typed
|
36
|
+
run: SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level typed
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
+
## 0.55.5 - July 1, 2025
|
2
|
+
- Ignore directory paths in Workspace#would_require? (#988)
|
3
|
+
|
4
|
+
## 0.55.4 - June 27, 2025
|
5
|
+
- Flatten results of DocMap external bundle query (#981)
|
6
|
+
|
1
7
|
## 0.55.3 - June 25, 2025
|
2
|
-
- Nil guards in flow-sensitive typing (patch release) #980
|
8
|
+
- Nil guards in flow-sensitive typing (patch release) (#980)
|
3
9
|
|
4
10
|
## 0.55.2 - June 21, 2025
|
5
11
|
- Require external bundle (#972)
|
data/README.md
CHANGED
@@ -63,12 +63,22 @@ The RSpec framework is supported via [solargraph-rspec](https://github.com/lekem
|
|
63
63
|
|
64
64
|
**Note: Before version 0.53.0, it was recommended to run `yard gems` periodically or automate it with `yard config` to ensure that Solargraph had access to gem documentation. These steps are no longer necessary. Solargraph maintains its own gem documentation cache independent of the yardocs in your gem installations.**
|
65
65
|
|
66
|
-
Solargraph automatically generates code maps from installed gems.
|
67
|
-
|
68
|
-
When editing code, a `require` call that references a gem will pull the documentation into the code maps and include the gem's API in code completion and intellisense.
|
66
|
+
When editing code, a `require` call that references a gem will pull the documentation into the code maps and include the gem's API in code completion and intellisense. Solargraph automatically generates code maps from installed gems, based on the YARD or RBS type information inside the gem. You can also eagerly cache gem documentation with the `solargraph gems` command.
|
69
67
|
|
70
68
|
If your project automatically requires bundled gems (e.g., `require 'bundler/require'`), Solargraph will add all of the Gemfile's default dependencies to the map.
|
71
69
|
|
70
|
+
To ensure you have types for gems which contain neither RBS nor YARD
|
71
|
+
information, use
|
72
|
+
[gem\_rbs\_collection](https://github.com/ruby/gem_rbs_collection) to
|
73
|
+
install a community-supported set of RBS types for various gems:
|
74
|
+
|
75
|
+
```sh
|
76
|
+
bundle exec rbs collection init
|
77
|
+
bundle exec rbs collection install
|
78
|
+
```
|
79
|
+
|
80
|
+
Once installed, you can also insert your own local overrides and definitions in RBS in a directory configured in the `rbs_collection.yaml` that the above commands create.
|
81
|
+
|
72
82
|
### Type Checking
|
73
83
|
|
74
84
|
As of version 0.33.0, Solargraph includes a [type checker](https://github.com/castwide/solargraph/issues/192) that uses a combination of YARD tags and code analysis to report missing type definitions. In strict mode, it performs type inference to determine whether the tags match the types it detects from code.
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Solargraph
|
4
4
|
class ApiMap
|
5
5
|
class Index
|
6
|
+
include Logging
|
7
|
+
|
6
8
|
# @param pins [Array<Pin::Base>]
|
7
9
|
def initialize pins = []
|
8
10
|
catalog pins
|
@@ -132,21 +134,24 @@ module Solargraph
|
|
132
134
|
# @return [void]
|
133
135
|
def map_overrides
|
134
136
|
pins_by_class(Pin::Reference::Override).each do |ovr|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
137
|
+
logger.debug { "ApiMap::Index#map_overrides: Looking at override #{ovr} for #{ovr.name}" }
|
138
|
+
pins = path_pin_hash[ovr.name]
|
139
|
+
logger.debug { "ApiMap::Index#map_overrides: pins for path=#{ovr.name}: #{pins}" }
|
140
|
+
pins.each do |pin|
|
141
|
+
new_pin = if pin.path.end_with?('#initialize')
|
142
|
+
path_pin_hash[pin.path.sub(/#initialize/, '.new')].first
|
143
|
+
end
|
144
|
+
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
145
|
+
pin.docstring.delete_tags tag
|
146
|
+
new_pin.docstring.delete_tags tag if new_pin
|
147
|
+
end
|
148
|
+
ovr.tags.each do |tag|
|
149
|
+
pin.docstring.add_tag(tag)
|
150
|
+
redefine_return_type pin, tag
|
151
|
+
if new_pin
|
152
|
+
new_pin.docstring.add_tag(tag)
|
153
|
+
redefine_return_type new_pin, tag
|
154
|
+
end
|
150
155
|
end
|
151
156
|
end
|
152
157
|
end
|
@@ -156,11 +161,14 @@ module Solargraph
|
|
156
161
|
# @param tag [YARD::Tags::Tag]
|
157
162
|
# @return [void]
|
158
163
|
def redefine_return_type pin, tag
|
164
|
+
# @todo can this be made to not mutate existing pins and use
|
165
|
+
# proxy() / proxy_with_signatures() instead?
|
159
166
|
return unless pin && tag.tag_name == 'return'
|
160
167
|
pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
161
168
|
pin.signatures.each do |sig|
|
162
169
|
sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
163
170
|
end
|
171
|
+
pin.reset_generated!
|
164
172
|
end
|
165
173
|
end
|
166
174
|
end
|
@@ -61,15 +61,19 @@ module Solargraph
|
|
61
61
|
# @param visibility [Array<Symbol>]
|
62
62
|
# @return [Enumerable<Solargraph::Pin::Method>]
|
63
63
|
def get_methods fqns, scope: :instance, visibility: [:public]
|
64
|
-
namespace_children(fqns).select do |pin|
|
64
|
+
all_pins = namespace_children(fqns).select do |pin|
|
65
65
|
pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
|
66
66
|
end
|
67
|
+
GemPins.combine_method_pins_by_path(all_pins)
|
67
68
|
end
|
68
69
|
|
69
|
-
# @param
|
70
|
+
# @param fq_tag [String]
|
70
71
|
# @return [String, nil]
|
71
|
-
def get_superclass
|
72
|
-
raise "Do not prefix fully qualified
|
72
|
+
def get_superclass fq_tag
|
73
|
+
raise "Do not prefix fully qualified tags with '::' - #{fq_tag.inspect}" if fq_tag.start_with?('::')
|
74
|
+
sub = ComplexType.parse(fq_tag)
|
75
|
+
fqns = sub.namespace
|
76
|
+
return superclass_references[fq_tag].first if superclass_references.key?(fq_tag)
|
73
77
|
return superclass_references[fqns].first if superclass_references.key?(fqns)
|
74
78
|
return 'Object' if fqns != 'BasicObject' && namespace_exists?(fqns)
|
75
79
|
return 'Object' if fqns == 'Boolean'
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -93,9 +93,13 @@ module Solargraph
|
|
93
93
|
implicit.merge map.environ
|
94
94
|
end
|
95
95
|
unresolved_requires = (bench.external_requires + implicit.requires + bench.workspace.config.required).to_a.compact.uniq
|
96
|
-
|
96
|
+
recreate_docmap = @unresolved_requires != unresolved_requires ||
|
97
|
+
@doc_map&.uncached_yard_gemspecs&.any? ||
|
98
|
+
@doc_map&.uncached_rbs_collection_gemspecs&.any? ||
|
99
|
+
@doc_map&.rbs_collection_path != bench.workspace.rbs_collection_path
|
100
|
+
if recreate_docmap
|
97
101
|
@doc_map = DocMap.new(unresolved_requires, [], bench.workspace) # @todo Implement gem preferences
|
98
|
-
@unresolved_requires = unresolved_requires
|
102
|
+
@unresolved_requires = @doc_map.unresolved_requires
|
99
103
|
end
|
100
104
|
@cache.clear if store.update(@@core_map.pins, @doc_map.pins, implicit.pins, iced_pins, live_pins)
|
101
105
|
@missing_docs = [] # @todo Implement missing docs
|
@@ -109,11 +113,25 @@ module Solargraph
|
|
109
113
|
[self.class, @source_map_hash, implicit, @doc_map, @unresolved_requires]
|
110
114
|
end
|
111
115
|
|
116
|
+
def doc_map
|
117
|
+
@doc_map ||= DocMap.new([], [])
|
118
|
+
end
|
119
|
+
|
112
120
|
# @return [::Array<Gem::Specification>]
|
113
121
|
def uncached_gemspecs
|
114
122
|
@doc_map&.uncached_gemspecs || []
|
115
123
|
end
|
116
124
|
|
125
|
+
# @return [::Array<Gem::Specification>]
|
126
|
+
def uncached_rbs_collection_gemspecs
|
127
|
+
@doc_map.uncached_rbs_collection_gemspecs
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [::Array<Gem::Specification>]
|
131
|
+
def uncached_yard_gemspecs
|
132
|
+
@doc_map.uncached_yard_gemspecs
|
133
|
+
end
|
134
|
+
|
117
135
|
# @return [Array<Pin::Base>]
|
118
136
|
def core_pins
|
119
137
|
@@core_map.pins
|
@@ -168,6 +186,18 @@ module Solargraph
|
|
168
186
|
api_map
|
169
187
|
end
|
170
188
|
|
189
|
+
def cache_all!(out)
|
190
|
+
@doc_map.cache_all!(out)
|
191
|
+
end
|
192
|
+
|
193
|
+
def cache_gem(gemspec, rebuild: false, out: nil)
|
194
|
+
@doc_map.cache(gemspec, rebuild: rebuild, out: out)
|
195
|
+
end
|
196
|
+
|
197
|
+
class << self
|
198
|
+
include Logging
|
199
|
+
end
|
200
|
+
|
171
201
|
# Create an ApiMap with a workspace in the specified directory and cache
|
172
202
|
# any missing gems.
|
173
203
|
#
|
@@ -178,15 +208,14 @@ module Solargraph
|
|
178
208
|
# @param directory [String]
|
179
209
|
# @param out [IO] The output stream for messages
|
180
210
|
# @return [ApiMap]
|
181
|
-
def self.load_with_cache directory, out
|
211
|
+
def self.load_with_cache directory, out
|
182
212
|
api_map = load(directory)
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
out.puts "Caching gem #{gemspec.name} #{gemspec.version}"
|
187
|
-
pins = GemPins.build(gemspec)
|
188
|
-
Solargraph::Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
213
|
+
if api_map.uncached_gemspecs.empty?
|
214
|
+
logger.info { "All gems cached for #{directory}" }
|
215
|
+
return api_map
|
189
216
|
end
|
217
|
+
|
218
|
+
api_map.cache_all!(out)
|
190
219
|
load(directory)
|
191
220
|
end
|
192
221
|
|
@@ -359,6 +388,11 @@ module Solargraph
|
|
359
388
|
# @param deep [Boolean] True to include superclasses, mixins, etc.
|
360
389
|
# @return [Array<Solargraph::Pin::Method>]
|
361
390
|
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
|
391
|
+
if rooted_tag.start_with? 'Array('
|
392
|
+
# Array() are really tuples - use our fill, as the RBS repo
|
393
|
+
# does not give us definitions for it
|
394
|
+
rooted_tag = "Solargraph::Fills::Tuple(#{rooted_tag[6..-2]})"
|
395
|
+
end
|
362
396
|
rooted_type = ComplexType.try_parse(rooted_tag)
|
363
397
|
fqns = rooted_type.namespace
|
364
398
|
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
|
@@ -386,18 +420,35 @@ module Solargraph
|
|
386
420
|
next pin unless init_pin
|
387
421
|
|
388
422
|
type = ComplexType::SELF
|
389
|
-
Pin::Method.new(
|
423
|
+
new_pin = Pin::Method.new(
|
390
424
|
name: 'new',
|
391
425
|
scope: :class,
|
392
426
|
location: init_pin.location,
|
393
|
-
parameters: init_pin.parameters,
|
394
|
-
signatures: init_pin.signatures.map { |sig| sig.proxy(type) },
|
395
427
|
return_type: type,
|
396
428
|
comments: init_pin.comments,
|
397
429
|
closure: init_pin.closure,
|
398
430
|
source: init_pin.source,
|
399
431
|
type_location: init_pin.type_location,
|
400
432
|
)
|
433
|
+
new_pin.parameters = init_pin.parameters.map do |init_param|
|
434
|
+
param = init_param.clone
|
435
|
+
param.closure = new_pin
|
436
|
+
param.reset_generated!
|
437
|
+
param
|
438
|
+
end.freeze
|
439
|
+
new_pin.signatures = init_pin.signatures.map do |init_sig|
|
440
|
+
sig = init_sig.proxy(type)
|
441
|
+
sig.parameters = init_sig.parameters.map do |param|
|
442
|
+
param = param.clone
|
443
|
+
param.closure = new_pin
|
444
|
+
param.reset_generated!
|
445
|
+
param
|
446
|
+
end.freeze
|
447
|
+
sig.closure = new_pin
|
448
|
+
sig.reset_generated!
|
449
|
+
sig
|
450
|
+
end.freeze
|
451
|
+
new_pin
|
401
452
|
end
|
402
453
|
end
|
403
454
|
result.concat inner_get_methods('Kernel', :instance, [:public], deep, skip) if visibility.include?(:private)
|
@@ -436,7 +487,7 @@ module Solargraph
|
|
436
487
|
result = Set.new
|
437
488
|
complex_type.each do |type|
|
438
489
|
if type.duck_type?
|
439
|
-
result.add Pin::DuckMethod.new(name: type.to_s[1..-1])
|
490
|
+
result.add Pin::DuckMethod.new(name: type.to_s[1..-1], source: :api_map)
|
440
491
|
result.merge get_methods('Object')
|
441
492
|
else
|
442
493
|
unless type.nil? || type.name == 'void'
|
@@ -505,13 +556,8 @@ module Solargraph
|
|
505
556
|
.select { |path| path.downcase.include?(query.downcase) }
|
506
557
|
end
|
507
558
|
|
508
|
-
#
|
509
|
-
#
|
510
|
-
# @example
|
511
|
-
# api_map.document('String#split')
|
512
|
-
#
|
513
|
-
# @todo This method is likely superfluous. Calling get_path_pins directly
|
514
|
-
# should be sufficient.
|
559
|
+
# @deprecated This method is likely superfluous. Calling #get_path_pins
|
560
|
+
# directly should be sufficient.
|
515
561
|
#
|
516
562
|
# @param path [String] The path to find
|
517
563
|
# @return [Enumerable<Pin::Base>]
|
@@ -605,6 +651,19 @@ module Solargraph
|
|
605
651
|
store.get_includes(host_ns).map { |inc_tag| ComplexType.parse(inc_tag).name }.include?(module_ns)
|
606
652
|
end
|
607
653
|
|
654
|
+
# @param pins [Enumerable<Pin::Base>]
|
655
|
+
# @param visibility [Enumerable<Symbol>]
|
656
|
+
# @return [Array<Pin::Base>]
|
657
|
+
def resolve_method_aliases pins, visibility = [:public, :private, :protected]
|
658
|
+
with_resolved_aliases = pins.map do |pin|
|
659
|
+
resolved = resolve_method_alias(pin)
|
660
|
+
next nil if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
|
661
|
+
resolved
|
662
|
+
end.compact
|
663
|
+
logger.debug { "ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}" }
|
664
|
+
GemPins.combine_method_pins_by_path(with_resolved_aliases)
|
665
|
+
end
|
666
|
+
|
608
667
|
private
|
609
668
|
|
610
669
|
# A hash of source maps with filename keys.
|
@@ -653,29 +712,20 @@ module Solargraph
|
|
653
712
|
if scope == :instance
|
654
713
|
store.get_includes(fqns).reverse.each do |include_tag|
|
655
714
|
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
|
715
|
+
result.concat inner_get_methods_from_reference(rooted_include_tag, namespace_pin, rooted_type, scope, visibility, deep, skip, true)
|
666
716
|
end
|
667
|
-
|
668
|
-
unless
|
669
|
-
result.concat
|
717
|
+
rooted_sc_tag = qualify_superclass(rooted_tag)
|
718
|
+
unless rooted_sc_tag.nil?
|
719
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, no_core)
|
670
720
|
end
|
671
721
|
else
|
672
722
|
store.get_extends(fqns).reverse.each do |em|
|
673
723
|
fqem = qualify(em, fqns)
|
674
724
|
result.concat inner_get_methods(fqem, :instance, visibility, deep, skip, true) unless fqem.nil?
|
675
725
|
end
|
676
|
-
|
677
|
-
unless
|
678
|
-
result.concat
|
726
|
+
rooted_sc_tag = qualify_superclass(rooted_tag)
|
727
|
+
unless rooted_sc_tag.nil?
|
728
|
+
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope, visibility, true, skip, true)
|
679
729
|
end
|
680
730
|
unless no_core || fqns.empty?
|
681
731
|
type = get_namespace_type(fqns)
|
@@ -691,6 +741,41 @@ module Solargraph
|
|
691
741
|
result
|
692
742
|
end
|
693
743
|
|
744
|
+
# @param fq_reference_tag [String] A fully qualified whose method should be pulled in
|
745
|
+
# @param namespace_pin [Pin::Base] Namespace pin for the rooted_type
|
746
|
+
# parameter - used to pull generics information
|
747
|
+
# @param type [ComplexType] The type which is having its
|
748
|
+
# methods supplemented from fq_reference_tag
|
749
|
+
# @param scope [Symbol] :class or :instance
|
750
|
+
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
751
|
+
# @param deep [Boolean]
|
752
|
+
# @param skip [Set<String>]
|
753
|
+
# @param no_core [Boolean] Skip core classes if true
|
754
|
+
# @return [Array<Pin::Base>]
|
755
|
+
def inner_get_methods_from_reference(fq_reference_tag, namespace_pin, type, scope, visibility, deep, skip, no_core)
|
756
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) starting" }
|
757
|
+
|
758
|
+
# Ensure the types returned by the methods in the referenced
|
759
|
+
# type are relative to the generic values passed in the
|
760
|
+
# reference. e.g., Foo<String> might include Enumerable<String>
|
761
|
+
#
|
762
|
+
# @todo perform the same translation in the other areas
|
763
|
+
# here after adding a spec and handling things correctly
|
764
|
+
# in ApiMap::Store and RbsMap::Conversions for each
|
765
|
+
resolved_reference_type = ComplexType.parse(fq_reference_tag).force_rooted.resolve_generics(namespace_pin, type)
|
766
|
+
# @todo Can inner_get_methods be cached? Lots of lookups of base types going on.
|
767
|
+
methods = inner_get_methods(resolved_reference_type.tag, scope, visibility, deep, skip, no_core)
|
768
|
+
if namespace_pin && !resolved_reference_type.all_params.empty?
|
769
|
+
reference_pin = store.get_path_pins(resolved_reference_type.name).select { |p| p.is_a?(Pin::Namespace) }.first
|
770
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolving generics with #{reference_pin.generics}, #{resolved_reference_type.rooted_tags}" }
|
771
|
+
methods = methods.map do |method_pin|
|
772
|
+
method_pin.resolve_generics(reference_pin, resolved_reference_type)
|
773
|
+
end
|
774
|
+
end
|
775
|
+
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolved_reference_type: #{resolved_reference_type} for type=#{type}: #{methods.map(&:name)}" }
|
776
|
+
methods
|
777
|
+
end
|
778
|
+
|
694
779
|
# @param fqns [String]
|
695
780
|
# @param visibility [Array<Symbol>]
|
696
781
|
# @param skip [Set<String>]
|
@@ -726,15 +811,19 @@ module Solargraph
|
|
726
811
|
qualify namespace, context.split('::')[0..-2].join('::')
|
727
812
|
end
|
728
813
|
|
729
|
-
# @param
|
814
|
+
# @param fq_tag [String]
|
730
815
|
# @return [String, nil]
|
731
|
-
def qualify_superclass
|
732
|
-
|
733
|
-
|
734
|
-
|
816
|
+
def qualify_superclass fq_sub_tag
|
817
|
+
fq_sub_type = ComplexType.try_parse(fq_sub_tag)
|
818
|
+
fq_sub_ns = fq_sub_type.name
|
819
|
+
sup_tag = store.get_superclass(fq_sub_tag)
|
820
|
+
sup_type = ComplexType.try_parse(sup_tag)
|
821
|
+
sup_ns = sup_type.name
|
822
|
+
return nil if sup_tag.nil?
|
823
|
+
parts = fq_sub_ns.split('::')
|
735
824
|
last = parts.pop
|
736
|
-
parts.pop if last ==
|
737
|
-
qualify(
|
825
|
+
parts.pop if last == sup_ns
|
826
|
+
qualify(sup_tag, parts.join('::'))
|
738
827
|
end
|
739
828
|
|
740
829
|
# @param name [String] Namespace to fully qualify
|
@@ -807,17 +896,6 @@ module Solargraph
|
|
807
896
|
result + nil_pins
|
808
897
|
end
|
809
898
|
|
810
|
-
# @param pins [Enumerable<Pin::Base>]
|
811
|
-
# @param visibility [Enumerable<Symbol>]
|
812
|
-
# @return [Array<Pin::Base>]
|
813
|
-
def resolve_method_aliases pins, visibility = [:public, :private, :protected]
|
814
|
-
pins.map do |pin|
|
815
|
-
resolved = resolve_method_alias(pin)
|
816
|
-
next pin if resolved.respond_to?(:visibility) && !visibility.include?(resolved.visibility)
|
817
|
-
resolved
|
818
|
-
end.compact
|
819
|
-
end
|
820
|
-
|
821
899
|
# @param pin [Pin::MethodAlias, Pin::Base]
|
822
900
|
# @return [Pin::Method]
|
823
901
|
def resolve_method_alias pin
|
@@ -829,18 +907,33 @@ module Solargraph
|
|
829
907
|
return nil if origin.nil?
|
830
908
|
args = {
|
831
909
|
location: pin.location,
|
910
|
+
type_location: origin.type_location,
|
832
911
|
closure: pin.closure,
|
833
912
|
name: pin.name,
|
834
913
|
comments: origin.comments,
|
835
914
|
scope: origin.scope,
|
836
915
|
# context: pin.context,
|
837
916
|
visibility: origin.visibility,
|
838
|
-
signatures: origin.signatures,
|
917
|
+
signatures: origin.signatures.map(&:clone).freeze,
|
839
918
|
attribute: origin.attribute?,
|
840
|
-
generics: origin.generics,
|
919
|
+
generics: origin.generics.clone,
|
841
920
|
return_type: origin.return_type,
|
921
|
+
source: :resolve_method_alias
|
842
922
|
}
|
843
|
-
Pin::Method.new **args
|
923
|
+
out = Pin::Method.new **args
|
924
|
+
out.signatures.each do |sig|
|
925
|
+
sig.parameters = sig.parameters.map(&:clone).freeze
|
926
|
+
sig.source = :resolve_method_alias
|
927
|
+
sig.parameters.each do |param|
|
928
|
+
param.closure = out
|
929
|
+
param.source = :resolve_method_alias
|
930
|
+
param.reset_generated!
|
931
|
+
end
|
932
|
+
sig.closure = out
|
933
|
+
sig.reset_generated!
|
934
|
+
end
|
935
|
+
logger.debug { "ApiMap#resolve_method_alias(pin=#{pin}) - returning #{out} from #{origin}" }
|
936
|
+
out
|
844
937
|
end
|
845
938
|
|
846
939
|
include Logging
|
@@ -88,6 +88,7 @@ module Solargraph
|
|
88
88
|
# @return [Symbol, nil]
|
89
89
|
attr_reader :parameters_type
|
90
90
|
|
91
|
+
# @type [Hash{String => Symbol}]
|
91
92
|
PARAMETERS_TYPE_BY_STARTING_TAG = {
|
92
93
|
'{' => :hash,
|
93
94
|
'(' => :fixed,
|
@@ -171,7 +172,11 @@ module Solargraph
|
|
171
172
|
elsif fixed_parameters?
|
172
173
|
"(#{subtypes_str})"
|
173
174
|
else
|
174
|
-
|
175
|
+
if name == 'Hash'
|
176
|
+
"<#{key_types_str}, #{subtypes_str}>"
|
177
|
+
else
|
178
|
+
"<#{key_types_str}#{subtypes_str}>"
|
179
|
+
end
|
175
180
|
end
|
176
181
|
end
|
177
182
|
|
@@ -55,6 +55,13 @@ module Solargraph
|
|
55
55
|
key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
|
56
56
|
# @sg-ignore
|
57
57
|
subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
|
58
|
+
elsif parameters_type == :list && name == 'Hash'
|
59
|
+
# Treat Hash<A, B> as Hash{A => B}
|
60
|
+
if subs.length != 2
|
61
|
+
raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring} - must have exactly two parameters"
|
62
|
+
end
|
63
|
+
key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
|
64
|
+
subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
|
58
65
|
else
|
59
66
|
subtypes.concat subs
|
60
67
|
end
|
@@ -306,7 +313,8 @@ module Solargraph
|
|
306
313
|
|
307
314
|
transform(name) do |t|
|
308
315
|
if t.name == GENERIC_TAG_NAME
|
309
|
-
|
316
|
+
generic_name = t.subtypes.first&.name
|
317
|
+
idx = definitions.generics.index(generic_name)
|
310
318
|
next t if idx.nil?
|
311
319
|
if context_type.parameters_type == :hash
|
312
320
|
if idx == 0
|
@@ -323,7 +331,7 @@ module Solargraph
|
|
323
331
|
ComplexType::UNDEFINED
|
324
332
|
end
|
325
333
|
else
|
326
|
-
context_type.all_params[idx] || ComplexType::UNDEFINED
|
334
|
+
context_type.all_params[idx] || definitions.generic_defaults[generic_name] || ComplexType::UNDEFINED
|
327
335
|
end
|
328
336
|
else
|
329
337
|
t
|
@@ -20,12 +20,12 @@ module Solargraph
|
|
20
20
|
EMPTY_ENVIRON
|
21
21
|
end
|
22
22
|
|
23
|
-
# The Environ for a
|
23
|
+
# The Environ for a DocMap.
|
24
24
|
# Subclasses can override this method.
|
25
25
|
#
|
26
|
-
# @param
|
26
|
+
# @param doc_map [DocMap]
|
27
27
|
# @return [Environ]
|
28
|
-
def global
|
28
|
+
def global doc_map
|
29
29
|
EMPTY_ENVIRON
|
30
30
|
end
|
31
31
|
end
|
@@ -31,12 +31,12 @@ module Solargraph
|
|
31
31
|
result
|
32
32
|
end
|
33
33
|
|
34
|
-
# @param yard_map [
|
34
|
+
# @param yard_map [DocMap]
|
35
35
|
# @return [Environ]
|
36
|
-
def self.for_global(
|
36
|
+
def self.for_global(doc_map)
|
37
37
|
result = Environ.new
|
38
38
|
@@conventions.each do |conv|
|
39
|
-
result.merge conv.global(
|
39
|
+
result.merge conv.global(doc_map)
|
40
40
|
end
|
41
41
|
result
|
42
42
|
end
|