solargraph 0.44.3 → 0.49.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/rspec.yml +41 -0
  4. data/CHANGELOG.md +57 -0
  5. data/LICENSE +1 -1
  6. data/README.md +18 -2
  7. data/SPONSORS.md +2 -2
  8. data/lib/solargraph/api_map/store.rb +13 -1
  9. data/lib/solargraph/api_map.rb +57 -34
  10. data/lib/solargraph/cache.rb +51 -0
  11. data/lib/solargraph/complex_type/type_methods.rb +10 -6
  12. data/lib/solargraph/complex_type/unique_type.rb +57 -0
  13. data/lib/solargraph/complex_type.rb +35 -2
  14. data/lib/solargraph/convention/rakefile.rb +17 -0
  15. data/lib/solargraph/convention/rspec.rb +13 -4
  16. data/lib/solargraph/convention.rb +2 -0
  17. data/lib/solargraph/diagnostics/require_not_found.rb +16 -0
  18. data/lib/solargraph/diagnostics/rubocop.rb +17 -3
  19. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
  20. data/lib/solargraph/language_server/host.rb +22 -18
  21. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  22. data/lib/solargraph/language_server/message/initialize.rb +2 -0
  23. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
  24. data/lib/solargraph/language_server/message/text_document/hover.rb +16 -4
  25. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  26. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  27. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
  28. data/lib/solargraph/language_server/uri_helpers.rb +1 -1
  29. data/lib/solargraph/library.rb +21 -20
  30. data/lib/solargraph/parser/legacy/class_methods.rb +0 -5
  31. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
  32. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
  33. data/lib/solargraph/parser/rubyvm/class_methods.rb +8 -4
  34. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
  35. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -9
  36. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
  37. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +2 -2
  38. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
  39. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
  40. data/lib/solargraph/parser/rubyvm/node_processors.rb +1 -0
  41. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  42. data/lib/solargraph/pin/base.rb +5 -2
  43. data/lib/solargraph/pin/block.rb +2 -1
  44. data/lib/solargraph/pin/conversions.rb +2 -6
  45. data/lib/solargraph/pin/method.rb +100 -10
  46. data/lib/solargraph/pin/namespace.rb +4 -1
  47. data/lib/solargraph/pin/parameter.rb +10 -7
  48. data/lib/solargraph/pin/search.rb +56 -0
  49. data/lib/solargraph/pin/signature.rb +23 -0
  50. data/lib/solargraph/pin.rb +2 -0
  51. data/lib/solargraph/range.rb +1 -1
  52. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  53. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  54. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  55. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  56. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  57. data/lib/solargraph/rbs_map.rb +73 -0
  58. data/lib/solargraph/shell.rb +38 -30
  59. data/lib/solargraph/source/chain/call.rb +34 -23
  60. data/lib/solargraph/source/chain.rb +21 -6
  61. data/lib/solargraph/source.rb +1 -1
  62. data/lib/solargraph/source_map/clip.rb +5 -0
  63. data/lib/solargraph/source_map/mapper.rb +31 -2
  64. data/lib/solargraph/source_map.rb +1 -10
  65. data/lib/solargraph/type_checker/checks.rb +13 -0
  66. data/lib/solargraph/type_checker.rb +90 -61
  67. data/lib/solargraph/version.rb +1 -1
  68. data/lib/solargraph/views/environment.erb +2 -2
  69. data/lib/solargraph/workspace.rb +12 -14
  70. data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
  71. data/lib/solargraph/yard_map.rb +54 -196
  72. data/lib/solargraph.rb +4 -4
  73. data/solargraph.gemspec +8 -6
  74. metadata +46 -37
  75. data/lib/solargraph/compat.rb +0 -37
  76. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  77. data/lib/solargraph/yard_map/core_fills.rb +0 -203
  78. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  79. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  80. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  81. data/yardoc/2.2.2.tar.gz +0 -0
@@ -11,6 +11,8 @@ module Solargraph
11
11
  s_visi = region.visibility
12
12
  s_visi = :public if region.scope != :class
13
13
  loc = get_node_location(node)
14
+ anon_splat = node_has_anon_splat?
15
+
14
16
  if node.children[0].is_a?(RubyVM::AbstractSyntaxTree::Node) && node.children[0].type == :SELF
15
17
  closure = region.closure
16
18
  else
@@ -26,7 +28,8 @@ module Solargraph
26
28
  comments: comments_for(node),
27
29
  scope: :class,
28
30
  visibility: :public,
29
- node: node
31
+ node: node,
32
+ anon_splat: anon_splat
30
33
  )
31
34
  pins.push Solargraph::Pin::Method.new(
32
35
  location: loc,
@@ -35,7 +38,8 @@ module Solargraph
35
38
  comments: comments_for(node),
36
39
  scope: :instance,
37
40
  visibility: :private,
38
- node: node
41
+ node: node,
42
+ anon_splat: anon_splat
39
43
  )
40
44
  else
41
45
  pins.push Solargraph::Pin::Method.new(
@@ -45,11 +49,18 @@ module Solargraph
45
49
  comments: comments_for(node),
46
50
  scope: :class,
47
51
  visibility: s_visi,
48
- node: node
52
+ node: node,
53
+ anon_splat: anon_splat
49
54
  )
50
55
  end
51
56
  process_children region.update(closure: pins.last, scope: :class)
52
57
  end
58
+
59
+ private
60
+
61
+ def node_has_anon_splat?
62
+ node.children[2]&.children&.first == [nil]
63
+ end
53
64
  end
54
65
  end
55
66
  end
@@ -11,8 +11,8 @@ module Solargraph
11
11
  closure: region.closure,
12
12
  comments: comments_for(node),
13
13
  name: node.children[0].children[0].to_s,
14
- # assignment: require_keyword?(node) ? nil : node.children[0].children[1],
15
- asgn_code: require_keyword?(node) ? nil: region.code_for(node.children[0].children[1]),
14
+ assignment: require_keyword?(node) ? nil : node.children[0].children[1],
15
+ asgn_code: require_keyword?(node) ? nil : region.code_for(node.children[0].children[1]),
16
16
  presence: region.closure.location.range,
17
17
  decl: require_keyword?(node) ? :kwarg : :kwoptarg
18
18
  )
@@ -6,11 +6,22 @@ module Solargraph
6
6
  module NodeProcessors
7
7
  class SclassNode < Parser::NodeProcessor::Base
8
8
  def process
9
- # @todo Temporarily skipping remote metaclasses
10
- return unless node.children[0].is_a?(RubyVM::AbstractSyntaxTree::Node) && node.children[0].type == :SELF
9
+ sclass = node.children[0]
10
+ if sclass.is_a?(RubyVM::AbstractSyntaxTree::Node) && sclass.type == :SELF
11
+ closure = region.closure
12
+ elsif sclass.is_a?(RubyVM::AbstractSyntaxTree::Node) && %i[CDECL CONST].include?(sclass.type)
13
+ names = [region.closure.namespace, region.closure.name]
14
+ if names.last != sclass.children[0].to_s
15
+ names << sclass.children[0].to_s
16
+ end
17
+ name = names.reject(&:empty?).join('::')
18
+ closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location)
19
+ else
20
+ return
21
+ end
11
22
  pins.push Solargraph::Pin::Singleton.new(
12
23
  location: get_node_location(node),
13
- closure: region.closure
24
+ closure: closure
14
25
  )
15
26
  process_children region.update(visibility: :public, scope: :class, closure: pins.last)
16
27
  end
@@ -226,8 +226,10 @@ module Solargraph
226
226
 
227
227
  # @return [void]
228
228
  def process_private_constant
229
- return unless Parser.is_ast_node?(node.children.last)
230
- node.children.last.children[0..-2].each do |child|
229
+ arr = node.children[1]
230
+ return unless Parser.is_ast_node?(arr) && [:ARRAY, :LIST].include?(arr.type)
231
+
232
+ arr.children.compact.each do |child|
231
233
  if [:LIT, :STR].include?(child.type)
232
234
  cn = child.children[0].to_s
233
235
  ref = pins.select{|p| [Solargraph::Pin::Namespace, Solargraph::Pin::Constant].include?(p.class) && p.namespace == region.closure.full_context.namespace && p.name == cn}.first
@@ -45,6 +45,7 @@ module Solargraph
45
45
  register :IASGN, Rubyvm::NodeProcessors::IvasgnNode
46
46
  register :CVASGN, Rubyvm::NodeProcessors::CvasgnNode
47
47
  register :LASGN, Rubyvm::NodeProcessors::LvasgnNode
48
+ register :DASGN, Rubyvm::NodeProcessors::LvasgnNode
48
49
  register :DASGN_CURR, Rubyvm::NodeProcessors::LvasgnNode
49
50
  register :GASGN, Rubyvm::NodeProcessors::GvasgnNode
50
51
  register :CDECL, Rubyvm::NodeProcessors::CasgnNode
@@ -0,0 +1,47 @@
1
+ require 'delegate'
2
+
3
+ module RubyVM::AbstractSyntaxTree
4
+ # Wrapper for RubyVM::AbstractSyntaxTree::Node. for return character based column
5
+ class NodeWrapper < SimpleDelegator
6
+ attr_reader :code
7
+ # @param node [RubyVM::AbstractSyntaxTree::Node] wrapped node to return character based column
8
+ # @param code [Array<String>] source code lines for generated this node
9
+ def initialize(node, code)
10
+ @code = code
11
+ super(node)
12
+ end
13
+
14
+ def self.from(node, code)
15
+ return node unless node.is_a?(RubyVM::AbstractSyntaxTree::Node) and !node.kind_of?(SimpleDelegator)
16
+
17
+ new(node, code)
18
+ end
19
+
20
+ def is_a?(type)
21
+ __getobj__.is_a?(type) || super.is_a?(type)
22
+ end
23
+
24
+ def class
25
+ __getobj__.class
26
+ end
27
+
28
+
29
+ def first_column
30
+ @first_column ||= begin
31
+ line = @code[__getobj__.first_lineno - 1] || ""
32
+ line.byteslice(0, __getobj__.first_column).length
33
+ end
34
+ end
35
+
36
+ def last_column
37
+ @last_column ||= begin
38
+ line = @code[__getobj__.last_lineno - 1] || ""
39
+ line.byteslice(0, __getobj__.last_column).length
40
+ end
41
+ end
42
+
43
+ def children
44
+ @children ||= __getobj__.children.map do |node| NodeWrapper.from(node, @code) end
45
+ end
46
+ end
47
+ end
@@ -21,9 +21,12 @@ module Solargraph
21
21
  # @return [String]
22
22
  attr_reader :path
23
23
 
24
- # @param location [Solargraph::Location]
24
+ # @return [::Symbol]
25
+ attr_accessor :source
26
+
27
+ # @param location [Solargraph::Location, nil]
25
28
  # @param kind [Integer]
26
- # @param closure [Solargraph::Pin::Closure]
29
+ # @param closure [Solargraph::Pin::Closure, nil]
27
30
  # @param name [String]
28
31
  # @param comments [String]
29
32
  def initialize location: nil, closure: nil, name: '', comments: ''
@@ -8,6 +8,7 @@ module Solargraph
8
8
  # @return [Parser::AST::Node]
9
9
  attr_reader :receiver
10
10
 
11
+ # @param args [Array<Parameter>]
11
12
  def initialize receiver: nil, args: [], context: nil, **splat
12
13
  super(**splat)
13
14
  @receiver = receiver
@@ -25,7 +26,7 @@ module Solargraph
25
26
  @binder || closure.binder
26
27
  end
27
28
 
28
- # @return [Array<String>]
29
+ # @return [Array<Parameter>]
29
30
  def parameters
30
31
  @parameters ||= []
31
32
  end
@@ -34,12 +34,9 @@ module Solargraph
34
34
  end
35
35
  end
36
36
 
37
- # @return [Hash]
37
+ # @return [Array<Hash>]
38
38
  def signature_help
39
- @signature_help ||= {
40
- label: name + '(' + parameters.map(&:full).join(', ') + ')',
41
- documentation: documentation
42
- }
39
+ []
43
40
  end
44
41
 
45
42
  # @return [String]
@@ -47,7 +44,6 @@ module Solargraph
47
44
  # This property is not cached in an instance variable because it can
48
45
  # change when pins get proxied.
49
46
  detail = String.new
50
- detail += "(#{parameters.map(&:full).join(', ')}) " unless !is_a?(Pin::Method) || parameters.empty?
51
47
  detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
52
48
  detail.strip!
53
49
  return nil if detail.empty?
@@ -18,13 +18,18 @@ module Solargraph
18
18
 
19
19
  # @param visibility [::Symbol] :public, :protected, or :private
20
20
  # @param explicit [Boolean]
21
- def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, **splat
21
+ # @param parameters [Array<Pin::Parameter>]
22
+ # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
23
+ # @param attribute [Boolean]
24
+ def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
22
25
  super(**splat)
23
26
  @visibility = visibility
24
27
  @explicit = explicit
25
28
  @parameters = parameters
26
29
  @node = node
27
30
  @attribute = attribute
31
+ @signatures = signatures
32
+ @anon_splat = anon_splat
28
33
  end
29
34
 
30
35
  # @return [Array<String>]
@@ -41,7 +46,45 @@ module Solargraph
41
46
  end
42
47
 
43
48
  def return_type
44
- @return_type ||= generate_complex_type
49
+ @return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
50
+ end
51
+
52
+ # @return [Array<Signature>]
53
+ def signatures
54
+ @signatures ||= begin
55
+ top_type = generate_complex_type
56
+ result = []
57
+ result.push Signature.new(parameters, top_type) if top_type.defined?
58
+ result.concat(overloads.map { |meth| Signature.new(meth.parameters, meth.return_type) })
59
+ result.push Signature.new(parameters, top_type) if result.empty?
60
+ result
61
+ end
62
+ end
63
+
64
+ # @return [String]
65
+ def detail
66
+ # This property is not cached in an instance variable because it can
67
+ # change when pins get proxied.
68
+ detail = String.new
69
+ detail += if signatures.length > 1
70
+ "(*) "
71
+ else
72
+ "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
73
+ end.to_s
74
+ detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
75
+ detail.strip!
76
+ return nil if detail.empty?
77
+ detail
78
+ end
79
+
80
+ # @return [Array<Hash>]
81
+ def signature_help
82
+ @signature_help ||= signatures.map do |sig|
83
+ {
84
+ label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
85
+ documentation: documentation
86
+ }
87
+ end
45
88
  end
46
89
 
47
90
  def path
@@ -119,27 +162,60 @@ module Solargraph
119
162
  # @return [Array<Pin::Method>]
120
163
  def overloads
121
164
  @overloads ||= docstring.tags(:overload).map do |tag|
122
- Solargraph::Pin::Method.new(
123
- name: name,
124
- closure: self,
125
- # args: tag.parameters.map(&:first),
126
- parameters: tag.parameters.map do |src|
165
+ Pin::Signature.new(
166
+ tag.parameters.map do |src|
167
+ name, decl = parse_overload_param(src.first)
127
168
  Pin::Parameter.new(
128
169
  location: location,
129
170
  closure: self,
130
171
  comments: tag.docstring.all.to_s,
131
- name: src.first,
172
+ name: name,
173
+ decl: decl,
132
174
  presence: location ? location.range : nil,
133
- decl: :arg
175
+ return_type: param_type_from_name(tag, src.first)
134
176
  )
135
177
  end,
136
- comments: tag.docstring.all.to_s
178
+ ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
137
179
  )
138
180
  end
181
+ @overloads
182
+ end
183
+
184
+ def anon_splat?
185
+ @anon_splat
139
186
  end
140
187
 
141
188
  private
142
189
 
190
+ def select_decl name, asgn
191
+ if name.start_with?('**')
192
+ :kwrestarg
193
+ elsif name.start_with?('*')
194
+ :restarg
195
+ elsif name.start_with?('&')
196
+ :blockarg
197
+ elsif name.end_with?(':') && asgn
198
+ :kwoptarg
199
+ elsif name.end_with?(':')
200
+ :kwarg
201
+ elsif asgn
202
+ :optarg
203
+ else
204
+ :arg
205
+ end
206
+ end
207
+
208
+ def clean_param name
209
+ name.gsub(/[*&:]/, '')
210
+ end
211
+
212
+ # @param tag [YARD::Tags::OverloadTag]
213
+ def param_type_from_name(tag, name)
214
+ param = tag.tags(:param).select { |t| t.name == name }.first
215
+ return ComplexType::UNDEFINED unless param
216
+ ComplexType.try_parse(*param.types)
217
+ end
218
+
143
219
  # @return [ComplexType]
144
220
  def generate_complex_type
145
221
  tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
@@ -240,6 +316,20 @@ module Solargraph
240
316
  return ComplexType::UNDEFINED if types.empty?
241
317
  ComplexType.try_parse(*types.map(&:tag).uniq)
242
318
  end
319
+
320
+ # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
321
+ #
322
+ # @param arg [String]
323
+ # @return [Array(String, Symbol)]
324
+ def parse_overload_param(name)
325
+ if name.start_with?('**')
326
+ [name[2..-1], :kwrestarg]
327
+ elsif name.start_with?('*')
328
+ [name[1..-1], :restarg]
329
+ else
330
+ [name, :arg]
331
+ end
332
+ end
243
333
  end
244
334
  end
245
335
  end
@@ -9,10 +9,12 @@ module Solargraph
9
9
  # @return [::Symbol] :class or :module
10
10
  attr_reader :type
11
11
 
12
+ attr_reader :parameters
13
+
12
14
  # @param type [::Symbol] :class or :module
13
15
  # @param visibility [::Symbol] :public or :private
14
16
  # @param gates [Array<String>]
15
- def initialize type: :class, visibility: :public, gates: [''], **splat
17
+ def initialize type: :class, visibility: :public, gates: [''], parameters: [], **splat
16
18
  # super(location, namespace, name, comments)
17
19
  super(**splat)
18
20
  @type = type
@@ -36,6 +38,7 @@ module Solargraph
36
38
  @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
37
39
  @context = nil
38
40
  end
41
+ @parameters = parameters
39
42
  end
40
43
 
41
44
  def namespace
@@ -3,14 +3,17 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Parameter < LocalVariable
6
+ # @return [Symbol]
6
7
  attr_reader :decl
7
8
 
9
+ # @return [String]
8
10
  attr_reader :asgn_code
9
11
 
10
- def initialize decl: :arg, asgn_code: nil, **splat
12
+ def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
11
13
  super(**splat)
12
14
  @asgn_code = asgn_code
13
15
  @decl = decl
16
+ @return_type = return_type
14
17
  end
15
18
 
16
19
  def keyword?
@@ -29,14 +32,18 @@ module Solargraph
29
32
  decl == :restarg || decl == :kwrestarg
30
33
  end
31
34
 
35
+ def block?
36
+ [:block, :blockarg].include?(decl)
37
+ end
38
+
32
39
  def full
33
40
  case decl
34
41
  when :optarg
35
- "#{name} = #{asgn_code}"
42
+ "#{name} = #{asgn_code || '?'}"
36
43
  when :kwarg
37
44
  "#{name}:"
38
45
  when :kwoptarg
39
- "#{name}: #{asgn_code}"
46
+ "#{name}: #{asgn_code || '?'}"
40
47
  when :restarg
41
48
  "*#{name}"
42
49
  when :kwrestarg
@@ -91,10 +98,6 @@ module Solargraph
91
98
  true
92
99
  end
93
100
 
94
- def probe api_map
95
- typify api_map
96
- end
97
-
98
101
  private
99
102
 
100
103
  # @return [YARD::Tags::Tag]
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jaro_winkler'
4
+
5
+ module Solargraph
6
+ module Pin
7
+ class Search
8
+ class Result
9
+ # @return [Float]
10
+ attr_reader :match
11
+
12
+ # @return [Pin::Base]
13
+ attr_reader :pin
14
+
15
+ def initialize match, pin
16
+ @match = match
17
+ @pin = pin
18
+ end
19
+ end
20
+
21
+ # @param pins [Array<Pin::Base>]
22
+ # @param query [String]
23
+ def initialize pins, query
24
+ @pins = pins
25
+ @query = query
26
+ end
27
+
28
+ # @return [Array<Pin::Base>]
29
+ def results
30
+ @results ||= do_query
31
+ end
32
+
33
+ private
34
+
35
+ # @return [Array<Pin::Base>]
36
+ def do_query
37
+ return @pins if @query.nil? || @query.empty?
38
+ @pins.map do |pin|
39
+ match = [fuzzy_string_match(pin.path, @query), fuzzy_string_match(pin.name, @query)].max
40
+ Result.new(match, pin) if match > 0.7
41
+ end
42
+ .compact
43
+ .sort { |a, b| b.match <=> a.match }
44
+ .map(&:pin)
45
+ end
46
+
47
+ # @param str1 [String]
48
+ # @param str2 [String]
49
+ # @return [Float]
50
+ def fuzzy_string_match str1, str2
51
+ return (1.0 + (str2.length.to_f / str1.length.to_f)) if str1.downcase.include?(str2.downcase)
52
+ JaroWinkler.distance(str1, str2, ignore_case: true)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,23 @@
1
+ module Solargraph
2
+ module Pin
3
+ class Signature
4
+ # @return [Array<Parameter>]
5
+ attr_reader :parameters
6
+
7
+ # @return [ComplexType]
8
+ attr_reader :return_type
9
+
10
+ attr_reader :block
11
+
12
+ def initialize parameters, return_type, block = nil
13
+ @parameters = parameters
14
+ @return_type = return_type
15
+ @block = block
16
+ end
17
+
18
+ def block?
19
+ !!@block
20
+ end
21
+ end
22
+ end
23
+ end
@@ -10,6 +10,7 @@ module Solargraph
10
10
  autoload :Conversions, 'solargraph/pin/conversions'
11
11
  autoload :Base, 'solargraph/pin/base'
12
12
  autoload :Method, 'solargraph/pin/method'
13
+ autoload :Signature, 'solargraph/pin/signature'
13
14
  autoload :MethodAlias, 'solargraph/pin/method_alias'
14
15
  autoload :BaseVariable, 'solargraph/pin/base_variable'
15
16
  autoload :InstanceVariable, 'solargraph/pin/instance_variable'
@@ -30,6 +31,7 @@ module Solargraph
30
31
  autoload :DuckMethod, 'solargraph/pin/duck_method'
31
32
  autoload :Singleton, 'solargraph/pin/singleton'
32
33
  autoload :KeywordParam, 'solargraph/pin/keyword_param'
34
+ autoload :Search, 'solargraph/pin/search'
33
35
 
34
36
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
35
37
  end
@@ -69,7 +69,7 @@ module Solargraph
69
69
  if node.is_a?(RubyVM::AbstractSyntaxTree::Node)
70
70
  Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
71
71
  end
72
- elsif node.loc && node.loc.expression
72
+ elsif node&.loc && node.loc.expression
73
73
  from_expr(node.loc.expression)
74
74
  end
75
75
  end