solargraph 0.51.2 → 0.52.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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -2
  3. data/CHANGELOG.md +25 -5
  4. data/lib/solargraph/api_map/cache.rb +2 -0
  5. data/lib/solargraph/api_map/store.rb +2 -2
  6. data/lib/solargraph/api_map.rb +11 -4
  7. data/lib/solargraph/complex_type/type_methods.rb +1 -1
  8. data/lib/solargraph/complex_type/unique_type.rb +20 -13
  9. data/lib/solargraph/complex_type.rb +13 -9
  10. data/lib/solargraph/documentor.rb +1 -1
  11. data/lib/solargraph/library.rb +12 -5
  12. data/lib/solargraph/parser/comment_ripper.rb +1 -0
  13. data/lib/solargraph/parser/legacy/class_methods.rb +2 -2
  14. data/lib/solargraph/parser/legacy/node_chainer.rb +9 -4
  15. data/lib/solargraph/parser/legacy/node_methods.rb +5 -3
  16. data/lib/solargraph/parser/node_methods.rb +1 -0
  17. data/lib/solargraph/parser/region.rb +1 -1
  18. data/lib/solargraph/parser/rubyvm/class_methods.rb +1 -3
  19. data/lib/solargraph/parser/rubyvm/node_chainer.rb +5 -2
  20. data/lib/solargraph/parser.rb +2 -0
  21. data/lib/solargraph/pin/base.rb +1 -1
  22. data/lib/solargraph/pin/block.rb +2 -2
  23. data/lib/solargraph/pin/delegated_method.rb +1 -1
  24. data/lib/solargraph/pin/method.rb +62 -5
  25. data/lib/solargraph/pin/namespace.rb +10 -3
  26. data/lib/solargraph/pin/parameter.rb +9 -10
  27. data/lib/solargraph/pin/signature.rb +9 -1
  28. data/lib/solargraph/rbs_map/conversions.rb +86 -31
  29. data/lib/solargraph/rbs_map/core_fills.rb +9 -10
  30. data/lib/solargraph/rbs_map/core_map.rb +1 -1
  31. data/lib/solargraph/rbs_map.rb +2 -3
  32. data/lib/solargraph/source/chain/array.rb +29 -0
  33. data/lib/solargraph/source/chain/call.rb +14 -30
  34. data/lib/solargraph/source/chain/link.rb +1 -1
  35. data/lib/solargraph/source/chain/z_super.rb +1 -1
  36. data/lib/solargraph/source/chain.rb +9 -10
  37. data/lib/solargraph/source/source_chainer.rb +2 -0
  38. data/lib/solargraph/source.rb +3 -3
  39. data/lib/solargraph/source_map/clip.rb +0 -16
  40. data/lib/solargraph/source_map/mapper.rb +2 -1
  41. data/lib/solargraph/source_map.rb +2 -2
  42. data/lib/solargraph/type_checker.rb +18 -7
  43. data/lib/solargraph/version.rb +1 -1
  44. data/lib/solargraph/workspace.rb +2 -1
  45. data/lib/solargraph/yard_map/mapper.rb +1 -1
  46. data/lib/solargraph/yard_map.rb +6 -5
  47. data/lib/solargraph/yard_tags.rb +20 -0
  48. data/lib/solargraph.rb +2 -3
  49. data/solargraph.gemspec +1 -0
  50. metadata +18 -3
  51. data/lib/yard-solargraph.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c031e57a0f9eb482a517ed584966ecfff9fd431aaee66d6c97d624393b56fb99
4
- data.tar.gz: d6cc56999dc9da2073584a54f5b2ed045e24e573c84408359a9c7f94f8bd8571
3
+ metadata.gz: fdf3486fdfc29fad9450f6c8dade8f6f9d2446b400c8032055adc93a0c9ed80f
4
+ data.tar.gz: 30cbae5663273333f57dd66eec6cc336a318bca17ea9ff2ba9da257d94f25ad3
5
5
  SHA512:
6
- metadata.gz: aa5be8998891287e3a92429f2317c3bc64235d71977476248cbf3ba1167842b2e65c666b7f1bb49254bcc9c1ad67b2f4ea7f4cd1c50ef3c16723bdbd5286049a
7
- data.tar.gz: 30b453fc424796b8b776d2c79b014d19645dd2f091fb6cb6822a6f373e1df719809d845bef66fc3146c821c42a7268f60ff65e034a93f5d51708e5a0028f7fb1
6
+ metadata.gz: '0739d9be8146ea6b09a9bf8151328d95bea64c3fe3ddd7af6334f140c0a2eedaacff84a0e6e5b70fb5e6909b8f25ff85fb5d18f7d73f06a0294ea617dde90263'
7
+ data.tar.gz: 29de344f99fc2f5f96b2ccc6df9fea4b6220074315ef4a04777e4afaa16253e166f238e51fbe18914ad6f9af6c1983587b7898d7abe003f4ad420f7e508b6edc
data/.yardopts CHANGED
@@ -1,2 +1,2 @@
1
- lib/**/*.rb
2
- -e lib/yard-solargraph.rb
1
+ lib/**/*.rb
2
+ --plugin yard-solargraph
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 0.52.0 - February 28, 2025
2
+ - Chains resolve identical names with different contexts (#679)
3
+ - Handle symbol tags in method tag values (#744)
4
+ - Infer more specific Array types when possible (#745)
5
+ - Handle interpolated symbol literals (#747)
6
+ - Handle combined conditions, else clauses in case statements (#746)
7
+ - fix: support find require xxx.rb in local workspace. (#722)
8
+ - Don't require redundant attribute @return and @param tags (#748)
9
+ - Use @yieldreturn tags for type inference (#749)
10
+ - Fix type annotations identified at 'typed' level (#750)
11
+ - Support RBS class aliases (#751)
12
+ - Better support for generics via Class @param tags (#743)
13
+ - Generic module support through RBS (#757)
14
+ - Fix inference of begin expression types (#754)
15
+ - Add argument to satisfy typechecker on which signature to use (#755)
16
+ - Fix RBS ingestion implicit initializer issues, missing param types (#756)
17
+ - Validate zsuper arity
18
+ - Use yard-solargraph plugin (#759)
19
+ - Add missing RBS types
20
+
1
21
  ## 0.51.2 - February 1, 2025
2
22
  - Fix exception from parser when anonymous block forwarding is used (#740)
3
23
  - Parameterized Object types
@@ -5,10 +25,10 @@
5
25
 
6
26
  ## 0.51.1 - January 23, 2025
7
27
  - Format example code
8
- - Block infers yieldself from chain
28
+ - Block infers yieldreceiver from chain
9
29
 
10
30
  ## 0.51.0 - January 19, 2025
11
- - Resolve self in yieldself tags
31
+ - Resolve self in yieldreceiver tags
12
32
  - Include absolute paths in config (#674)
13
33
  - Enable diagnostics by default
14
34
  - Fix cache resolution (#704)
@@ -597,7 +617,7 @@
597
617
  ## 0.31.2 - January 27, 2019
598
618
  - Use YARD documentation rules to associate directives with namespaces
599
619
  - Handle non-unique pin locations in completionItem/resolve
600
- - Clip#complete handles @yieldself and @yieldpublic contexts
620
+ - Clip#complete handles @yieldreceiver and @yieldpublic contexts
601
621
  - Host::Dispatch filters library updates (castwide/vscode-solargraph#99)
602
622
  - Qualify included namespaces (#148)
603
623
 
@@ -953,7 +973,7 @@
953
973
 
954
974
  ## 0.17.0 - February 1, 2018
955
975
  - Support Solargraph configurations in workspace folders.
956
- - Use @yieldself tag to change block contexts.
976
+ - Use @yieldreceiver tag to change block contexts.
957
977
  - Handle whitespace in signatures.
958
978
  - Convert 'self' when inferring signature types.
959
979
  - Handle bare periods without signatures.
@@ -996,7 +1016,7 @@
996
1016
  - Map pins to code objects.
997
1017
  - Infer return types from domain (DSL) methods.
998
1018
  - Fixed visibility and results for superclasses.
999
- - Experimental @yieldself tag.
1019
+ - Experimental @yieldreceiver tag.
1000
1020
  - Improved syntax error handling in Source.fix.
1001
1021
  - Gem ships with Ruby 2.2.2 yardocs.
1002
1022
  - Experimental plugin architecture and Runtime plugin.
@@ -4,6 +4,7 @@ module Solargraph
4
4
  class ApiMap
5
5
  class Cache
6
6
  def initialize
7
+ # @type [Hash{Array => Array<Pin::Method>}]
7
8
  @methods = {}
8
9
  @constants = {}
9
10
  @qualified_namespaces = {}
@@ -15,6 +16,7 @@ module Solargraph
15
16
  @methods[[fqns, scope, visibility.sort, deep]]
16
17
  end
17
18
 
19
+ # @return [Array<Pin::Method>]
18
20
  def set_methods fqns, scope, visibility, deep, value
19
21
  @methods[[fqns, scope, visibility.sort, deep]] = value
20
22
  end
@@ -147,8 +147,6 @@ module Solargraph
147
147
  @pin_select_cache[klass] ||= @pin_class_hash.each_with_object(Set.new) { |(key, o), n| n.merge(o) if key <= klass }
148
148
  end
149
149
 
150
- private
151
-
152
150
  # @param fqns [String]
153
151
  # @return [Array<Solargraph::Pin::Namespace>]
154
152
  def fqns_pins fqns
@@ -164,6 +162,8 @@ module Solargraph
164
162
  fqns_pins_map[[base, name]]
165
163
  end
166
164
 
165
+ private
166
+
167
167
  def fqns_pins_map
168
168
  @fqns_pins_map ||= Hash.new do |h, (base, name)|
169
169
  value = namespace_children(base).select { |pin| pin.name == name && pin.is_a?(Pin::Namespace) }
@@ -4,7 +4,7 @@ require 'rubygems'
4
4
  require 'set'
5
5
  require 'pathname'
6
6
  require 'yard'
7
- require 'yard-solargraph'
7
+ require 'solargraph/yard_tags'
8
8
 
9
9
  module Solargraph
10
10
  # An aggregate provider for information about workspaces, sources, gems, and
@@ -137,7 +137,7 @@ module Solargraph
137
137
  api_map
138
138
  end
139
139
 
140
- # @return [Array<Solargraph::Pin::Base>]
140
+ # @return [Enumerable<Solargraph::Pin::Base>]
141
141
  def pins
142
142
  store.pins
143
143
  end
@@ -199,6 +199,13 @@ module Solargraph
199
199
  result
200
200
  end
201
201
 
202
+ # @param namespace [String]
203
+ # @param context [String]
204
+ # @return [Array<Pin::Namespace>]
205
+ def get_namespace_pins namespace, context
206
+ store.fqns_pins(qualify(namespace, context))
207
+ end
208
+
202
209
  # Get a fully qualified namespace name. This method will start the search
203
210
  # in the specified context until it finds a match for the name.
204
211
  #
@@ -245,12 +252,12 @@ module Solargraph
245
252
  prefer_non_nil_variables(store.get_class_variables(namespace))
246
253
  end
247
254
 
248
- # @return [Array<Solargraph::Pin::Base>]
255
+ # @return [Enumerable<Solargraph::Pin::Base>]
249
256
  def get_symbols
250
257
  store.get_symbols
251
258
  end
252
259
 
253
- # @return [Array<Solargraph::Pin::GlobalVariable>]
260
+ # @return [Enumerable<Solargraph::Pin::GlobalVariable>]
254
261
  def get_global_variable_pins
255
262
  store.pins_by_class(Pin::GlobalVariable)
256
263
  end
@@ -101,7 +101,7 @@ module Solargraph
101
101
  # @param context [String] The namespace from which to resolve names
102
102
  # @return [ComplexType] The generated ComplexType
103
103
  def qualify api_map, context = ''
104
- return self if name == 'param'
104
+ return self if name == GENERIC_TAG_NAME
105
105
  return ComplexType.new([self]) if duck_type? || void? || undefined?
106
106
  recon = (rooted? ? '' : context)
107
107
  fqns = api_map.qualify(name, recon)
@@ -51,35 +51,42 @@ module Solargraph
51
51
  tag
52
52
  end
53
53
 
54
+ def items
55
+ [self]
56
+ end
57
+
54
58
  def to_rbs
55
59
  "#{namespace}#{parameters? ? "[#{subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
56
60
  end
57
-
58
- def parameterized?
59
- name == 'param' || all_params.any?(&:parameterized?)
61
+
62
+ def generic?
63
+ name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
60
64
  end
61
65
 
62
- def resolve_parameters definitions, context
63
- new_name = if name == 'param'
64
- idx = definitions.parameters.index(subtypes.first.name)
66
+ # @param definitions [Pin::Namespace]
67
+ # @param context_type [ComplexType]
68
+ # @return [UniqueType]
69
+ def resolve_generics definitions, context_type
70
+ new_name = if name == GENERIC_TAG_NAME
71
+ idx = definitions.generics.index(subtypes.first&.name)
65
72
  return ComplexType::UNDEFINED if idx.nil?
66
- param_type = context.return_type.all_params[idx]
73
+ param_type = context_type.all_params[idx]
67
74
  return ComplexType::UNDEFINED unless param_type
68
75
  param_type.to_s
69
76
  else
70
77
  name
71
78
  end
72
- new_key_types = if name != 'param'
73
- @key_types.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
79
+ new_key_types = if name != GENERIC_TAG_NAME
80
+ @key_types.map { |t| t.resolve_generics(definitions, context_type) }.select(&:defined?)
74
81
  else
75
82
  []
76
83
  end
77
- new_subtypes = if name != 'param'
78
- @subtypes.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
84
+ new_subtypes = if name != GENERIC_TAG_NAME
85
+ @subtypes.map { |t| t.resolve_generics(definitions, context_type) }.select(&:defined?)
79
86
  else
80
87
  []
81
88
  end
82
- if name != 'param' && !(new_key_types.empty? && new_subtypes.empty?)
89
+ if name != GENERIC_TAG_NAME && !(new_key_types.empty? && new_subtypes.empty?)
83
90
  if hash_parameters?
84
91
  UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
85
92
  elsif parameters?
@@ -124,7 +131,7 @@ module Solargraph
124
131
  def selfy?
125
132
  @name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
126
133
  end
127
-
134
+
128
135
  UNDEFINED = UniqueType.new('undefined')
129
136
  BOOLEAN = UniqueType.new('Boolean')
130
137
  end
@@ -4,15 +4,16 @@ module Solargraph
4
4
  # A container for type data based on YARD type tags.
5
5
  #
6
6
  class ComplexType
7
+ GENERIC_TAG_NAME = 'generic'.freeze
7
8
  # @!parse
8
9
  # include TypeMethods
9
10
 
10
11
  autoload :TypeMethods, 'solargraph/complex_type/type_methods'
11
12
  autoload :UniqueType, 'solargraph/complex_type/unique_type'
12
13
 
13
- # @param types [Array<UniqueType>]
14
+ # @param types [Array<[UniqueType, ComplexType]>]
14
15
  def initialize types = [UniqueType::UNDEFINED]
15
- @items = types.uniq(&:to_s)
16
+ @items = types.flat_map(&:items).uniq(&:to_s)
16
17
  end
17
18
 
18
19
  # @param api_map [ApiMap]
@@ -42,7 +43,7 @@ module Solargraph
42
43
  end
43
44
 
44
45
  # @yieldparam [UniqueType]
45
- # @return [Array]
46
+ # @return [Enumerator<UniqueType>]
46
47
  def each &block
47
48
  @items.each &block
48
49
  end
@@ -106,12 +107,15 @@ module Solargraph
106
107
  @items.any?(&:selfy?)
107
108
  end
108
109
 
109
- def parameterized?
110
- any?(&:parameterized?)
110
+ def generic?
111
+ any?(&:generic?)
111
112
  end
112
113
 
113
- def resolve_parameters definitions, context
114
- result = @items.map { |i| i.resolve_parameters(definitions, context) }
114
+ # @param definitions [Pin::Namespace]
115
+ # @param context_type [ComplexType]
116
+ # @return [ComplexType]
117
+ def resolve_generics definitions, context_type
118
+ result = @items.map { |i| i.resolve_generics(definitions, context_type) }
115
119
  ComplexType.parse(*result.map(&:tag))
116
120
  end
117
121
 
@@ -132,10 +136,10 @@ module Solargraph
132
136
  @items.first.all_params || []
133
137
  end
134
138
 
135
- protected
136
-
137
139
  attr_reader :items
138
140
 
141
+ protected
142
+
139
143
  def reduce_object
140
144
  return self if name != 'Object' || subtypes.empty?
141
145
  ComplexType.try_parse(reduce_class(subtypes.join(', ')))
@@ -56,7 +56,7 @@ module Solargraph
56
56
  end
57
57
 
58
58
  # @param directory [String]
59
- # @return [Hash]
59
+ # @return [Hash{String => BasicObject}]
60
60
  def self.specs_from_bundle directory
61
61
  Solargraph.with_clean_env do
62
62
  cmd = [
@@ -283,10 +283,15 @@ module Solargraph
283
283
  return if map.nil?
284
284
  pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
285
285
  return nil if pin.nil?
286
+ return_if_match = proc do |full|
287
+ if source_map_hash.key?(full)
288
+ return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
289
+ end
290
+ end
286
291
  workspace.require_paths.each do |path|
287
- full = Pathname.new(path).join("#{pin.name}.rb").to_s
288
- next unless source_map_hash.key?(full)
289
- return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
292
+ full = File.join path, pin.name
293
+ return_if_match.(full)
294
+ return_if_match.(full << ".rb")
290
295
  end
291
296
  nil
292
297
  rescue FileNotFoundError
@@ -497,10 +502,12 @@ module Solargraph
497
502
  def find_external_requires source_map
498
503
  new_set = source_map.requires.map(&:name).to_set
499
504
  # return if new_set == source_map_external_require_hash[source_map.filename]
505
+ _filenames = nil
506
+ filenames = ->{ _filenames ||= workspace.filenames.to_set }
500
507
  source_map_external_require_hash[source_map.filename] = new_set.reject do |path|
501
508
  workspace.require_paths.any? do |base|
502
- full = Pathname.new(base).join("#{path}.rb").to_s
503
- workspace.filenames.include?(full)
509
+ full = File.join(base, path)
510
+ filenames[].include?(full) or filenames[].include?(full << ".rb")
504
511
  end
505
512
  end
506
513
  @external_requires = nil
@@ -42,6 +42,7 @@ module Solargraph
42
42
  result
43
43
  end
44
44
 
45
+ # @return [Hash{Integer => String}]
45
46
  def parse
46
47
  @comments = {}
47
48
  super
@@ -5,7 +5,7 @@ module Solargraph
5
5
  module Legacy
6
6
  module ClassMethods
7
7
  # @param code [String]
8
- # @param filename [String]
8
+ # @param filename [String, nil]
9
9
  # @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
10
10
  def parse_with_comments code, filename = nil
11
11
  buffer = ::Parser::Source::Buffer.new(filename, 0)
@@ -128,7 +128,7 @@ module Solargraph
128
128
  end
129
129
  end
130
130
  result
131
- end
131
+ end
132
132
  end
133
133
  end
134
134
  end
@@ -10,7 +10,7 @@ module Solargraph
10
10
  Chain = Source::Chain
11
11
 
12
12
  # @param node [Parser::AST::Node]
13
- # @param filename [String]
13
+ # @param filename [String, nil]
14
14
  def initialize node, filename = nil, in_block = false
15
15
  @node = node
16
16
  @filename = filename
@@ -25,7 +25,7 @@ module Solargraph
25
25
 
26
26
  class << self
27
27
  # @param node [Parser::AST::Node]
28
- # @param filename [String]
28
+ # @param filename [String, nil]
29
29
  # @return [Source::Chain]
30
30
  def chain node, filename = nil, in_block = false
31
31
  NodeChainer.new(node, filename, in_block).chain
@@ -47,7 +47,6 @@ module Solargraph
47
47
  # @return [Array<Chain::Link>]
48
48
  def generate_links n
49
49
  return [] unless n.is_a?(::Parser::AST::Node)
50
- return generate_links(n.children[0]) if n.type == :begin
51
50
  return generate_links(n.children[0]) if n.type == :splat
52
51
  result = []
53
52
  if n.type == :block
@@ -95,6 +94,9 @@ module Solargraph
95
94
  elsif n.type == :super
96
95
  args = n.children.map { |c| NodeChainer.chain(c) }
97
96
  result.push Chain::Call.new('super', args, @in_block > 0 || block_passed?(n))
97
+ elsif n.type == :yield
98
+ args = n.children.map { |c| NodeChainer.chain(c) }
99
+ result.push Chain::Call.new('yield', args, @in_block > 0 || block_passed?(n))
98
100
  elsif n.type == :const
99
101
  const = unpack_name(n)
100
102
  result.push Chain::Constant.new(const)
@@ -116,7 +118,7 @@ module Solargraph
116
118
  elsif n.type == :or
117
119
  result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename)])
118
120
  elsif [:begin, :kwbegin].include?(n.type)
119
- result.concat generate_links(n.children[0])
121
+ result.concat generate_links(n.children.last)
120
122
  elsif n.type == :block_pass
121
123
  block_variable_name_node = n.children[0]
122
124
  if block_variable_name_node.nil?
@@ -128,6 +130,9 @@ module Solargraph
128
130
  end
129
131
  elsif n.type == :hash
130
132
  result.push Chain::Hash.new('::Hash', hash_is_splatted?(n))
133
+ elsif n.type == :array
134
+ chained_children = n.children.map { |c| NodeChainer.chain(c) }
135
+ result.push Source::Chain::Array.new(chained_children)
131
136
  else
132
137
  lit = infer_literal_node_type(n)
133
138
  result.push (lit ? Chain::Literal.new(lit) : Chain::Link.new)
@@ -48,7 +48,7 @@ module Solargraph
48
48
  return '::Integer'
49
49
  elsif node.type == :float
50
50
  return '::Float'
51
- elsif node.type == :sym
51
+ elsif node.type == :sym || node.type == :dsym
52
52
  return '::Symbol'
53
53
  elsif node.type == :regexp
54
54
  return '::Regexp'
@@ -244,9 +244,11 @@ module Solargraph
244
244
  node.children[1..-1].each do |cc|
245
245
  if cc.nil?
246
246
  result.push NIL_NODE
247
- else
248
- result.concat reduce_to_value_nodes(cc.children[1..-2]) unless cc.children.length < 1
247
+ elsif cc.type == :when
249
248
  result.concat reduce_to_value_nodes([cc.children.last])
249
+ else
250
+ # else clause in case
251
+ result.concat reduce_to_value_nodes([cc])
250
252
  end
251
253
  end
252
254
  else
@@ -27,6 +27,7 @@ module Solargraph
27
27
  raise NotImplementedError
28
28
  end
29
29
 
30
+ # @return [Source::Chain]
30
31
  def chain node, filename = nil, in_block = false
31
32
  raise NotImplementedError
32
33
  end
@@ -23,7 +23,7 @@ module Solargraph
23
23
 
24
24
  # @param source [Source]
25
25
  # @param namespace [String]
26
- # @param scope [Symbol]
26
+ # @param scope [Symbol, nil]
27
27
  # @param visibility [Symbol]
28
28
  def initialize source: Solargraph::Source.load_string(''), closure: nil,
29
29
  scope: nil, visibility: :public, lvars: []
@@ -6,9 +6,8 @@ module Solargraph
6
6
  module Rubyvm
7
7
  module ClassMethods
8
8
  # @param code [String]
9
- # @param filename [String]
9
+ # @param filename [String, nil]
10
10
  # @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
11
- # @sg-ignore
12
11
  def parse_with_comments code, filename = nil
13
12
  node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
14
13
  node &&= RubyVM::AbstractSyntaxTree::NodeWrapper.from(node, code.lines)
@@ -22,7 +21,6 @@ module Solargraph
22
21
  # @param filename [String, nil]
23
22
  # @param line [Integer]
24
23
  # @return [Parser::AST::Node]
25
- # @sg-ignore
26
24
  def parse code, filename = nil, line = 0
27
25
  node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
28
26
  node and RubyVM::AbstractSyntaxTree::NodeWrapper.from(node, code.lines)
@@ -11,7 +11,7 @@ module Solargraph
11
11
  Chain = Source::Chain
12
12
 
13
13
  # @param node [Parser::AST::Node]
14
- # @param filename [String]
14
+ # @param filename [String, nil]
15
15
  def initialize node, filename = nil, in_block = false
16
16
  @node = node
17
17
  @filename = filename
@@ -26,7 +26,7 @@ module Solargraph
26
26
 
27
27
  class << self
28
28
  # @param node [Parser::AST::Node]
29
- # @param filename [String]
29
+ # @param filename [String, nil]
30
30
  # @return [Source::Chain]
31
31
  def chain node, filename = nil, in_block = false
32
32
  NodeChainer.new(node, filename, in_block).chain
@@ -104,6 +104,9 @@ module Solargraph
104
104
  result.push Chain::BlockVariable.new("&#{n.children[1].children[0].to_s}")
105
105
  elsif n.type == :HASH
106
106
  result.push Chain::Hash.new('::Hash', hash_is_splatted?(n))
107
+ elsif n.type == :ARRAY
108
+ chained_children = n.children[0..-2].map { |c| NodeChainer.chain(c) }
109
+ result.push Source::Chain::Array.new(chained_children)
107
110
  else
108
111
  lit = infer_literal_node_type(n)
109
112
  if lit
@@ -19,6 +19,8 @@ module Solargraph
19
19
 
20
20
  selected = rubyvm? ? Rubyvm : Legacy
21
21
  # include selected
22
+ # @!parse
23
+ # extend Solargraph::Parser::Legacy::ClassMethods
22
24
  extend selected::ClassMethods
23
25
 
24
26
  NodeMethods = (rubyvm? ? Rubyvm::NodeMethods : Legacy::NodeMethods)
@@ -217,7 +217,7 @@ module Solargraph
217
217
  end
218
218
 
219
219
  def identity
220
- @identity ||= "#{closure.context.namespace}|#{name}"
220
+ @identity ||= "#{closure.path}|#{name}"
221
221
  end
222
222
 
223
223
  def inspect
@@ -58,10 +58,10 @@ module Solargraph
58
58
  return Solargraph::ComplexType.parse(closure.binder.namespace)
59
59
  end
60
60
  end
61
- # other case without early return, read block yieldself tags
61
+ # other case without early return, read block yieldreceiver tags
62
62
  receiver_pin = chain.define(api_map, self, locals).first
63
63
  if receiver_pin && receiver_pin.docstring
64
- ys = receiver_pin.docstring.tag(:yieldself)
64
+ ys = receiver_pin.docstring.tag(:yieldreceiver)
65
65
  if ys && ys.types && !ys.types.empty?
66
66
  target = if chain.links.first.is_a?(Source::Chain::Constant)
67
67
  receiver_pin.full_context.namespace
@@ -12,7 +12,7 @@ module Solargraph
12
12
  # to a method pin on that type.
13
13
  #
14
14
  # @param resolved_method [Method] an already resolved method pin.
15
- # @param receiver [Source::Chain] the source code used to resolve the receiver for this delegated method.
15
+ # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
16
16
  # @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
17
17
  def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
18
18
  raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
@@ -19,7 +19,7 @@ module Solargraph
19
19
  # @param visibility [::Symbol] :public, :protected, or :private
20
20
  # @param explicit [Boolean]
21
21
  # @param parameters [Array<Pin::Parameter>]
22
- # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
22
+ # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node, nil]
23
23
  # @param attribute [Boolean]
24
24
  def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
25
25
  super(**splat)
@@ -46,7 +46,38 @@ module Solargraph
46
46
  end
47
47
 
48
48
  def return_type
49
- @return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
49
+ @return_type ||= ComplexType.new(signatures.map(&:return_type).flat_map(&:items))
50
+ end
51
+
52
+ # @return [Signature]
53
+ def generate_signature(parameters, return_type)
54
+ block = nil
55
+ yieldparam_tags = docstring.tags(:yieldparam)
56
+ yieldreturn_tags = docstring.tags(:yieldreturn)
57
+ needs_block_param_signature =
58
+ parameters.last&.block? || !yieldreturn_tags.empty? || !yieldparam_tags.empty?
59
+ if needs_block_param_signature
60
+ yield_parameters = yieldparam_tags.map do |p|
61
+ name = p.name
62
+ decl = :arg
63
+ if name
64
+ decl = select_decl(name, false)
65
+ name = clean_param(name)
66
+ end
67
+ Pin::Parameter.new(
68
+ location: location,
69
+ closure: self,
70
+ comments: p.text,
71
+ name: name,
72
+ decl: decl,
73
+ presence: location ? location.range : nil,
74
+ return_type: ComplexType.try_parse(*p.types)
75
+ )
76
+ end
77
+ yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
78
+ block = Signature.new(yield_parameters, yield_return_type)
79
+ end
80
+ Signature.new(parameters, return_type, block)
50
81
  end
51
82
 
52
83
  # @return [Array<Signature>]
@@ -54,9 +85,9 @@ module Solargraph
54
85
  @signatures ||= begin
55
86
  top_type = generate_complex_type
56
87
  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?
88
+ result.push generate_signature(parameters, top_type) if top_type.defined?
89
+ result.concat(overloads.map { |meth| generate_signature(meth.parameters, meth.return_type) }) unless overloads.empty?
90
+ result.push generate_signature(parameters, top_type) if result.empty?
60
91
  result
61
92
  end
62
93
  end
@@ -115,6 +146,32 @@ module Solargraph
115
146
  end
116
147
  @documentation += lines.join("\n")
117
148
  end
149
+ yieldparam_tags = docstring.tags(:yieldparam)
150
+ unless yieldparam_tags.nil? or yieldparam_tags.empty?
151
+ @documentation += "\n\n" unless @documentation.empty?
152
+ @documentation += "Block Params:\n"
153
+ lines = []
154
+ yieldparam_tags.each do |p|
155
+ l = "* #{p.name}"
156
+ l += " [#{escape_brackets(p.types.join(', '))}]" unless p.types.nil? or p.types.empty?
157
+ l += " #{p.text}"
158
+ lines.push l
159
+ end
160
+ @documentation += lines.join("\n")
161
+ end
162
+ yieldreturn_tags = docstring.tags(:yieldreturn)
163
+ unless yieldreturn_tags.empty?
164
+ @documentation += "\n\n" unless @documentation.empty?
165
+ @documentation += "Block Returns:\n"
166
+ lines = []
167
+ yieldreturn_tags.each do |r|
168
+ l = "*"
169
+ l += " [#{escape_brackets(r.types.join(', '))}]" unless r.types.nil? or r.types.empty?
170
+ l += " #{r.text}"
171
+ lines.push l
172
+ end
173
+ @documentation += lines.join("\n")
174
+ end
118
175
  return_tags = docstring.tags(:return)
119
176
  unless return_tags.empty?
120
177
  @documentation += "\n\n" unless @documentation.empty?