solargraph 0.54.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +58 -0
  3. data/lib/solargraph/api_map/cache.rb +10 -1
  4. data/lib/solargraph/api_map/index.rb +167 -0
  5. data/lib/solargraph/api_map/store.rb +75 -122
  6. data/lib/solargraph/api_map.rb +109 -41
  7. data/lib/solargraph/bench.rb +17 -1
  8. data/lib/solargraph/complex_type/type_methods.rb +17 -11
  9. data/lib/solargraph/complex_type/unique_type.rb +181 -17
  10. data/lib/solargraph/complex_type.rb +103 -24
  11. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +51 -0
  12. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
  13. data/lib/solargraph/convention/struct_definition.rb +101 -0
  14. data/lib/solargraph/convention.rb +2 -0
  15. data/lib/solargraph/doc_map.rb +43 -18
  16. data/lib/solargraph/equality.rb +33 -0
  17. data/lib/solargraph/language_server/host/message_worker.rb +51 -5
  18. data/lib/solargraph/language_server/host.rb +13 -11
  19. data/lib/solargraph/language_server/message/base.rb +19 -12
  20. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  21. data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
  22. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  23. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  24. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
  25. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  26. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  27. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  28. data/lib/solargraph/language_server/progress.rb +19 -2
  29. data/lib/solargraph/library.rb +31 -41
  30. data/lib/solargraph/location.rb +29 -1
  31. data/lib/solargraph/parser/comment_ripper.rb +11 -6
  32. data/lib/solargraph/parser/flow_sensitive_typing.rb +226 -0
  33. data/lib/solargraph/parser/node_methods.rb +15 -1
  34. data/lib/solargraph/parser/parser_gem/class_methods.rb +11 -6
  35. data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
  36. data/lib/solargraph/parser/parser_gem/node_methods.rb +6 -4
  37. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  38. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
  39. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +21 -1
  40. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
  41. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
  42. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +26 -5
  43. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
  44. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
  45. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +28 -0
  46. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +28 -0
  47. data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
  48. data/lib/solargraph/parser.rb +3 -5
  49. data/lib/solargraph/pin/base.rb +47 -17
  50. data/lib/solargraph/pin/base_variable.rb +11 -4
  51. data/lib/solargraph/pin/block.rb +8 -26
  52. data/lib/solargraph/pin/breakable.rb +9 -0
  53. data/lib/solargraph/pin/callable.rb +147 -0
  54. data/lib/solargraph/pin/closure.rb +8 -3
  55. data/lib/solargraph/pin/common.rb +2 -6
  56. data/lib/solargraph/pin/conversions.rb +3 -2
  57. data/lib/solargraph/pin/instance_variable.rb +2 -2
  58. data/lib/solargraph/pin/local_variable.rb +7 -1
  59. data/lib/solargraph/pin/method.rb +76 -48
  60. data/lib/solargraph/pin/namespace.rb +14 -11
  61. data/lib/solargraph/pin/parameter.rb +24 -17
  62. data/lib/solargraph/pin/proxy_type.rb +13 -7
  63. data/lib/solargraph/pin/signature.rb +3 -129
  64. data/lib/solargraph/pin/until.rb +18 -0
  65. data/lib/solargraph/pin/while.rb +18 -0
  66. data/lib/solargraph/pin.rb +7 -1
  67. data/lib/solargraph/position.rb +7 -0
  68. data/lib/solargraph/range.rb +9 -4
  69. data/lib/solargraph/rbs_map/conversions.rb +84 -45
  70. data/lib/solargraph/rbs_map/core_fills.rb +16 -9
  71. data/lib/solargraph/rbs_map.rb +1 -0
  72. data/lib/solargraph/shell.rb +19 -2
  73. data/lib/solargraph/source/chain/array.rb +10 -8
  74. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  75. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  76. data/lib/solargraph/source/chain/call.rb +125 -61
  77. data/lib/solargraph/source/chain/constant.rb +1 -1
  78. data/lib/solargraph/source/chain/hash.rb +8 -2
  79. data/lib/solargraph/source/chain/if.rb +5 -0
  80. data/lib/solargraph/source/chain/link.rb +28 -5
  81. data/lib/solargraph/source/chain/literal.rb +27 -2
  82. data/lib/solargraph/source/chain/or.rb +1 -1
  83. data/lib/solargraph/source/chain/z_super.rb +1 -1
  84. data/lib/solargraph/source/chain.rb +131 -63
  85. data/lib/solargraph/source/cursor.rb +3 -2
  86. data/lib/solargraph/source/source_chainer.rb +2 -2
  87. data/lib/solargraph/source.rb +104 -86
  88. data/lib/solargraph/source_map/clip.rb +8 -6
  89. data/lib/solargraph/source_map/data.rb +30 -0
  90. data/lib/solargraph/source_map.rb +28 -16
  91. data/lib/solargraph/type_checker/checks.rb +4 -0
  92. data/lib/solargraph/type_checker/rules.rb +6 -1
  93. data/lib/solargraph/type_checker.rb +48 -21
  94. data/lib/solargraph/version.rb +1 -1
  95. data/lib/solargraph/views/environment.erb +3 -5
  96. data/lib/solargraph/workspace/config.rb +7 -3
  97. data/lib/solargraph/workspace.rb +1 -1
  98. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
  99. data/lib/solargraph/yard_map/mapper/to_method.rb +42 -15
  100. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  101. data/lib/solargraph/yard_map/mapper.rb +1 -0
  102. data/lib/solargraph/yardoc.rb +1 -1
  103. data/lib/solargraph.rb +1 -0
  104. data/solargraph.gemspec +5 -5
  105. metadata +41 -25
@@ -2,7 +2,9 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class Block < Closure
5
+ class Block < Callable
6
+ include Breakable
7
+
6
8
  # @return [Parser::AST::Node]
7
9
  attr_reader :receiver
8
10
 
@@ -14,10 +16,9 @@ module Solargraph
14
16
  # @param context [ComplexType, nil]
15
17
  # @param args [::Array<Parameter>]
16
18
  def initialize receiver: nil, args: [], context: nil, node: nil, **splat
17
- super(**splat)
19
+ super(**splat, parameters: args)
18
20
  @receiver = receiver
19
21
  @context = context
20
- @parameters = args
21
22
  @return_type = ComplexType.parse('::Proc')
22
23
  @node = node
23
24
  end
@@ -32,38 +33,19 @@ module Solargraph
32
33
  @rebind&.defined? ? @rebind : closure.binder
33
34
  end
34
35
 
35
- # @return [::Array<Parameter>]
36
- def parameters
37
- @parameters ||= []
38
- end
39
-
40
- # @return [::Array<String>]
41
- def parameter_names
42
- @parameter_names ||= parameters.map(&:name)
43
- end
44
-
45
36
  # @param yield_types [::Array<ComplexType>]
46
37
  # @param parameters [::Array<Parameter>]
47
38
  #
48
39
  # @return [::Array<ComplexType>]
49
40
  def destructure_yield_types(yield_types, parameters)
50
- return yield_types if yield_types.length == parameters.length
51
-
52
41
  # yielding a tuple into a block will destructure the tuple
53
42
  if yield_types.length == 1
54
43
  yield_type = yield_types.first
55
44
  return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
56
45
  end
57
- parameters.map { ComplexType::UNDEFINED }
46
+ parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
58
47
  end
59
48
 
60
- # @todo the next step with parameters, arguments, destructuring,
61
- # kwargs, etc logic is probably either creating a Parameters
62
- # or Callable pin that encapsulates and shares the logic
63
- # between methods, blocks and signatures. It could live in
64
- # Signature if Method didn't also own potentially different
65
- # set of parameters, generics and return types.
66
-
67
49
  # @param api_map [ApiMap]
68
50
  # @return [::Array<ComplexType>]
69
51
  def typify_parameters(api_map)
@@ -87,7 +69,7 @@ module Solargraph
87
69
  namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
88
70
  arg_type.resolve_generics(namespace_pin, param_type)
89
71
  else
90
- arg_type.self_to(chain.base.infer(api_map, self, locals).namespace).qualify(api_map, meth.context.namespace)
72
+ arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.context.namespace)
91
73
  end
92
74
  end
93
75
  end
@@ -105,7 +87,7 @@ module Solargraph
105
87
 
106
88
  chain = Parser.chain(receiver, location.filename)
107
89
  locals = api_map.source_map(location.filename).locals_at(location)
108
- receiver_pin = chain.define(api_map, self, locals).first
90
+ receiver_pin = chain.define(api_map, closure, locals).first
109
91
  return ComplexType::UNDEFINED unless receiver_pin
110
92
 
111
93
  types = receiver_pin.docstring.tag(:yieldreceiver)&.types
@@ -114,7 +96,7 @@ module Solargraph
114
96
  target = chain.base.infer(api_map, receiver_pin, locals)
115
97
  target = full_context unless target.defined?
116
98
 
117
- ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to(target.to_s)
99
+ ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to_type(target)
118
100
  end
119
101
  end
120
102
  end
@@ -0,0 +1,9 @@
1
+ module Solargraph
2
+ module Pin
3
+ # Mix-in for pins which enclose code which the 'break' statement works with-in - e.g., blocks, when, until, ...
4
+ module Breakable
5
+ # @return [Parser::AST::Node]
6
+ attr_reader :node
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Callable < Closure
6
+ # @return [Signature]
7
+ attr_reader :block
8
+
9
+ attr_reader :parameters
10
+
11
+ # @return [ComplexType, nil]
12
+ attr_reader :return_type
13
+
14
+ # @param block [Signature, nil]
15
+ # @param return_type [ComplexType, nil]
16
+ # @param parameters [::Array<Pin::Parameter>]
17
+ def initialize block: nil, return_type: nil, parameters: [], **splat
18
+ super(**splat)
19
+ @block = block
20
+ @return_type = return_type
21
+ @parameters = parameters
22
+ end
23
+
24
+ # @return [::Array<String>]
25
+ def parameter_names
26
+ @parameter_names ||= parameters.map(&:name)
27
+ end
28
+
29
+ # @param generics_to_resolve [Enumerable<String>]
30
+ # @param arg_types [Array<ComplexType>, nil]
31
+ # @param return_type_context [ComplexType, nil]
32
+ # @param yield_arg_types [Array<ComplexType>, nil]
33
+ # @param yield_return_type_context [ComplexType, nil]
34
+ # @param context [ComplexType, nil]
35
+ # @param resolved_generic_values [Hash{String => ComplexType}]
36
+ # @return [self]
37
+ def resolve_generics_from_context(generics_to_resolve,
38
+ arg_types = nil,
39
+ return_type_context = nil,
40
+ yield_arg_types = nil,
41
+ yield_return_type_context = nil,
42
+ resolved_generic_values: {})
43
+ callable = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values)
44
+ callable.parameters = callable.parameters.each_with_index.map do |param, i|
45
+ if arg_types.nil?
46
+ param.dup
47
+ else
48
+ param.resolve_generics_from_context(generics_to_resolve,
49
+ arg_types[i],
50
+ resolved_generic_values: resolved_generic_values)
51
+ end
52
+ end
53
+ callable.block = block.resolve_generics_from_context(generics_to_resolve,
54
+ yield_arg_types,
55
+ yield_return_type_context,
56
+ resolved_generic_values: resolved_generic_values) if callable.block?
57
+ callable
58
+ end
59
+
60
+ # @param generics_to_resolve [::Array<String>]
61
+ # @param arg_types [Array<ComplexType>, nil]
62
+ # @param return_type_context [ComplexType, nil]
63
+ # @param yield_arg_types [Array<ComplexType>, nil]
64
+ # @param yield_return_type_context [ComplexType, nil]
65
+ # @param context [ComplexType, nil]
66
+ # @param resolved_generic_values [Hash{String => ComplexType}]
67
+ # @return [self]
68
+ def resolve_generics_from_context_until_complete(generics_to_resolve,
69
+ arg_types = nil,
70
+ return_type_context = nil,
71
+ yield_arg_types = nil,
72
+ yield_return_type_context = nil,
73
+ resolved_generic_values: {})
74
+ # See
75
+ # https://github.com/soutaro/steep/tree/master/lib/steep/type_inference
76
+ # and
77
+ # https://github.com/sorbet/sorbet/blob/master/infer/inference.cc
78
+ # for other implementations
79
+
80
+ return self if generics_to_resolve.empty?
81
+
82
+ last_resolved_generic_values = resolved_generic_values.dup
83
+ new_pin = resolve_generics_from_context(generics_to_resolve,
84
+ arg_types,
85
+ return_type_context,
86
+ yield_arg_types,
87
+ yield_return_type_context,
88
+ resolved_generic_values: resolved_generic_values)
89
+ if last_resolved_generic_values == resolved_generic_values
90
+ # erase anything unresolved
91
+ return new_pin.erase_generics(self.generics)
92
+ end
93
+ new_pin.resolve_generics_from_context_until_complete(generics_to_resolve,
94
+ arg_types,
95
+ return_type_context,
96
+ yield_arg_types,
97
+ yield_return_type_context,
98
+ resolved_generic_values: resolved_generic_values)
99
+ end
100
+
101
+ # @return [Array<String>]
102
+ # @yieldparam [ComplexType]
103
+ # @yieldreturn [ComplexType]
104
+ # @return [self]
105
+ def transform_types(&transform)
106
+ # @todo 'super' alone should work here I think, but doesn't typecheck at level typed
107
+ callable = super(&transform)
108
+ callable.block = block.transform_types(&transform) if block?
109
+ callable.parameters = parameters.map do |param|
110
+ param.transform_types(&transform)
111
+ end
112
+ callable
113
+ end
114
+
115
+ # @param arguments [::Array<Chain>]
116
+ # @param with_block [Boolean]
117
+ # @return [Boolean]
118
+ def arity_matches? arguments, with_block
119
+ argcount = arguments.length
120
+ parcount = mandatory_positional_param_count
121
+ parcount -= 1 if !parameters.empty? && parameters.last.block?
122
+ return false if block? && !with_block
123
+ return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
124
+ true
125
+ end
126
+
127
+ def mandatory_positional_param_count
128
+ parameters.count(&:arg?)
129
+ end
130
+
131
+ # @return [String]
132
+ def to_rbs
133
+ rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
134
+ end
135
+
136
+ def block?
137
+ !!@block
138
+ end
139
+
140
+ protected
141
+
142
+ attr_writer :block
143
+
144
+ attr_writer :parameters
145
+ end
146
+ end
147
+ end
@@ -18,7 +18,7 @@ module Solargraph
18
18
  @context ||= begin
19
19
  result = super
20
20
  if scope == :instance
21
- Solargraph::ComplexType.parse(result.namespace)
21
+ result.reduce_class_type
22
22
  else
23
23
  result
24
24
  end
@@ -42,10 +42,15 @@ module Solargraph
42
42
  end
43
43
 
44
44
  # @return [String]
45
- def generics_as_rbs
45
+ def to_rbs
46
+ rbs_generics + return_type.to_rbs
47
+ end
48
+
49
+ # @return [String]
50
+ def rbs_generics
46
51
  return '' if generics.empty?
47
52
 
48
- generics.join(', ') + ' '
53
+ '[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
49
54
  end
50
55
  end
51
56
  end
@@ -19,7 +19,7 @@ module Solargraph
19
19
  @return_type ||= ComplexType::UNDEFINED
20
20
  end
21
21
 
22
- # @return [ComplexType, Array<UniqueType>]
22
+ # @return [ComplexType]
23
23
  def context
24
24
  # Get the static context from the nearest namespace
25
25
  @context ||= find_context
@@ -59,11 +59,7 @@ module Solargraph
59
59
  if here.is_a?(Pin::Namespace)
60
60
  return here.return_type
61
61
  elsif here.is_a?(Pin::Method)
62
- if here.scope == :instance
63
- return ComplexType.try_parse(here.context.tag)
64
- else
65
- return here.context
66
- end
62
+ return here.context
67
63
  end
68
64
  here = here.closure
69
65
  end
@@ -87,7 +87,7 @@ module Solargraph
87
87
 
88
88
  # @return [String, nil]
89
89
  def text_documentation
90
- this_path = path || return_type.tag
90
+ this_path = path || name || return_type.tag
91
91
  return nil if this_path == 'undefined'
92
92
  escape_brackets this_path
93
93
  end
@@ -105,9 +105,10 @@ module Solargraph
105
105
 
106
106
  # @return [String, nil]
107
107
  def generate_link
108
- this_path = path || return_type.tag
108
+ this_path = path || name || return_type.tag
109
109
  return nil if this_path == 'undefined'
110
110
  return nil if this_path.nil? || this_path == 'undefined'
111
+ return this_path if path.nil?
111
112
  "[#{escape_brackets(this_path).gsub('_', '\\\\_')}](solargraph:/document?query=#{CGI.escape(this_path)})"
112
113
  end
113
114
 
@@ -18,9 +18,9 @@ module Solargraph
18
18
  @context ||= begin
19
19
  result = super
20
20
  if scope == :class
21
- ComplexType.parse("Class<#{result.namespace}>")
21
+ ComplexType.parse("::Class<#{result.rooted_namespace}>")
22
22
  else
23
- ComplexType.parse("#{result.namespace}")
23
+ result.reduce_class_type
24
24
  end
25
25
  end
26
26
  end
@@ -6,13 +6,19 @@ module Solargraph
6
6
  # @return [Range]
7
7
  attr_reader :presence
8
8
 
9
+ def presence_certain?
10
+ @presence_certain
11
+ end
12
+
9
13
  # @param assignment [AST::Node, nil]
10
14
  # @param presence [Range, nil]
15
+ # @param presence_certain [Boolean]
11
16
  # @param splat [Hash]
12
- def initialize assignment: nil, presence: nil, **splat
17
+ def initialize assignment: nil, presence: nil, presence_certain: false, **splat
13
18
  super(**splat)
14
19
  @assignment = assignment
15
20
  @presence = presence
21
+ @presence_certain = presence_certain
16
22
  end
17
23
 
18
24
  # @param pin [self]
@@ -4,12 +4,9 @@ module Solargraph
4
4
  module Pin
5
5
  # The base class for method and attribute pins.
6
6
  #
7
- class Method < Closure
7
+ class Method < Callable
8
8
  include Solargraph::Parser::NodeMethods
9
9
 
10
- # @return [::Array<Pin::Parameter>]
11
- attr_reader :parameters
12
-
13
10
  # @return [::Symbol] :public, :private, or :protected
14
11
  attr_reader :visibility
15
12
 
@@ -18,24 +15,24 @@ module Solargraph
18
15
 
19
16
  # @param visibility [::Symbol] :public, :protected, or :private
20
17
  # @param explicit [Boolean]
21
- # @param parameters [::Array<Pin::Parameter>]
22
18
  # @param block [Pin::Signature, nil, ::Symbol]
23
- # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node, nil]
19
+ # @param node [Parser::AST::Node, nil]
24
20
  # @param attribute [Boolean]
25
21
  # @param signatures [::Array<Signature>, nil]
26
22
  # @param anon_splat [Boolean]
27
- # @param return_type [ComplexType, nil]
28
- def initialize visibility: :public, explicit: true, parameters: [], block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, return_type: nil, **splat
23
+ def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
29
24
  super(**splat)
30
25
  @visibility = visibility
31
26
  @explicit = explicit
32
- @parameters = parameters
33
27
  @block = block
34
28
  @node = node
35
29
  @attribute = attribute
36
30
  @signatures = signatures
37
31
  @anon_splat = anon_splat
38
- @return_type = return_type
32
+ end
33
+
34
+ def == other
35
+ super && other.node == node
39
36
  end
40
37
 
41
38
  def transform_types(&transform)
@@ -44,15 +41,16 @@ module Solargraph
44
41
  m.signatures = m.signatures.map do |sig|
45
42
  sig.transform_types(&transform)
46
43
  end
47
- m.parameters = m.parameters.map do |param|
48
- param.transform_types(&transform)
49
- end
50
44
  m.block = block&.transform_types(&transform)
51
45
  m.signature_help = nil
52
46
  m.documentation = nil
53
47
  m
54
48
  end
55
49
 
50
+ def all_rooted?
51
+ super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
52
+ end
53
+
56
54
  # @param signature [Pin::Signature]
57
55
  # @return [Pin::Method]
58
56
  def with_single_signature(signature)
@@ -71,15 +69,14 @@ module Solargraph
71
69
  m
72
70
  end
73
71
 
72
+ def block?
73
+ !block.nil?
74
+ end
75
+
74
76
  # @return [Pin::Signature, nil]
75
77
  def block
76
78
  return @block unless @block == :undefined
77
- @block = signatures.first.block
78
- end
79
-
80
- # @return [::Array<String>]
81
- def parameter_names
82
- @parameter_names ||= parameters.map(&:name)
79
+ @block = signatures.first&.block
83
80
  end
84
81
 
85
82
  def completion_item_kind
@@ -123,9 +120,9 @@ module Solargraph
123
120
  )
124
121
  end
125
122
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
126
- block = Signature.new(generics, yield_parameters, yield_return_type)
123
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
127
124
  end
128
- Signature.new(generics, parameters, return_type, block)
125
+ Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
129
126
  end
130
127
 
131
128
  # @return [::Array<Signature>]
@@ -169,9 +166,9 @@ module Solargraph
169
166
  def desc
170
167
  # ensure the signatures line up when logged
171
168
  if signatures.length > 1
172
- "\n#{to_rbs}\n"
169
+ path + " \n#{to_rbs}\n"
173
170
  else
174
- to_rbs
171
+ super
175
172
  end
176
173
  end
177
174
 
@@ -199,13 +196,14 @@ module Solargraph
199
196
  name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
200
197
  end
201
198
 
199
+ # @sg-ignore
202
200
  def documentation
203
201
  if @documentation.nil?
204
- @documentation ||= super || ''
202
+ method_docs ||= super || ''
205
203
  param_tags = docstring.tags(:param)
206
204
  unless param_tags.nil? or param_tags.empty?
207
- @documentation += "\n\n" unless @documentation.empty?
208
- @documentation += "Params:\n"
205
+ method_docs += "\n\n" unless method_docs.empty?
206
+ method_docs += "Params:\n"
209
207
  lines = []
210
208
  param_tags.each do |p|
211
209
  l = "* #{p.name}"
@@ -213,12 +211,12 @@ module Solargraph
213
211
  l += " #{p.text}"
214
212
  lines.push l
215
213
  end
216
- @documentation += lines.join("\n")
214
+ method_docs += lines.join("\n")
217
215
  end
218
216
  yieldparam_tags = docstring.tags(:yieldparam)
219
217
  unless yieldparam_tags.nil? or yieldparam_tags.empty?
220
- @documentation += "\n\n" unless @documentation.empty?
221
- @documentation += "Block Params:\n"
218
+ method_docs += "\n\n" unless method_docs.empty?
219
+ method_docs += "Block Params:\n"
222
220
  lines = []
223
221
  yieldparam_tags.each do |p|
224
222
  l = "* #{p.name}"
@@ -226,12 +224,12 @@ module Solargraph
226
224
  l += " #{p.text}"
227
225
  lines.push l
228
226
  end
229
- @documentation += lines.join("\n")
227
+ method_docs += lines.join("\n")
230
228
  end
231
229
  yieldreturn_tags = docstring.tags(:yieldreturn)
232
230
  unless yieldreturn_tags.empty?
233
- @documentation += "\n\n" unless @documentation.empty?
234
- @documentation += "Block Returns:\n"
231
+ method_docs += "\n\n" unless method_docs.empty?
232
+ method_docs += "Block Returns:\n"
235
233
  lines = []
236
234
  yieldreturn_tags.each do |r|
237
235
  l = "*"
@@ -239,12 +237,12 @@ module Solargraph
239
237
  l += " #{r.text}"
240
238
  lines.push l
241
239
  end
242
- @documentation += lines.join("\n")
240
+ method_docs += lines.join("\n")
243
241
  end
244
242
  return_tags = docstring.tags(:return)
245
243
  unless return_tags.empty?
246
- @documentation += "\n\n" unless @documentation.empty?
247
- @documentation += "Returns:\n"
244
+ method_docs += "\n\n" unless method_docs.empty?
245
+ method_docs += "Returns:\n"
248
246
  lines = []
249
247
  return_tags.each do |r|
250
248
  l = "*"
@@ -252,10 +250,11 @@ module Solargraph
252
250
  l += " #{r.text}"
253
251
  lines.push l
254
252
  end
255
- @documentation += lines.join("\n")
253
+ method_docs += lines.join("\n")
256
254
  end
257
- @documentation += "\n\n" unless @documentation.empty?
258
- @documentation += "Visibility: #{visibility}"
255
+ method_docs += "\n\n" unless method_docs.empty?
256
+ method_docs += "Visibility: #{visibility}"
257
+ @documentation = method_docs
259
258
  concat_example_tags
260
259
  end
261
260
  @documentation.to_s
@@ -269,10 +268,11 @@ module Solargraph
269
268
  @attribute
270
269
  end
271
270
 
271
+ # @parm other [Method]
272
272
  def nearly? other
273
- return false unless super
274
- parameters == other.parameters and
275
- scope == other.scope and
273
+ super &&
274
+ parameters == other.parameters &&
275
+ scope == other.scope &&
276
276
  visibility == other.visibility
277
277
  end
278
278
 
@@ -280,9 +280,11 @@ module Solargraph
280
280
  attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
281
281
  end
282
282
 
283
+ # @param pin [Pin::Method]
283
284
  def try_merge! pin
284
285
  return false unless super
285
286
  @node = pin.node
287
+ @resolved_ref_tag = false
286
288
  true
287
289
  end
288
290
 
@@ -292,8 +294,8 @@ module Solargraph
292
294
  # tag's source is likely malformed.
293
295
  @overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
294
296
  Pin::Signature.new(
295
- generics,
296
- tag.parameters.map do |src|
297
+ generics: generics,
298
+ parameters: tag.parameters.map do |src|
297
299
  name, decl = parse_overload_param(src.first)
298
300
  Pin::Parameter.new(
299
301
  location: location,
@@ -305,7 +307,7 @@ module Solargraph
305
307
  return_type: param_type_from_name(tag, src.first)
306
308
  )
307
309
  end,
308
- ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
310
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
309
311
  )
310
312
  end
311
313
  @overloads
@@ -315,12 +317,33 @@ module Solargraph
315
317
  @anon_splat
316
318
  end
317
319
 
320
+ # @param api_map [ApiMap]
321
+ # @return [self]
322
+ def resolve_ref_tag api_map
323
+ return self if @resolved_ref_tag
324
+
325
+ @resolved_ref_tag = true
326
+ return self unless docstring.ref_tags.any?
327
+ docstring.ref_tags.each do |tag|
328
+ ref = if tag.owner.to_s.start_with?(/[#\.]/)
329
+ api_map.get_methods(namespace)
330
+ .select { |pin| pin.path.end_with?(tag.owner.to_s) }
331
+ .first
332
+ else
333
+ # @todo Resolve relative namespaces
334
+ api_map.get_path_pins(tag.owner.to_s).first
335
+ end
336
+ next unless ref
337
+
338
+ docstring.add_tag(*ref.docstring.tags(:param))
339
+ end
340
+ self
341
+ end
342
+
318
343
  protected
319
344
 
320
345
  attr_writer :block
321
346
 
322
- attr_writer :parameters
323
-
324
347
  attr_writer :signatures
325
348
 
326
349
  attr_writer :signature_help
@@ -452,7 +475,7 @@ module Solargraph
452
475
  end
453
476
  result.push ComplexType::NIL if has_nil
454
477
  return ComplexType::UNDEFINED if result.empty?
455
- ComplexType.try_parse(*result.map(&:tag).uniq)
478
+ ComplexType.new(result.uniq)
456
479
  end
457
480
 
458
481
  # @param [ApiMap] api_map
@@ -467,7 +490,7 @@ module Solargraph
467
490
  types.push type if type.defined?
468
491
  end
469
492
  return ComplexType::UNDEFINED if types.empty?
470
- ComplexType.try_parse(*types.map(&:tag).uniq)
493
+ ComplexType.new(types.uniq)
471
494
  end
472
495
 
473
496
  # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
@@ -475,6 +498,7 @@ module Solargraph
475
498
  # @param name [String]
476
499
  # @return [::Array(String, ::Symbol)]
477
500
  def parse_overload_param(name)
501
+ # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
478
502
  if name.start_with?('**')
479
503
  [name[2..-1], :kwrestarg]
480
504
  elsif name.start_with?('*')
@@ -496,6 +520,10 @@ module Solargraph
496
520
  .join("\n")
497
521
  .concat("```\n")
498
522
  end
523
+
524
+ protected
525
+
526
+ attr_writer :signatures
499
527
  end
500
528
  end
501
529
  end