solargraph 0.59.1 → 0.60.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/linting.yml +6 -0
- data/.github/workflows/plugins.yml +8 -0
- data/.github/workflows/rspec.yml +4 -1
- data/.github/workflows/typecheck.yml +2 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +18 -0
- data/Gemfile +3 -0
- data/lib/solargraph/api_map/index.rb +13 -2
- data/lib/solargraph/api_map/store.rb +22 -8
- data/lib/solargraph/api_map.rb +38 -8
- data/lib/solargraph/complex_type/type_methods.rb +1 -0
- data/lib/solargraph/complex_type/unique_type.rb +16 -13
- data/lib/solargraph/complex_type.rb +5 -0
- data/lib/solargraph/convention/active_support_concern.rb +111 -111
- data/lib/solargraph/convention/base.rb +50 -50
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/doc_map.rb +1 -0
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/gem_pins.rb +0 -11
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/initialized.rb +28 -28
- data/lib/solargraph/language_server/message/text_document.rb +28 -28
- data/lib/solargraph/language_server/progress.rb +143 -143
- data/lib/solargraph/language_server/transport/adapter.rb +68 -68
- data/lib/solargraph/language_server.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_methods.rb +42 -0
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -5
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
- data/lib/solargraph/pin/base.rb +31 -3
- data/lib/solargraph/pin/callable.rb +2 -2
- data/lib/solargraph/pin/common.rb +12 -0
- data/lib/solargraph/pin/method.rb +56 -16
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/rbs_map/conversions.rb +103 -145
- data/lib/solargraph/rbs_translator.rb +206 -0
- data/lib/solargraph/shell.rb +131 -64
- data/lib/solargraph/source/chain/array.rb +1 -12
- data/lib/solargraph/source/chain/block_symbol.rb +13 -13
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/call.rb +8 -76
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/literal.rb +18 -14
- data/lib/solargraph/source/source_chainer.rb +4 -4
- data/lib/solargraph/source_map/mapper.rb +5 -135
- data/lib/solargraph/source_map.rb +14 -0
- data/lib/solargraph/version.rb +19 -1
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
- data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
- data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
- data/lib/solargraph/yard_map/directives.rb +35 -0
- data/lib/solargraph/yard_map/macro.rb +113 -0
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- data/lib/solargraph/yard_map/mapper.rb +19 -1
- data/lib/solargraph/yard_map.rb +2 -0
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +1 -0
- metadata +24 -2
- data/rbs/fills/tuple/tuple.rbs +0 -177
data/lib/solargraph/shell.rb
CHANGED
|
@@ -4,10 +4,14 @@ require 'benchmark'
|
|
|
4
4
|
require 'thor'
|
|
5
5
|
require 'yard'
|
|
6
6
|
require 'yaml'
|
|
7
|
+
require 'sord'
|
|
8
|
+
require 'tmpdir'
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
module Solargraph
|
|
9
12
|
class Shell < Thor
|
|
10
13
|
include Solargraph::ServerMethods
|
|
14
|
+
include ApiMap::SourceToYard
|
|
11
15
|
|
|
12
16
|
# Tell Thor to ensure the process exits with status 1 if any error happens.
|
|
13
17
|
def self.exit_on_failure?
|
|
@@ -112,12 +116,10 @@ module Solargraph
|
|
|
112
116
|
PinCache.serialize_yard_gem(gemspec, pins)
|
|
113
117
|
end
|
|
114
118
|
|
|
115
|
-
workspace = Solargraph::Workspace.new(Dir.pwd)
|
|
116
|
-
rbs_map = RbsMap.from_gemspec(gemspec, workspace
|
|
119
|
+
workspace = Solargraph::Workspace.new(Dir.pwd) if File.exist?('rbs_collection.yaml')
|
|
120
|
+
rbs_map = RbsMap.from_gemspec(gemspec, workspace&.rbs_collection_path, workspace&.rbs_collection_config_path)
|
|
117
121
|
if options[:rebuild] || !PinCache.has_rbs_collection?(gemspec, rbs_map.cache_key)
|
|
118
|
-
|
|
119
|
-
pins = rbs_map.pins || []
|
|
120
|
-
PinCache.serialize_rbs_collection_gem(gemspec, rbs_map.cache_key, pins)
|
|
122
|
+
PinCache.serialize_rbs_collection_gem(gemspec, rbs_map.cache_key, rbs_map.pins)
|
|
121
123
|
end
|
|
122
124
|
rescue Gem::MissingSpecError
|
|
123
125
|
warn "Gem '#{gem}' not found"
|
|
@@ -188,7 +190,7 @@ module Solargraph
|
|
|
188
190
|
names.each do |name|
|
|
189
191
|
if name == 'core'
|
|
190
192
|
# @sg-ignore cache_core and core? are dynamically defined
|
|
191
|
-
PinCache.cache_core(out: $stdout) if !PinCache.core? || options[:rebuild]
|
|
193
|
+
PinCache.cache_core(out: $stdout) # if !PinCache.core? || options[:rebuild]
|
|
192
194
|
next
|
|
193
195
|
end
|
|
194
196
|
|
|
@@ -261,7 +263,7 @@ module Solargraph
|
|
|
261
263
|
next if problems.empty?
|
|
262
264
|
problems.sort! { |a, b| a.location.range.start.line <=> b.location.range.start.line }
|
|
263
265
|
puts problems.map { |prob|
|
|
264
|
-
"#{prob.location.filename}:#{prob.location.range.start.line + 1}
|
|
266
|
+
"#{prob.location.filename}:#{prob.location.range.start.line + 1}: #{prob.message}"
|
|
265
267
|
}.join("\n")
|
|
266
268
|
filecount += 1
|
|
267
269
|
probcount += problems.length
|
|
@@ -420,74 +422,139 @@ module Solargraph
|
|
|
420
422
|
puts "Notification: #{method} - #{params}"
|
|
421
423
|
end
|
|
422
424
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
425
|
+
parse_path = File.join(options[:output_dir], 'parse_benchmark.json.gz')
|
|
426
|
+
catalog_path = File.join(options[:output_dir], 'catalog_benchmark.json.gz')
|
|
427
|
+
definition_path = File.join(options[:output_dir], 'definition_benchmark.json.gz')
|
|
428
|
+
|
|
429
|
+
prepare_time = catalog_time = definition_time = nil
|
|
430
|
+
|
|
431
|
+
# Trap CTRL-C so the in-progress Vernier.profile block can unwind through
|
|
432
|
+
# its ensure clause and still write its output file. A second CTRL-C
|
|
433
|
+
# restores default handling for a hard exit.
|
|
434
|
+
interrupted = false
|
|
435
|
+
previous_int_trap = Signal.trap('INT') do
|
|
436
|
+
if interrupted
|
|
437
|
+
Signal.trap('INT', 'DEFAULT')
|
|
438
|
+
Process.kill('INT', Process.pid)
|
|
439
|
+
else
|
|
440
|
+
interrupted = true
|
|
441
|
+
puts "\nInterrupted. Finishing current profile (CTRL-C again to force exit)..."
|
|
442
|
+
raise Interrupt
|
|
443
|
+
end
|
|
429
444
|
end
|
|
430
|
-
prepare_time = Time.now - prepare_start
|
|
431
445
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
446
|
+
begin
|
|
447
|
+
puts 'Parsing and mapping source files...'
|
|
448
|
+
prepare_start = Time.now
|
|
449
|
+
Vernier.profile(out: parse_path, hooks: hooks) do
|
|
450
|
+
puts 'Mapping libraries'
|
|
451
|
+
host.prepare(directory)
|
|
452
|
+
sleep 0.2 until host.libraries.all?(&:mapped?)
|
|
453
|
+
end
|
|
454
|
+
prepare_time = Time.now - prepare_start
|
|
438
455
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
456
|
+
puts 'Building the catalog...'
|
|
457
|
+
catalog_start = Time.now
|
|
458
|
+
Vernier.profile(out: catalog_path, hooks: hooks) do
|
|
459
|
+
host.catalog
|
|
460
|
+
end
|
|
461
|
+
catalog_time = Time.now - catalog_start
|
|
462
|
+
|
|
463
|
+
# Determine test file
|
|
464
|
+
if file
|
|
465
|
+
test_file = File.join(directory, file)
|
|
466
|
+
else
|
|
467
|
+
test_file = File.join(directory, 'lib', 'other.rb')
|
|
468
|
+
unless File.exist?(test_file)
|
|
469
|
+
# Fallback to any Ruby file in the workspace
|
|
470
|
+
workspace = Solargraph::Workspace.new(directory)
|
|
471
|
+
test_file = workspace.filenames.find { |f| f.end_with?('.rb') }
|
|
472
|
+
unless test_file
|
|
473
|
+
puts 'No Ruby files found in workspace'
|
|
474
|
+
return
|
|
475
|
+
end
|
|
451
476
|
end
|
|
452
477
|
end
|
|
453
|
-
end
|
|
454
478
|
|
|
455
|
-
|
|
479
|
+
file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path(test_file))
|
|
456
480
|
|
|
457
|
-
|
|
458
|
-
|
|
481
|
+
puts "Profiling go-to-definition for #{test_file}"
|
|
482
|
+
puts "Position: line #{options[:line]}, column #{options[:column]}"
|
|
459
483
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
484
|
+
definition_start = Time.now
|
|
485
|
+
Vernier.profile(out: definition_path, hooks: hooks) do
|
|
486
|
+
message = Solargraph::LanguageServer::Message::TextDocument::Definition.new(
|
|
487
|
+
host, {
|
|
488
|
+
'params' => {
|
|
489
|
+
'textDocument' => { 'uri' => file_uri },
|
|
490
|
+
'position' => { 'line' => options[:line], 'character' => options[:column] }
|
|
491
|
+
}
|
|
467
492
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
493
|
+
)
|
|
494
|
+
puts 'Processing go-to-definition request...'
|
|
495
|
+
result = message.process
|
|
496
|
+
|
|
497
|
+
puts "Result: #{result.inspect}"
|
|
498
|
+
end
|
|
499
|
+
definition_time = Time.now - definition_start
|
|
500
|
+
rescue Interrupt
|
|
501
|
+
puts "\nProfile run interrupted; partial profile(s) have been written."
|
|
502
|
+
ensure
|
|
503
|
+
Signal.trap('INT', previous_int_trap || 'DEFAULT')
|
|
504
|
+
|
|
505
|
+
puts "\n=== Timing Results ==="
|
|
506
|
+
puts "Parsing & mapping: #{(prepare_time * 1000).round(2)}ms" if prepare_time
|
|
507
|
+
puts "Catalog building: #{(catalog_time * 1000).round(2)}ms" if catalog_time
|
|
508
|
+
puts "Go-to-definition: #{(definition_time * 1000).round(2)}ms" if definition_time
|
|
509
|
+
if prepare_time && catalog_time && definition_time
|
|
510
|
+
total_time = prepare_time + catalog_time + definition_time
|
|
511
|
+
puts "Total time: #{(total_time * 1000).round(2)}ms"
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
saved = [parse_path, catalog_path, definition_path].select { |p| File.exist?(p) }
|
|
515
|
+
unless saved.empty?
|
|
516
|
+
puts "\nProfiles saved to:"
|
|
517
|
+
saved.each { |p| puts " - #{File.expand_path(p)}" }
|
|
518
|
+
|
|
519
|
+
puts "\nUpload the JSON files to https://vernier.prof/ to view the profiles."
|
|
520
|
+
puts 'Or use https://rubygems.org/gems/profile-viewer to view them locally.'
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|
|
472
524
|
|
|
473
|
-
|
|
525
|
+
desc 'rbs', 'Generate RBS definitions'
|
|
526
|
+
option :filename, type: :string, alias: :f, desc: 'Generated file name', default: 'sig.rbs'
|
|
527
|
+
option :inference, type: :boolean, desc: 'Enhance definitions with type inference', default: true
|
|
528
|
+
def rbs
|
|
529
|
+
api_map = Solargraph::ApiMap.load('.')
|
|
530
|
+
pins = api_map.source_maps.flat_map(&:pins)
|
|
531
|
+
store = Solargraph::ApiMap::Store.new(pins)
|
|
532
|
+
if options[:inference]
|
|
533
|
+
puts 'Inferring untyped methods...'
|
|
534
|
+
store.method_pins.each do |pin|
|
|
535
|
+
next unless pin.return_type.undefined?
|
|
536
|
+
type = pin.typify(api_map)
|
|
537
|
+
type = pin.probe(api_map) if type.undefined?
|
|
538
|
+
pin.docstring.add_tag YARD::Tags::Tag.new('return', nil, type.items.map(&:to_s))
|
|
539
|
+
pin.instance_variable_set(:@return_type, type)
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
puts 'Generating yardocs...'
|
|
543
|
+
rake_yard(store)
|
|
544
|
+
work_dir = Dir.pwd
|
|
545
|
+
Dir.mktmpdir do |tmpdir|
|
|
546
|
+
Dir.chdir tmpdir do
|
|
547
|
+
yardoc = File.join(tmpdir, '.yardoc')
|
|
548
|
+
YARD::Registry.save(false, yardoc)
|
|
549
|
+
YARD::Registry.load(yardoc)
|
|
550
|
+
rel_dir = File.join('sig', options[:filename])
|
|
551
|
+
puts "Writing #{rel_dir}..."
|
|
552
|
+
target = File.join(work_dir, rel_dir)
|
|
553
|
+
FileUtils.mkdir_p(File.join(work_dir, 'sig'))
|
|
554
|
+
`sord #{target} --rbs --no-regenerate`
|
|
555
|
+
end
|
|
474
556
|
end
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
puts "\n=== Timing Results ==="
|
|
478
|
-
puts "Parsing & mapping: #{(prepare_time * 1000).round(2)}ms"
|
|
479
|
-
puts "Catalog building: #{(catalog_time * 1000).round(2)}ms"
|
|
480
|
-
puts "Go-to-definition: #{(definition_time * 1000).round(2)}ms"
|
|
481
|
-
total_time = prepare_time + catalog_time + definition_time
|
|
482
|
-
puts "Total time: #{(total_time * 1000).round(2)}ms"
|
|
483
|
-
|
|
484
|
-
puts "\nProfiles saved to:"
|
|
485
|
-
puts " - #{File.expand_path('parse_benchmark.json.gz', options[:output_dir])}"
|
|
486
|
-
puts " - #{File.expand_path('catalog_benchmark.json.gz', options[:output_dir])}"
|
|
487
|
-
puts " - #{File.expand_path('definition_benchmark.json.gz', options[:output_dir])}"
|
|
488
|
-
|
|
489
|
-
puts "\nUpload the JSON files to https://vernier.prof/ to view the profiles."
|
|
490
|
-
puts 'Or use https://rubygems.org/gems/profile-viewer to view them locally.'
|
|
557
|
+
puts 'Done.'
|
|
491
558
|
end
|
|
492
559
|
|
|
493
560
|
private
|
|
@@ -19,18 +19,7 @@ module Solargraph
|
|
|
19
19
|
# @param name_pin [Pin::Base]
|
|
20
20
|
# @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
|
|
21
21
|
def resolve api_map, name_pin, locals
|
|
22
|
-
|
|
23
|
-
child.infer(api_map, name_pin, locals).simplify_literals
|
|
24
|
-
end
|
|
25
|
-
type = if child_types.empty? || child_types.any?(&:undefined?)
|
|
26
|
-
ComplexType::UniqueType.new('Array', rooted: true)
|
|
27
|
-
elsif child_types.uniq.length == 1 && child_types.first.defined?
|
|
28
|
-
ComplexType::UniqueType.new('Array', [], child_types.uniq, rooted: true, parameters_type: :list)
|
|
29
|
-
elsif child_types.empty?
|
|
30
|
-
ComplexType::UniqueType.new('Array', rooted: true, parameters_type: :list)
|
|
31
|
-
else
|
|
32
|
-
ComplexType::UniqueType.new('Array', [], child_types, rooted: true, parameters_type: :fixed)
|
|
33
|
-
end
|
|
22
|
+
type = ComplexType::UniqueType.new('Array', rooted: true)
|
|
34
23
|
[Pin::ProxyType.anonymous(type, source: :chain)]
|
|
35
24
|
end
|
|
36
25
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
class BlockSymbol < Link
|
|
7
|
-
def resolve api_map, name_pin, locals
|
|
8
|
-
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
class BlockSymbol < Link
|
|
7
|
+
def resolve api_map, name_pin, locals
|
|
8
|
+
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
class BlockVariable < Link
|
|
7
|
-
def resolve api_map, name_pin, locals
|
|
8
|
-
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
class BlockVariable < Link
|
|
7
|
+
def resolve api_map, name_pin, locals
|
|
8
|
+
[Pin::ProxyType.anonymous(ComplexType.try_parse('::Proc'), source: :chain)]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -127,10 +127,15 @@ module Solargraph
|
|
|
127
127
|
block_call_type(api_map, name_pin, locals)
|
|
128
128
|
end
|
|
129
129
|
end
|
|
130
|
-
# @type new_signature_pin [Pin::Signature]
|
|
131
130
|
new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil,
|
|
132
131
|
blocktype)
|
|
133
|
-
|
|
132
|
+
# @todo It shouldn't be necessary to choose either generics or macros
|
|
133
|
+
new_return_type = if new_signature_pin.return_type.defined?
|
|
134
|
+
new_signature_pin.return_type
|
|
135
|
+
else
|
|
136
|
+
named_types = p.parameter_names.zip(arguments.map { |arg| ComplexType.try_parse(simple_convert(arg.node).to_s) }).to_h
|
|
137
|
+
p.typify(api_map).expand(named_types)
|
|
138
|
+
end
|
|
134
139
|
self_type = if head?
|
|
135
140
|
# If we're at the head of the chain, we called a
|
|
136
141
|
# method somewhere that marked itself as returning
|
|
@@ -153,8 +158,7 @@ module Solargraph
|
|
|
153
158
|
# the docs were written - from the method pin.
|
|
154
159
|
# @todo Need to add nil check here
|
|
155
160
|
if new_return_type.defined?
|
|
156
|
-
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map,
|
|
157
|
-
*p.gates)
|
|
161
|
+
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, *p.gates)
|
|
158
162
|
end
|
|
159
163
|
type ||= ComplexType::UNDEFINED
|
|
160
164
|
end
|
|
@@ -162,15 +166,6 @@ module Solargraph
|
|
|
162
166
|
end
|
|
163
167
|
p = p.with_single_signature(new_signature_pin) unless new_signature_pin.nil?
|
|
164
168
|
next p.proxy(type) if type.defined?
|
|
165
|
-
if !p.macros.empty?
|
|
166
|
-
result = process_macro(p, api_map, name_pin.context, locals)
|
|
167
|
-
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
168
|
-
next result unless result.return_type.undefined?
|
|
169
|
-
elsif !p.directives.empty?
|
|
170
|
-
result = process_directive(p, api_map, name_pin.context, locals)
|
|
171
|
-
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
172
|
-
next result unless result.return_type.undefined?
|
|
173
|
-
end
|
|
174
169
|
p
|
|
175
170
|
end
|
|
176
171
|
logger.debug do
|
|
@@ -191,69 +186,6 @@ module Solargraph
|
|
|
191
186
|
end
|
|
192
187
|
end
|
|
193
188
|
|
|
194
|
-
# @param pin [Pin::Base]
|
|
195
|
-
# @param api_map [ApiMap]
|
|
196
|
-
# @param context [ComplexType, ComplexType::UniqueType]
|
|
197
|
-
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
198
|
-
# @return [Pin::Base]
|
|
199
|
-
def process_macro pin, api_map, context, locals
|
|
200
|
-
pin.macros.each do |macro|
|
|
201
|
-
# @todo 'Wrong argument type for
|
|
202
|
-
# Solargraph::Source::Chain::Call#inner_process_macro:
|
|
203
|
-
# macro expected YARD::Tags::MacroDirective, received
|
|
204
|
-
# generic<Elem>' is because we lose 'rooted' information
|
|
205
|
-
# in the 'Chain::Array' class internally, leaving
|
|
206
|
-
# ::Array#each shadowed when it shouldn't be.
|
|
207
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
208
|
-
return result unless result.return_type.undefined?
|
|
209
|
-
end
|
|
210
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
# @param pin [Pin::Method]
|
|
214
|
-
# @param api_map [ApiMap]
|
|
215
|
-
# @param context [ComplexType, ComplexType::UniqueType]
|
|
216
|
-
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
217
|
-
# @return [Pin::ProxyType]
|
|
218
|
-
def process_directive pin, api_map, context, locals
|
|
219
|
-
pin.directives.each do |dir|
|
|
220
|
-
macro = api_map.named_macro(dir.tag.name)
|
|
221
|
-
next if macro.nil?
|
|
222
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
223
|
-
return result unless result.return_type.undefined?
|
|
224
|
-
end
|
|
225
|
-
Pin::ProxyType.anonymous ComplexType::UNDEFINED, source: :chain
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
# @param pin [Pin::Base]
|
|
229
|
-
# @param macro [YARD::Tags::MacroDirective]
|
|
230
|
-
# @param api_map [ApiMap]
|
|
231
|
-
# @param context [ComplexType, ComplexType::UniqueType]
|
|
232
|
-
# @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
|
|
233
|
-
# @return [Pin::ProxyType]
|
|
234
|
-
def inner_process_macro pin, macro, api_map, context, locals
|
|
235
|
-
vals = arguments.map { |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals), source: :chain) }
|
|
236
|
-
txt = macro.tag.text.clone
|
|
237
|
-
# @sg-ignore Need to add nil check here
|
|
238
|
-
if txt.empty? && macro.tag.name
|
|
239
|
-
named = api_map.named_macro(macro.tag.name)
|
|
240
|
-
txt = named.tag.text.clone if named
|
|
241
|
-
end
|
|
242
|
-
i = 1
|
|
243
|
-
vals.each do |v|
|
|
244
|
-
# @sg-ignore Need to add nil check here
|
|
245
|
-
txt.gsub!(/\$#{i}/, v.context.namespace)
|
|
246
|
-
i += 1
|
|
247
|
-
end
|
|
248
|
-
# @sg-ignore Need to add nil check here
|
|
249
|
-
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
|
250
|
-
tag = docstring.tag(:return)
|
|
251
|
-
unless tag.nil? || tag.types.nil?
|
|
252
|
-
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types), source: :chain)
|
|
253
|
-
end
|
|
254
|
-
Pin::ProxyType.anonymous(ComplexType::UNDEFINED, source: :chain)
|
|
255
|
-
end
|
|
256
|
-
|
|
257
189
|
# @param docstring [YARD::Docstring]
|
|
258
190
|
# @param context [ComplexType]
|
|
259
191
|
# @return [ComplexType, nil]
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
# Chain::Head is a link for ambiguous words, e.g.; `String` can refer to
|
|
7
|
-
# either a class (`String`) or a function (`Kernel#String`).
|
|
8
|
-
#
|
|
9
|
-
# @note Chain::Head is only intended to handle `self` and `super`.
|
|
10
|
-
class Head < Link
|
|
11
|
-
def resolve api_map, name_pin, locals
|
|
12
|
-
return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
|
|
13
|
-
# return super_pins(api_map, name_pin) if word == 'super'
|
|
14
|
-
[]
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
# Chain::Head is a link for ambiguous words, e.g.; `String` can refer to
|
|
7
|
+
# either a class (`String`) or a function (`Kernel#String`).
|
|
8
|
+
#
|
|
9
|
+
# @note Chain::Head is only intended to handle `self` and `super`.
|
|
10
|
+
class Head < Link
|
|
11
|
+
def resolve api_map, name_pin, locals
|
|
12
|
+
return [Pin::ProxyType.anonymous(name_pin.binder, source: :chain)] if word == 'self'
|
|
13
|
+
# return super_pins(api_map, name_pin) if word == 'super'
|
|
14
|
+
[]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -13,21 +13,25 @@ module Solargraph
|
|
|
13
13
|
def initialize type, node
|
|
14
14
|
super("<#{type}>")
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
# @todo We might be able to do some light inference from literals and
|
|
17
|
+
# tuples as long as literal values are intransitive.
|
|
18
|
+
|
|
19
|
+
# if node.is_a?(::Parser::AST::Node)
|
|
20
|
+
# # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
21
|
+
# if node.type == :true
|
|
22
|
+
# @value = true
|
|
23
|
+
# # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
24
|
+
# elsif node.type == :false
|
|
25
|
+
# @value = false
|
|
26
|
+
# # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
27
|
+
# elsif %i[int sym].include?(node.type)
|
|
28
|
+
# # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
29
|
+
# @value = node.children.first
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
29
32
|
@type = type
|
|
30
|
-
@literal_type = ComplexType.try_parse(@value.inspect)
|
|
33
|
+
# @literal_type = ComplexType.try_parse(@value.inspect)
|
|
34
|
+
@literal_type = ComplexType::UNDEFINED
|
|
31
35
|
@complex_type = ComplexType.try_parse(type)
|
|
32
36
|
end
|
|
33
37
|
|
|
@@ -32,10 +32,10 @@ module Solargraph
|
|
|
32
32
|
# @return [Source::Chain]
|
|
33
33
|
def chain
|
|
34
34
|
# Special handling for files that end with an integer and a period
|
|
35
|
-
if phrase =~ /^[0-9]+\.$/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
35
|
+
# if phrase =~ /^[0-9]+\.$/
|
|
36
|
+
# return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])),
|
|
37
|
+
# Chain::UNDEFINED_CALL])
|
|
38
|
+
# end
|
|
39
39
|
if phrase.start_with?(':') && !phrase.start_with?('::')
|
|
40
40
|
return Chain.new([Chain::Literal.new('Symbol',
|
|
41
41
|
# @sg-ignore Need to add nil check here
|