solargraph 0.39.11 → 0.39.13

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 005ae6488ba3fec9c5cd26d961b60ee1085a3020e3e52819b7da9351a6480cdd
4
- data.tar.gz: 0f8bf29d0c2d6a4577d4432cf89209d037d51186a5b709869fbcce793e98763e
3
+ metadata.gz: b06a4823fe5895875513bafc0192b627ecc2a5eff460bdc4e9bd511e8d31ecda
4
+ data.tar.gz: e5cfad1cfaa75dec019e2a772297c4f5c936370a9dcb49d1a61ae1e9e0529581
5
5
  SHA512:
6
- metadata.gz: 656cf961069df0d647886a0ea0555182a0be4c3fc3794ed0b70c41decee645ef76cdec1240c6e1c0d389fab842ce33a0dba6df74c49a59efc04359963d2e848d
7
- data.tar.gz: 1cb435e7a3b218fde5a0d3e3c9b5f27d376157fd7f316cd29cb4711de81fd5bac133b41c6e95b72249ec11d616fc98d13f6a5486d75b5dedede21e7bd12b43db
6
+ metadata.gz: 3e169cdfe2badf421a2323c6e796d346dea9c17f1b919a2d96de47ac7f1d0a3ebc77a799ac1ff7f44022b6621c01936fb31178ec9db56ea0b6ee63f44e279f47
7
+ data.tar.gz: 1c7783cd9b43ed4b9dc29a30fea180c10c9440961a630e7180f4101bcc064b40db9fd9018b5d94594cf061c9b993402cf18ffdcff3a4537f0366dd6f29992865
@@ -4,6 +4,11 @@ Solargraph is developed and maintained by [Castwide Technologies](https://castwi
4
4
 
5
5
  The following people and organizations provide funding or other resources. [Become a sponsor](https://patreon.com/castwide)
6
6
 
7
+ ## Linked Sponsors
8
+
9
+ - **[Calyptix Security](https://www.calyptix.com/)**
10
+
7
11
  ## Named Sponsors
8
12
 
9
13
  - Emily Strickland
14
+ - Tom de Grunt
@@ -423,7 +423,7 @@ module Solargraph
423
423
  # api_map.document('String#split')
424
424
  #
425
425
  # @param path [String] The path to find
426
- # @return [Array<YARD::CodeObject::Base>]
426
+ # @return [Array<YARD::CodeObjects::Base>]
427
427
  def document path
428
428
  rake_yard(store)
429
429
  docs = []
@@ -26,10 +26,10 @@ module Solargraph
26
26
  store = RuboCop::ConfigStore.new
27
27
  redirect_stdout { RuboCop::Runner.new(options, store).run(paths) }
28
28
  result = File.read(tempfile)
29
- File.unlink tempfile
30
29
  format original, result
31
30
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
32
31
  set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
32
+ ensure
33
33
  File.unlink tempfile
34
34
  end
35
35
  end
@@ -171,7 +171,21 @@ module Solargraph
171
171
  def definitions_at filename, line, column
172
172
  position = Position.new(line, column)
173
173
  cursor = Source::Cursor.new(read(filename), position)
174
- api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
174
+ if cursor.comment?
175
+ source = read(filename)
176
+ offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
177
+ lft = source.code[0..offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
178
+ rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
179
+ if lft && rgt
180
+ tag = lft[1] + rgt[1]
181
+ clip = api_map.clip(cursor)
182
+ clip.translate tag
183
+ else
184
+ []
185
+ end
186
+ else
187
+ api_map.clip(cursor).define.map { |pin| pin.realize(api_map) }
188
+ end
175
189
  end
176
190
 
177
191
  # Get signature suggestions for the method at the specified file and
@@ -245,7 +259,7 @@ module Solargraph
245
259
  end
246
260
 
247
261
  # @param query [String]
248
- # @return [Array<YARD::CodeObject::Base>]
262
+ # @return [Array<YARD::CodeObjects::Base>]
249
263
  def document query
250
264
  catalog
251
265
  api_map.document query
@@ -124,7 +124,9 @@ module Solargraph
124
124
  result = []
125
125
  if node.type == :block
126
126
  result.push node
127
- node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
127
+ if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
128
+ node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
129
+ end
128
130
  node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
129
131
  elsif node.type == :send
130
132
  result.push node
@@ -6,6 +6,12 @@ module Solargraph
6
6
  class Method < Pin::Method
7
7
  include YardMixin
8
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
10
+ # @param name [String, nil]
11
+ # @param scope [Symbol, nil]
12
+ # @param visibility [Symbol, nil]
13
+ # @param closure [Solargraph::Pin::Closure, nil]
14
+ # @param spec [Gem::Specification]
9
15
  def initialize code_object, name = nil, scope = nil, visibility = nil, closure = nil, spec = nil
10
16
  closure ||= Solargraph::Pin::Namespace.new(
11
17
  name: code_object.namespace.to_s,
@@ -25,9 +31,14 @@ module Solargraph
25
31
 
26
32
  private
27
33
 
34
+ # @param code_object [YARD::CodeObjects::Base]
35
+ # @return [Array<Solargraph::Pin::Parameter>]
28
36
  def get_parameters code_object
29
37
  return [] unless code_object.is_a?(YARD::CodeObjects::MethodObject)
30
- code_object.parameters.map do |a|
38
+ # HACK: Skip `nil` and `self` parameters that are sometimes emitted
39
+ # for methods defined in C
40
+ # See https://github.com/castwide/solargraph/issues/345
41
+ code_object.parameters.select { |a| a[0] && a[0] != 'self' }.map do |a|
31
42
  Solargraph::Pin::Parameter.new(
32
43
  location: location,
33
44
  closure: self,
@@ -40,10 +51,14 @@ module Solargraph
40
51
  end
41
52
  end
42
53
 
54
+ # @param a [Array]
55
+ # @return [String]
43
56
  def arg_name a
44
57
  a[0].match(/[A-Za-z0-9_]*/)[0]
45
58
  end
46
59
 
60
+ # @param a [Array]
61
+ # @return [Symbol]
47
62
  def arg_type a
48
63
  if a[0].start_with?('**')
49
64
  :kwrestarg
@@ -4,16 +4,10 @@ module Solargraph
4
4
  module Pin
5
5
  module YardPin
6
6
  module YardMixin
7
- attr_reader :code_object
8
-
9
- attr_reader :spec
10
-
11
- attr_reader :location
12
-
13
- @@gate_cache ||= {}
14
-
15
7
  private
16
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
10
+ # @param spec [Gem::Specification]
17
11
  # @return [Solargraph::Location, nil]
18
12
  def object_location code_object, spec
19
13
  return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
@@ -18,166 +18,12 @@ module Solargraph
18
18
  super(word, [], with_block)
19
19
  end
20
20
 
21
- def with_block?
22
- @with_block
23
- end
24
-
25
21
  # @param api_map [ApiMap]
26
22
  # @param name_pin [Pin::Base]
27
23
  # @param locals [Array<Pin::Base>]
28
24
  def resolve api_map, name_pin, locals
29
25
  return super_pins(api_map, name_pin)
30
26
  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
27
  end
182
28
  end
183
29
  end
@@ -25,51 +25,12 @@ module Solargraph
25
25
  def complete
26
26
  return package_completions([]) if !source_map.source.parsed? || cursor.string?
27
27
  return package_completions(api_map.get_symbols) if cursor.chain.literal? && cursor.chain.links.last.word == '<Symbol>'
28
- return Completion.new([], cursor.range) if cursor.chain.literal? || cursor.comment?
29
- result = []
30
- result.concat complete_keyword_parameters
31
- if cursor.chain.constant? || cursor.start_of_constant?
32
- full = cursor.chain.links.first.word
33
- type = if cursor.chain.undefined?
34
- cursor.chain.base.infer(api_map, context_pin, locals)
35
- else
36
- if full.include?('::') && cursor.chain.links.length == 1
37
- ComplexType.try_parse(full.split('::')[0..-2].join('::'))
38
- elsif cursor.chain.links.length > 1
39
- ComplexType.try_parse(full)
40
- else
41
- ComplexType::UNDEFINED
42
- end
43
- end
44
- if type.undefined?
45
- if full.include?('::')
46
- result.concat api_map.get_constants(full, *gates)
47
- else
48
- result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
49
- end
50
- else
51
- result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
52
- end
28
+ return Completion.new([], cursor.range) if cursor.chain.literal?
29
+ if cursor.comment?
30
+ tag_complete
53
31
  else
54
- type = cursor.chain.base.infer(api_map, block, locals)
55
- result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
56
- if cursor.chain.links.length == 1
57
- if cursor.word.start_with?('@@')
58
- return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
59
- elsif cursor.word.start_with?('@')
60
- return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
61
- elsif cursor.word.start_with?('$')
62
- return package_completions(api_map.get_global_variable_pins)
63
- end
64
- result.concat locals
65
- result.concat api_map.get_constants(context_pin.context.namespace, *gates)
66
- result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
67
- result.concat api_map.get_methods('Kernel')
68
- result.concat ApiMap.keywords
69
- result.concat yielded_self_pins
70
- end
32
+ code_complete
71
33
  end
72
- package_completions(result)
73
34
  end
74
35
 
75
36
  # @return [Array<Pin::Base>]
@@ -111,6 +72,13 @@ module Solargraph
111
72
  end
112
73
  end
113
74
 
75
+ # @param phrase [String]
76
+ # @return [Array<Solargraph::Pin::Base>]
77
+ def translate phrase
78
+ chain = Parser.chain(Parser.parse(phrase))
79
+ chain.define(api_map, block, locals)
80
+ end
81
+
114
82
  private
115
83
 
116
84
  # @return [ApiMap]
@@ -185,6 +153,71 @@ module Solargraph
185
153
  }
186
154
  Completion.new(filtered, cursor.range)
187
155
  end
156
+
157
+ def tag_complete
158
+ result = []
159
+ match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
160
+ if match
161
+ full = match[1]
162
+ if full.include?('::')
163
+ if full.end_with?('::')
164
+ result.concat api_map.get_constants(full[0..-3], *gates)
165
+ else
166
+ result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
167
+ end
168
+ else
169
+ result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
170
+ end
171
+ end
172
+ package_completions(result)
173
+ end
174
+
175
+ def code_complete
176
+ result = []
177
+ result.concat complete_keyword_parameters
178
+ if cursor.chain.constant? || cursor.start_of_constant?
179
+ full = cursor.chain.links.first.word
180
+ type = if cursor.chain.undefined?
181
+ cursor.chain.base.infer(api_map, context_pin, locals)
182
+ else
183
+ if full.include?('::') && cursor.chain.links.length == 1
184
+ ComplexType.try_parse(full.split('::')[0..-2].join('::'))
185
+ elsif cursor.chain.links.length > 1
186
+ ComplexType.try_parse(full)
187
+ else
188
+ ComplexType::UNDEFINED
189
+ end
190
+ end
191
+ if type.undefined?
192
+ if full.include?('::')
193
+ result.concat api_map.get_constants(full, *gates)
194
+ else
195
+ result.concat api_map.get_constants('', cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
196
+ end
197
+ else
198
+ result.concat api_map.get_constants(type.namespace, cursor.start_of_constant? ? '' : context_pin.full_context.namespace, *gates)
199
+ end
200
+ else
201
+ type = cursor.chain.base.infer(api_map, block, locals)
202
+ result.concat api_map.get_complex_type_methods(type, block.binder.namespace, cursor.chain.links.length == 1)
203
+ if cursor.chain.links.length == 1
204
+ if cursor.word.start_with?('@@')
205
+ return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
206
+ elsif cursor.word.start_with?('@')
207
+ return package_completions(api_map.get_instance_variable_pins(block.binder.namespace, block.binder.scope))
208
+ elsif cursor.word.start_with?('$')
209
+ return package_completions(api_map.get_global_variable_pins)
210
+ end
211
+ result.concat locals
212
+ result.concat api_map.get_constants(context_pin.context.namespace, *gates)
213
+ result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
214
+ result.concat api_map.get_methods('Kernel')
215
+ result.concat ApiMap.keywords
216
+ result.concat yielded_self_pins
217
+ end
218
+ end
219
+ package_completions(result)
220
+ end
188
221
  end
189
222
  end
190
223
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.39.11'
4
+ VERSION = '0.39.13'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.11
4
+ version: 0.39.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-03 00:00:00.000000000 Z
11
+ date: 2020-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport