solargraph 0.52.0 → 0.53.0
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 +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/CHANGELOG.md +30 -0
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +59 -21
- data/lib/solargraph/api_map/store.rb +45 -9
- data/lib/solargraph/api_map.rb +152 -93
- data/lib/solargraph/bench.rb +2 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +53 -8
- data/lib/solargraph/complex_type/unique_type.rb +149 -59
- data/lib/solargraph/complex_type.rb +62 -9
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +146 -0
- data/lib/solargraph/gem_pins.rb +64 -0
- data/lib/solargraph/language_server/host/cataloger.rb +1 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +10 -4
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +7 -4
- data/lib/solargraph/language_server/host.rb +15 -6
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +5 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/library.rb +58 -11
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +3 -0
- data/lib/solargraph/parser/node_methods.rb +47 -8
- data/lib/solargraph/parser/node_processor/base.rb +9 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
- data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -11
- data/lib/solargraph/pin/base.rb +63 -8
- data/lib/solargraph/pin/base_variable.rb +6 -2
- data/lib/solargraph/pin/block.rb +11 -6
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +33 -3
- data/lib/solargraph/pin/documenting.rb +25 -34
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +109 -15
- data/lib/solargraph/pin/namespace.rb +16 -10
- data/lib/solargraph/pin/parameter.rb +41 -10
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +114 -2
- data/lib/solargraph/pin.rb +0 -1
- data/lib/solargraph/range.rb +2 -2
- data/lib/solargraph/rbs_map/conversions.rb +212 -25
- data/lib/solargraph/rbs_map/core_fills.rb +4 -26
- data/lib/solargraph/rbs_map/core_map.rb +1 -0
- data/lib/solargraph/rbs_map/core_signs.rb +2 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +19 -9
- data/lib/solargraph/shell.rb +62 -59
- data/lib/solargraph/source/chain/array.rb +4 -1
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +95 -26
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +7 -1
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +2 -2
- data/lib/solargraph/source/chain.rb +20 -4
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +6 -5
- data/lib/solargraph/source.rb +15 -16
- data/lib/solargraph/source_map/clip.rb +11 -7
- data/lib/solargraph/source_map/mapper.rb +10 -0
- data/lib/solargraph/source_map.rb +13 -3
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +74 -19
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +8 -6
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +0 -292
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +4 -1
- data/solargraph.gemspec +2 -2
- metadata +35 -57
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
data/lib/solargraph/shell.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'thor'
|
4
|
+
require 'yard'
|
4
5
|
|
5
6
|
module Solargraph
|
6
7
|
class Shell < Thor
|
7
8
|
include Solargraph::ServerMethods
|
8
9
|
|
10
|
+
# Tell Thor to ensure the process exits with status 1 if any error happens.
|
11
|
+
def self.exit_on_failure?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
9
15
|
map %w[--version -v] => :version
|
10
16
|
|
11
17
|
desc "--version, -v", "Print the version"
|
18
|
+
# @return [void]
|
12
19
|
def version
|
13
20
|
puts Solargraph::VERSION
|
14
21
|
end
|
@@ -16,6 +23,7 @@ module Solargraph
|
|
16
23
|
desc 'socket', 'Run a Solargraph socket server'
|
17
24
|
option :host, type: :string, aliases: :h, desc: 'The server host', default: '127.0.0.1'
|
18
25
|
option :port, type: :numeric, aliases: :p, desc: 'The server port', default: 7658
|
26
|
+
# @return [void]
|
19
27
|
def socket
|
20
28
|
require 'backport'
|
21
29
|
port = options[:port]
|
@@ -33,6 +41,7 @@ module Solargraph
|
|
33
41
|
end
|
34
42
|
|
35
43
|
desc 'stdio', 'Run a Solargraph stdio server'
|
44
|
+
# @return [void]
|
36
45
|
def stdio
|
37
46
|
require 'backport'
|
38
47
|
Backport.run do
|
@@ -49,6 +58,8 @@ module Solargraph
|
|
49
58
|
|
50
59
|
desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
|
51
60
|
option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
|
61
|
+
# @param directory [String]
|
62
|
+
# @return [void]
|
52
63
|
def config(directory = '.')
|
53
64
|
matches = []
|
54
65
|
if options[:extensions]
|
@@ -71,43 +82,11 @@ module Solargraph
|
|
71
82
|
STDOUT.puts "Configuration file initialized."
|
72
83
|
end
|
73
84
|
|
74
|
-
desc 'download-core [VERSION]', 'Download core documentation [deprecated]', hide: true
|
75
|
-
long_desc %(
|
76
|
-
The `download-core` command is deprecated. Current versions of Solargraph
|
77
|
-
use RBS for core and stdlib documentation.
|
78
|
-
)
|
79
|
-
# @deprecated
|
80
|
-
def download_core _version = nil
|
81
|
-
puts 'The `download-core` command is deprecated.'
|
82
|
-
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
83
|
-
end
|
84
|
-
|
85
|
-
desc 'list-cores', 'List the local documentation versions [deprecated]', hide: true
|
86
|
-
long_desc %(
|
87
|
-
The `list-cores` command is deprecated. Current versions of Solargraph use
|
88
|
-
RBS for core and stdlib documentation.
|
89
|
-
)
|
90
|
-
# @deprecated
|
91
|
-
def list_cores
|
92
|
-
puts 'The `list-cores` command is deprecated.'
|
93
|
-
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
94
|
-
end
|
95
|
-
|
96
|
-
desc 'available-cores', 'List available documentation versions [deprecated]', hide: true
|
97
|
-
long_desc %(
|
98
|
-
The `available-cores` command is deprecated. Current versions of Solargraph
|
99
|
-
use RBS for core and stdlib documentation.
|
100
|
-
)
|
101
|
-
# @deprecated
|
102
|
-
def available_cores
|
103
|
-
puts 'The `available-cores` command is deprecated.'
|
104
|
-
puts 'Current versions of Solargraph use RBS for core and stdlib documentation.'
|
105
|
-
end
|
106
|
-
|
107
85
|
desc 'clear', 'Delete all cached documentation'
|
108
86
|
long_desc %(
|
109
87
|
This command will delete all core and gem documentation from the cache.
|
110
88
|
)
|
89
|
+
# @return [void]
|
111
90
|
def clear
|
112
91
|
puts "Deleting the cached documentation"
|
113
92
|
Solargraph::Cache.clear
|
@@ -115,18 +94,45 @@ module Solargraph
|
|
115
94
|
map 'clear-cache' => :clear
|
116
95
|
map 'clear-cores' => :clear
|
117
96
|
|
97
|
+
desc 'cache', 'Cache a gem', hide: true
|
98
|
+
# @return [void]
|
99
|
+
# @param gem [String]
|
100
|
+
# @param version [String, nil]
|
101
|
+
def cache gem, version = nil
|
102
|
+
spec = Gem::Specification.find_by_name(gem, version)
|
103
|
+
pins = GemPins.build(spec)
|
104
|
+
Cache.save('gems', "#{spec.name}-#{spec.version}.ser", pins)
|
105
|
+
end
|
106
|
+
|
118
107
|
desc 'uncache GEM [...GEM]', "Delete cached gem documentation"
|
108
|
+
# @return [void]
|
119
109
|
def uncache *gems
|
120
110
|
raise ArgumentError, 'No gems specified.' if gems.empty?
|
121
111
|
gems.each do |gem|
|
122
|
-
|
123
|
-
|
124
|
-
|
112
|
+
spec = Gem::Specification.find_by_name(gem)
|
113
|
+
Cache.uncache('gems', "#{spec.name}-#{spec.version}.ser")
|
114
|
+
Cache.uncache('gems', "#{spec.name}-#{spec.version}.yardoc")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
desc 'gems [GEM[=VERSION]]', 'Cache documentation for installed gems'
|
119
|
+
option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
|
120
|
+
# @return [void]
|
121
|
+
def gems *names
|
122
|
+
if names.empty?
|
123
|
+
Gem::Specification.to_a.each { |spec| do_cache spec }
|
124
|
+
else
|
125
|
+
names.each do |name|
|
126
|
+
spec = Gem::Specification.find_by_name(*name.split('='))
|
127
|
+
do_cache spec
|
128
|
+
rescue Gem::MissingSpecError
|
129
|
+
warn "Gem '#{name}' not found"
|
125
130
|
end
|
126
131
|
end
|
127
132
|
end
|
128
133
|
|
129
134
|
desc 'reporters', 'Get a list of diagnostics reporters'
|
135
|
+
# @return [void]
|
130
136
|
def reporters
|
131
137
|
puts Solargraph::Diagnostics.reporters
|
132
138
|
end
|
@@ -140,9 +146,10 @@ module Solargraph
|
|
140
146
|
)
|
141
147
|
option :level, type: :string, aliases: [:mode, :m, :l], desc: 'Type checking level', default: 'normal'
|
142
148
|
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
149
|
+
# @return [void]
|
143
150
|
def typecheck *files
|
144
151
|
directory = File.realpath(options[:directory])
|
145
|
-
api_map = Solargraph::ApiMap.
|
152
|
+
api_map = Solargraph::ApiMap.load_with_cache(directory)
|
146
153
|
if files.empty?
|
147
154
|
files = api_map.source_maps.map(&:filename)
|
148
155
|
else
|
@@ -160,6 +167,7 @@ module Solargraph
|
|
160
167
|
probcount += problems.length
|
161
168
|
end
|
162
169
|
puts "#{probcount} problem#{probcount != 1 ? 's' : ''} found#{files.length != 1 ? " in #{filecount} of #{files.length} files" : ''}."
|
170
|
+
# "
|
163
171
|
exit 1 if probcount > 0
|
164
172
|
end
|
165
173
|
|
@@ -172,12 +180,13 @@ module Solargraph
|
|
172
180
|
)
|
173
181
|
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
174
182
|
option :verbose, type: :boolean, aliases: :v, desc: 'Verbose output', default: false
|
183
|
+
# @return [void]
|
175
184
|
def scan
|
176
185
|
require 'benchmark'
|
177
186
|
directory = File.realpath(options[:directory])
|
178
187
|
api_map = nil
|
179
188
|
time = Benchmark.measure {
|
180
|
-
api_map = Solargraph::ApiMap.
|
189
|
+
api_map = Solargraph::ApiMap.load_with_cache(directory)
|
181
190
|
api_map.pins.each do |pin|
|
182
191
|
begin
|
183
192
|
puts pin_description(pin) if options[:verbose]
|
@@ -197,32 +206,13 @@ module Solargraph
|
|
197
206
|
desc 'list', 'List the files in the workspace and the total count'
|
198
207
|
option :count, type: :boolean, aliases: :c, desc: 'Display the file count only', default: false
|
199
208
|
option :directory, type: :string, aliases: :d, desc: 'The directory to read', default: '.'
|
209
|
+
# @return [void]
|
200
210
|
def list
|
201
211
|
workspace = Solargraph::Workspace.new(options[:directory])
|
202
|
-
unless options[:count]
|
203
|
-
workspace.filenames.each { |f| puts f }
|
204
|
-
end
|
212
|
+
puts workspace.filenames unless options[:count]
|
205
213
|
puts "#{workspace.filenames.length} files total."
|
206
214
|
end
|
207
215
|
|
208
|
-
desc 'bundle', 'Generate documentation for bundled gems [deprecated]', hide: true
|
209
|
-
long_desc %(
|
210
|
-
The `bundle` command is deprecated. Solargraph currently uses RBS instead.
|
211
|
-
)
|
212
|
-
option :directory, type: :string, aliases: :d, desc: 'The workspace directory', default: '.'
|
213
|
-
option :rebuild, type: :boolean, aliases: :r, desc: 'Rebuild existing documentation', default: false
|
214
|
-
def bundle
|
215
|
-
puts 'The `bundle` command is deprecated. Solargraph currently uses RBS instead.'
|
216
|
-
end
|
217
|
-
|
218
|
-
desc 'rdoc GEM [VERSION]', 'Use RDoc to cache documentation [deprecated]', hide: true
|
219
|
-
long_desc %(
|
220
|
-
The `rdoc` command is deprecated. Solargraph currently uses RBS instead.
|
221
|
-
)
|
222
|
-
def rdoc _gem, _version = '>= 0'
|
223
|
-
puts 'The `rdoc` command is deprecated. Solargraph currently uses RBS instead.'
|
224
|
-
end
|
225
|
-
|
226
216
|
private
|
227
217
|
|
228
218
|
# @param pin [Solargraph::Pin::Base]
|
@@ -240,5 +230,18 @@ module Solargraph
|
|
240
230
|
desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
|
241
231
|
desc
|
242
232
|
end
|
233
|
+
|
234
|
+
# @param gemspec [Gem::Specification]
|
235
|
+
# @return [void]
|
236
|
+
def do_cache gemspec
|
237
|
+
cached = Yardoc.cached?(gemspec)
|
238
|
+
if cached && !options.rebuild
|
239
|
+
puts "Cache already exists for #{gemspec.name} #{gemspec.version}"
|
240
|
+
else
|
241
|
+
puts "#{cached ? 'Rebuilding' : 'Caching'} gem documentation for #{gemspec.name} #{gemspec.version}"
|
242
|
+
pins = GemPins.build(gemspec)
|
243
|
+
Cache.save('gems', "#{gemspec.name}-#{gemspec.version}.ser", pins)
|
244
|
+
end
|
245
|
+
end
|
243
246
|
end
|
244
247
|
end
|
@@ -2,7 +2,7 @@ module Solargraph
|
|
2
2
|
class Source
|
3
3
|
class Chain
|
4
4
|
class Array < Literal
|
5
|
-
# @param
|
5
|
+
# @param children [::Array<Chain>]
|
6
6
|
def initialize children
|
7
7
|
super('::Array')
|
8
8
|
@children = children
|
@@ -12,6 +12,9 @@ module Solargraph
|
|
12
12
|
@word ||= "<#{@type}>"
|
13
13
|
end
|
14
14
|
|
15
|
+
# @param api_map [ApiMap]
|
16
|
+
# @param name_pin [Pin::Base]
|
17
|
+
# @param locals [Enumerable<Pin::LocalVariable>]
|
15
18
|
def resolve api_map, name_pin, locals
|
16
19
|
child_types = @children.map do |child|
|
17
20
|
child.infer(api_map, name_pin, locals).tag
|
@@ -7,26 +7,29 @@ module Solargraph
|
|
7
7
|
# @return [String]
|
8
8
|
attr_reader :word
|
9
9
|
|
10
|
-
# @return [Array<Chain>]
|
10
|
+
# @return [::Array<Chain>]
|
11
11
|
attr_reader :arguments
|
12
12
|
|
13
|
+
# @return [Chain, nil]
|
14
|
+
attr_reader :block
|
15
|
+
|
13
16
|
# @param word [String]
|
14
17
|
# @param arguments [::Array<Chain>]
|
15
|
-
# @param
|
16
|
-
|
17
|
-
def initialize word, arguments = [], with_block = false
|
18
|
+
# @param block [Chain, nil]
|
19
|
+
def initialize word, arguments = [], block = nil
|
18
20
|
@word = word
|
19
21
|
@arguments = arguments
|
20
|
-
@
|
22
|
+
@block = block
|
23
|
+
fix_block_pass
|
21
24
|
end
|
22
25
|
|
23
26
|
def with_block?
|
24
|
-
|
27
|
+
!!@block
|
25
28
|
end
|
26
29
|
|
27
30
|
# @param api_map [ApiMap]
|
28
31
|
# @param name_pin [Pin::Base]
|
29
|
-
# @param locals [::Array<Pin::
|
32
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
30
33
|
def resolve api_map, name_pin, locals
|
31
34
|
return super_pins(api_map, name_pin) if word == 'super'
|
32
35
|
return yield_pins(api_map, name_pin) if word == 'yield'
|
@@ -38,7 +41,7 @@ module Solargraph
|
|
38
41
|
return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
|
39
42
|
# @param [ComplexType::UniqueType]
|
40
43
|
pins = name_pin.binder.each_unique_type.flat_map do |context|
|
41
|
-
api_map.get_method_stack(context.namespace, word, scope: context.scope)
|
44
|
+
api_map.get_method_stack(context.namespace == '' ? '' : context.tag, word, scope: context.scope)
|
42
45
|
end
|
43
46
|
return [] if pins.empty?
|
44
47
|
inferred_pins(pins, api_map, name_pin.context, locals)
|
@@ -46,43 +49,58 @@ module Solargraph
|
|
46
49
|
|
47
50
|
private
|
48
51
|
|
49
|
-
# @param pins [
|
52
|
+
# @param pins [::Enumerable<Pin::Method>]
|
50
53
|
# @param api_map [ApiMap]
|
51
54
|
# @param context [ComplexType]
|
52
|
-
# @param locals [Pin::LocalVariable]
|
53
|
-
# @return [Array<Pin::Base>]
|
55
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
56
|
+
# @return [::Array<Pin::Base>]
|
54
57
|
def inferred_pins pins, api_map, context, locals
|
55
58
|
result = pins.map do |p|
|
56
59
|
next p unless p.is_a?(Pin::Method)
|
57
60
|
overloads = p.signatures
|
58
61
|
# next p if overloads.empty?
|
59
62
|
type = ComplexType::UNDEFINED
|
60
|
-
overloads
|
61
|
-
|
62
|
-
|
63
|
+
# start with overloads that require blocks; if we are
|
64
|
+
# passing a block, we want to find a signature that will
|
65
|
+
# use it. If we didn't pass a block, the logic below will
|
66
|
+
# reject it regardless
|
67
|
+
|
68
|
+
sorted_overloads = overloads.sort { |ol| ol.block? ? -1 : 1 }
|
69
|
+
new_signature_pin = nil
|
70
|
+
sorted_overloads.each do |ol|
|
71
|
+
next unless arity_matches?(arguments, ol)
|
63
72
|
match = true
|
73
|
+
|
74
|
+
atypes = []
|
64
75
|
arguments.each_with_index do |arg, idx|
|
65
76
|
param = ol.parameters[idx]
|
66
77
|
if param.nil?
|
67
|
-
match =
|
78
|
+
match = ol.parameters.any?(&:restarg?)
|
68
79
|
break
|
69
80
|
end
|
70
|
-
atype = arg.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
81
|
+
atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
71
82
|
# @todo Weak type comparison
|
72
83
|
# unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
|
73
|
-
unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name)
|
84
|
+
unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name) || param.return_type.generic?
|
74
85
|
match = false
|
75
86
|
break
|
76
87
|
end
|
77
88
|
end
|
78
89
|
if match
|
79
|
-
|
90
|
+
if ol.block && with_block?
|
91
|
+
block_atypes = ol.block.parameters.map(&:return_type)
|
92
|
+
blocktype = block_call_type(api_map, context, block_atypes, locals)
|
93
|
+
end
|
94
|
+
new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
|
95
|
+
new_return_type = new_signature_pin.return_type
|
96
|
+
type = with_params(new_return_type.self_to(context.to_s), context).qualify(api_map, context.namespace) if new_return_type.defined?
|
80
97
|
type ||= ComplexType::UNDEFINED
|
81
98
|
end
|
82
99
|
break if type.defined?
|
83
100
|
end
|
101
|
+
p = p.with_single_signature(new_signature_pin) unless new_signature_pin.nil?
|
84
102
|
next p.proxy(type) if type.defined?
|
85
|
-
if
|
103
|
+
if !p.macros.empty?
|
86
104
|
result = process_macro(p, api_map, context, locals)
|
87
105
|
next result unless result.return_type.undefined?
|
88
106
|
elsif !p.directives.empty?
|
@@ -102,13 +120,19 @@ module Solargraph
|
|
102
120
|
end
|
103
121
|
end
|
104
122
|
|
105
|
-
# @param pin [Pin::
|
123
|
+
# @param pin [Pin::Base]
|
106
124
|
# @param api_map [ApiMap]
|
107
125
|
# @param context [ComplexType]
|
108
|
-
# @param locals [Pin::Base]
|
126
|
+
# @param locals [Enumerable<Pin::Base>]
|
109
127
|
# @return [Pin::Base]
|
110
128
|
def process_macro pin, api_map, context, locals
|
111
129
|
pin.macros.each do |macro|
|
130
|
+
# @todo 'Wrong argument type for
|
131
|
+
# Solargraph::Source::Chain::Call#inner_process_macro:
|
132
|
+
# macro expected YARD::Tags::MacroDirective, received
|
133
|
+
# generic<Elem>' is because we lose 'rooted' information
|
134
|
+
# in the 'Chain::Array' class internally, leaving
|
135
|
+
# ::Array#each shadowed when it shouldn't be.
|
112
136
|
result = inner_process_macro(pin, macro, api_map, context, locals)
|
113
137
|
return result unless result.return_type.undefined?
|
114
138
|
end
|
@@ -118,7 +142,7 @@ module Solargraph
|
|
118
142
|
# @param pin [Pin::Method]
|
119
143
|
# @param api_map [ApiMap]
|
120
144
|
# @param context [ComplexType]
|
121
|
-
# @param locals [Pin::Base]
|
145
|
+
# @param locals [Enumerable<Pin::Base>]
|
122
146
|
# @return [Pin::ProxyType]
|
123
147
|
def process_directive pin, api_map, context, locals
|
124
148
|
pin.directives.each do |dir|
|
@@ -130,11 +154,11 @@ module Solargraph
|
|
130
154
|
Pin::ProxyType.anonymous ComplexType::UNDEFINED
|
131
155
|
end
|
132
156
|
|
133
|
-
# @param pin [Pin]
|
157
|
+
# @param pin [Pin::Base]
|
134
158
|
# @param macro [YARD::Tags::MacroDirective]
|
135
159
|
# @param api_map [ApiMap]
|
136
160
|
# @param context [ComplexType]
|
137
|
-
# @param locals [
|
161
|
+
# @param locals [Enumerable<Pin::Base>]
|
138
162
|
# @return [Pin::ProxyType]
|
139
163
|
def inner_process_macro pin, macro, api_map, context, locals
|
140
164
|
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
@@ -156,10 +180,22 @@ module Solargraph
|
|
156
180
|
Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
|
157
181
|
end
|
158
182
|
|
159
|
-
# @param
|
183
|
+
# @param docstring [YARD::Docstring]
|
184
|
+
# @param context [ComplexType]
|
185
|
+
# @return [ComplexType, nil]
|
186
|
+
def extra_return_type docstring, context
|
187
|
+
if docstring.has_tag?('return_single_parameter') #&& context.subtypes.one?
|
188
|
+
return context.subtypes.first || ComplexType::UNDEFINED
|
189
|
+
elsif docstring.has_tag?('return_value_parameter') && context.value_types.one?
|
190
|
+
return context.value_types.first
|
191
|
+
end
|
192
|
+
nil
|
193
|
+
end
|
194
|
+
|
195
|
+
# @param arguments [::Array<Chain>]
|
160
196
|
# @param signature [Pin::Signature]
|
161
197
|
# @return [Boolean]
|
162
|
-
def
|
198
|
+
def arity_matches? arguments, signature
|
163
199
|
parameters = signature.parameters
|
164
200
|
argcount = arguments.length
|
165
201
|
parcount = parameters.length
|
@@ -189,10 +225,43 @@ module Solargraph
|
|
189
225
|
|
190
226
|
# @param type [ComplexType]
|
191
227
|
# @param context [ComplexType]
|
228
|
+
# @return [ComplexType]
|
192
229
|
def with_params type, context
|
193
230
|
return type unless type.to_s.include?('$')
|
194
231
|
ComplexType.try_parse(type.to_s.gsub('$', context.value_types.map(&:tag).join(', ')).gsub('<>', ''))
|
195
232
|
end
|
233
|
+
|
234
|
+
# @return [void]
|
235
|
+
def fix_block_pass
|
236
|
+
argument = @arguments.last&.links&.first
|
237
|
+
@block = @arguments.pop if argument.is_a?(BlockSymbol) || argument.is_a?(BlockVariable)
|
238
|
+
end
|
239
|
+
|
240
|
+
# @param api_map [ApiMap]
|
241
|
+
# @param context [ComplexType]
|
242
|
+
# @param block_parameter_types [::Array<ComplexType>]
|
243
|
+
# @param locals [::Array<Pin::LocalVariable>]
|
244
|
+
# @return [ComplexType, nil]
|
245
|
+
def block_call_type(api_map, context, block_parameter_types, locals)
|
246
|
+
return nil unless with_block?
|
247
|
+
|
248
|
+
# @todo Handle BlockVariable
|
249
|
+
if block.links.map(&:class) == [BlockSymbol]
|
250
|
+
# Ruby's shorthand for sending the passed in method name
|
251
|
+
# to the first yield parameter with no arguments
|
252
|
+
block_symbol_name = block.links.first.word
|
253
|
+
block_symbol_call_path = "#{block_parameter_types.first}##{block_symbol_name}"
|
254
|
+
callee = api_map.get_path_pins(block_symbol_call_path).first
|
255
|
+
return_type = callee&.return_type
|
256
|
+
# @todo: Figure out why we get unresolved generics at
|
257
|
+
# this point and need to assume method return types
|
258
|
+
# based on the generic type
|
259
|
+
return_type ||= api_map.get_path_pins("#{context.subtypes.first}##{block.links.first.word}").first&.return_type
|
260
|
+
return_type || ComplexType::UNDEFINED
|
261
|
+
else
|
262
|
+
block.infer(api_map, Pin::ProxyType.anonymous(context), locals)
|
263
|
+
end
|
264
|
+
end
|
196
265
|
end
|
197
266
|
end
|
198
267
|
end
|
@@ -19,8 +19,14 @@ module Solargraph
|
|
19
19
|
end
|
20
20
|
parts = base.split('::')
|
21
21
|
gates.each do |gate|
|
22
|
+
# @todo 'Wrong argument type for
|
23
|
+
# Solargraph::Source::Chain::Constant#deep_constant_type:
|
24
|
+
# gate expected String, received generic<Elem>' is because
|
25
|
+
# we lose 'rooted' information in the 'Chain::Array' class
|
26
|
+
# internally, leaving ::Array#each shadowed when it
|
27
|
+
# shouldn't be.
|
22
28
|
type = deep_constant_type(gate, api_map)
|
23
|
-
# Use deep inference to resolve root
|
29
|
+
# Use deep inference to resolve root
|
24
30
|
parts[0..-2].each do |sym|
|
25
31
|
pins = api_map.get_constants('', type.namespace).select{ |pin| pin.name == sym }
|
26
32
|
type = first_pin_type(pins, api_map)
|
@@ -35,6 +41,8 @@ module Solargraph
|
|
35
41
|
|
36
42
|
private
|
37
43
|
|
44
|
+
# @param pin [Pin::Base]
|
45
|
+
# @return [::Array<String>]
|
38
46
|
def crawl_gates pin
|
39
47
|
clos = pin
|
40
48
|
until clos.nil?
|
@@ -48,6 +56,9 @@ module Solargraph
|
|
48
56
|
['']
|
49
57
|
end
|
50
58
|
|
59
|
+
# @param pins [::Array<Pin::Base>]
|
60
|
+
# @param api_map [ApiMap]
|
61
|
+
# @return [ComplexType]
|
51
62
|
def first_pin_type(pins, api_map)
|
52
63
|
type = ComplexType::UNDEFINED
|
53
64
|
pins.each do |pin|
|
@@ -59,6 +70,9 @@ module Solargraph
|
|
59
70
|
type
|
60
71
|
end
|
61
72
|
|
73
|
+
# @param gate [String]
|
74
|
+
# @param api_map [ApiMap]
|
75
|
+
# @return [ComplexType]
|
62
76
|
def deep_constant_type(gate, api_map)
|
63
77
|
type = ComplexType::ROOT
|
64
78
|
return type if gate == ''
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class Source
|
5
|
+
class Chain
|
6
|
+
class If < Link
|
7
|
+
def word
|
8
|
+
'<if>'
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param links [::Array<Link>]
|
12
|
+
def initialize links
|
13
|
+
@links = links
|
14
|
+
end
|
15
|
+
|
16
|
+
def resolve api_map, name_pin, locals
|
17
|
+
types = @links.map { |link| link.infer(api_map, name_pin, locals) }
|
18
|
+
[Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')))]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,8 +7,10 @@ module Solargraph
|
|
7
7
|
# @return [String]
|
8
8
|
attr_reader :word
|
9
9
|
|
10
|
+
# @return [Pin::Base]
|
10
11
|
attr_accessor :last_context
|
11
12
|
|
13
|
+
# @param word [String]
|
12
14
|
def initialize word = '<undefined>'
|
13
15
|
@word = word
|
14
16
|
end
|
@@ -23,12 +25,16 @@ module Solargraph
|
|
23
25
|
|
24
26
|
# @param api_map [ApiMap]
|
25
27
|
# @param name_pin [Pin::Base]
|
26
|
-
# @param locals [
|
28
|
+
# @param locals [::Enumerable<Pin::Base>]
|
27
29
|
# @return [::Array<Pin::Base>]
|
28
30
|
def resolve api_map, name_pin, locals
|
29
31
|
[]
|
30
32
|
end
|
31
33
|
|
34
|
+
def inspect
|
35
|
+
"#{self.class} #{word}"
|
36
|
+
end
|
37
|
+
|
32
38
|
def head?
|
33
39
|
@head ||= false
|
34
40
|
end
|
@@ -7,11 +7,11 @@ module Solargraph
|
|
7
7
|
# @return [String]
|
8
8
|
attr_reader :word
|
9
9
|
|
10
|
-
# @return [Array<Chain>]
|
10
|
+
# @return [::Array<Chain>]
|
11
11
|
attr_reader :arguments
|
12
12
|
|
13
13
|
# @param word [String]
|
14
|
-
# @param arguments [Array<Chain>]
|
14
|
+
# @param arguments [::Array<Chain>]
|
15
15
|
# @param with_block [Boolean] True if the chain is inside a block
|
16
16
|
# @param head [Boolean] True if the call is the start of its chain
|
17
17
|
def initialize word, with_block = false
|