solargraph 0.39.7 → 0.39.12

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: 86abdabe74326a279a6dc6c3f02ff09dc469e1e92cfd5f89ac3a3363ce47e146
4
- data.tar.gz: 1772fe6f16f7531758d5c5853201b86c334eec8ef3f049ae764f6aa3d2d4c118
3
+ metadata.gz: 94e2150b6575ab34c7a13a51616cdbce7e21e13bff1b6cc2e6f4307960501acb
4
+ data.tar.gz: 474e22c2f716481a1410a8ba5199ce94b9d912573a29e077c29cea075fb8fd3d
5
5
  SHA512:
6
- metadata.gz: 6256341e8373235c53af95ab62fc61b02c2a3b755391786d6d28ae8b2373a141f8b4b875789760adfbdf333dfd020bff15d791c4d423cd90f5b96b6e8d9e2750
7
- data.tar.gz: da4580767cecf3c62ad1e949a3ee0a97ac3a07785e52cacc5d53977f6ac6db8db4507c912136455646be196aa915920632e776aec98ddeb1d686868539707290
6
+ metadata.gz: ded8a57414921d2fc45616d9f8d10c8c6581d1769657968bd3b40e3b59d199f4090e9e086319cbea26dd9f4cab0d7231ebfd2b58b7f8f15524de745fc351ea88
7
+ data.tar.gz: f6fabb492847eb4091b0d642d9b41a28abb1b39e983f338828b17baf3a79aad1006244ef2dafbbd51757e11e4ac91eb721431151afe0e61ee11dc792e3d045f5
@@ -7,3 +7,4 @@ The following people and organizations provide funding or other resources. [Beco
7
7
  ## Named Sponsors
8
8
 
9
9
  - Emily Strickland
10
+ - Tom de Grunt
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ Encoding.default_external = 'UTF-8'
4
+
5
+ require 'solargraph/compat'
3
6
  require 'solargraph/version'
4
7
 
5
8
  # The top-level namespace for the Solargraph code mapping, documentation,
@@ -26,7 +26,6 @@ module Solargraph
26
26
  def initialize pins: []
27
27
  @source_map_hash = {}
28
28
  @cache = Cache.new
29
- @mutex = Mutex.new
30
29
  @method_alias_stack = []
31
30
  index pins
32
31
  end
@@ -34,13 +33,11 @@ module Solargraph
34
33
  # @param pins [Array<Pin::Base>]
35
34
  # @return [self]
36
35
  def index pins
37
- @mutex.synchronize {
38
- @source_map_hash.clear
39
- @cache.clear
40
- @store = Store.new(pins + YardMap.new.pins)
41
- @unresolved_requires = []
42
- workspace_filenames.clear
43
- }
36
+ @source_map_hash.clear
37
+ @cache.clear
38
+ @store = Store.new(pins + YardMap.new.pins)
39
+ @unresolved_requires = []
40
+ workspace_filenames.clear
44
41
  self
45
42
  end
46
43
 
@@ -123,14 +120,14 @@ module Solargraph
123
120
  reqs.merge br.keys
124
121
  yard_map.change(reqs.to_a, br, bundle.workspace.gemnames)
125
122
  new_store = Store.new(pins + yard_map.pins)
126
- @mutex.synchronize {
127
- @cache.clear
128
- @source_map_hash = new_map_hash
129
- @store = new_store
130
- @unresolved_requires = yard_map.unresolved_requires
131
- workspace_filenames.clear
132
- workspace_filenames.concat bundle.workspace.filenames
133
- }
123
+ @cache.clear
124
+ @source_map_hash = new_map_hash
125
+ @store = new_store
126
+ @unresolved_requires = yard_map.unresolved_requires
127
+ workspace_filenames.clear
128
+ workspace_filenames.concat bundle.workspace.filenames
129
+ @rebindable_method_names = nil
130
+ store.block_pins.each { |blk| blk.rebind(self) }
134
131
  self
135
132
  end
136
133
 
@@ -179,6 +176,16 @@ module Solargraph
179
176
  store.pins
180
177
  end
181
178
 
179
+ def rebindable_method_names
180
+ @rebindable_method_names ||= begin
181
+ result = yard_map.rebindable_method_names
182
+ source_maps.each do |map|
183
+ result.merge map.rebindable_method_names
184
+ end
185
+ result
186
+ end
187
+ end
188
+
182
189
  # An array of pins based on Ruby keywords (`if`, `end`, etc.).
183
190
  #
184
191
  # @return [Array<Solargraph::Pin::Keyword>]
@@ -280,8 +287,7 @@ module Solargraph
280
287
 
281
288
  # @return [Array<Solargraph::Pin::GlobalVariable>]
282
289
  def get_global_variable_pins
283
- # @todo Slow version
284
- pins.select{ |p| p.is_a?(Pin::GlobalVariable) }
290
+ store.pins_by_class(Pin::GlobalVariable)
285
291
  end
286
292
 
287
293
  # Get an array of methods available in a particular context.
@@ -535,17 +541,17 @@ module Solargraph
535
541
  #
536
542
  # @return [Hash{String => SourceMap}]
537
543
  def source_map_hash
538
- @mutex.synchronize { @source_map_hash }
544
+ @source_map_hash
539
545
  end
540
546
 
541
547
  # @return [ApiMap::Store]
542
548
  def store
543
- @mutex.synchronize { @store }
549
+ @store
544
550
  end
545
551
 
546
552
  # @return [Solargraph::ApiMap::Cache]
547
553
  def cache
548
- @mutex.synchronize { @cache }
554
+ @cache
549
555
  end
550
556
 
551
557
  # @param fqns [String] A fully qualified namespace
@@ -10,6 +10,7 @@ module Solargraph
10
10
  @receiver_definitions = {}
11
11
  end
12
12
 
13
+ # @return [Array<Pin::BaseMethod>]
13
14
  def get_methods fqns, scope, visibility, deep
14
15
  @methods[[fqns, scope, visibility.sort, deep]]
15
16
  end
@@ -18,6 +19,7 @@ module Solargraph
18
19
  @methods[[fqns, scope, visibility.sort, deep]] = value
19
20
  end
20
21
 
22
+ # @return [Array<Pin::Base>]
21
23
  def get_constants namespace, context
22
24
  @constants[[namespace, context]]
23
25
  end
@@ -26,6 +28,7 @@ module Solargraph
26
28
  @constants[[namespace, context]] = value
27
29
  end
28
30
 
31
+ # @return [String]
29
32
  def get_qualified_namespace name, context
30
33
  @qualified_namespaces[[name, context]]
31
34
  end
@@ -38,6 +41,7 @@ module Solargraph
38
41
  @receiver_definitions.key? path
39
42
  end
40
43
 
44
+ # @return [Pin::BaseMethod]
41
45
  def get_receiver_definition path
42
46
  @receiver_definitions[path]
43
47
  end
@@ -99,12 +99,12 @@ module Solargraph
99
99
 
100
100
  # @return [Array<Solargraph::Pin::Base>]
101
101
  def namespace_pins
102
- @namespace_pins ||= []
102
+ pins_by_class(Solargraph::Pin::Namespace)
103
103
  end
104
104
 
105
- # @return [Array<Solargraph::Pin::Base>]
105
+ # @return [Array<Solargraph::Pin::BaseMethod>]
106
106
  def method_pins
107
- @method_pins ||= []
107
+ pins_by_class(Solargraph::Pin::BaseMethod)
108
108
  end
109
109
 
110
110
  # @param fqns [String]
@@ -133,7 +133,7 @@ module Solargraph
133
133
 
134
134
  # @return [Array<Pin::Block>]
135
135
  def block_pins
136
- @block_pins ||= []
136
+ pins_by_class(Pin::Block)
137
137
  end
138
138
 
139
139
  def inspect
@@ -141,6 +141,12 @@ module Solargraph
141
141
  to_s
142
142
  end
143
143
 
144
+ # @param klass [Class]
145
+ # @return [Array<Solargraph::Pin::Base>]
146
+ def pins_by_class klass
147
+ @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
148
+ end
149
+
144
150
  private
145
151
 
146
152
  # @param fqns [String]
@@ -167,7 +173,7 @@ module Solargraph
167
173
 
168
174
  # @return [Array<Solargraph::Pin::Symbol>]
169
175
  def symbols
170
- @symbols ||= []
176
+ pins_by_class(Pin::Symbol)
171
177
  end
172
178
 
173
179
  def superclass_references
@@ -198,7 +204,7 @@ module Solargraph
198
204
  end
199
205
 
200
206
  def all_instance_variables
201
- @all_instance_variables ||= []
207
+ pins_by_class(Pin::InstanceVariable)
202
208
  end
203
209
 
204
210
  def path_pin_hash
@@ -207,48 +213,29 @@ module Solargraph
207
213
 
208
214
  # @return [void]
209
215
  def index
210
- namespace_map.clear
211
- namespaces.clear
212
- namespace_pins.clear
213
- method_pins.clear
214
- symbols.clear
215
- block_pins.clear
216
- all_instance_variables.clear
217
- path_pin_hash.clear
218
- namespace_map[''] = []
219
- override_pins = []
220
- pins.each do |pin|
221
- namespace_map[pin.namespace] ||= []
222
- namespace_map[pin.namespace].push pin
223
- namespaces.add pin.path if pin.is_a?(Pin::Namespace) && !pin.path.empty?
224
- namespace_pins.push pin if pin.is_a?(Pin::Namespace)
225
- method_pins.push pin if pin.is_a?(Pin::BaseMethod)
226
- symbols.push pin if pin.is_a?(Pin::Symbol)
227
- if pin.is_a?(Pin::Reference::Include)
228
- include_references[pin.namespace] ||= []
229
- include_references[pin.namespace].push pin.name
230
- elsif pin.is_a?(Pin::Reference::Prepend)
231
- prepend_references[pin.namespace] ||= []
232
- prepend_references[pin.namespace].push pin.name
233
- elsif pin.is_a?(Pin::Reference::Extend)
234
- extend_references[pin.namespace] ||= []
235
- extend_references[pin.namespace].push pin.name
236
- elsif pin.is_a?(Pin::Reference::Superclass)
237
- superclass_references[pin.namespace] ||= []
238
- superclass_references[pin.namespace].push pin.name
239
- elsif pin.is_a?(Pin::Block)
240
- block_pins.push pin
241
- elsif pin.is_a?(Pin::InstanceVariable)
242
- all_instance_variables.push pin
243
- elsif pin.is_a?(Pin::Reference::Override)
244
- override_pins.push pin
245
- end
246
- if pin.path
247
- path_pin_hash[pin.path] ||= []
248
- path_pin_hash[pin.path].push pin
249
- end
216
+ set = pins.to_set
217
+ @pin_class_hash = set.classify(&:class).transform_values(&:to_a)
218
+ @pin_select_cache = {}
219
+ @namespace_map = set.classify(&:namespace).transform_values(&:to_a)
220
+ @path_pin_hash = set.classify(&:path).transform_values(&:to_a)
221
+ @namespaces = @path_pin_hash.keys.compact
222
+ pins_by_class(Pin::Reference::Include).each do |pin|
223
+ include_references[pin.namespace] ||= []
224
+ include_references[pin.namespace].push pin.name
225
+ end
226
+ pins_by_class(Pin::Reference::Prepend).each do |pin|
227
+ prepend_references[pin.namespace] ||= []
228
+ prepend_references[pin.namespace].push pin.name
229
+ end
230
+ pins_by_class(Pin::Reference::Extend).each do |pin|
231
+ extend_references[pin.namespace] ||= []
232
+ extend_references[pin.namespace].push pin.name
233
+ end
234
+ pins_by_class(Pin::Reference::Superclass).each do |pin|
235
+ superclass_references[pin.namespace] ||= []
236
+ superclass_references[pin.namespace].push pin.name
250
237
  end
251
- override_pins.each do |ovr|
238
+ pins_by_class(Pin::Reference::Override).each do |ovr|
252
239
  pin = get_path_pins(ovr.name).first
253
240
  next if pin.nil?
254
241
  (ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
@@ -261,6 +248,7 @@ module Solargraph
261
248
  # @todo This is probably not the best place for these overrides
262
249
  superclass_references['Integer'] = ['Numeric']
263
250
  superclass_references['Float'] = ['Numeric']
251
+ superclass_references['File'] = ['IO']
264
252
  end
265
253
  end
266
254
  end
@@ -0,0 +1,9 @@
1
+ unless Hash.method_defined?(:transform_values)
2
+ class Hash
3
+ def transform_values &block
4
+ each_pair do |k, v|
5
+ self[k] = block.call(v)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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
@@ -339,7 +353,7 @@ module Solargraph
339
353
  logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
340
354
  api_map.catalog bundle
341
355
  @synchronized = true
342
- logger.info "Catalog complete (#{api_map.pins.length} pins)"
356
+ logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)" if logger.info?
343
357
  end
344
358
  end
345
359
 
@@ -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
@@ -36,6 +36,8 @@ module Solargraph
36
36
  process_prepend
37
37
  elsif node.children[1] == :require
38
38
  process_require
39
+ elsif node.children[1] == :autoload
40
+ process_autoload
39
41
  elsif node.children[1] == :private_constant
40
42
  process_private_constant
41
43
  elsif node.children[1] == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
@@ -138,6 +140,14 @@ module Solargraph
138
140
  end
139
141
  end
140
142
 
143
+ # @return [void]
144
+ def process_autoload
145
+ if node.children[3].is_a?(AST::Node) && node.children[3].type == :str
146
+ path = node.children[3].children[0].to_s
147
+ pins.push Pin::Reference::Require.new(get_node_location(node), path)
148
+ end
149
+ end
150
+
141
151
  # @return [void]
142
152
  def process_module_function
143
153
  if node.children[2].nil?
@@ -28,6 +28,8 @@ module Solargraph
28
28
  process_module_function
29
29
  elsif node.children[0] == :require
30
30
  process_require
31
+ elsif node.children[0] == :autoload
32
+ process_autoload
31
33
  elsif node.children[0] == :alias_method
32
34
  process_alias_method
33
35
  elsif node.children[0] == :private_class_method
@@ -143,6 +145,15 @@ module Solargraph
143
145
  end
144
146
  end
145
147
 
148
+ # @return [void]
149
+ def process_autoload
150
+ return unless Parser.is_ast_node?(node.children[1]) && Parser.is_ast_node?(node.children[1].children[1])
151
+ arg = node.children[1].children[1]
152
+ if arg.type == :STR
153
+ pins.push Pin::Reference::Require.new(get_node_location(arg), arg.children[0])
154
+ end
155
+ end
156
+
146
157
  # @return [void]
147
158
  def process_module_function
148
159
  if node.type == :VCALL
@@ -23,7 +23,7 @@ module Solargraph
23
23
 
24
24
  # @param location [Solargraph::Location]
25
25
  # @param kind [Integer]
26
- # @param closure [String]
26
+ # @param closure [Solargraph::Pin::Closure]
27
27
  # @param name [String]
28
28
  # @param comments [String]
29
29
  def initialize location: nil, closure: nil, name: '', comments: ''
@@ -38,7 +38,7 @@ module Solargraph
38
38
  @comments ||= ''
39
39
  end
40
40
 
41
- # @return [String]
41
+ # @return [String, nil]
42
42
  def filename
43
43
  return nil if location.nil?
44
44
  location.filename
@@ -14,17 +14,14 @@ module Solargraph
14
14
  @parameters = args
15
15
  end
16
16
 
17
- def rebind context
18
- @rebound = true
19
- @binder = context unless context.undefined?
20
- end
21
-
22
- def rebound?
23
- @rebound ||= false
17
+ # @param api_map [ApiMap]
18
+ # @return [void]
19
+ def rebind api_map
20
+ @binder ||= binder_or_nil(api_map)
24
21
  end
25
22
 
26
23
  def binder
27
- @binder || context
24
+ @binder || closure.binder
28
25
  end
29
26
 
30
27
  # @return [Array<String>]
@@ -37,11 +34,28 @@ module Solargraph
37
34
  @parameter_names ||= parameters.map(&:name)
38
35
  end
39
36
 
40
- def nearly? other
41
- return false unless super
42
- # @todo Trying to not to block merges too much
43
- # receiver == other.receiver and parameters == other.parameters
44
- true
37
+ private
38
+
39
+ # @param api_map [ApiMap]
40
+ # @return [ComplexType, nil]
41
+ def binder_or_nil api_map
42
+ return nil unless receiver
43
+ word = receiver.children.find { |c| c.is_a?(::Symbol) }.to_s
44
+ return nil unless api_map.rebindable_method_names.include?(word)
45
+ chain = Parser.chain(receiver, location.filename)
46
+ locals = api_map.source_map(location.filename).locals_at(location)
47
+ if ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'].include?(chain.links.last.word)
48
+ return chain.base.infer(api_map, self, locals)
49
+ else
50
+ receiver_pin = chain.define(api_map, self, locals).first
51
+ if receiver_pin && receiver_pin.docstring
52
+ ys = receiver_pin.docstring.tag(:yieldself)
53
+ if ys && ys.types && !ys.types.empty?
54
+ return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
55
+ end
56
+ end
57
+ end
58
+ nil
45
59
  end
46
60
  end
47
61
  end
@@ -53,13 +53,14 @@ module Solargraph
53
53
  # @param text [String]
54
54
  # @return [String]
55
55
  def escape_brackets text
56
- text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '!!!`\1`!!!\2')
56
+ # text.gsub(/(\[[^\]]*\])([^\(]|\z)/, '!!!^\1^!!!\2')
57
+ text.gsub('[', '!!!!b').gsub(']', 'e!!!!')
57
58
  end
58
59
 
59
60
  # @param text [String]
60
61
  # @return [String]
61
62
  def unescape_brackets text
62
- text.gsub('!!!`[', '[').gsub(']`!!!', ']')
63
+ text.gsub('!!!!b', '[').gsub('e!!!!', ']')
63
64
  end
64
65
  end
65
66
 
@@ -5,7 +5,7 @@ module Solargraph
5
5
  class Method < BaseMethod
6
6
  include Solargraph::Parser::NodeMethods
7
7
 
8
- # @return [Array<String>]
8
+ # @return [Array<Pin::Parameter>]
9
9
  attr_reader :parameters
10
10
 
11
11
  # @param args [Array<String>]
@@ -57,7 +57,6 @@ module Solargraph
57
57
  # @param locals [Array<Pin::Base>]
58
58
  # @return [Array<Pin::Base>]
59
59
  def define api_map, name_pin, locals
60
- rebind_block name_pin, api_map, locals
61
60
  return [] if undefined?
62
61
  working_pin = name_pin
63
62
  links[0..-2].each do |link|
@@ -79,7 +78,6 @@ module Solargraph
79
78
  # @param locals [Array<Pin::Base>]
80
79
  # @return [ComplexType]
81
80
  def infer api_map, name_pin, locals
82
- rebind_block name_pin, api_map, locals
83
81
  pins = define(api_map, name_pin, locals)
84
82
  infer_first_defined(pins, links.last.last_context, api_map)
85
83
  end
@@ -138,35 +136,6 @@ module Solargraph
138
136
  return type if context.nil? || context.return_type.undefined?
139
137
  type.self_to(context.return_type.namespace)
140
138
  end
141
-
142
- def skippable_block_receivers api_map
143
- @@skippable_block_receivers ||= (
144
- api_map.get_methods('Array', deep: false).map(&:name) +
145
- api_map.get_methods('Enumerable', deep: false).map(&:name) +
146
- api_map.get_methods('Hash', deep: false).map(&:name) +
147
- ['new']
148
- ).to_set
149
- end
150
-
151
- def rebind_block pin, api_map, locals
152
- return unless pin.is_a?(Pin::Block) && pin.receiver && !pin.rebound?
153
- # This first rebind just sets the block pin's rebound state
154
- pin.rebind ComplexType::UNDEFINED
155
- chain = Parser.chain(pin.receiver, pin.location.filename)
156
- return if skippable_block_receivers(api_map).include?(chain.links.last.word)
157
- if ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'].include?(chain.links.last.word)
158
- type = chain.base.infer(api_map, pin, locals)
159
- pin.rebind type
160
- else
161
- receiver_pin = chain.define(api_map, pin, locals).first
162
- return if receiver_pin.nil? || receiver_pin.docstring.nil?
163
- ys = receiver_pin.docstring.tag(:yieldself)
164
- unless ys.nil? || ys.types.nil? || ys.types.empty?
165
- ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
166
- pin.rebind ysct
167
- end
168
- end
169
- end
170
139
  end
171
140
  end
172
141
  end
@@ -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
@@ -17,7 +17,6 @@ module Solargraph
17
17
  # @param position [Position]
18
18
  # @return [Source::Chain]
19
19
  def chain source, position
20
- # raise "Not a source" unless source.is_a?(Source)
21
20
  new(source, position).chain
22
21
  end
23
22
  end
@@ -32,6 +31,8 @@ module Solargraph
32
31
 
33
32
  # @return [Source::Chain]
34
33
  def chain
34
+ # Special handling for files that end with an integer and a period
35
+ return Chain.new([Chain::Literal.new('Integer'), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/
35
36
  return Chain.new([Chain::Literal.new('Symbol')]) if phrase.start_with?(':') && !phrase.start_with?('::')
36
37
  begin
37
38
  return Chain.new([]) if phrase.end_with?('..')
@@ -3,6 +3,7 @@
3
3
  require 'jaro_winkler'
4
4
  require 'yard'
5
5
  require 'yard-solargraph'
6
+ require 'set'
6
7
 
7
8
  module Solargraph
8
9
  # An index of pins and other ApiMap-related data for a Source.
@@ -30,6 +31,19 @@ module Solargraph
30
31
  @pins = pins
31
32
  @locals = locals
32
33
  environ.merge Convention.for(source)
34
+ @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
35
+ @pin_select_cache = {}
36
+ end
37
+
38
+ def pins_by_class klass
39
+ @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
40
+ end
41
+
42
+ def rebindable_method_names
43
+ @rebindable_method_names ||= pins_by_class(Pin::Method)
44
+ .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
45
+ .map(&:name)
46
+ .to_set
33
47
  end
34
48
 
35
49
  # @return [String]
@@ -44,7 +58,7 @@ module Solargraph
44
58
 
45
59
  # @return [Array<Pin::Reference::Require>]
46
60
  def requires
47
- @requires ||= pins.select{ |p| p.is_a?(Pin::Reference::Require) }
61
+ pins_by_class(Pin::Reference::Require)
48
62
  end
49
63
 
50
64
  # @return [Environ]
@@ -62,6 +76,7 @@ module Solargraph
62
76
  # @param query [String]
63
77
  # @return [Array<Pin::Base>]
64
78
  def query_symbols query
79
+ return document_symbols if query && query.empty?
65
80
  document_symbols.select{ |pin| fuzzy_string_match(pin.path, query) || fuzzy_string_match(pin.name, query) }
66
81
  end
67
82
 
@@ -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
@@ -95,6 +95,7 @@ module Solargraph
95
95
  # @param source_position [Position]
96
96
  # @param comment_position [Position]
97
97
  # @param directive [YARD::Tags::Directive]
98
+ # @return [void]
98
99
  def process_directive source_position, comment_position, directive
99
100
  docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
100
101
  location = Location.new(@filename, Range.new(comment_position, comment_position))
@@ -104,10 +105,10 @@ module Solargraph
104
105
  if namespace.location.range.start.line < comment_position.line
105
106
  namespace = closure_at(comment_position)
106
107
  end
107
- region = Parser::Region.new(source: @source, closure: namespace)
108
108
  begin
109
- src_node = Parser.parse("def #{directive.tag.name};end", @filename, location.range.start.line)
110
- gen_pin = Parser.process_node(src_node, region).first.last
109
+ src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
110
+ region = Parser::Region.new(source: src, closure: namespace)
111
+ gen_pin = Parser.process_node(src.node, region).first.last
111
112
  return if gen_pin.nil?
112
113
  # Move the location to the end of the line so it gets recognized
113
114
  # as originating from a comment
@@ -148,12 +149,23 @@ module Solargraph
148
149
  )
149
150
  end
150
151
  when 'parse'
151
- ns = closure_at(source_position)
152
- region = Parser::Region.new(source: @source, closure: ns)
153
152
  begin
154
- node = Parser.parse(directive.tag.text, @filename, comment_position.line)
153
+ ns = closure_at(source_position)
154
+ src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
155
+ region = Parser::Region.new(source: src, closure: ns)
155
156
  # @todo These pins may need to be marked not explicit
156
- Parser.process_node(node, region, @pins)
157
+ index = @pins.length
158
+ loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
159
+ comment_position.line + 1
160
+ else
161
+ comment_position.line
162
+ end
163
+ Parser.process_node(src.node, region, @pins)
164
+ @pins[index..-1].each do |p|
165
+ # @todo Smelly instance variable access
166
+ p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
167
+ p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
168
+ end
157
169
  rescue Parser::SyntaxError => e
158
170
  # @todo Handle parser errors in !parse directives
159
171
  end
@@ -190,7 +202,7 @@ module Solargraph
190
202
  code_lines = @code.lines
191
203
  @source.associated_comments.each do |line, comments|
192
204
  src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
193
- com_pos = Position.new(line - 1, 0)
205
+ com_pos = Position.new(line + 1 - comments.lines.length, 0)
194
206
  process_comment(src_pos, com_pos, comments)
195
207
  end
196
208
  end
@@ -20,6 +20,14 @@ module Solargraph
20
20
  Override.method_return('Pathname#cleanpath', 'Pathname'),
21
21
  Override.method_return('Pathname#children', 'Array<Pathname>'),
22
22
  Override.method_return('Pathname#entries', 'Array<Pathname>')
23
+ ],
24
+
25
+ 'set' => [
26
+ Override.method_return('Enumerable#to_set', 'Set'),
27
+ Override.method_return('Set#add', 'self'),
28
+ Override.method_return('Set#add?', 'self, nil'),
29
+ Override.method_return('Set#classify', 'Hash'),
30
+ Override.from_comment('Set#each', '@yieldparam_single_parameter')
23
31
  ]
24
32
  }
25
33
 
@@ -74,7 +74,7 @@ module Solargraph
74
74
  def method_tag_problems
75
75
  result = []
76
76
  # @param pin [Pin::BaseMethod]
77
- source_map.pins.select { |pin| pin.is_a?(Pin::BaseMethod) }.each do |pin|
77
+ source_map.pins_by_class(Pin::BaseMethod).each do |pin|
78
78
  result.concat method_return_type_problems_for(pin)
79
79
  result.concat method_param_type_problems_for(pin)
80
80
  end
@@ -184,8 +184,7 @@ module Solargraph
184
184
 
185
185
  # @return [Array<Pin::BaseVariable>]
186
186
  def all_variables
187
- source_map.pins.select { |pin| pin.is_a?(Pin::BaseVariable) } +
188
- source_map.locals.select { |pin| pin.is_a?(Pin::LocalVariable) }
187
+ source_map.pins_by_class(Pin::BaseVariable) + source_map.locals.select { |pin| pin.is_a?(Pin::LocalVariable) }
189
188
  end
190
189
 
191
190
  def const_problems
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.39.7'
4
+ VERSION = '0.39.12'
5
5
  end
@@ -3,6 +3,7 @@
3
3
  require 'yard'
4
4
  require 'yard-solargraph'
5
5
  require 'rubygems/package'
6
+ require 'set'
6
7
 
7
8
  module Solargraph
8
9
  # The YardMap provides access to YARD documentation for the Ruby core, the
@@ -56,6 +57,7 @@ module Solargraph
56
57
  @source_gems = []
57
58
  process_requires
58
59
  yardocs.uniq!
60
+ @pin_select_cache = {}
59
61
  end
60
62
 
61
63
  # @return [Array<Solargraph::Pin::Base>]
@@ -80,10 +82,22 @@ module Solargraph
80
82
  @gemset = new_gemset
81
83
  @source_gems = source_gems
82
84
  process_requires
85
+ @rebindable_method_names = nil
86
+ @pin_class_hash = nil
87
+ @pin_select_cache = {}
83
88
  true
84
89
  end
85
90
  end
86
91
 
92
+ # @return [Set<String>]
93
+ def rebindable_method_names
94
+ @rebindable_method_names ||= pins_by_class(Pin::Method)
95
+ .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
96
+ .map(&:name)
97
+ .concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'])
98
+ .to_set
99
+ end
100
+
87
101
  # @return [Array<String>]
88
102
  def yardocs
89
103
  @yardocs ||= []
@@ -144,6 +158,14 @@ module Solargraph
144
158
  @cache ||= YardMap::Cache.new
145
159
  end
146
160
 
161
+ def pin_class_hash
162
+ @pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
163
+ end
164
+
165
+ def pins_by_class klass
166
+ @pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
167
+ end
168
+
147
169
  # @param ns [YARD::CodeObjects::NamespaceObject]
148
170
  # @return [Array<YARD::CodeObjects::Base>]
149
171
  def recurse_namespace_object ns
@@ -15,23 +15,23 @@ module Solargraph
15
15
  # @return [void]
16
16
  def self.run spec, cache_dir: nil
17
17
  Dir.mktmpdir do |tmpdir|
18
- rdir = File.join(tmpdir, 'rdoc')
19
- Dir.chdir spec.full_gem_path do
18
+ rdir = File.join(tmpdir, 'sg_tmp_rdoc')
19
+ FileUtils.cp_r Dir.glob(File.join(spec.full_gem_path, '*')), tmpdir
20
+ Dir.chdir tmpdir do
20
21
  pins = []
21
22
  pins.push Solargraph::Pin::ROOT_PIN
22
23
  name_hash = {}
23
24
 
24
- argv = ['-q', '-N', '-r', '-o', rdir]
25
+ argv = ['-q', '-r', '-N', '-o', rdir]
25
26
  spec.load_paths.each do |path|
26
27
  argv.concat ['-i', path]
27
28
  end
28
29
  rdoc = RDoc::RDoc.new
29
30
  rdoc.document argv
30
-
31
- store = RDoc::Store.new(rdir)
32
- store.load_all
31
+ # @type [RDoc::Store]
32
+ store = rdoc.store
33
+ store.path = rdir
33
34
  store.cache[:modules].each do |mod|
34
- # store.load_class(mod)
35
35
  # @type [RDoc::NormalClass]
36
36
  mod = store.find_class_or_module(mod)
37
37
  closure = pins.select { |pin| pin.path == mod.full_name.split('::')[0..-2].join('::') }.first || pins.first
@@ -51,7 +51,7 @@ module Solargraph
51
51
  closure: namepin
52
52
  )
53
53
  end
54
- # @param inc [RDoc::Extend]
54
+ # @param ext [RDoc::Extend]
55
55
  mod.extends.each do |ext|
56
56
  pins.push Solargraph::Pin::Reference::Extend.new(
57
57
  location: locate(ext),
@@ -105,7 +105,11 @@ module Solargraph
105
105
  mod.full_name.split('::')[0..-2].join('::')
106
106
  end
107
107
 
108
+ # @param cmnt [RDoc::Comment]
109
+ # @return [String]
108
110
  def self.commentary cmnt
111
+ return cmnt if cmnt.is_a?(String)
112
+ return cmnt.text if cmnt.is_a?(RDoc::Comment)
109
113
  result = []
110
114
  cmnt.parts.each do |part|
111
115
  result.push RDoc::Markup::ToHtml.new({}).to_html(part.text) if part.respond_to?(:text)
@@ -126,9 +130,9 @@ module Solargraph
126
130
 
127
131
  def self.find_file obj
128
132
  if obj.respond_to?(:in_files) && !obj.in_files.empty?
129
- [obj.in_files.first.to_s.sub(/^file /, ''), obj.in_files.first.line]
133
+ [obj.in_files.first.to_s.sub(/^file /, ''), obj.line]
130
134
  else
131
- [obj.file_name, obj.line]
135
+ [obj.file, obj.line]
132
136
  end
133
137
  end
134
138
  end
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency 'maruku', '~> 0.7', '>= 0.7.3'
28
28
  s.add_runtime_dependency 'nokogiri', '~> 1.9', '>= 1.9.1'
29
29
  s.add_runtime_dependency 'parser', '~> 2.3'
30
- s.add_runtime_dependency 'reverse_markdown', '~> 1.0', '>= 1.0.5'
30
+ s.add_runtime_dependency 'reverse_markdown', '>= 1.0.5', '< 3'
31
31
  s.add_runtime_dependency 'rubocop', '~> 0.52'
32
32
  s.add_runtime_dependency 'thor', '~> 1.0'
33
33
  s.add_runtime_dependency 'tilt', '~> 2.0'
Binary file
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.7
4
+ version: 0.39.12
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-05-04 00:00:00.000000000 Z
11
+ date: 2020-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -138,22 +138,22 @@ dependencies:
138
138
  name: reverse_markdown
139
139
  requirement: !ruby/object:Gem::Requirement
140
140
  requirements:
141
- - - "~>"
142
- - !ruby/object:Gem::Version
143
- version: '1.0'
144
141
  - - ">="
145
142
  - !ruby/object:Gem::Version
146
143
  version: 1.0.5
144
+ - - "<"
145
+ - !ruby/object:Gem::Version
146
+ version: '3'
147
147
  type: :runtime
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
- - - "~>"
152
- - !ruby/object:Gem::Version
153
- version: '1.0'
154
151
  - - ">="
155
152
  - !ruby/object:Gem::Version
156
153
  version: 1.0.5
154
+ - - "<"
155
+ - !ruby/object:Gem::Version
156
+ version: '3'
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: rubocop
159
159
  requirement: !ruby/object:Gem::Requirement
@@ -317,6 +317,7 @@ files:
317
317
  - lib/solargraph/api_map/source_to_yard.rb
318
318
  - lib/solargraph/api_map/store.rb
319
319
  - lib/solargraph/bundle.rb
320
+ - lib/solargraph/compat.rb
320
321
  - lib/solargraph/complex_type.rb
321
322
  - lib/solargraph/complex_type/type_methods.rb
322
323
  - lib/solargraph/complex_type/unique_type.rb