solargraph 0.39.0 → 0.39.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71e5d6fa6baec1130d64df74ed6fcf49c6c41df2f1386cb5cd2760a7605a9e48
4
- data.tar.gz: 91d9d6c695a63a0defab2c31967b2828907c800a94eb220c9210db9b672f2f27
3
+ metadata.gz: b287c1f54a79a771b343e16110cc0640a948abd0a6a5d7f187cd43e7bbea8b45
4
+ data.tar.gz: 9b425158e5ee4f420c0ea84397d7d171f1893f2e49aed6ebbb3c7f920618679d
5
5
  SHA512:
6
- metadata.gz: 2b37f7a917d8c865063f14c62e185e919cb88f221219fdc611ef003aa0a17af99bdd762fd4d4fc36105f37c36b0bdd4017500abe17b3aa1506423df8b16ee55a
7
- data.tar.gz: 60110bec4c847690cecdfa0d73d0495d09340a56ddf650dfbfc737e1f8b62682e1cce3de568edec7e52f4d4ff052e4c4746a2ec907c20320b6b133de610b6f3a
6
+ metadata.gz: b7c6214462ba598bfd184367c39d05264f82a5b0f94503ffe55ab321b8a8e7c8ef9da470780a7608b47c2360b8dc647d05a0546ff4ecddc6005ff2b015371629
7
+ data.tar.gz: 6810ce41c48475b6875b1337f56f3cd4553abba55e51a0c42158678a6545a4255e0c2ae96b51961fe4c23bee95afb3c8a78322db93a36ac85506a433ee73aaf8
@@ -78,6 +78,10 @@ module Solargraph
78
78
  NodeChainer.chain *args
79
79
  end
80
80
 
81
+ def chain_string *args
82
+ NodeChainer.load_string *args
83
+ end
84
+
81
85
  def process_node *args
82
86
  Solargraph::Parser::NodeProcessor.process *args
83
87
  end
@@ -73,8 +73,11 @@ module Solargraph
73
73
  end
74
74
  elsif n.type == :self
75
75
  result.push Chain::Head.new('self')
76
- elsif [:super, :zsuper].include?(n.type)
77
- result.push Chain::Head.new('super')
76
+ elsif n.type == :zsuper
77
+ result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
78
+ elsif n.type == :super
79
+ args = n.children.map { |c| NodeChainer.chain(c) }
80
+ result.push Chain::Call.new('super', args, @in_block || block_passed?(n))
78
81
  elsif n.type == :const
79
82
  const = unpack_name(n)
80
83
  result.push Chain::Constant.new(const)
@@ -126,7 +126,7 @@ module Solargraph
126
126
  result.push node
127
127
  node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
128
128
  node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
129
- elsif node.type == :send
129
+ elsif [:send, :super, :zsuper].include?(node.type)
130
130
  result.push node
131
131
  node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
132
132
  else
@@ -210,8 +210,12 @@ module Solargraph
210
210
  result.concat get_return_nodes_only(node.children[2])
211
211
  elsif node.type == :case
212
212
  node.children[1..-1].each do |cc|
213
- result.concat reduce_to_value_nodes(cc.children[1..-2])
214
- result.concat reduce_to_value_nodes([cc.children.last])
213
+ if cc.nil?
214
+ result.push NIL_NODE
215
+ else
216
+ result.concat reduce_to_value_nodes(cc.children[1..-2]) unless cc.children.length < 1
217
+ result.concat reduce_to_value_nodes([cc.children.last])
218
+ end
215
219
  end
216
220
  else
217
221
  result.push node
@@ -8,7 +8,7 @@ module Solargraph
8
8
  # @param filename [String]
9
9
  # @return [Array(Parser::AST::Node, Array<Parser::Source::Comment>)]
10
10
  def parse_with_comments code, filename = nil
11
- node = RubyVM::AbstractSyntaxTree.parse(code)
11
+ node = RubyVM::AbstractSyntaxTree.parse(code).children[2]
12
12
  comments = CommentRipper.new(code).parse
13
13
  [node, comments]
14
14
  rescue ::SyntaxError => e
@@ -20,7 +20,7 @@ module Solargraph
20
20
  # @param line [Integer]
21
21
  # @return [Parser::AST::Node]
22
22
  def parse code, filename = nil, line = 0
23
- RubyVM::AbstractSyntaxTree.parse(code)
23
+ RubyVM::AbstractSyntaxTree.parse(code).children[2]
24
24
  rescue ::SyntaxError => e
25
25
  raise Parser::SyntaxError, e.message
26
26
  end
@@ -83,6 +83,10 @@ module Solargraph
83
83
  NodeChainer.chain *args
84
84
  end
85
85
 
86
+ def chain_string *args
87
+ NodeChainer.load_string *args
88
+ end
89
+
86
90
  def process_node *args
87
91
  Solargraph::Parser::NodeProcessor.process *args
88
92
  end
@@ -69,8 +69,10 @@ module Solargraph
69
69
  result.push Chain::Call.new(n.children[0].to_s, node_to_argchains(n.children[1]), @in_block || block_passed?(n))
70
70
  elsif n.type == :SELF
71
71
  result.push Chain::Head.new('self')
72
- elsif [:SUPER, :ZSUPER].include?(n.type)
73
- result.push Chain::Head.new('super')
72
+ elsif n.type == :ZSUPER
73
+ result.push Chain::ZSuper.new('super', @in_block || block_passed?(n))
74
+ elsif n.type == :SUPER
75
+ result.push Chain::Call.new('super', node_to_argchains(n.children.last), @in_block || block_passed?(n))
74
76
  elsif [:COLON2, :COLON3, :CONST].include?(n.type)
75
77
  const = unpack_name(n)
76
78
  result.push Chain::Constant.new(const)
@@ -20,6 +20,7 @@ module Solargraph
20
20
  autoload :Head, 'solargraph/source/chain/head'
21
21
  autoload :Or, 'solargraph/source/chain/or'
22
22
  autoload :BlockVariable, 'solargraph/source/chain/block_variable'
23
+ autoload :ZSuper, 'solargraph/source/chain/z_super'
23
24
 
24
25
  @@inference_stack = []
25
26
  @@inference_depth = 0
@@ -28,6 +28,7 @@ module Solargraph
28
28
  # @param name_pin [Pin::Base]
29
29
  # @param locals [Array<Pin::Base>]
30
30
  def resolve api_map, name_pin, locals
31
+ return super_pins(api_map, name_pin) if word == 'super'
31
32
  found = if head?
32
33
  locals.select { |p| p.name == word }
33
34
  else
@@ -188,6 +189,14 @@ module Solargraph
188
189
  return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
189
190
  true
190
191
  end
192
+
193
+ # @param api_map [ApiMap]
194
+ # @param name_pin [Pin::Base]
195
+ # @return [Array<Pin::Base>]
196
+ def super_pins api_map, name_pin
197
+ pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
198
+ pins.reject{|p| p.path == name_pin.path}
199
+ end
191
200
  end
192
201
  end
193
202
  end
@@ -10,19 +10,25 @@ module Solargraph
10
10
  class Head < Link
11
11
  def resolve api_map, name_pin, locals
12
12
  return [Pin::ProxyType.anonymous(name_pin.binder)] if word == 'self'
13
- return super_pins(api_map, name_pin) if word == 'super'
13
+ # return super_pins(api_map, name_pin) if word == 'super'
14
14
  []
15
15
  end
16
16
 
17
+ # @todo This is temporary. Chain heads need to handle arguments to
18
+ # `super`.
19
+ # def arguments
20
+ # []
21
+ # end
22
+
17
23
  private
18
24
 
19
- # @param api_map [ApiMap]
20
- # @param name_pin [Pin::Base]
21
- # @return [Array<Pin::Base>]
22
- def super_pins api_map, name_pin
23
- pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
24
- pins.reject{|p| p.path == name_pin.path}
25
- end
25
+ # # @param api_map [ApiMap]
26
+ # # @param name_pin [Pin::Base]
27
+ # # @return [Array<Pin::Base>]
28
+ # def super_pins api_map, name_pin
29
+ # pins = api_map.get_method_stack(name_pin.namespace, name_pin.name, scope: name_pin.scope)
30
+ # pins.reject{|p| p.path == name_pin.path}
31
+ # end
26
32
  end
27
33
  end
28
34
  end
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ class Source
5
+ class Chain
6
+ class ZSuper < Call
7
+ # @return [String]
8
+ attr_reader :word
9
+
10
+ # @return [Array<Chain>]
11
+ attr_reader :arguments
12
+
13
+ # @param word [String]
14
+ # @param arguments [Array<Chain>]
15
+ # @param with_block [Boolean] True if the chain is inside a block
16
+ # @param head [Boolean] True if the call is the start of its chain
17
+ def initialize word, with_block = false
18
+ super(word, [], with_block)
19
+ end
20
+
21
+ def with_block?
22
+ @with_block
23
+ end
24
+
25
+ # @param api_map [ApiMap]
26
+ # @param name_pin [Pin::Base]
27
+ # @param locals [Array<Pin::Base>]
28
+ def resolve api_map, name_pin, locals
29
+ return super_pins(api_map, name_pin)
30
+ end
31
+
32
+ private
33
+
34
+ # @param pins [Array<Pin::Base>]
35
+ # @param api_map [ApiMap]
36
+ # @param context [ComplexType]
37
+ # @param locals [Pin::LocalVariable]
38
+ # @return [Array<Pin::Base>]
39
+ def inferred_pins pins, api_map, context, locals
40
+ result = pins.map do |p|
41
+ overloads = p.docstring.tags(:overload)
42
+ # next p if overloads.empty?
43
+ type = ComplexType::UNDEFINED
44
+ # @param [YARD::Tags::OverloadTag]
45
+ overloads.each do |ol|
46
+ next unless arguments_match(arguments, ol.parameters)
47
+ next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
48
+ match = true
49
+ arguments.each_with_index do |arg, idx|
50
+ achain = arguments[idx]
51
+ next if achain.nil?
52
+ param = ol.parameters[idx]
53
+ if param.nil?
54
+ match = false unless ol.parameters.last && ol.parameters.last.first.start_with?('*')
55
+ break
56
+ end
57
+ par = ol.tags(:param).select { |pp| pp.name == param.first }.first
58
+ next if par.nil? || par.types.nil? || par.types.empty?
59
+ atype = achain.infer(api_map, Pin::ProxyType.anonymous(context), locals)
60
+ other = ComplexType.try_parse(*par.types)
61
+ # @todo Weak type comparison
62
+ unless atype.tag == other.tag || api_map.super_and_sub?(other.tag, atype.tag)
63
+ match = false
64
+ break
65
+ end
66
+ end
67
+ if match
68
+ type = extra_return_type(ol, context)
69
+ type = ComplexType.try_parse(*ol.tag(:return).types).self_to(context.to_s).qualify(api_map, context.namespace) if ol.has_tag?(:return) && ol.tag(:return).types && !ol.tag(:return).types.empty? && (type.nil? || type.undefined?)
70
+ type ||= ComplexType::UNDEFINED
71
+ end
72
+ break if type.defined?
73
+ end
74
+ next p.proxy(type) if type.defined?
75
+ type = extra_return_type(p.docstring, context)
76
+ if type
77
+ next Solargraph::Pin::Method.new(
78
+ location: p.location,
79
+ closure: p.closure,
80
+ name: p.name,
81
+ comments: "@return [#{context.subtypes.first.to_s}]",
82
+ scope: p.scope,
83
+ visibility: p.visibility,
84
+ parameters: p.parameters,
85
+ node: p.node
86
+ )
87
+ end
88
+ if p.is_a?(Pin::Method) && !p.macros.empty?
89
+ result = process_macro(p, api_map, context, locals)
90
+ next result unless result.return_type.undefined?
91
+ elsif !p.directives.empty?
92
+ result = process_directive(p, api_map, context, locals)
93
+ next result unless result.return_type.undefined?
94
+ end
95
+ p
96
+ end
97
+ result.map do |pin|
98
+ next pin if pin.return_type.undefined?
99
+ selfy = pin.return_type.self_to(context.tag)
100
+ selfy == pin.return_type ? pin : pin.proxy(selfy)
101
+ end
102
+ end
103
+
104
+ # @param pin [Pin::Method]
105
+ # @param api_map [ApiMap]
106
+ # @param context [ComplexType]
107
+ # @param locals [Pin::Base]
108
+ # @return [Pin::Base]
109
+ def process_macro pin, api_map, context, locals
110
+ pin.macros.each do |macro|
111
+ result = inner_process_macro(pin, macro, api_map, context, locals)
112
+ return result unless result.return_type.undefined?
113
+ end
114
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
115
+ end
116
+
117
+ # @param pin [Pin::Method]
118
+ # @param api_map [ApiMap]
119
+ # @param context [ComplexType]
120
+ # @param locals [Pin::Base]
121
+ # @return [Pin::ProxyType]
122
+ def process_directive pin, api_map, context, locals
123
+ pin.directives.each do |dir|
124
+ macro = api_map.named_macro(dir.tag.name)
125
+ next if macro.nil?
126
+ result = inner_process_macro(pin, macro, api_map, context, locals)
127
+ return result unless result.return_type.undefined?
128
+ end
129
+ Pin::ProxyType.anonymous ComplexType::UNDEFINED
130
+ end
131
+
132
+ # @param pin [Pin]
133
+ # @param macro [YARD::Tags::MacroDirective]
134
+ # @param api_map [ApiMap]
135
+ # @param context [ComplexType]
136
+ # @param locals [Array<Pin::Base>]
137
+ # @return [Pin::ProxyType]
138
+ def inner_process_macro pin, macro, api_map, context, locals
139
+ vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
140
+ txt = macro.tag.text.clone
141
+ if txt.empty? && macro.tag.name
142
+ named = api_map.named_macro(macro.tag.name)
143
+ txt = named.tag.text.clone if named
144
+ end
145
+ i = 1
146
+ vals.each do |v|
147
+ txt.gsub!(/\$#{i}/, v.context.namespace)
148
+ i += 1
149
+ end
150
+ docstring = Solargraph::Source.parse_docstring(txt).to_docstring
151
+ tag = docstring.tag(:return)
152
+ unless tag.nil? || tag.types.nil?
153
+ return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
154
+ end
155
+ Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
156
+ end
157
+
158
+ # @param docstring [YARD::Docstring]
159
+ # @param context [ComplexType]
160
+ # @return [ComplexType]
161
+ def extra_return_type docstring, context
162
+ if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
163
+ return context.subtypes.first
164
+ elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
165
+ return context.value_types.first
166
+ end
167
+ nil
168
+ end
169
+
170
+ # @param arguments [Array<Chain>]
171
+ # @param parameters [Array<String>]
172
+ # @return [Boolean]
173
+ def arguments_match arguments, parameters
174
+ argcount = arguments.length
175
+ # argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
176
+ parcount = parameters.length
177
+ parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
178
+ return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
179
+ true
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -248,7 +248,11 @@ module Solargraph
248
248
  if pins.first.is_a?(Pin::BaseMethod)
249
249
  # @type [Pin::BaseMethod]
250
250
  pin = pins.first
251
- ap = arity_problems_for(pin, base.links.last.arguments, location)
251
+ if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
252
+ ap = arity_problems_for(pin, fake_args_for(block_pin), location)
253
+ else
254
+ ap = arity_problems_for(pin, base.links.last.arguments, location)
255
+ end
252
256
  unless ap.empty?
253
257
  result.concat ap
254
258
  break
@@ -470,5 +474,25 @@ module Solargraph
470
474
  pin.docstring.has_tag?(:abstract) ||
471
475
  (pin.closure && pin.closure.docstring.has_tag?(:abstract))
472
476
  end
477
+
478
+ def fake_args_for(pin)
479
+ args = []
480
+ with_opts = false
481
+ with_block = false
482
+ pin.parameters.each do |pin|
483
+ if [:kwarg, :kwoptarg, :kwrestarg].include?(pin.decl)
484
+ with_opts = true
485
+ elsif pin.decl == :block
486
+ with_block = true
487
+ elsif pin.decl == :restarg
488
+ args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)], nil, true)
489
+ else
490
+ args.push Solargraph::Source::Chain.new([Solargraph::Source::Chain::Variable.new(pin.name)])
491
+ end
492
+ end
493
+ args.push Solargraph::Parser.chain_string('{}') if with_opts
494
+ args.push Solargraph::Parser.chain_string('&') if with_block
495
+ args
496
+ end
473
497
  end
474
498
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.39.0'
4
+ VERSION = '0.39.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.39.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
@@ -513,6 +513,7 @@ files:
513
513
  - lib/solargraph/source/chain/literal.rb
514
514
  - lib/solargraph/source/chain/or.rb
515
515
  - lib/solargraph/source/chain/variable.rb
516
+ - lib/solargraph/source/chain/z_super.rb
516
517
  - lib/solargraph/source/change.rb
517
518
  - lib/solargraph/source/cursor.rb
518
519
  - lib/solargraph/source/encoding_fixes.rb