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
|
@@ -67,7 +67,6 @@ module Solargraph
|
|
|
67
67
|
unless closure.name == '' || decl.name.absolute?
|
|
68
68
|
Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on interface #{decl.inspect}")
|
|
69
69
|
end
|
|
70
|
-
# STDERR.puts "Skipping interface #{decl.name.relative!}"
|
|
71
70
|
interface_decl_to_pin decl
|
|
72
71
|
when RBS::AST::Declarations::TypeAlias
|
|
73
72
|
# @sg-ignore flow sensitive typing should support case/when
|
|
@@ -80,7 +79,7 @@ module Solargraph
|
|
|
80
79
|
# @sg-ignore Wrong argument type for Solargraph::Pin::Reference::TypeAlias.new: return_type expected Solargraph::ComplexType, received Solargraph::ComplexType::UniqueType, Solargraph::ComplexType
|
|
81
80
|
Solargraph::Pin::Reference::TypeAlias.new(
|
|
82
81
|
# @sg-ignore Unresolved calls to name, type, type_location; return_type type mismatch
|
|
83
|
-
name: ComplexType.try_parse(decl.name.to_s).to_s, return_type:
|
|
82
|
+
name: ComplexType.try_parse(decl.name.to_s).to_s, return_type: RbsTranslator.to_complex_type(decl.type).force_rooted, closure: closure, source: :rbs, type_location: location_decl_to_pin_location(decl.location)
|
|
84
83
|
)
|
|
85
84
|
)
|
|
86
85
|
when RBS::AST::Declarations::Module
|
|
@@ -169,7 +168,8 @@ module Solargraph
|
|
|
169
168
|
rbs_name = type_name.relative!.to_s
|
|
170
169
|
base = RBS_TO_CLASS.fetch(rbs_name, rbs_name)
|
|
171
170
|
|
|
172
|
-
params = type_args.map { |a|
|
|
171
|
+
params = type_args.map { |a| RbsTranslator.to_complex_type(a) }
|
|
172
|
+
# @todo Tuples are in flux
|
|
173
173
|
# tuples have their own class and are handled in other_type_to_type
|
|
174
174
|
if base == 'Hash' && params.length == 2
|
|
175
175
|
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: type_name.absolute?,
|
|
@@ -185,9 +185,9 @@ module Solargraph
|
|
|
185
185
|
# @return [void]
|
|
186
186
|
def convert_self_type_to_pins decl, closure
|
|
187
187
|
type = build_type(decl.name, decl.args)
|
|
188
|
-
generic_values = type.all_params.map(&:
|
|
188
|
+
generic_values = type.all_params.map(&:to_s)
|
|
189
189
|
include_pin = Solargraph::Pin::Reference::Include.new(
|
|
190
|
-
name:
|
|
190
|
+
name: decl.name.relative!.to_s,
|
|
191
191
|
type_location: location_decl_to_pin_location(decl.location),
|
|
192
192
|
generic_values: generic_values,
|
|
193
193
|
closure: closure,
|
|
@@ -274,7 +274,10 @@ module Solargraph
|
|
|
274
274
|
# @type [Hash{String => ComplexType, ComplexType::UniqueType}]
|
|
275
275
|
generic_defaults = {}
|
|
276
276
|
decl.type_params.each do |param|
|
|
277
|
-
|
|
277
|
+
if param.default_type
|
|
278
|
+
complex_type = RbsTranslator.to_complex_type(param.default_type).force_rooted
|
|
279
|
+
generic_defaults[param.name.to_s] = complex_type
|
|
280
|
+
end
|
|
278
281
|
end
|
|
279
282
|
|
|
280
283
|
class_name = fqns(decl.name)
|
|
@@ -297,7 +300,8 @@ module Solargraph
|
|
|
297
300
|
pins.push class_pin
|
|
298
301
|
if decl.super_class
|
|
299
302
|
type = build_type(decl.super_class.name, decl.super_class.args)
|
|
300
|
-
generic_values = type.all_params.map(&:
|
|
303
|
+
generic_values = type.all_params.map(&:to_s)
|
|
304
|
+
superclass_name = decl.super_class.name.to_s
|
|
301
305
|
pins.push Solargraph::Pin::Reference::Superclass.new(
|
|
302
306
|
type_location: location_decl_to_pin_location(decl.super_class.location),
|
|
303
307
|
closure: class_pin,
|
|
@@ -316,7 +320,7 @@ module Solargraph
|
|
|
316
320
|
class_pin = Solargraph::Pin::Namespace.new(
|
|
317
321
|
type: :module,
|
|
318
322
|
type_location: location_decl_to_pin_location(decl.location),
|
|
319
|
-
name:
|
|
323
|
+
name: decl.name.relative!.to_s,
|
|
320
324
|
closure: Solargraph::Pin::ROOT_PIN,
|
|
321
325
|
comments: decl.comment&.string,
|
|
322
326
|
generics: type_parameter_names(decl),
|
|
@@ -335,7 +339,7 @@ module Solargraph
|
|
|
335
339
|
def module_decl_to_pin decl
|
|
336
340
|
module_pin = Solargraph::Pin::Namespace.new(
|
|
337
341
|
type: :module,
|
|
338
|
-
name:
|
|
342
|
+
name: decl.name.relative!.to_s,
|
|
339
343
|
type_location: location_decl_to_pin_location(decl.location),
|
|
340
344
|
closure: Solargraph::Pin::ROOT_PIN,
|
|
341
345
|
comments: decl.comment&.string,
|
|
@@ -380,6 +384,9 @@ module Solargraph
|
|
|
380
384
|
)
|
|
381
385
|
rooted_tag = type.rooted_tags
|
|
382
386
|
rooted_tag = "#{base}<#{rooted_tag}>" if base
|
|
387
|
+
# @todo alt version
|
|
388
|
+
# tag = "#{base}<#{tag}>" if base
|
|
389
|
+
# rooted_tag = ComplexType.parse(tag).force_rooted.rooted_tags
|
|
383
390
|
constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
384
391
|
constant_pin
|
|
385
392
|
end
|
|
@@ -406,9 +413,8 @@ module Solargraph
|
|
|
406
413
|
# @param decl [RBS::AST::Declarations::Constant]
|
|
407
414
|
# @return [void]
|
|
408
415
|
def constant_decl_to_pin decl
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
pins.push create_constant(constant_name, target_type, decl.comment&.string, decl)
|
|
416
|
+
tag = RbsTranslator.to_complex_type(decl.type)
|
|
417
|
+
pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string, decl)
|
|
412
418
|
end
|
|
413
419
|
|
|
414
420
|
# @param decl [RBS::AST::Declarations::Global]
|
|
@@ -423,7 +429,7 @@ module Solargraph
|
|
|
423
429
|
type_location: location_decl_to_pin_location(decl.location),
|
|
424
430
|
source: :rbs
|
|
425
431
|
)
|
|
426
|
-
rooted_tag =
|
|
432
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
427
433
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
428
434
|
pins.push pin
|
|
429
435
|
end
|
|
@@ -529,73 +535,69 @@ module Solargraph
|
|
|
529
535
|
pin.instance_variable_set(:@return_type, ComplexType::VOID)
|
|
530
536
|
end
|
|
531
537
|
end
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
538
|
+
if decl.singleton?
|
|
539
|
+
final_scope = :class
|
|
540
|
+
name = decl.name.to_s
|
|
541
|
+
visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
|
|
542
|
+
pin = Solargraph::Pin::Method.new(
|
|
543
|
+
name: name,
|
|
544
|
+
closure: closure,
|
|
545
|
+
comments: decl.comment&.string,
|
|
546
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
547
|
+
visibility: visibility,
|
|
548
|
+
scope: final_scope,
|
|
549
|
+
signatures: [],
|
|
550
|
+
generics: generics,
|
|
551
|
+
source: :rbs
|
|
552
|
+
)
|
|
553
|
+
pin.signatures.concat method_def_to_sigs(decl, pin)
|
|
554
|
+
pins.push pin
|
|
555
|
+
end
|
|
549
556
|
end
|
|
550
557
|
|
|
551
558
|
# @param decl [RBS::AST::Members::MethodDefinition]
|
|
552
559
|
# @param pin [Pin::Method]
|
|
553
560
|
# @return [void]
|
|
554
561
|
def method_def_to_sigs decl, pin
|
|
555
|
-
#
|
|
562
|
+
# rubocop:disable Style/SafeNavigationChainLength
|
|
563
|
+
implicit_nil = decl.overloads.first&.annotations&.map(&:string)&.include?('implicitly-returns-nil') || false
|
|
564
|
+
# rubocop:enable Style/SafeNavigationChainLength # @param overload [RBS::AST::Members::MethodDefinition::Overload]
|
|
556
565
|
decl.overloads.map do |overload|
|
|
557
|
-
# @sg-ignore Wrong argument type for Solargraph::RbsMap::Conversions#location_decl_to_pin_location:
|
|
558
|
-
# location expected RBS::Location, nil, received RBS::Location<:type, :type_params>, RBS::AST::Members::Attribute::loc, nil
|
|
559
566
|
type_location = location_decl_to_pin_location(overload.method_type.location)
|
|
560
|
-
generics =
|
|
561
|
-
signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
block_parameters, block_return_type
|
|
565
|
-
Pin::Signature.new(generics: generics, parameters: block_parameters,
|
|
566
|
-
return_type: block_return_type, source: :rbs,
|
|
567
|
+
generics = overload.method_type.type_params.map(&:name).map(&:to_s)
|
|
568
|
+
signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin, implicit_nil)
|
|
569
|
+
block = if overload.method_type.block
|
|
570
|
+
block_parameters, block_return_type = parts_of_function(overload.method_type.block, pin, implicit_nil)
|
|
571
|
+
Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs,
|
|
567
572
|
type_location: type_location, closure: pin)
|
|
568
573
|
end
|
|
569
|
-
Pin::Signature.new(generics: generics, parameters: signature_parameters,
|
|
570
|
-
return_type: signature_return_type, block: block, source: :rbs,
|
|
574
|
+
Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block, source: :rbs,
|
|
571
575
|
type_location: type_location, closure: pin)
|
|
572
576
|
end
|
|
573
577
|
end
|
|
574
578
|
|
|
575
579
|
# @param location [RBS::Location, nil]
|
|
576
580
|
# @return [Solargraph::Location, nil]
|
|
577
|
-
def location_decl_to_pin_location
|
|
581
|
+
def location_decl_to_pin_location(location)
|
|
578
582
|
return nil if location&.name.nil?
|
|
579
583
|
|
|
580
|
-
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
581
584
|
start_pos = Position.new(location.start_line - 1, location.start_column)
|
|
582
|
-
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
583
585
|
end_pos = Position.new(location.end_line - 1, location.end_column)
|
|
584
586
|
range = Range.new(start_pos, end_pos)
|
|
585
|
-
# @sg-ignore flow sensitve typing should handle return nil if location&.name.nil?
|
|
586
587
|
Location.new(location.name.to_s, range)
|
|
587
588
|
end
|
|
588
589
|
|
|
589
590
|
# @param type [RBS::MethodType, RBS::Types::Block]
|
|
590
591
|
# @param pin [Pin::Method]
|
|
592
|
+
# @param implicit_nil [Boolean]
|
|
591
593
|
# @return [Array(Array<Pin::Parameter>, ComplexType)]
|
|
592
|
-
def parts_of_function type, pin
|
|
594
|
+
def parts_of_function type, pin, implicit_nil
|
|
593
595
|
type_location = pin.type_location
|
|
594
596
|
if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
|
|
595
597
|
return [
|
|
596
598
|
[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs,
|
|
597
599
|
type_location: type_location)],
|
|
598
|
-
method_type_to_type(type)
|
|
600
|
+
method_type_to_type(type, implicit_nil)
|
|
599
601
|
]
|
|
600
602
|
end
|
|
601
603
|
|
|
@@ -659,10 +661,21 @@ module Solargraph
|
|
|
659
661
|
source: :rbs, type_location: type_location)
|
|
660
662
|
end
|
|
661
663
|
|
|
662
|
-
return_type = method_type_to_type(type)
|
|
664
|
+
return_type = method_type_to_type(type, implicit_nil)
|
|
663
665
|
[parameters, return_type]
|
|
664
666
|
end
|
|
665
667
|
|
|
668
|
+
# @param type [RBS::MethodType,RBS::Types::Block]
|
|
669
|
+
# @param pin [Pin::Method]
|
|
670
|
+
# @param implicit_nil [Boolean]
|
|
671
|
+
# @return [Array(Array<Pin::Parameter>, ComplexType)]
|
|
672
|
+
def parts_of_function type, pin, implicit_nil
|
|
673
|
+
[
|
|
674
|
+
RbsTranslator.to_parameter_pins(type, pin, pin.parameter_names),
|
|
675
|
+
extract_method_type_return_type(type, implicit_nil).force_rooted
|
|
676
|
+
]
|
|
677
|
+
end
|
|
678
|
+
|
|
666
679
|
# @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
|
|
667
680
|
# @param closure [Pin::Namespace]
|
|
668
681
|
# @param context [Context]
|
|
@@ -681,7 +694,7 @@ module Solargraph
|
|
|
681
694
|
visibility: visibility,
|
|
682
695
|
source: :rbs
|
|
683
696
|
)
|
|
684
|
-
rooted_tag =
|
|
697
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
685
698
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
686
699
|
logger.debug do
|
|
687
700
|
"Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}"
|
|
@@ -712,13 +725,13 @@ module Solargraph
|
|
|
712
725
|
pin.parameters <<
|
|
713
726
|
Solargraph::Pin::Parameter.new(
|
|
714
727
|
name: 'value',
|
|
715
|
-
return_type:
|
|
728
|
+
return_type: RbsTranslator.to_complex_type(decl.type).force_rooted,
|
|
716
729
|
source: :rbs,
|
|
717
730
|
closure: pin,
|
|
718
731
|
type_location: type_location
|
|
719
732
|
)
|
|
720
|
-
|
|
721
|
-
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '',
|
|
733
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
734
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
722
735
|
pins.push pin
|
|
723
736
|
end
|
|
724
737
|
|
|
@@ -742,7 +755,7 @@ module Solargraph
|
|
|
742
755
|
comments: decl.comment&.string,
|
|
743
756
|
source: :rbs
|
|
744
757
|
)
|
|
745
|
-
rooted_tag =
|
|
758
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
746
759
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
747
760
|
pins.push pin
|
|
748
761
|
end
|
|
@@ -759,7 +772,7 @@ module Solargraph
|
|
|
759
772
|
type_location: location_decl_to_pin_location(decl.location),
|
|
760
773
|
source: :rbs
|
|
761
774
|
)
|
|
762
|
-
rooted_tag =
|
|
775
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
763
776
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
764
777
|
pins.push pin
|
|
765
778
|
end
|
|
@@ -776,7 +789,7 @@ module Solargraph
|
|
|
776
789
|
type_location: location_decl_to_pin_location(decl.location),
|
|
777
790
|
source: :rbs
|
|
778
791
|
)
|
|
779
|
-
rooted_tag =
|
|
792
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
780
793
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
781
794
|
pins.push pin
|
|
782
795
|
end
|
|
@@ -786,9 +799,9 @@ module Solargraph
|
|
|
786
799
|
# @return [void]
|
|
787
800
|
def include_to_pin decl, closure
|
|
788
801
|
type = build_type(decl.name, decl.args)
|
|
789
|
-
generic_values = type.all_params.map(&:
|
|
802
|
+
generic_values = type.all_params.map(&:to_s)
|
|
790
803
|
pins.push Solargraph::Pin::Reference::Include.new(
|
|
791
|
-
name:
|
|
804
|
+
name: decl.name.relative!.to_s,
|
|
792
805
|
type_location: location_decl_to_pin_location(decl.location),
|
|
793
806
|
generic_values: generic_values,
|
|
794
807
|
closure: closure,
|
|
@@ -803,9 +816,8 @@ module Solargraph
|
|
|
803
816
|
type = build_type(decl.name, decl.args)
|
|
804
817
|
generic_values = type.all_params.map(&:rooted_tags)
|
|
805
818
|
pins.push Solargraph::Pin::Reference::Prepend.new(
|
|
806
|
-
name:
|
|
819
|
+
name: decl.name.relative!.to_s,
|
|
807
820
|
type_location: location_decl_to_pin_location(decl.location),
|
|
808
|
-
generic_values: generic_values,
|
|
809
821
|
closure: closure,
|
|
810
822
|
source: :rbs
|
|
811
823
|
)
|
|
@@ -818,9 +830,8 @@ module Solargraph
|
|
|
818
830
|
type = build_type(decl.name, decl.args)
|
|
819
831
|
generic_values = type.all_params.map(&:rooted_tags)
|
|
820
832
|
pins.push Solargraph::Pin::Reference::Extend.new(
|
|
821
|
-
name:
|
|
833
|
+
name: decl.name.relative!.to_s,
|
|
822
834
|
type_location: location_decl_to_pin_location(decl.location),
|
|
823
|
-
generic_values: generic_values,
|
|
824
835
|
closure: closure,
|
|
825
836
|
source: :rbs
|
|
826
837
|
)
|
|
@@ -841,90 +852,37 @@ module Solargraph
|
|
|
841
852
|
)
|
|
842
853
|
end
|
|
843
854
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
855
|
+
RBS_TO_YARD_TYPE = {
|
|
856
|
+
'bool' => 'Boolean',
|
|
857
|
+
'string' => 'String',
|
|
858
|
+
'int' => 'Integer',
|
|
859
|
+
'untyped' => '',
|
|
860
|
+
'NilClass' => 'nil'
|
|
861
|
+
}
|
|
862
|
+
private_constant :RBS_TO_YARD_TYPE
|
|
849
863
|
|
|
850
|
-
#
|
|
851
|
-
# Note: Generally these extend from RBS::Types::Bases::Base,
|
|
852
|
-
# but not all.
|
|
864
|
+
# Extract a ComplexType from a MethodType's return type.
|
|
853
865
|
#
|
|
854
|
-
#
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
ComplexType.
|
|
872
|
-
when RBS::Types::Union
|
|
873
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
874
|
-
ComplexType.new(type.types.map { |t| other_type_to_type(t) })
|
|
875
|
-
when RBS::Types::Record
|
|
876
|
-
# @todo Better record support
|
|
877
|
-
ComplexType::UniqueType.new('Hash', rooted: true)
|
|
878
|
-
when RBS::Types::Bases::Nil
|
|
879
|
-
ComplexType::NIL
|
|
880
|
-
when RBS::Types::Bases::Self
|
|
881
|
-
ComplexType::SELF
|
|
882
|
-
when RBS::Types::Bases::Void
|
|
883
|
-
ComplexType::VOID
|
|
884
|
-
when RBS::Types::Variable
|
|
885
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
886
|
-
ComplexType.parse("generic<#{type.name}>").force_rooted
|
|
887
|
-
when RBS::Types::ClassInstance # && !type.args.empty?
|
|
888
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
889
|
-
build_type(type.name, type.args)
|
|
890
|
-
when RBS::Types::Bases::Instance
|
|
891
|
-
ComplexType::SELF
|
|
892
|
-
when RBS::Types::Bases::Top
|
|
893
|
-
# top is the most super superclass
|
|
894
|
-
ComplexType::UniqueType.new('BasicObject', rooted: true)
|
|
895
|
-
when RBS::Types::Bases::Bottom
|
|
896
|
-
# bottom is used in contexts where nothing will ever return
|
|
897
|
-
# - e.g., it could be the return type of 'exit()' or 'raise'
|
|
898
|
-
#
|
|
899
|
-
# @todo define a specific bottom type and use it to
|
|
900
|
-
# determine dead code
|
|
901
|
-
ComplexType::UNDEFINED
|
|
902
|
-
when RBS::Types::Intersection
|
|
903
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
904
|
-
ComplexType.new(type.types.map { |member| other_type_to_type(member) })
|
|
905
|
-
when RBS::Types::Proc
|
|
906
|
-
ComplexType::UniqueType.new('Proc', rooted: true)
|
|
907
|
-
when RBS::Types::Alias
|
|
908
|
-
# type-level alias use - e.g., 'bool' in "type bool = true | false"
|
|
909
|
-
# @todo ensure these get resolved after processing all aliases
|
|
910
|
-
# @todo handle recursive aliases
|
|
911
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
912
|
-
build_type(type.name, type.args)
|
|
913
|
-
when RBS::Types::Interface
|
|
914
|
-
# represents a mix-in module which can be considered a
|
|
915
|
-
# subtype of a consumer of it
|
|
916
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
917
|
-
build_type(type.name, type.args)
|
|
918
|
-
when RBS::Types::ClassSingleton
|
|
919
|
-
# e.g., singleton(String)
|
|
920
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
921
|
-
build_type(type.name)
|
|
866
|
+
# This method will convert type aliases to concrete types.
|
|
867
|
+
#
|
|
868
|
+
# @param type [RBS::MethodType]
|
|
869
|
+
# @return [ComplexType]
|
|
870
|
+
def extract_method_type_return_type type, implicit_nil
|
|
871
|
+
tag = RbsTranslator.to_complex_type(type.type.return_type)
|
|
872
|
+
return ComplexType.parse("#{tag}, nil") if tag && implicit_nil
|
|
873
|
+
tag
|
|
874
|
+
end
|
|
875
|
+
|
|
876
|
+
# @param type_name [RBS::TypeName]
|
|
877
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
878
|
+
# @return [ComplexType::UniqueType]
|
|
879
|
+
def build_type(type_name, type_args = [])
|
|
880
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
881
|
+
params = type_args.map { |arg| RbsTranslator.to_complex_type(arg).force_rooted }
|
|
882
|
+
if base == 'Hash' && params.length == 2
|
|
883
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
922
884
|
else
|
|
923
|
-
|
|
924
|
-
#
|
|
925
|
-
# @sg-ignore all types should include location
|
|
926
|
-
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
|
|
927
|
-
ComplexType::UNDEFINED
|
|
885
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
928
886
|
end
|
|
929
887
|
end
|
|
930
888
|
|
|
@@ -937,9 +895,9 @@ module Solargraph
|
|
|
937
895
|
# @todo are we handling prepend correctly?
|
|
938
896
|
klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
|
|
939
897
|
type = build_type(mixin.name, mixin.args)
|
|
940
|
-
generic_values = type.all_params.map(&:
|
|
898
|
+
generic_values = type.all_params.map(&:to_s)
|
|
941
899
|
pins.push klass.new(
|
|
942
|
-
name:
|
|
900
|
+
name: mixin.name.relative!.to_s,
|
|
943
901
|
type_location: location_decl_to_pin_location(mixin.location),
|
|
944
902
|
generic_values: generic_values,
|
|
945
903
|
closure: namespace,
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
# Convert RBS types to complex types and pins.
|
|
5
|
+
#
|
|
6
|
+
module RbsTranslator
|
|
7
|
+
RBS_TO_YARD_TYPE = {
|
|
8
|
+
'bool' => 'Boolean',
|
|
9
|
+
'string' => 'String',
|
|
10
|
+
'int' => 'Integer',
|
|
11
|
+
'untyped' => '',
|
|
12
|
+
'NilClass' => 'nil'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# @param type [RBS::Types::Bases::Base]
|
|
16
|
+
# @return [ComplexType]
|
|
17
|
+
def self.to_complex_type(type)
|
|
18
|
+
tag = type_to_tag(type)
|
|
19
|
+
ComplexType.try_parse(tag).force_rooted
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param param_type [RBS::Types::Function::Param]
|
|
23
|
+
# @param name [String]
|
|
24
|
+
# @param decl [Symbol]
|
|
25
|
+
# @param closure [Pin::Closure]
|
|
26
|
+
# @return [Pin::Parameter]
|
|
27
|
+
def self.to_parameter_pin(param_type, name, decl, closure)
|
|
28
|
+
return_type = if decl == :restarg
|
|
29
|
+
ComplexType.parse('Array')
|
|
30
|
+
elsif decl == :kwrestarg
|
|
31
|
+
ComplexType.parse('Hash{Symbol => Object}')
|
|
32
|
+
else
|
|
33
|
+
RbsTranslator.to_complex_type(param_type.type)
|
|
34
|
+
end
|
|
35
|
+
Solargraph::Pin::Parameter.new(decl: decl, name: name, closure: closure, return_type: return_type, source: :rbs, type_location: to_sg_location(param_type.location) || closure.type_location)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param method_type [RBS::MethodType]
|
|
39
|
+
# @param closure [Pin::Closure]
|
|
40
|
+
# @param parameter_names [Array<String>]
|
|
41
|
+
# @return [Array<Pin::Parameter>]
|
|
42
|
+
def self.to_parameter_pins method_type, closure, parameter_names = []
|
|
43
|
+
if defined?(RBS::Types::UntypedFunction) && method_type.type.is_a?(RBS::Types::UntypedFunction)
|
|
44
|
+
return [
|
|
45
|
+
Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: closure, source: :rbs)
|
|
46
|
+
]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
arg_num = 0
|
|
50
|
+
params = []
|
|
51
|
+
method_type.type.required_positionals.each do |param|
|
|
52
|
+
params.push RbsTranslator.to_parameter_pin(param, param.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :arg, closure)
|
|
53
|
+
arg_num += 1
|
|
54
|
+
end
|
|
55
|
+
method_type.type.optional_positionals.each do |param|
|
|
56
|
+
params.push RbsTranslator.to_parameter_pin(param, param.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :optarg, closure)
|
|
57
|
+
arg_num += 1
|
|
58
|
+
end
|
|
59
|
+
if method_type.type.rest_positionals
|
|
60
|
+
params.push RbsTranslator.to_parameter_pin(method_type.type.rest_positionals, method_type.type.rest_positionals.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :restarg, closure)
|
|
61
|
+
arg_num += 1
|
|
62
|
+
end
|
|
63
|
+
method_type.type.required_keywords.each do |param|
|
|
64
|
+
params.push RbsTranslator.to_parameter_pin(param.last, param.first.to_s, :kwarg, closure)
|
|
65
|
+
arg_num += 1
|
|
66
|
+
end
|
|
67
|
+
method_type.type.optional_keywords.each do |param|
|
|
68
|
+
params.push RbsTranslator.to_parameter_pin(param.last, param.first.to_s, :kwoptarg, closure)
|
|
69
|
+
arg_num += 1
|
|
70
|
+
end
|
|
71
|
+
if method_type.type.rest_keywords
|
|
72
|
+
params.push RbsTranslator.to_parameter_pin(method_type.type.rest_keywords, method_type.type.rest_keywords.name&.to_s || parameter_names[arg_num] || "arg_#{arg_num}", :kwrestarg, closure)
|
|
73
|
+
end
|
|
74
|
+
params
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @param method_type [RBS::MethodType]
|
|
78
|
+
# @param closure [Pin::Closure]
|
|
79
|
+
# @param parameter_names [Array<String>]
|
|
80
|
+
# @return [Pin::Signature]
|
|
81
|
+
def self.to_signature method_type, closure, parameter_names = []
|
|
82
|
+
# There may be edge cases here around different signatures
|
|
83
|
+
# having different type params / orders - we may need to match
|
|
84
|
+
# this data model and have generics live in signatures to
|
|
85
|
+
# handle those correctly
|
|
86
|
+
generics = method_type.type_params.map(&:name).map(&:to_s).uniq
|
|
87
|
+
parameters = to_parameter_pins(method_type, closure, parameter_names)
|
|
88
|
+
return_type = to_complex_type(method_type.type.return_type)
|
|
89
|
+
block = if method_type.block
|
|
90
|
+
block_parameters = to_parameter_pins(method_type.block, closure)
|
|
91
|
+
block_return_type = to_complex_type(method_type.block.type.return_type)
|
|
92
|
+
Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs, type_location: closure.location, closure: closure)
|
|
93
|
+
end
|
|
94
|
+
Pin::Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block, source: :rbs, type_location: closure.location, closure: closure)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @param type_name [RBS::TypeName]
|
|
98
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
99
|
+
# @return [ComplexType::UniqueType]
|
|
100
|
+
def self.build_unique_type(type_name, type_args = [])
|
|
101
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
102
|
+
params = type_args.map do |a|
|
|
103
|
+
RbsTranslator.to_complex_type(a)
|
|
104
|
+
end
|
|
105
|
+
if base == 'Hash' && params.length == 2
|
|
106
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
107
|
+
else
|
|
108
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# @param location [RBS::Location, nil]
|
|
113
|
+
# @return [Solargraph::Location, nil]
|
|
114
|
+
def self.to_sg_location(location)
|
|
115
|
+
return nil if location&.name.nil?
|
|
116
|
+
|
|
117
|
+
start_pos = Position.new(location.start_line - 1, location.start_column)
|
|
118
|
+
end_pos = Position.new(location.end_line - 1, location.end_column)
|
|
119
|
+
range = Range.new(start_pos, end_pos)
|
|
120
|
+
Location.new(location.name.to_s, range)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class << self
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
# @param type [RBS::Types::Bases::Base]
|
|
127
|
+
# @return [String]
|
|
128
|
+
def type_to_tag type
|
|
129
|
+
case type
|
|
130
|
+
when RBS::Types::Optional
|
|
131
|
+
"#{type_to_tag(type.type)}, nil"
|
|
132
|
+
when RBS::Types::Bases::Bool
|
|
133
|
+
'Boolean'
|
|
134
|
+
when RBS::Types::Tuple
|
|
135
|
+
"Array(#{type.types.map { |t| type_to_tag(t) }.join(', ')})"
|
|
136
|
+
when RBS::Types::Literal
|
|
137
|
+
type.literal.inspect
|
|
138
|
+
when RBS::Types::Union
|
|
139
|
+
type.types.map { |t| type_to_tag(t) }.join(', ')
|
|
140
|
+
when RBS::Types::Record
|
|
141
|
+
# @todo Better record support
|
|
142
|
+
'Hash'
|
|
143
|
+
when RBS::Types::Bases::Nil
|
|
144
|
+
'nil'
|
|
145
|
+
when RBS::Types::Bases::Void
|
|
146
|
+
'void'
|
|
147
|
+
when RBS::Types::Variable
|
|
148
|
+
"#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
|
|
149
|
+
when RBS::Types::Bases::Self, RBS::Types::Bases::Instance
|
|
150
|
+
'self'
|
|
151
|
+
when RBS::Types::Bases::Top
|
|
152
|
+
# `Top` is the most super superclass
|
|
153
|
+
'BasicObject'
|
|
154
|
+
when RBS::Types::Intersection
|
|
155
|
+
type.types.map { |member| type_to_tag(member) }.join(', ')
|
|
156
|
+
when RBS::Types::Proc
|
|
157
|
+
'Proc'
|
|
158
|
+
when RBS::Types::ClassInstance, RBS::Types::Alias, RBS::Types::Interface
|
|
159
|
+
# `Alias` is a top-level type alias, e.g., 'bool' in "type bool = true | false"
|
|
160
|
+
# @todo ensure these get resolved after processing all aliases
|
|
161
|
+
# @todo handle recursive aliases
|
|
162
|
+
#
|
|
163
|
+
# `Interface represents a mix-in module which can be considered a
|
|
164
|
+
# subtype of a consumer of it
|
|
165
|
+
#
|
|
166
|
+
type_tag(type.name, type.args)
|
|
167
|
+
when RBS::Types::ClassSingleton
|
|
168
|
+
# e.g., singleton(String)
|
|
169
|
+
type_tag(type.name)
|
|
170
|
+
when RBS::Types::Bases::Any, RBS::Types::Bases::Bottom
|
|
171
|
+
# `Bottom`` is used in contexts where nothing will ever return
|
|
172
|
+
# - e.g., it could be the return type of 'exit()' or 'raise'
|
|
173
|
+
# @todo define a specific bottom type and use it to
|
|
174
|
+
# determine dead code
|
|
175
|
+
#
|
|
176
|
+
'undefined'
|
|
177
|
+
else
|
|
178
|
+
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
|
|
179
|
+
'undefined'
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# @param type_name [RBS::TypeName]
|
|
184
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
185
|
+
# @return [String]
|
|
186
|
+
def type_tag(type_name, type_args = [])
|
|
187
|
+
build_type(type_name, type_args).tags
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @param type_name [RBS::TypeName]
|
|
191
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
192
|
+
# @return [ComplexType::UniqueType]
|
|
193
|
+
def build_type(type_name, type_args = [])
|
|
194
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
195
|
+
params = type_args.map { |a| type_to_tag(a) }.map do |t|
|
|
196
|
+
ComplexType.try_parse(t)
|
|
197
|
+
end
|
|
198
|
+
if base == 'Hash' && params.length == 2
|
|
199
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
200
|
+
else
|
|
201
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|