solargraph 0.54.0 → 0.54.1

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/lib/solargraph/api_map/store.rb +6 -2
  4. data/lib/solargraph/api_map.rb +15 -8
  5. data/lib/solargraph/complex_type/type_methods.rb +10 -11
  6. data/lib/solargraph/complex_type/unique_type.rb +72 -9
  7. data/lib/solargraph/complex_type.rb +66 -17
  8. data/lib/solargraph/language_server/host/message_worker.rb +29 -3
  9. data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
  10. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
  11. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  12. data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
  13. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
  14. data/lib/solargraph/language_server/progress.rb +19 -2
  15. data/lib/solargraph/library.rb +30 -39
  16. data/lib/solargraph/location.rb +14 -1
  17. data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -7
  18. data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -1
  19. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
  20. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -2
  21. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
  22. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
  23. data/lib/solargraph/parser.rb +2 -5
  24. data/lib/solargraph/pin/base.rb +15 -1
  25. data/lib/solargraph/pin/base_variable.rb +1 -1
  26. data/lib/solargraph/pin/block.rb +5 -23
  27. data/lib/solargraph/pin/callable.rb +147 -0
  28. data/lib/solargraph/pin/closure.rb +8 -3
  29. data/lib/solargraph/pin/common.rb +2 -6
  30. data/lib/solargraph/pin/conversions.rb +3 -2
  31. data/lib/solargraph/pin/instance_variable.rb +2 -2
  32. data/lib/solargraph/pin/method.rb +51 -31
  33. data/lib/solargraph/pin/namespace.rb +4 -4
  34. data/lib/solargraph/pin/parameter.rb +9 -11
  35. data/lib/solargraph/pin/proxy_type.rb +1 -1
  36. data/lib/solargraph/pin/signature.rb +3 -129
  37. data/lib/solargraph/pin.rb +4 -1
  38. data/lib/solargraph/range.rb +2 -4
  39. data/lib/solargraph/rbs_map/conversions.rb +70 -37
  40. data/lib/solargraph/rbs_map/core_fills.rb +6 -6
  41. data/lib/solargraph/shell.rb +17 -2
  42. data/lib/solargraph/source/chain/array.rb +6 -5
  43. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  44. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  45. data/lib/solargraph/source/chain/call.rb +78 -50
  46. data/lib/solargraph/source/chain/link.rb +9 -0
  47. data/lib/solargraph/source/chain/or.rb +1 -1
  48. data/lib/solargraph/source/chain.rb +41 -17
  49. data/lib/solargraph/source/cursor.rb +13 -2
  50. data/lib/solargraph/source.rb +102 -85
  51. data/lib/solargraph/source_map/clip.rb +4 -4
  52. data/lib/solargraph/source_map/data.rb +30 -0
  53. data/lib/solargraph/source_map.rb +28 -16
  54. data/lib/solargraph/type_checker/rules.rb +6 -1
  55. data/lib/solargraph/type_checker.rb +7 -7
  56. data/lib/solargraph/version.rb +1 -1
  57. data/lib/solargraph/views/environment.erb +3 -5
  58. metadata +4 -2
@@ -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
@@ -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,20 @@ 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
39
32
  end
40
33
 
41
34
  def transform_types(&transform)
@@ -44,15 +37,16 @@ module Solargraph
44
37
  m.signatures = m.signatures.map do |sig|
45
38
  sig.transform_types(&transform)
46
39
  end
47
- m.parameters = m.parameters.map do |param|
48
- param.transform_types(&transform)
49
- end
50
40
  m.block = block&.transform_types(&transform)
51
41
  m.signature_help = nil
52
42
  m.documentation = nil
53
43
  m
54
44
  end
55
45
 
46
+ def all_rooted?
47
+ super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
48
+ end
49
+
56
50
  # @param signature [Pin::Signature]
57
51
  # @return [Pin::Method]
58
52
  def with_single_signature(signature)
@@ -71,15 +65,14 @@ module Solargraph
71
65
  m
72
66
  end
73
67
 
68
+ def block?
69
+ !block.nil?
70
+ end
71
+
74
72
  # @return [Pin::Signature, nil]
75
73
  def block
76
74
  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)
75
+ @block = signatures.first&.block
83
76
  end
84
77
 
85
78
  def completion_item_kind
@@ -123,9 +116,9 @@ module Solargraph
123
116
  )
124
117
  end
125
118
  yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
126
- block = Signature.new(generics, yield_parameters, yield_return_type)
119
+ block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
127
120
  end
128
- Signature.new(generics, parameters, return_type, block)
121
+ Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
129
122
  end
130
123
 
131
124
  # @return [::Array<Signature>]
@@ -270,9 +263,9 @@ module Solargraph
270
263
  end
271
264
 
272
265
  def nearly? other
273
- return false unless super
274
- parameters == other.parameters and
275
- scope == other.scope and
266
+ super &&
267
+ parameters == other.parameters &&
268
+ scope == other.scope &&
276
269
  visibility == other.visibility
277
270
  end
278
271
 
@@ -283,6 +276,7 @@ module Solargraph
283
276
  def try_merge! pin
284
277
  return false unless super
285
278
  @node = pin.node
279
+ @resolved_ref_tag = false
286
280
  true
287
281
  end
288
282
 
@@ -292,8 +286,8 @@ module Solargraph
292
286
  # tag's source is likely malformed.
293
287
  @overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
294
288
  Pin::Signature.new(
295
- generics,
296
- tag.parameters.map do |src|
289
+ generics: generics,
290
+ parameters: tag.parameters.map do |src|
297
291
  name, decl = parse_overload_param(src.first)
298
292
  Pin::Parameter.new(
299
293
  location: location,
@@ -305,7 +299,7 @@ module Solargraph
305
299
  return_type: param_type_from_name(tag, src.first)
306
300
  )
307
301
  end,
308
- ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
302
+ return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
309
303
  )
310
304
  end
311
305
  @overloads
@@ -315,12 +309,33 @@ module Solargraph
315
309
  @anon_splat
316
310
  end
317
311
 
312
+ # @param [ApiMap]
313
+ # @return [self]
314
+ def resolve_ref_tag api_map
315
+ return self if @resolved_ref_tag
316
+
317
+ @resolved_ref_tag = true
318
+ return self unless docstring.ref_tags.any?
319
+ docstring.ref_tags.each do |tag|
320
+ ref = if tag.owner.to_s.start_with?(/[#\.]/)
321
+ api_map.get_methods(namespace)
322
+ .select { |pin| pin.path.end_with?(tag.owner.to_s) }
323
+ .first
324
+ else
325
+ # @todo Resolve relative namespaces
326
+ api_map.get_path_pins(tag.owner.to_s).first
327
+ end
328
+ next unless ref
329
+
330
+ docstring.add_tag(*ref.docstring.tags(:param))
331
+ end
332
+ self
333
+ end
334
+
318
335
  protected
319
336
 
320
337
  attr_writer :block
321
338
 
322
- attr_writer :parameters
323
-
324
339
  attr_writer :signatures
325
340
 
326
341
  attr_writer :signature_help
@@ -452,7 +467,7 @@ module Solargraph
452
467
  end
453
468
  result.push ComplexType::NIL if has_nil
454
469
  return ComplexType::UNDEFINED if result.empty?
455
- ComplexType.try_parse(*result.map(&:tag).uniq)
470
+ ComplexType.new(result.uniq)
456
471
  end
457
472
 
458
473
  # @param [ApiMap] api_map
@@ -467,7 +482,7 @@ module Solargraph
467
482
  types.push type if type.defined?
468
483
  end
469
484
  return ComplexType::UNDEFINED if types.empty?
470
- ComplexType.try_parse(*types.map(&:tag).uniq)
485
+ ComplexType.new(types.uniq)
471
486
  end
472
487
 
473
488
  # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
@@ -475,6 +490,7 @@ module Solargraph
475
490
  # @param name [String]
476
491
  # @return [::Array(String, ::Symbol)]
477
492
  def parse_overload_param(name)
493
+ # @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
478
494
  if name.start_with?('**')
479
495
  [name[2..-1], :kwrestarg]
480
496
  elsif name.start_with?('*')
@@ -496,6 +512,10 @@ module Solargraph
496
512
  .join("\n")
497
513
  .concat("```\n")
498
514
  end
515
+
516
+ protected
517
+
518
+ attr_writer :signatures
499
519
  end
500
520
  end
501
521
  end
@@ -41,11 +41,11 @@ module Solargraph
41
41
  end
42
42
 
43
43
  def to_rbs
44
- "#{@type.to_s} #{generics_as_rbs}#{return_type.to_rbs}"
44
+ "#{@type.to_s} #{return_type.all_params.first.to_rbs}#{rbs_generics}".strip
45
45
  end
46
46
 
47
47
  def desc
48
- if name.nil?
48
+ if name.nil? || name.empty?
49
49
  '(top-level)'
50
50
  else
51
51
  to_rbs
@@ -57,7 +57,7 @@ module Solargraph
57
57
  end
58
58
 
59
59
  def full_context
60
- @full_context ||= ComplexType.try_parse("#{type.to_s.capitalize}<#{path}>")
60
+ @full_context ||= ComplexType.try_parse("::#{type.to_s.capitalize}<#{path}>")
61
61
  end
62
62
 
63
63
  def binder
@@ -83,7 +83,7 @@ module Solargraph
83
83
  end
84
84
 
85
85
  def return_type
86
- @return_type ||= ComplexType.try_parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
86
+ @return_type ||= ComplexType.try_parse( (type == :class ? '::Class' : '::Module') + "<::#{path}>")
87
87
  end
88
88
 
89
89
  # @return [Array<String>]
@@ -27,6 +27,10 @@ module Solargraph
27
27
  decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
28
28
  end
29
29
 
30
+ def arg?
31
+ decl == :arg
32
+ end
33
+
30
34
  def restarg?
31
35
  decl == :restarg
32
36
  end
@@ -84,11 +88,11 @@ module Solargraph
84
88
  @return_type = ComplexType.try_parse(*found.types) unless found.nil? or found.types.nil?
85
89
  if @return_type.undefined?
86
90
  if decl == :restarg
87
- @return_type = ComplexType.try_parse('Array')
91
+ @return_type = ComplexType.try_parse('::Array')
88
92
  elsif decl == :kwrestarg
89
- @return_type = ComplexType.try_parse('Hash')
93
+ @return_type = ComplexType.try_parse('::Hash')
90
94
  elsif decl == :blockarg
91
- @return_type = ComplexType.try_parse('Proc')
95
+ @return_type = ComplexType.try_parse('::Proc')
92
96
  end
93
97
  end
94
98
  end
@@ -126,17 +130,11 @@ module Solargraph
126
130
 
127
131
  # @return [YARD::Tags::Tag, nil]
128
132
  def param_tag
129
- found = nil
130
133
  params = closure.docstring.tags(:param)
131
134
  params.each do |p|
132
- next unless p.name == name
133
- found = p
134
- break
135
- end
136
- if found.nil? and !index.nil?
137
- found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
135
+ return p if p.name == name
138
136
  end
139
- found
137
+ params[index] if index && params[index] && (params[index].name.nil? || params[index].name.empty?)
140
138
  end
141
139
 
142
140
  # @param api_map [ApiMap]
@@ -18,7 +18,7 @@ module Solargraph
18
18
  def self.anonymous return_type
19
19
  parts = return_type.namespace.split('::')
20
20
  namespace = parts[0..-2].join('::').to_s
21
- name = parts.last.to_s
21
+ # name = parts.last.to_s
22
22
  # ProxyType.new(nil, namespace, name, return_type)
23
23
  ProxyType.new(
24
24
  closure: Solargraph::Pin::Namespace.new(name: namespace), return_type: return_type
@@ -1,143 +1,17 @@
1
1
  module Solargraph
2
2
  module Pin
3
- class Signature < Base
4
- # @return [::Array<Parameter>]
5
- attr_reader :parameters
6
-
7
- # @return [ComplexType]
8
- attr_reader :return_type
9
-
10
- # @return [self]
11
- attr_reader :block
12
-
13
- # @param generics [Array<String>]
14
- # @param parameters [Array<Parameter>]
15
- # @param return_type [ComplexType]
16
- # @param block [Signature, nil]
17
- def initialize generics, parameters, return_type, block = nil
18
- @generics = generics
19
- @parameters = parameters
20
- @return_type = return_type
21
- @block = block
3
+ class Signature < Callable
4
+ def initialize **splat
5
+ super(**splat)
22
6
  end
23
7
 
24
8
  def generics
25
9
  @generics ||= [].freeze
26
10
  end
27
11
 
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
-
128
12
  def identity
129
13
  @identity ||= "signature#{object_id}"
130
14
  end
131
-
132
- def block?
133
- !!@block
134
- end
135
-
136
- protected
137
-
138
- attr_writer :block
139
-
140
- attr_writer :parameters
141
15
  end
142
16
  end
143
17
  end
@@ -3,7 +3,9 @@
3
3
  require 'yard'
4
4
 
5
5
  module Solargraph
6
- # The namespace for pins used in maps.
6
+ # The namespace for Pins used in SourceMaps.
7
+ #
8
+ # Pins represent declarations, from gems, Sources, and the Ruby core.
7
9
  #
8
10
  module Pin
9
11
  autoload :Common, 'solargraph/pin/common'
@@ -32,6 +34,7 @@ module Solargraph
32
34
  autoload :Singleton, 'solargraph/pin/singleton'
33
35
  autoload :KeywordParam, 'solargraph/pin/keyword_param'
34
36
  autoload :Search, 'solargraph/pin/search'
37
+ autoload :Callable, 'solargraph/pin/callable'
35
38
 
36
39
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
37
40
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- # A pair of positions that compose a section of text.
4
+ # A pair of Positions that compose a section of text in code.
5
5
  #
6
6
  class Range
7
7
  # @return [Position]
@@ -65,9 +65,7 @@ module Solargraph
65
65
  # @param node [Parser::AST::Node]
66
66
  # @return [Range, nil]
67
67
  def self.from_node node
68
- if Parser.rubyvm? && node.is_a?(RubyVM::AbstractSyntaxTree::Node)
69
- Solargraph::Range.from_to(node.first_lineno - 1, node.first_column, node.last_lineno - 1, node.last_column)
70
- elsif node&.loc && node.loc.expression
68
+ if node&.loc && node.loc.expression
71
69
  from_expr(node.loc.expression)
72
70
  end
73
71
  end