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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +6 -0
  3. data/.github/workflows/plugins.yml +8 -0
  4. data/.github/workflows/rspec.yml +4 -1
  5. data/.github/workflows/typecheck.yml +2 -0
  6. data/.rubocop.yml +1 -0
  7. data/.rubocop_todo.yml +1 -1
  8. data/CHANGELOG.md +18 -0
  9. data/Gemfile +3 -0
  10. data/lib/solargraph/api_map/index.rb +13 -2
  11. data/lib/solargraph/api_map/store.rb +22 -8
  12. data/lib/solargraph/api_map.rb +38 -8
  13. data/lib/solargraph/complex_type/type_methods.rb +1 -0
  14. data/lib/solargraph/complex_type/unique_type.rb +16 -13
  15. data/lib/solargraph/complex_type.rb +5 -0
  16. data/lib/solargraph/convention/active_support_concern.rb +111 -111
  17. data/lib/solargraph/convention/base.rb +50 -50
  18. data/lib/solargraph/diagnostics.rb +55 -55
  19. data/lib/solargraph/doc_map.rb +1 -0
  20. data/lib/solargraph/environ.rb +52 -52
  21. data/lib/solargraph/gem_pins.rb +0 -11
  22. data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
  23. data/lib/solargraph/language_server/message/initialized.rb +28 -28
  24. data/lib/solargraph/language_server/message/text_document.rb +28 -28
  25. data/lib/solargraph/language_server/progress.rb +143 -143
  26. data/lib/solargraph/language_server/transport/adapter.rb +68 -68
  27. data/lib/solargraph/language_server.rb +20 -20
  28. data/lib/solargraph/parser/parser_gem/node_chainer.rb +1 -0
  29. data/lib/solargraph/parser/parser_gem/node_methods.rb +42 -0
  30. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
  31. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
  32. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
  33. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
  34. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -5
  35. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
  36. data/lib/solargraph/pin/base.rb +31 -3
  37. data/lib/solargraph/pin/callable.rb +2 -2
  38. data/lib/solargraph/pin/common.rb +12 -0
  39. data/lib/solargraph/pin/method.rb +56 -16
  40. data/lib/solargraph/pin/reference/require.rb +14 -14
  41. data/lib/solargraph/pin/singleton.rb +11 -11
  42. data/lib/solargraph/rbs_map/conversions.rb +103 -145
  43. data/lib/solargraph/rbs_translator.rb +206 -0
  44. data/lib/solargraph/shell.rb +131 -64
  45. data/lib/solargraph/source/chain/array.rb +1 -12
  46. data/lib/solargraph/source/chain/block_symbol.rb +13 -13
  47. data/lib/solargraph/source/chain/block_variable.rb +13 -13
  48. data/lib/solargraph/source/chain/call.rb +8 -76
  49. data/lib/solargraph/source/chain/head.rb +19 -19
  50. data/lib/solargraph/source/chain/literal.rb +18 -14
  51. data/lib/solargraph/source/source_chainer.rb +4 -4
  52. data/lib/solargraph/source_map/mapper.rb +5 -135
  53. data/lib/solargraph/source_map.rb +14 -0
  54. data/lib/solargraph/version.rb +19 -1
  55. data/lib/solargraph/yard_map/cache.rb +25 -25
  56. data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
  57. data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
  58. data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
  59. data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
  60. data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
  61. data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
  62. data/lib/solargraph/yard_map/directives.rb +35 -0
  63. data/lib/solargraph/yard_map/macro.rb +113 -0
  64. data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
  65. data/lib/solargraph/yard_map/mapper.rb +19 -1
  66. data/lib/solargraph/yard_map.rb +2 -0
  67. data/lib/solargraph.rb +1 -0
  68. data/solargraph.gemspec +1 -0
  69. metadata +24 -2
  70. data/rbs/fills/tuple/tuple.rbs +0 -177
@@ -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.rbs_collection_path, workspace.rbs_collection_config_path)
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
- # cache pins even if result is zero, so we don't retry building pins
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} - #{prob.message}"
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
- puts 'Parsing and mapping source files...'
424
- prepare_start = Time.now
425
- Vernier.profile(out: "#{options[:output_dir]}/parse_benchmark.json.gz", hooks: hooks) do
426
- puts 'Mapping libraries'
427
- host.prepare(directory)
428
- sleep 0.2 until host.libraries.all?(&:mapped?)
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
- puts 'Building the catalog...'
433
- catalog_start = Time.now
434
- Vernier.profile(out: "#{options[:output_dir]}/catalog_benchmark.json.gz", hooks: hooks) do
435
- host.catalog
436
- end
437
- catalog_time = Time.now - catalog_start
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
- # Determine test file
440
- if file
441
- test_file = File.join(directory, file)
442
- else
443
- test_file = File.join(directory, 'lib', 'other.rb')
444
- unless File.exist?(test_file)
445
- # Fallback to any Ruby file in the workspace
446
- workspace = Solargraph::Workspace.new(directory)
447
- test_file = workspace.filenames.find { |f| f.end_with?('.rb') }
448
- unless test_file
449
- warn 'No Ruby files found in workspace'
450
- return
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
- file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path(test_file))
479
+ file_uri = Solargraph::LanguageServer::UriHelpers.file_to_uri(File.absolute_path(test_file))
456
480
 
457
- puts "Profiling go-to-definition for #{test_file}"
458
- puts "Position: line #{options[:line]}, column #{options[:column]}"
481
+ puts "Profiling go-to-definition for #{test_file}"
482
+ puts "Position: line #{options[:line]}, column #{options[:column]}"
459
483
 
460
- definition_start = Time.now
461
- Vernier.profile(out: "#{options[:output_dir]}/definition_benchmark.json.gz", hooks: hooks) do
462
- message = Solargraph::LanguageServer::Message::TextDocument::Definition.new(
463
- host, {
464
- 'params' => {
465
- 'textDocument' => { 'uri' => file_uri },
466
- 'position' => { 'line' => options[:line], 'character' => options[:column] }
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
- puts 'Processing go-to-definition request...'
471
- result = message.process
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
- puts "Result: #{result.inspect}"
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
- definition_time = Time.now - definition_start
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
- child_types = @children.map do |child|
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
- new_return_type = new_signature_pin.return_type
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
- if node.is_a?(::Parser::AST::Node)
17
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
18
- if node.type == :true
19
- @value = true
20
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
21
- elsif node.type == :false
22
- @value = false
23
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
24
- elsif %i[int sym].include?(node.type)
25
- # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
26
- @value = node.children.first
27
- end
28
- end
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
- return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])),
37
- Chain::UNDEFINED_CALL])
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