solargraph 0.59.2 → 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/rspec.yml +4 -1
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile +3 -0
- data/lib/solargraph/api_map/index.rb +13 -2
- data/lib/solargraph/api_map/store.rb +21 -6
- data/lib/solargraph/api_map.rb +34 -2
- data/lib/solargraph/complex_type/unique_type.rb +4 -0
- data/lib/solargraph/complex_type.rb +4 -0
- data/lib/solargraph/doc_map.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_methods.rb +42 -0
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -5
- 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/rbs_map/conversions.rb +96 -145
- data/lib/solargraph/rbs_translator.rb +206 -0
- data/lib/solargraph/shell.rb +130 -63
- data/lib/solargraph/source/chain/call.rb +8 -76
- 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/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.rb +19 -1
- data/lib/solargraph/yard_map.rb +2 -0
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +1 -0
- metadata +24 -1
|
@@ -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,23 +535,24 @@ 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]
|
|
@@ -554,38 +561,29 @@ module Solargraph
|
|
|
554
561
|
def method_def_to_sigs decl, pin
|
|
555
562
|
# rubocop:disable Style/SafeNavigationChainLength
|
|
556
563
|
implicit_nil = decl.overloads.first&.annotations&.map(&:string)&.include?('implicitly-returns-nil') || false
|
|
557
|
-
# rubocop:enable Style/SafeNavigationChainLength
|
|
558
|
-
# @param overload [RBS::AST::Members::MethodDefinition::Overload]
|
|
564
|
+
# rubocop:enable Style/SafeNavigationChainLength # @param overload [RBS::AST::Members::MethodDefinition::Overload]
|
|
559
565
|
decl.overloads.map do |overload|
|
|
560
|
-
# @sg-ignore Wrong argument type for Solargraph::RbsMap::Conversions#location_decl_to_pin_location:
|
|
561
|
-
# location expected RBS::Location, nil, received RBS::Location<:type, :type_params>, RBS::AST::Members::Attribute::loc, nil
|
|
562
566
|
type_location = location_decl_to_pin_location(overload.method_type.location)
|
|
563
|
-
generics =
|
|
567
|
+
generics = overload.method_type.type_params.map(&:name).map(&:to_s)
|
|
564
568
|
signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin, implicit_nil)
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
block_parameters, block_return_type
|
|
568
|
-
Pin::Signature.new(generics: generics, parameters: block_parameters,
|
|
569
|
-
return_type: block_return_type, source: :rbs,
|
|
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,
|
|
570
572
|
type_location: type_location, closure: pin)
|
|
571
573
|
end
|
|
572
|
-
Pin::Signature.new(generics: generics, parameters: signature_parameters,
|
|
573
|
-
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,
|
|
574
575
|
type_location: type_location, closure: pin)
|
|
575
576
|
end
|
|
576
577
|
end
|
|
577
578
|
|
|
578
579
|
# @param location [RBS::Location, nil]
|
|
579
580
|
# @return [Solargraph::Location, nil]
|
|
580
|
-
def location_decl_to_pin_location
|
|
581
|
+
def location_decl_to_pin_location(location)
|
|
581
582
|
return nil if location&.name.nil?
|
|
582
583
|
|
|
583
|
-
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
584
584
|
start_pos = Position.new(location.start_line - 1, location.start_column)
|
|
585
|
-
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
586
585
|
end_pos = Position.new(location.end_line - 1, location.end_column)
|
|
587
586
|
range = Range.new(start_pos, end_pos)
|
|
588
|
-
# @sg-ignore flow sensitve typing should handle return nil if location&.name.nil?
|
|
589
587
|
Location.new(location.name.to_s, range)
|
|
590
588
|
end
|
|
591
589
|
|
|
@@ -667,6 +665,17 @@ module Solargraph
|
|
|
667
665
|
[parameters, return_type]
|
|
668
666
|
end
|
|
669
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
|
+
|
|
670
679
|
# @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
|
|
671
680
|
# @param closure [Pin::Namespace]
|
|
672
681
|
# @param context [Context]
|
|
@@ -685,7 +694,7 @@ module Solargraph
|
|
|
685
694
|
visibility: visibility,
|
|
686
695
|
source: :rbs
|
|
687
696
|
)
|
|
688
|
-
rooted_tag =
|
|
697
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
689
698
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
690
699
|
logger.debug do
|
|
691
700
|
"Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}"
|
|
@@ -716,13 +725,13 @@ module Solargraph
|
|
|
716
725
|
pin.parameters <<
|
|
717
726
|
Solargraph::Pin::Parameter.new(
|
|
718
727
|
name: 'value',
|
|
719
|
-
return_type:
|
|
728
|
+
return_type: RbsTranslator.to_complex_type(decl.type).force_rooted,
|
|
720
729
|
source: :rbs,
|
|
721
730
|
closure: pin,
|
|
722
731
|
type_location: type_location
|
|
723
732
|
)
|
|
724
|
-
|
|
725
|
-
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))
|
|
726
735
|
pins.push pin
|
|
727
736
|
end
|
|
728
737
|
|
|
@@ -746,7 +755,7 @@ module Solargraph
|
|
|
746
755
|
comments: decl.comment&.string,
|
|
747
756
|
source: :rbs
|
|
748
757
|
)
|
|
749
|
-
rooted_tag =
|
|
758
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
750
759
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
751
760
|
pins.push pin
|
|
752
761
|
end
|
|
@@ -763,7 +772,7 @@ module Solargraph
|
|
|
763
772
|
type_location: location_decl_to_pin_location(decl.location),
|
|
764
773
|
source: :rbs
|
|
765
774
|
)
|
|
766
|
-
rooted_tag =
|
|
775
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
767
776
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
768
777
|
pins.push pin
|
|
769
778
|
end
|
|
@@ -780,7 +789,7 @@ module Solargraph
|
|
|
780
789
|
type_location: location_decl_to_pin_location(decl.location),
|
|
781
790
|
source: :rbs
|
|
782
791
|
)
|
|
783
|
-
rooted_tag =
|
|
792
|
+
rooted_tag = RbsTranslator.to_complex_type(decl.type).force_rooted.rooted_tags
|
|
784
793
|
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
785
794
|
pins.push pin
|
|
786
795
|
end
|
|
@@ -790,9 +799,9 @@ module Solargraph
|
|
|
790
799
|
# @return [void]
|
|
791
800
|
def include_to_pin decl, closure
|
|
792
801
|
type = build_type(decl.name, decl.args)
|
|
793
|
-
generic_values = type.all_params.map(&:
|
|
802
|
+
generic_values = type.all_params.map(&:to_s)
|
|
794
803
|
pins.push Solargraph::Pin::Reference::Include.new(
|
|
795
|
-
name:
|
|
804
|
+
name: decl.name.relative!.to_s,
|
|
796
805
|
type_location: location_decl_to_pin_location(decl.location),
|
|
797
806
|
generic_values: generic_values,
|
|
798
807
|
closure: closure,
|
|
@@ -807,9 +816,8 @@ module Solargraph
|
|
|
807
816
|
type = build_type(decl.name, decl.args)
|
|
808
817
|
generic_values = type.all_params.map(&:rooted_tags)
|
|
809
818
|
pins.push Solargraph::Pin::Reference::Prepend.new(
|
|
810
|
-
name:
|
|
819
|
+
name: decl.name.relative!.to_s,
|
|
811
820
|
type_location: location_decl_to_pin_location(decl.location),
|
|
812
|
-
generic_values: generic_values,
|
|
813
821
|
closure: closure,
|
|
814
822
|
source: :rbs
|
|
815
823
|
)
|
|
@@ -822,9 +830,8 @@ module Solargraph
|
|
|
822
830
|
type = build_type(decl.name, decl.args)
|
|
823
831
|
generic_values = type.all_params.map(&:rooted_tags)
|
|
824
832
|
pins.push Solargraph::Pin::Reference::Extend.new(
|
|
825
|
-
name:
|
|
833
|
+
name: decl.name.relative!.to_s,
|
|
826
834
|
type_location: location_decl_to_pin_location(decl.location),
|
|
827
|
-
generic_values: generic_values,
|
|
828
835
|
closure: closure,
|
|
829
836
|
source: :rbs
|
|
830
837
|
)
|
|
@@ -845,93 +852,37 @@ module Solargraph
|
|
|
845
852
|
)
|
|
846
853
|
end
|
|
847
854
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
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
|
|
856
863
|
|
|
857
|
-
#
|
|
858
|
-
# Note: Generally these extend from RBS::Types::Bases::Base,
|
|
859
|
-
# but not all.
|
|
864
|
+
# Extract a ComplexType from a MethodType's return type.
|
|
860
865
|
#
|
|
861
|
-
#
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
ComplexType.
|
|
879
|
-
when RBS::Types::Union
|
|
880
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
881
|
-
ComplexType.new(type.types.map { |t| other_type_to_type(t) })
|
|
882
|
-
when RBS::Types::Record
|
|
883
|
-
# @todo Better record support
|
|
884
|
-
ComplexType::UniqueType.new('Hash', rooted: true)
|
|
885
|
-
when RBS::Types::Bases::Nil
|
|
886
|
-
ComplexType::NIL
|
|
887
|
-
when RBS::Types::Bases::Self
|
|
888
|
-
ComplexType::SELF
|
|
889
|
-
when RBS::Types::Bases::Void
|
|
890
|
-
ComplexType::VOID
|
|
891
|
-
when RBS::Types::Variable
|
|
892
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
893
|
-
ComplexType.parse("generic<#{type.name}>").force_rooted
|
|
894
|
-
when RBS::Types::ClassInstance # && !type.args.empty?
|
|
895
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
896
|
-
build_type(type.name, type.args)
|
|
897
|
-
when RBS::Types::Bases::Instance
|
|
898
|
-
ComplexType::SELF
|
|
899
|
-
when RBS::Types::Bases::Top
|
|
900
|
-
# top is the most super superclass
|
|
901
|
-
ComplexType::UniqueType.new('BasicObject', rooted: true)
|
|
902
|
-
when RBS::Types::Bases::Bottom
|
|
903
|
-
# bottom is used in contexts where nothing will ever return
|
|
904
|
-
# - e.g., it could be the return type of 'exit()' or 'raise'
|
|
905
|
-
#
|
|
906
|
-
# @todo define a specific bottom type and use it to
|
|
907
|
-
# determine dead code
|
|
908
|
-
ComplexType::UNDEFINED
|
|
909
|
-
when RBS::Types::Intersection
|
|
910
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
911
|
-
ComplexType.new(type.types.map { |member| other_type_to_type(member) })
|
|
912
|
-
when RBS::Types::Proc
|
|
913
|
-
ComplexType::UniqueType.new('Proc', rooted: true)
|
|
914
|
-
when RBS::Types::Alias
|
|
915
|
-
# type-level alias use - e.g., 'bool' in "type bool = true | false"
|
|
916
|
-
# @todo ensure these get resolved after processing all aliases
|
|
917
|
-
# @todo handle recursive aliases
|
|
918
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
919
|
-
build_type(type.name, type.args)
|
|
920
|
-
when RBS::Types::Interface
|
|
921
|
-
# represents a mix-in module which can be considered a
|
|
922
|
-
# subtype of a consumer of it
|
|
923
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
924
|
-
build_type(type.name, type.args)
|
|
925
|
-
when RBS::Types::ClassSingleton
|
|
926
|
-
# e.g., singleton(String)
|
|
927
|
-
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
928
|
-
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)
|
|
929
884
|
else
|
|
930
|
-
|
|
931
|
-
#
|
|
932
|
-
# @sg-ignore all types should include location
|
|
933
|
-
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
|
|
934
|
-
ComplexType::UNDEFINED
|
|
885
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
935
886
|
end
|
|
936
887
|
end
|
|
937
888
|
|
|
@@ -944,9 +895,9 @@ module Solargraph
|
|
|
944
895
|
# @todo are we handling prepend correctly?
|
|
945
896
|
klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
|
|
946
897
|
type = build_type(mixin.name, mixin.args)
|
|
947
|
-
generic_values = type.all_params.map(&:
|
|
898
|
+
generic_values = type.all_params.map(&:to_s)
|
|
948
899
|
pins.push klass.new(
|
|
949
|
-
name:
|
|
900
|
+
name: mixin.name.relative!.to_s,
|
|
950
901
|
type_location: location_decl_to_pin_location(mixin.location),
|
|
951
902
|
generic_values: generic_values,
|
|
952
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
|