solargraph 0.52.0 → 0.53.4

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/CHANGELOG.md +53 -0
  6. data/README.md +13 -16
  7. data/SPONSORS.md +1 -7
  8. data/lib/solargraph/api_map/cache.rb +59 -21
  9. data/lib/solargraph/api_map/source_to_yard.rb +17 -10
  10. data/lib/solargraph/api_map/store.rb +45 -9
  11. data/lib/solargraph/api_map.rb +178 -113
  12. data/lib/solargraph/bench.rb +3 -2
  13. data/lib/solargraph/cache.rb +29 -5
  14. data/lib/solargraph/complex_type/type_methods.rb +53 -8
  15. data/lib/solargraph/complex_type/unique_type.rb +171 -58
  16. data/lib/solargraph/complex_type.rb +62 -9
  17. data/lib/solargraph/convention.rb +0 -1
  18. data/lib/solargraph/converters/dd.rb +5 -0
  19. data/lib/solargraph/converters/dl.rb +3 -0
  20. data/lib/solargraph/converters/dt.rb +3 -0
  21. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  22. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  23. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  24. data/lib/solargraph/diagnostics.rb +2 -2
  25. data/lib/solargraph/doc_map.rb +171 -0
  26. data/lib/solargraph/gem_pins.rb +64 -0
  27. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  28. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  29. data/lib/solargraph/language_server/host/dispatch.rb +15 -5
  30. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  31. data/lib/solargraph/language_server/host/sources.rb +7 -4
  32. data/lib/solargraph/language_server/host.rb +35 -7
  33. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  34. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  35. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  37. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  38. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  39. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  40. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  41. data/lib/solargraph/library.rb +71 -12
  42. data/lib/solargraph/location.rb +1 -0
  43. data/lib/solargraph/page.rb +6 -0
  44. data/lib/solargraph/parser/comment_ripper.rb +3 -0
  45. data/lib/solargraph/parser/node_methods.rb +47 -8
  46. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  47. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +29 -3
  48. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  49. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +42 -34
  50. data/lib/solargraph/parser/{legacy → parser_gem}/node_methods.rb +201 -29
  51. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  52. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  53. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  65. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  66. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  67. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  68. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  69. data/lib/solargraph/parser/parser_gem.rb +12 -0
  70. data/lib/solargraph/parser/snippet.rb +2 -0
  71. data/lib/solargraph/parser.rb +8 -11
  72. data/lib/solargraph/pin/base.rb +63 -8
  73. data/lib/solargraph/pin/base_variable.rb +7 -3
  74. data/lib/solargraph/pin/block.rb +26 -38
  75. data/lib/solargraph/pin/closure.rb +17 -2
  76. data/lib/solargraph/pin/common.rb +7 -3
  77. data/lib/solargraph/pin/conversions.rb +33 -3
  78. data/lib/solargraph/pin/documenting.rb +25 -34
  79. data/lib/solargraph/pin/instance_variable.rb +4 -0
  80. data/lib/solargraph/pin/local_variable.rb +13 -1
  81. data/lib/solargraph/pin/method.rb +110 -16
  82. data/lib/solargraph/pin/namespace.rb +16 -10
  83. data/lib/solargraph/pin/parameter.rb +41 -10
  84. data/lib/solargraph/pin/reference/override.rb +2 -2
  85. data/lib/solargraph/pin/reference.rb +8 -0
  86. data/lib/solargraph/pin/search.rb +3 -3
  87. data/lib/solargraph/pin/signature.rb +114 -2
  88. data/lib/solargraph/pin.rb +0 -1
  89. data/lib/solargraph/range.rb +2 -2
  90. data/lib/solargraph/rbs_map/conversions.rb +213 -61
  91. data/lib/solargraph/rbs_map/core_fills.rb +12 -28
  92. data/lib/solargraph/rbs_map/core_map.rb +2 -12
  93. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  94. data/lib/solargraph/rbs_map.rb +24 -12
  95. data/lib/solargraph/shell.rb +62 -59
  96. data/lib/solargraph/source/chain/array.rb +4 -1
  97. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  98. data/lib/solargraph/source/chain/call.rb +95 -26
  99. data/lib/solargraph/source/chain/constant.rb +15 -1
  100. data/lib/solargraph/source/chain/if.rb +23 -0
  101. data/lib/solargraph/source/chain/link.rb +7 -1
  102. data/lib/solargraph/source/chain/or.rb +1 -1
  103. data/lib/solargraph/source/chain/z_super.rb +2 -2
  104. data/lib/solargraph/source/chain.rb +20 -4
  105. data/lib/solargraph/source/change.rb +3 -0
  106. data/lib/solargraph/source/cursor.rb +2 -0
  107. data/lib/solargraph/source/source_chainer.rb +6 -5
  108. data/lib/solargraph/source.rb +15 -16
  109. data/lib/solargraph/source_map/clip.rb +14 -9
  110. data/lib/solargraph/source_map/mapper.rb +10 -0
  111. data/lib/solargraph/source_map.rb +12 -10
  112. data/lib/solargraph/type_checker/checks.rb +10 -2
  113. data/lib/solargraph/type_checker.rb +96 -21
  114. data/lib/solargraph/version.rb +1 -1
  115. data/lib/solargraph/workspace/config.rb +8 -6
  116. data/lib/solargraph/workspace.rb +15 -2
  117. data/lib/solargraph/yard_map/cache.rb +6 -0
  118. data/lib/solargraph/yard_map/helpers.rb +1 -1
  119. data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
  120. data/lib/solargraph/yard_map/to_method.rb +11 -4
  121. data/lib/solargraph/yard_map.rb +0 -292
  122. data/lib/solargraph/yardoc.rb +52 -0
  123. data/lib/solargraph.rb +4 -1
  124. data/solargraph.gemspec +2 -2
  125. metadata +35 -58
  126. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  127. data/lib/solargraph/documentor.rb +0 -76
  128. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  129. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  130. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  131. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  132. data/lib/solargraph/parser/legacy.rb +0 -12
  133. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -151
  134. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -163
  135. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  136. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  137. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  138. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  139. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  140. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  141. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  142. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  143. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  144. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  145. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  146. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  147. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  148. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  149. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  150. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  151. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  152. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  153. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  154. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  155. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  156. data/lib/solargraph/parser/rubyvm.rb +0 -40
  157. data/lib/solargraph/rbs_map/core_signs.rb +0 -33
@@ -1,7 +1,7 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  class Signature < Base
4
- # @return [Array<Parameter>]
4
+ # @return [::Array<Parameter>]
5
5
  attr_reader :parameters
6
6
 
7
7
  # @return [ComplexType]
@@ -10,15 +10,121 @@ module Solargraph
10
10
  # @return [self]
11
11
  attr_reader :block
12
12
 
13
+ # @param generics [Array<String>]
13
14
  # @param parameters [Array<Parameter>]
14
15
  # @param return_type [ComplexType]
15
16
  # @param block [Signature, nil]
16
- def initialize parameters, return_type, block = nil
17
+ def initialize generics, parameters, return_type, block = nil
18
+ @generics = generics
17
19
  @parameters = parameters
18
20
  @return_type = return_type
19
21
  @block = block
20
22
  end
21
23
 
24
+ def generics
25
+ @generics ||= [].freeze
26
+ end
27
+
28
+ # @return [String]
29
+ def to_rbs
30
+ rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
31
+ end
32
+
33
+ # @return [String]
34
+ def rbs_generics
35
+ if generics.empty?
36
+ return ''
37
+ else
38
+ return '[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
39
+ end
40
+ end
41
+
42
+ # @return [Array<String>]
43
+ # @yieldparam [ComplexType]
44
+ # @yieldreturn [ComplexType]
45
+ # @return [self]
46
+ def transform_types(&transform)
47
+ # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
48
+ signature = super(&transform)
49
+ signature.parameters = signature.parameters.map do |param|
50
+ param.transform_types(&transform)
51
+ end
52
+ signature.block = block.transform_types(&transform) if signature.block?
53
+ signature
54
+ end
55
+
56
+ # @param generics_to_resolve [Enumerable<String>]
57
+ # @param arg_types [Array<ComplexType>, nil]
58
+ # @param return_type_context [ComplexType, nil]
59
+ # @param yield_arg_types [Array<ComplexType>, nil]
60
+ # @param yield_return_type_context [ComplexType, nil]
61
+ # @param context [ComplexType, nil]
62
+ # @param resolved_generic_values [Hash{String => ComplexType}]
63
+ # @return [self]
64
+ def resolve_generics_from_context(generics_to_resolve,
65
+ arg_types = nil,
66
+ return_type_context = nil,
67
+ yield_arg_types = nil,
68
+ yield_return_type_context = nil,
69
+ resolved_generic_values: {})
70
+ signature = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values)
71
+ signature.parameters = signature.parameters.each_with_index.map do |param, i|
72
+ if arg_types.nil?
73
+ param.dup
74
+ else
75
+ param.resolve_generics_from_context(generics_to_resolve,
76
+ arg_types[i],
77
+ resolved_generic_values: resolved_generic_values)
78
+ end
79
+ end
80
+ signature.block = block.resolve_generics_from_context(generics_to_resolve,
81
+ yield_arg_types,
82
+ yield_return_type_context,
83
+ resolved_generic_values: resolved_generic_values) if signature.block?
84
+ signature
85
+ end
86
+
87
+ # @param generics_to_resolve [Enumerable<String>]
88
+ # @param arg_types [Array<ComplexType>, nil]
89
+ # @param return_type_context [ComplexType, nil]
90
+ # @param yield_arg_types [Array<ComplexType>, nil]
91
+ # @param yield_return_type_context [ComplexType, nil]
92
+ # @param context [ComplexType, nil]
93
+ # @param resolved_generic_values [Hash{String => ComplexType}]
94
+ # @return [self]
95
+ def resolve_generics_from_context_until_complete(generics_to_resolve,
96
+ arg_types = nil,
97
+ return_type_context = nil,
98
+ yield_arg_types = nil,
99
+ yield_return_type_context = nil,
100
+ resolved_generic_values: {})
101
+ # See
102
+ # https://github.com/soutaro/steep/tree/master/lib/steep/type_inference
103
+ # and
104
+ # https://github.com/sorbet/sorbet/blob/master/infer/inference.cc
105
+ # for other implementations
106
+
107
+ return self if generics_to_resolve.empty?
108
+
109
+ last_resolved_generic_values = resolved_generic_values.dup
110
+ new_pin = resolve_generics_from_context(generics_to_resolve,
111
+ arg_types,
112
+ return_type_context,
113
+ yield_arg_types,
114
+ yield_return_type_context,
115
+ resolved_generic_values: resolved_generic_values)
116
+ if last_resolved_generic_values == resolved_generic_values
117
+ # erase anything unresolved
118
+ return new_pin.erase_generics(self.generics)
119
+ end
120
+ new_pin.resolve_generics_from_context_until_complete(generics_to_resolve,
121
+ arg_types,
122
+ return_type_context,
123
+ yield_arg_types,
124
+ yield_return_type_context,
125
+ resolved_generic_values: resolved_generic_values)
126
+ end
127
+
22
128
  def identity
23
129
  @identity ||= "signature#{object_id}"
24
130
  end
@@ -26,6 +132,12 @@ module Solargraph
26
132
  def block?
27
133
  !!@block
28
134
  end
135
+
136
+ protected
137
+
138
+ attr_writer :block
139
+
140
+ attr_writer :parameters
29
141
  end
30
142
  end
31
143
  end
@@ -27,7 +27,6 @@ module Solargraph
27
27
  autoload :Reference, 'solargraph/pin/reference'
28
28
  autoload :Documenting, 'solargraph/pin/documenting'
29
29
  autoload :Block, 'solargraph/pin/block'
30
- autoload :Localized, 'solargraph/pin/localized'
31
30
  autoload :ProxyType, 'solargraph/pin/proxy_type'
32
31
  autoload :DuckMethod, 'solargraph/pin/duck_method'
33
32
  autoload :Singleton, 'solargraph/pin/singleton'
@@ -62,8 +62,8 @@ module Solargraph
62
62
 
63
63
  # Get a range from a node.
64
64
  #
65
- # @param node [RubyVM::AbstractSyntaxTree::Node, Parser::AST::Node]
66
- # @return [Range]
65
+ # @param node [Parser::AST::Node]
66
+ # @return [Range, nil]
67
67
  def self.from_node node
68
68
  if Parser.rubyvm? && node.is_a?(RubyVM::AbstractSyntaxTree::Node)
69
69
  Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
@@ -27,7 +27,7 @@ module Solargraph
27
27
 
28
28
  private
29
29
 
30
- # @return Hash{String => RBS::AST::Declarations::TypeAlias}
30
+ # @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
31
31
  def type_aliases
32
32
  @type_aliases ||= {}
33
33
  end
@@ -39,24 +39,7 @@ module Solargraph
39
39
  cursor = pins.length
40
40
  environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
41
41
  added_pins = pins[cursor..-1]
42
- add_back_implicit_pins(added_pins)
43
- end
44
-
45
- # @param added_pins [Range<Pin>]
46
- # @return [void]
47
- def add_back_implicit_pins(added_pins)
48
- added_pins.each do |pin|
49
- pin.source = :rbs
50
- next unless pin.is_a?(Pin::Namespace) && pin.type == :class
51
- next if pins.any? { |p| p.path == "#{pin.path}.new"}
52
- pins.push Solargraph::Pin::Method.new(
53
- location: nil,
54
- closure: pin,
55
- name: 'new',
56
- comments: pin.comments,
57
- scope: :class
58
- )
59
- end
42
+ added_pins.each { |pin| pin.source = :rbs }
60
43
  end
61
44
 
62
45
  # @param decl [RBS::AST::Declarations::Base]
@@ -68,7 +51,7 @@ module Solargraph
68
51
  class_decl_to_pin decl
69
52
  when RBS::AST::Declarations::Interface
70
53
  # STDERR.puts "Skipping interface #{decl.name.relative!}"
71
- interface_decl_to_pin decl
54
+ interface_decl_to_pin decl, closure
72
55
  when RBS::AST::Declarations::TypeAlias
73
56
  type_aliases[decl.name.to_s] = decl
74
57
  when RBS::AST::Declarations::Module
@@ -77,16 +60,46 @@ module Solargraph
77
60
  constant_decl_to_pin decl
78
61
  when RBS::AST::Declarations::ClassAlias
79
62
  class_alias_decl_to_pin decl
63
+ when RBS::AST::Declarations::ModuleAlias
64
+ module_alias_decl_to_pin decl
65
+ when RBS::AST::Declarations::Global
66
+ global_decl_to_pin decl
80
67
  else
81
- Solargraph.logger.info "Skipping declaration #{decl.class}"
68
+ Solargraph.logger.warn "Skipping declaration #{decl.class}"
82
69
  end
83
70
  end
84
71
 
85
- def convert_members_to_pin decl, closure
72
+ # @param decl [RBS::AST::Declarations::Module]
73
+ # @param module_pin [Pin::Namespace]
74
+ # @return [void]
75
+ def convert_self_types_to_pins decl, module_pin
76
+ decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) }
77
+ end
78
+
79
+ # @param decl [RBS::AST::Declarations::Module::Self]
80
+ # @param closure [Pin::Namespace]
81
+ # @return [void]
82
+ def convert_self_type_to_pins decl, closure
83
+ include_pin = Solargraph::Pin::Reference::Include.new(
84
+ name: decl.name.relative!.to_s,
85
+ location: rbs_location_to_location(decl.location),
86
+ closure: closure
87
+ )
88
+ pins.push include_pin
89
+ end
90
+
91
+ # @param decl [RBS::AST::Declarations::Module,RBS::AST::Declarations::Class,RBS::AST::Declarations::Interface]
92
+ # @param closure [Pin::Namespace]
93
+ # @return [void]
94
+ def convert_members_to_pins decl, closure
86
95
  context = Context.new
87
96
  decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
88
97
  end
89
98
 
99
+ # @param member [RBS::AST::Members::Base,RBS::AST::Declarations::Base]
100
+ # @param closure [Pin::Namespace]
101
+ # @param context [Context]
102
+ # @return [void]
90
103
  def convert_member_to_pin member, closure, context
91
104
  case member
92
105
  when RBS::AST::Members::MethodDefinition
@@ -105,6 +118,10 @@ module Solargraph
105
118
  extend_to_pin(member, closure)
106
119
  when RBS::AST::Members::Alias
107
120
  alias_to_pin(member, closure)
121
+ when RBS::AST::Members::ClassInstanceVariable
122
+ civar_to_pin(member, closure)
123
+ when RBS::AST::Members::ClassVariable
124
+ cvar_to_pin(member, closure)
108
125
  when RBS::AST::Members::InstanceVariable
109
126
  ivar_to_pin(member, closure)
110
127
  when RBS::AST::Members::Public
@@ -114,7 +131,7 @@ module Solargraph
114
131
  when RBS::AST::Declarations::Base
115
132
  convert_decl_to_pin(member, closure)
116
133
  else
117
- Solargraph.logger.warn "Skipping member #{member.class}"
134
+ Solargraph.logger.warn "Skipping member type #{member.class}"
118
135
  end
119
136
  context
120
137
  end
@@ -127,6 +144,9 @@ module Solargraph
127
144
  name: decl.name.relative!.to_s,
128
145
  closure: Solargraph::Pin::ROOT_PIN,
129
146
  comments: decl.comment&.string,
147
+ # @todo some type parameters in core/stdlib have default
148
+ # values; Solargraph doesn't support that yet as so these
149
+ # get treated as undefined if not specified
130
150
  generics: decl.type_params.map(&:name).map(&:to_s)
131
151
  )
132
152
  pins.push class_pin
@@ -136,24 +156,27 @@ module Solargraph
136
156
  name: decl.super_class.name.relative!.to_s
137
157
  )
138
158
  end
139
- convert_members_to_pin decl, class_pin
159
+ add_mixins decl, class_pin
160
+ convert_members_to_pins decl, class_pin
140
161
  end
141
162
 
142
163
  # @param decl [RBS::AST::Declarations::Interface]
164
+ # @param closure [Pin::Closure]
143
165
  # @return [void]
144
- def interface_decl_to_pin decl
166
+ def interface_decl_to_pin decl, closure
145
167
  class_pin = Solargraph::Pin::Namespace.new(
146
168
  type: :module,
147
169
  name: decl.name.relative!.to_s,
148
170
  closure: Solargraph::Pin::ROOT_PIN,
149
171
  comments: decl.comment&.string,
172
+ generics: decl.type_params.map(&:name).map(&:to_s),
150
173
  # HACK: Using :hidden to keep interfaces from appearing in
151
174
  # autocompletion
152
175
  visibility: :hidden
153
176
  )
154
177
  class_pin.docstring.add_tag(YARD::Tags::Tag.new(:abstract, '(RBS interface)'))
155
178
  pins.push class_pin
156
- convert_members_to_pin decl, class_pin
179
+ convert_members_to_pins decl, class_pin
157
180
  end
158
181
 
159
182
  # @param decl [RBS::AST::Declarations::Module]
@@ -167,15 +190,19 @@ module Solargraph
167
190
  generics: decl.type_params.map(&:name).map(&:to_s),
168
191
  )
169
192
  pins.push module_pin
170
- convert_members_to_pin decl, module_pin
193
+ convert_self_types_to_pins decl, module_pin
194
+ convert_members_to_pins decl, module_pin
195
+
196
+ add_mixins decl, module_pin.closure
171
197
  end
172
198
 
173
199
  # @param name [String]
174
200
  # @param tag [String]
175
201
  # @param comments [String]
202
+ # @param base [String, nil] Optional conversion of tag to base<tag>
176
203
  #
177
204
  # @return [Solargraph::Pin::Constant]
178
- def create_constant(name, tag, comments)
205
+ def create_constant(name, tag, comments, base = nil)
179
206
  parts = name.split('::')
180
207
  if parts.length > 1
181
208
  name = parts.last
@@ -189,8 +216,8 @@ module Solargraph
189
216
  closure: closure,
190
217
  comments: comments
191
218
  )
192
- # @todo Class or Module?
193
- constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>"))
219
+ tag = "#{base}<#{tag}>" if base
220
+ constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', tag))
194
221
  constant_pin
195
222
  end
196
223
 
@@ -201,7 +228,17 @@ module Solargraph
201
228
  new_name = decl.new_name.relative!.to_s
202
229
  old_name = decl.old_name.relative!.to_s
203
230
 
204
- pins.push create_constant(new_name, old_name, decl.comment&.string)
231
+ pins.push create_constant(new_name, old_name, decl.comment&.string, 'Class')
232
+ end
233
+
234
+ # @param decl [RBS::AST::Declarations::ModuleAlias]
235
+ # @return [void]
236
+ def module_alias_decl_to_pin decl
237
+ # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ModuleAlias
238
+ new_name = decl.new_name.relative!.to_s
239
+ old_name = decl.old_name.relative!.to_s
240
+
241
+ pins.push create_constant(new_name, old_name, decl.comment&.string, 'Module')
205
242
  end
206
243
 
207
244
  # @param decl [RBS::AST::Declarations::Constant]
@@ -211,40 +248,46 @@ module Solargraph
211
248
  pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string)
212
249
  end
213
250
 
251
+ # @param decl [RBS::AST::Declarations::Global]
252
+ # @return [void]
253
+ def global_decl_to_pin decl
254
+ closure = Solargraph::Pin::ROOT_PIN
255
+ name = decl.name.to_s
256
+ tag = other_type_to_tag(decl.type)
257
+ pin = Solargraph::Pin::GlobalVariable.new(
258
+ name: name,
259
+ closure: closure,
260
+ comments: decl.comment&.string,
261
+ )
262
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', tag))
263
+ pins.push pin
264
+ end
265
+
214
266
  # @param decl [RBS::AST::Members::MethodDefinition]
215
267
  # @param closure [Pin::Closure]
216
268
  # @return [void]
217
269
  def method_def_to_pin decl, closure
270
+ # there may be edge cases here around different signatures
271
+ # having different type params / orders - we may need to match
272
+ # this data model and have generics live in signatures to
273
+ # handle those correctly
274
+ generics = decl.overloads.map(&:method_type).flat_map(&:type_params).map(&:name).map(&:to_s).uniq
218
275
  if decl.instance?
219
276
  pin = Solargraph::Pin::Method.new(
220
277
  name: decl.name.to_s,
221
278
  closure: closure,
222
279
  comments: decl.comment&.string,
223
280
  scope: :instance,
224
- signatures: []
281
+ signatures: [],
282
+ generics: generics,
283
+ # @todo RBS core has unreliable visibility definitions
284
+ visibility: closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name) ? :private : :public
225
285
  )
226
286
  pin.signatures.concat method_def_to_sigs(decl, pin)
227
287
  pins.push pin
228
288
  if pin.name == 'initialize'
229
- pins.push Solargraph::Pin::Method.new(
230
- location: pin.location,
231
- closure: pin.closure,
232
- name: 'new',
233
- comments: pin.comments,
234
- scope: :class,
235
- signatures: pin.signatures
236
- )
237
- pins.last.signatures.replace(
238
- pin.signatures.map do |p|
239
- Pin::Signature.new(
240
- p.parameters,
241
- ComplexType::SELF
242
- )
243
- end
244
- )
245
- # @todo Is this necessary?
246
- # pin.instance_variable_set(:@visibility, :private)
247
- # pin.instance_variable_set(:@return_type, ComplexType::VOID)
289
+ pin.instance_variable_set(:@visibility, :private)
290
+ pin.instance_variable_set(:@return_type, ComplexType::VOID)
248
291
  end
249
292
  end
250
293
  if decl.singleton?
@@ -253,7 +296,8 @@ module Solargraph
253
296
  closure: closure,
254
297
  comments: decl.comment&.string,
255
298
  scope: :class,
256
- signatures: []
299
+ signatures: [],
300
+ generics: generics
257
301
  )
258
302
  pin.signatures.concat method_def_to_sigs(decl, pin)
259
303
  pins.push pin
@@ -262,17 +306,33 @@ module Solargraph
262
306
 
263
307
  # @param decl [RBS::AST::Members::MethodDefinition]
264
308
  # @param pin [Pin::Method]
309
+ # @return [void]
265
310
  def method_def_to_sigs decl, pin
266
311
  decl.overloads.map do |overload|
312
+ generics = overload.method_type.type_params.map(&:to_s)
267
313
  parameters, return_type = parts_of_function(overload.method_type, pin)
268
314
  block = if overload.method_type.block
269
- Pin::Signature.new(*parts_of_function(overload.method_type.block, pin))
315
+ Pin::Signature.new(generics, *parts_of_function(overload.method_type.block, pin))
270
316
  end
271
317
  return_type = ComplexType.try_parse(method_type_to_tag(overload.method_type))
272
- Pin::Signature.new(parameters, return_type, block)
318
+ Pin::Signature.new(generics, parameters, return_type, block)
273
319
  end
274
320
  end
275
321
 
322
+ # @param location [RBS::Location, nil]
323
+ # @return [Solargraph::Location, nil]
324
+ def rbs_location_to_location(location)
325
+ return nil if location&.name.nil?
326
+
327
+ start_pos = Position.new(location.start_line - 1, location.start_column)
328
+ end_pos = Position.new(location.end_line - 1, location.end_column)
329
+ range = Range.new(start_pos, end_pos)
330
+ Location.new(location.name, range)
331
+ end
332
+
333
+ # @param type [RBS::MethodType,RBS::Types::Block]
334
+ # @param pin [Pin::Method]
335
+ # @return [Array<Array<Pin::Parameter>, ComplexType>]
276
336
  def parts_of_function type, pin
277
337
  return [[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin)], ComplexType.try_parse(method_type_to_tag(type))] if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
278
338
 
@@ -313,6 +373,9 @@ module Solargraph
313
373
  [parameters, return_type]
314
374
  end
315
375
 
376
+ # @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
377
+ # @param closure [Pin::Namespace]
378
+ # @return [void]
316
379
  def attr_reader_to_pin(decl, closure)
317
380
  pin = Solargraph::Pin::Method.new(
318
381
  name: decl.name.to_s,
@@ -325,6 +388,9 @@ module Solargraph
325
388
  pins.push pin
326
389
  end
327
390
 
391
+ # @param decl [RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
392
+ # @param closure [Pin::Namespace]
393
+ # @return [void]
328
394
  def attr_writer_to_pin(decl, closure)
329
395
  pin = Solargraph::Pin::Method.new(
330
396
  name: "#{decl.name.to_s}=",
@@ -337,11 +403,17 @@ module Solargraph
337
403
  pins.push pin
338
404
  end
339
405
 
406
+ # @param decl [RBS::AST::Members::AttrAccessor]
407
+ # @param closure [Pin::Namespace]
408
+ # @return [void]
340
409
  def attr_accessor_to_pin(decl, closure)
341
410
  attr_reader_to_pin(decl, closure)
342
411
  attr_writer_to_pin(decl, closure)
343
412
  end
344
413
 
414
+ # @param decl [RBS::AST::Members::InstanceVariable]
415
+ # @param closure [Pin::Namespace]
416
+ # @return [void]
345
417
  def ivar_to_pin(decl, closure)
346
418
  pin = Solargraph::Pin::InstanceVariable.new(
347
419
  name: decl.name.to_s,
@@ -352,13 +424,50 @@ module Solargraph
352
424
  pins.push pin
353
425
  end
354
426
 
427
+ # @param decl [RBS::AST::Members::ClassVariable]
428
+ # @param closure [Pin::Namespace]
429
+ # @return [void]
430
+ def cvar_to_pin(decl, closure)
431
+ name = decl.name.to_s
432
+ pin = Solargraph::Pin::ClassVariable.new(
433
+ name: name,
434
+ closure: closure,
435
+ comments: decl.comment&.string
436
+ )
437
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
438
+ pins.push pin
439
+ end
440
+
441
+ # @param decl [RBS::AST::Members::ClassInstanceVariable]
442
+ # @param closure [Pin::Namespace]
443
+ # @return [void]
444
+ def civar_to_pin(decl, closure)
445
+ name = decl.name.to_s
446
+ pin = Solargraph::Pin::InstanceVariable.new(
447
+ name: name,
448
+ closure: closure,
449
+ comments: decl.comment&.string
450
+ )
451
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
452
+ pins.push pin
453
+ end
454
+
455
+ # @param decl [RBS::AST::Members::Include]
456
+ # @param closure [Pin::Namespace]
457
+ # @return [void]
355
458
  def include_to_pin decl, closure
459
+ type = generic_type(decl.name, decl.args)
460
+ generic_values = type.all_params.map(&:to_s)
356
461
  pins.push Solargraph::Pin::Reference::Include.new(
357
462
  name: decl.name.relative!.to_s,
463
+ generic_values: generic_values,
358
464
  closure: closure
359
465
  )
360
466
  end
361
467
 
468
+ # @param decl [RBS::AST::Members::Prepend]
469
+ # @param closure [Pin::Namespace]
470
+ # @return [void]
362
471
  def prepend_to_pin decl, closure
363
472
  pins.push Solargraph::Pin::Reference::Prepend.new(
364
473
  name: decl.name.relative!.to_s,
@@ -366,6 +475,9 @@ module Solargraph
366
475
  )
367
476
  end
368
477
 
478
+ # @param decl [RBS::AST::Members::Extend]
479
+ # @param closure [Pin::Namespace]
480
+ # @return [void]
369
481
  def extend_to_pin decl, closure
370
482
  pins.push Solargraph::Pin::Reference::Extend.new(
371
483
  name: decl.name.relative!.to_s,
@@ -374,6 +486,8 @@ module Solargraph
374
486
  end
375
487
 
376
488
  # @param decl [RBS::AST::Members::Alias]
489
+ # @param closure [Pin::Namespace]
490
+ # @return [void]
377
491
  def alias_to_pin decl, closure
378
492
  pins.push Solargraph::Pin::MethodAlias.new(
379
493
  name: decl.new_name.to_s,
@@ -390,7 +504,7 @@ module Solargraph
390
504
  'NilClass' => 'nil'
391
505
  }
392
506
 
393
- # @param type [RBS::AST::Members::MethodDefinition::Overload]
507
+ # @param type [RBS::MethodType]
394
508
  # @return [String]
395
509
  def method_type_to_tag type
396
510
  if type_aliases.key?(type.type.return_type.to_s)
@@ -400,6 +514,25 @@ module Solargraph
400
514
  end
401
515
  end
402
516
 
517
+ # @param type_name [RBS::TypeName]
518
+ # @param type_args [Enumerable<RBS::Types::Bases::Base>]
519
+ # @return [ComplexType]
520
+ def generic_type(type_name, type_args)
521
+ base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
522
+ params = type_args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
523
+ params_str = params.empty? ? '' : "<#{params.join(', ')}>"
524
+ type_string = "#{base}#{params_str}"
525
+ ComplexType.parse(type_string)
526
+ end
527
+
528
+ # @param type_name [RBS::TypeName]
529
+ # @param type_args [Enumerable<RBS::Types::Bases::Base>]
530
+ # @return [String]
531
+ def generic_type_tag(type_name, type_args)
532
+ generic_type(type_name, type_args).tag
533
+ end
534
+
535
+ # @param type [RBS::Types::Bases::Base]
403
536
  # @return [String]
404
537
  def other_type_to_tag type
405
538
  if type.is_a?(RBS::Types::Optional)
@@ -427,14 +560,19 @@ module Solargraph
427
560
  elsif type.is_a?(RBS::Types::Variable)
428
561
  "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
429
562
  elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
430
- base = RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
431
- params = type.args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
432
- return base if params.empty?
433
- "#{base}<#{params.join(', ')}>"
563
+ generic_type_tag(type.name, type.args)
434
564
  elsif type.is_a?(RBS::Types::Bases::Instance)
435
565
  'self'
436
- elsif type.is_a?(RBS::Types::Bases::Top) || type.is_a?(RBS::Types::Bases::Bottom)
437
- 'self'
566
+ elsif type.is_a?(RBS::Types::Bases::Top)
567
+ # top is the most super superclass
568
+ 'BasicObject'
569
+ elsif type.is_a?(RBS::Types::Bases::Bottom)
570
+ # bottom is used in contexts where nothing will ever return
571
+ # - e.g., it could be the return type of 'exit()' or 'raise'
572
+ #
573
+ # @todo define a specific bottom type and use it to
574
+ # determine dead code
575
+ 'undefined'
438
576
  elsif type.is_a?(RBS::Types::Intersection)
439
577
  type.types.map { |member| other_type_to_tag(member) }.join(', ')
440
578
  elsif type.is_a?(RBS::Types::Proc)
@@ -446,6 +584,20 @@ module Solargraph
446
584
  'undefined'
447
585
  end
448
586
  end
587
+
588
+ # @param decl [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
589
+ # @param closure [Pin::Namespace]
590
+ # @return [void]
591
+ def add_mixins decl, namespace
592
+ decl.each_mixin do |mixin|
593
+ klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
594
+ pins.push klass.new(
595
+ name: mixin.name.relative!.to_s,
596
+ location: rbs_location_to_location(mixin.location),
597
+ closure: namespace
598
+ )
599
+ end
600
+ end
449
601
  end
450
602
  end
451
603
  end