solargraph 0.18.2 → 0.18.3

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +33 -28
  3. data/lib/solargraph/api_map.rb +997 -1044
  4. data/lib/solargraph/api_map/source_to_yard.rb +4 -3
  5. data/lib/solargraph/diagnostics/rubocop.rb +4 -3
  6. data/lib/solargraph/language_server/host.rb +140 -70
  7. data/lib/solargraph/language_server/message/base.rb +1 -0
  8. data/lib/solargraph/language_server/message/client.rb +6 -2
  9. data/lib/solargraph/language_server/message/text_document/completion.rb +34 -39
  10. data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
  11. data/lib/solargraph/language_server/message/text_document/did_close.rb +1 -0
  12. data/lib/solargraph/language_server/message/text_document/did_save.rb +1 -3
  13. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +1 -1
  14. data/lib/solargraph/language_server/message/text_document/hover.rb +25 -30
  15. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +1 -1
  16. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +8 -7
  17. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
  18. data/lib/solargraph/language_server/transport/socket.rb +15 -17
  19. data/lib/solargraph/library.rb +34 -16
  20. data/lib/solargraph/node_methods.rb +96 -96
  21. data/lib/solargraph/pin.rb +1 -0
  22. data/lib/solargraph/pin/base.rb +2 -1
  23. data/lib/solargraph/pin/base_variable.rb +45 -5
  24. data/lib/solargraph/pin/block_parameter.rb +5 -2
  25. data/lib/solargraph/pin/method.rb +22 -0
  26. data/lib/solargraph/pin/namespace.rb +32 -2
  27. data/lib/solargraph/pin/reference.rb +21 -0
  28. data/lib/solargraph/pin/yard_object.rb +9 -0
  29. data/lib/solargraph/shell.rb +136 -136
  30. data/lib/solargraph/source.rb +134 -188
  31. data/lib/solargraph/source/change.rb +70 -0
  32. data/lib/solargraph/source/fragment.rb +120 -66
  33. data/lib/solargraph/source/position.rb +41 -0
  34. data/lib/solargraph/source/updater.rb +48 -0
  35. data/lib/solargraph/version.rb +3 -3
  36. data/lib/solargraph/workspace/config.rb +4 -9
  37. data/lib/solargraph/yard_map/core_docs.rb +0 -1
  38. metadata +5 -2
@@ -7,6 +7,8 @@ module Solargraph
7
7
  autoload :Fragment, 'solargraph/source/fragment'
8
8
  autoload :Position, 'solargraph/source/position'
9
9
  autoload :Range, 'solargraph/source/range'
10
+ autoload :Updater, 'solargraph/source/updater'
11
+ autoload :Change, 'solargraph/source/change'
10
12
 
11
13
  # @return [String]
12
14
  attr_reader :code
@@ -25,9 +27,6 @@ module Solargraph
25
27
  # @return [Time]
26
28
  attr_reader :mtime
27
29
 
28
- # @return [Array<Integer>]
29
- attr_reader :stubbed_lines
30
-
31
30
  attr_reader :directives
32
31
 
33
32
  attr_reader :path_macros
@@ -41,42 +40,55 @@ module Solargraph
41
40
 
42
41
  include NodeMethods
43
42
 
44
- def initialize code, node, comments, filename, stubbed_lines = []
43
+ def initialize code, filename = nil
45
44
  @code = code
46
45
  @fixed = code
47
46
  @filename = filename
48
- @stubbed_lines = stubbed_lines
47
+ # @stubbed_lines = stubbed_lines
49
48
  @version = 0
50
- process_parsed node, comments
49
+ begin
50
+ parse
51
+ rescue Parser::SyntaxError
52
+ hard_fix_node
53
+ end
51
54
  end
52
55
 
53
56
  def macro path
54
57
  @path_macros[path]
55
58
  end
56
59
 
60
+ # @return [Array<String>]
57
61
  def namespaces
58
- @namespace_nodes.keys
59
- end
60
-
61
- def namespace_nodes
62
- @namespace_nodes
63
- end
64
-
65
- def namespace_includes
66
- @namespace_includes ||= {}
67
- end
68
-
69
- def namespace_extends
70
- @namespaces_extends ||= {}
62
+ @namespaces ||= namespace_pin_map.keys
63
+ end
64
+
65
+ def qualify(signature, fqns)
66
+ return signature if signature.nil? or signature.empty?
67
+ base, rest = signature.split('.', 2)
68
+ parts = fqns.split('::')
69
+ until parts.empty?
70
+ here = parts.join('::')
71
+ parts.pop
72
+ name = "#{here}::#{base}"
73
+ next if namespace_pins(name).empty?
74
+ base = name
75
+ break
76
+ end
77
+ base + (rest.nil? ? '' : ".#{rest}")
71
78
  end
72
79
 
73
- def superclasses
74
- @superclasses ||= {}
80
+ # @param fqns [String] The namespace (nil for all)
81
+ # @return [Array<Solargraph::Pin::Namespace>]
82
+ def namespace_pins fqns = nil
83
+ return namespace_pin_map.values.flatten if fqns.nil?
84
+ namespace_pin_map[fqns] || []
75
85
  end
76
86
 
87
+ # @param fqns [String] The namespace (nil for all)
77
88
  # @return [Array<Solargraph::Pin::Method>]
78
- def method_pins
79
- @method_pins ||= []
89
+ def method_pins fqns = nil
90
+ return method_pin_map.values.flatten if fqns.nil?
91
+ method_pin_map[fqns] || []
80
92
  end
81
93
 
82
94
  # @return [Array<Solargraph::Pin::Attribute>]
@@ -114,11 +126,6 @@ module Solargraph
114
126
  @symbol_pins ||= []
115
127
  end
116
128
 
117
- # @return [Array<Solargraph::Pin::Namespace>]
118
- def namespace_pins
119
- @namespace_pins ||= []
120
- end
121
-
122
129
  # @return [Array<String>]
123
130
  def required
124
131
  @required ||= []
@@ -138,8 +145,9 @@ module Solargraph
138
145
  frag.strip.gsub(/,$/, '')
139
146
  end
140
147
 
148
+ # @param node [Parser::AST::Node]
141
149
  def tree_for node
142
- @node_tree[node] || []
150
+ @node_tree[node.object_id] || []
143
151
  end
144
152
 
145
153
  # Get the nearest node that contains the specified index.
@@ -156,16 +164,17 @@ module Solargraph
156
164
  # @param index [Integer]
157
165
  # @return [Array<AST::Node>]
158
166
  def tree_at(line, column)
159
- offset = get_parsed_offset(line, column)
167
+ # offset = get_parsed_offset(line, column)
168
+ offset = Position.line_char_to_offset(@code, line, column)
160
169
  @all_nodes.reverse.each do |n|
161
170
  if n.respond_to?(:loc)
162
171
  if n.respond_to?(:begin) and n.respond_to?(:end)
163
172
  if offset >= n.begin.begin_pos and offset < n.end.end_pos
164
- return [n] + @node_tree[n]
173
+ return [n] + @node_tree[n.object_id]
165
174
  end
166
175
  elsif !n.loc.expression.nil?
167
176
  if offset >= n.loc.expression.begin_pos and offset < n.loc.expression.end_pos
168
- return [n] + @node_tree[n]
177
+ return [n] + @node_tree[n.object_id]
169
178
  end
170
179
  end
171
180
  end
@@ -192,7 +201,7 @@ module Solargraph
192
201
  # @return [String]
193
202
  def namespace_for node
194
203
  parts = []
195
- ([node] + (@node_tree[node] || [])).each do |n|
204
+ ([node] + (@node_tree[node.object_id] || [])).each do |n|
196
205
  next unless n.kind_of?(AST::Node)
197
206
  if n.type == :class or n.type == :module
198
207
  parts.unshift unpack_name(n.children[0])
@@ -214,16 +223,25 @@ module Solargraph
214
223
  node_object_ids.include? node.object_id
215
224
  end
216
225
 
217
- def synchronize changes, version
218
- changes.each do |change|
219
- reparse change
226
+ def synchronize updater
227
+ raise 'Invalid synchronization' unless updater.filename == filename
228
+ original_code = @code
229
+ original_fixed = @fixed
230
+ @code = updater.write(original_code)
231
+ @fixed = updater.write(original_code, true)
232
+ @version = updater.version
233
+ return if @code == original_code
234
+ begin
235
+ parse
236
+ @fixed = @code
237
+ rescue Parser::SyntaxError => e
238
+ @fixed = updater.repair(original_fixed)
239
+ begin
240
+ parse
241
+ rescue Parser::SyntaxError => e
242
+ hard_fix_node
243
+ end
220
244
  end
221
- @version = version
222
- self
223
- end
224
-
225
- def overwrite text
226
- reparse({'text' => text})
227
245
  end
228
246
 
229
247
  def query_symbols query
@@ -234,7 +252,7 @@ module Solargraph
234
252
 
235
253
  def all_symbols
236
254
  result = []
237
- result.concat namespace_pins
255
+ result.concat namespace_pin_map.values.flatten
238
256
  result.concat method_pins
239
257
  result.concat constant_pins
240
258
  result
@@ -247,103 +265,59 @@ module Solargraph
247
265
 
248
266
  # @return [Solargraph::Source::Fragment]
249
267
  def fragment_at line, column
250
- # Fragment.new(self, line, column)
251
268
  Fragment.new(self, line, column, tree_at(line, column))
252
269
  end
253
270
 
254
- private
255
-
256
- def get_offset line, column, parsed
257
- offset = 0
258
- feed = 0
259
- (parsed ? @code.gsub(/\r\n/, "\n") : @code).lines.each do |l|
260
- break if line == feed
261
- offset += l.length
262
- feed += 1
263
- end
264
- offset + column
271
+ def fragment_for node
272
+ inside = tree_for(node)
273
+ return nil if inside.empty?
274
+ line = node.loc.expression.last_line - 1
275
+ column = node.loc.expression.last_column
276
+ Fragment.new(self, line, column, inside)
265
277
  end
266
278
 
267
- def get_original_offset line, column
268
- get_offset line, column, false
279
+ def parsed?
280
+ @parsed
269
281
  end
270
282
 
271
- def get_parsed_offset line, column
272
- get_offset line, column, true
273
- end
283
+ private
274
284
 
275
- def reparse change
276
- if change['range']
277
- start_offset = get_original_offset(change['range']['start']['line'], change['range']['start']['character'])
278
- end_offset = get_original_offset(change['range']['end']['line'], change['range']['end']['character'])
279
- rewrite = (start_offset == 0 ? '' : @code[0..start_offset-1].to_s) + change['text'].force_encoding('utf-8') + @code[end_offset..-1].to_s
280
- # return if @code == rewrite
281
- again = true
282
- # if change['text'].match(/^[^a-z0-9\s]+?$/i)
283
- # tmp = (start_offset == 0 ? '' : @fixed[0..start_offset-1].to_s) + change['text'].gsub(/[^\s]/, ' ') + @fixed[end_offset..-1].to_s
284
- # again = false
285
- # else
286
- tmp = rewrite
287
- # end
288
- @code = rewrite
289
- begin
290
- node, comments = Source.parse(tmp, filename)
291
- process_parsed node, comments
292
- @fixed = tmp
293
- rescue Parser::SyntaxError => e
294
- if again
295
- again = false
296
- tmp = (start_offset == 0 ? '' : @fixed[0..start_offset-1].to_s) + change['text'].gsub(/[^\s]/, ' ') + @fixed[end_offset..-1].to_s
297
- retry
298
- else
299
- @code = rewrite
300
- hard_fix_node
301
- end
302
- end
303
- else
304
- tmp = change['text']
305
- return if @code == tmp
306
- @code = tmp
307
- begin
308
- node, comments = Source.parse(@code, filename)
309
- process_parsed node, comments
310
- @fixed = @code
311
- rescue Parser::SyntaxError => e
312
- hard_fix_node
313
- end
314
- end
285
+ def parse
286
+ node, comments = Source.parse(@fixed, filename)
287
+ process_parsed node, comments
288
+ @parsed = true
315
289
  end
316
290
 
317
291
  def hard_fix_node
318
- tmp = @code.gsub(/[^\s]/, ' ')
319
- @fixed = tmp
320
- node, comments = Source.parse(tmp, filename)
292
+ @fixed = @code.gsub(/[^\s]/, ' ')
293
+ node, comments = Source.parse(@fixed, filename)
321
294
  process_parsed node, comments
295
+ @parsed = false
322
296
  end
323
297
 
324
298
  def process_parsed node, comments
325
299
  root = AST::Node.new(:source, [filename])
326
300
  root = root.append node
327
301
  @node = root
302
+ @namespaces = nil
328
303
  @comments = comments
329
304
  @directives = {}
330
305
  @path_macros = {}
331
306
  @docstring_hash = associate_comments(node, comments)
332
307
  @mtime = (!filename.nil? and File.exist?(filename) ? File.mtime(filename) : nil)
333
- @namespace_nodes = {}
334
308
  @all_nodes = []
335
309
  @node_stack = []
336
310
  @node_tree = {}
337
- namespace_pins.clear
311
+ namespace_pin_map.clear
312
+ namespace_pin_map[''] = [Solargraph::Pin::Namespace.new(self, @node, '', :public)]
313
+ @namespace_pins = nil
338
314
  instance_variable_pins.clear
339
315
  class_variable_pins.clear
340
316
  local_variable_pins.clear
341
317
  symbol_pins.clear
342
318
  constant_pins.clear
343
- method_pins.clear
344
- namespace_includes.clear
345
- namespace_extends.clear
346
- superclasses.clear
319
+ method_pin_map.clear
320
+ # namespace_includes.clear
347
321
  attribute_pins.clear
348
322
  @node_object_ids = nil
349
323
  inner_map_node @node
@@ -360,9 +334,10 @@ module Solargraph
360
334
  attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :writer, docstring, "#{d.tag.name}=")
361
335
  end
362
336
  elsif d.tag.tag_name == 'method'
363
- gen_src = Source.virtual("def #{d.tag.name};end", filename)
337
+ gen_src = Source.new("def #{d.tag.name};end", filename)
364
338
  gen_pin = gen_src.method_pins.first
365
- method_pins.push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name)
339
+ method_pin_map[ns] ||= []
340
+ method_pin_map[ns].push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name)
366
341
  elsif d.tag.tag_name == 'macro'
367
342
  # @todo Handle various types of macros (attach, new, whatever)
368
343
  path = path_for(k.node)
@@ -372,7 +347,7 @@ module Solargraph
372
347
  end
373
348
  end
374
349
  end
375
- @all_pins = namespace_pins + instance_variable_pins + class_variable_pins + local_variable_pins + symbol_pins + constant_pins + method_pins + attribute_pins
350
+ @all_pins = namespace_pin_map.values.flatten + instance_variable_pins + class_variable_pins + local_variable_pins + symbol_pins + constant_pins + method_pins + attribute_pins
376
351
  @stime = Time.now
377
352
  end
378
353
 
@@ -408,16 +383,11 @@ module Solargraph
408
383
  yard_hash
409
384
  end
410
385
 
411
- def inner_map_node node, tree = [], visibility = :public, scope = :instance, fqn = nil, stack = []
386
+ def inner_map_node node, tree = [], visibility = :public, scope = :instance, fqn = '', stack = []
412
387
  stack.push node
413
388
  source = self
414
389
  if node.kind_of?(AST::Node)
415
- # @node_tree[node] = @node_stack.clone
416
390
  @all_nodes.push node
417
- # if node.type == :str or node.type == :dstr
418
- # stack.pop
419
- # return
420
- # end
421
391
  @node_stack.unshift node
422
392
  if node.type == :class or node.type == :module
423
393
  visibility = :public
@@ -427,18 +397,18 @@ module Solargraph
427
397
  tree = tree + pack_name(node.children[0])
428
398
  end
429
399
  fqn = tree.join('::')
430
- @namespace_nodes[fqn] ||= []
431
- @namespace_nodes[fqn].push node
432
- namespace_pins.push Solargraph::Pin::Namespace.new(self, node, tree[0..-2].join('::') || '', :public)
400
+ sc = nil
401
+ nspin = Solargraph::Pin::Namespace.new(self, node, tree[0..-2].join('::') || '', :public, sc)
433
402
  if node.type == :class and !node.children[1].nil?
434
- sc = unpack_name(node.children[1])
435
- superclasses[fqn] = sc
403
+ nspin.reference_superclass unpack_name(node.children[1])
436
404
  end
405
+ namespace_pin_map[nspin.path] ||= []
406
+ namespace_pin_map[nspin.path].push nspin
437
407
  end
438
408
  file = source.filename
439
409
  node.children.each do |c|
440
410
  if c.kind_of?(AST::Node)
441
- @node_tree[c] = @node_stack.clone
411
+ @node_tree[c.object_id] = @node_stack.clone
442
412
  if c.type == :ivasgn
443
413
  par = find_parent(stack, :class, :module, :def, :defs)
444
414
  local_scope = ( (par.kind_of?(AST::Node) and par.type == :def) ? :instance : :class )
@@ -447,7 +417,7 @@ module Solargraph
447
417
  unless ora.nil?
448
418
  u = c.updated(:ivasgn, c.children + ora.children[1..-1], nil)
449
419
  @all_nodes.push u
450
- @node_tree[u] = @node_stack.clone
420
+ @node_tree[u.object_id] = @node_stack.clone
451
421
  @docstring_hash[u.loc] = docstring_for(ora)
452
422
  instance_variable_pins.push Solargraph::Pin::InstanceVariable.new(self, u, fqn || '', local_scope)
453
423
  end
@@ -459,7 +429,7 @@ module Solargraph
459
429
  ora = find_parent(stack, :or_asgn)
460
430
  unless ora.nil?
461
431
  u = c.updated(:cvasgn, c.children + ora.children[1..-1], nil)
462
- @node_tree[u] = @node_stack.clone
432
+ @node_tree[u.object_id] = @node_stack.clone
463
433
  @all_nodes.push u
464
434
  @docstring_hash[u.loc] = docstring_for(ora)
465
435
  class_variable_pins.push Solargraph::Pin::ClassVariable.new(self, u, fqn || '')
@@ -488,7 +458,8 @@ module Solargraph
488
458
  elsif c.type == :casgn
489
459
  constant_pins.push Solargraph::Pin::Constant.new(self, c, fqn, :public)
490
460
  elsif c.type == :def and c.children[0].to_s[0].match(/[a-z]/i)
491
- method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', scope, visibility)
461
+ method_pin_map[fqn || ''] ||= []
462
+ method_pin_map[fqn || ''].push Solargraph::Pin::Method.new(source, c, fqn || '', scope, visibility)
492
463
  elsif c.type == :defs
493
464
  s_visi = visibility
494
465
  s_visi = :public if scope != :class
@@ -498,7 +469,8 @@ module Solargraph
498
469
  dfqn = unpack_name(c.children[0])
499
470
  end
500
471
  unless dfqn.nil?
501
- method_pins.push Solargraph::Pin::Method.new(source, c, dfqn, :class, s_visi)
472
+ method_pin_map[dfqn] ||= []
473
+ method_pin_map[dfqn].push Solargraph::Pin::Method.new(source, c, dfqn, :class, s_visi)
502
474
  inner_map_node c, tree, scope, :class, dfqn, stack
503
475
  end
504
476
  next
@@ -506,10 +478,10 @@ module Solargraph
506
478
  visibility = c.children[1]
507
479
  elsif c.type == :send and [:private_class_method].include?(c.children[1]) and c.children[2].kind_of?(AST::Node)
508
480
  if c.children[2].type == :sym or c.children[2].type == :str
509
- ref = method_pins.select{|p| p.name == c.children[2].children[0].to_s}.first
481
+ ref = method_pins(fqn || '').select{|p| p.name == c.children[2].children[0].to_s}.first
510
482
  unless ref.nil?
511
- source.method_pins.delete ref
512
- source.method_pins.push Solargraph::Pin::Method.new(ref.source, ref.node, ref.namespace, ref.scope, :private)
483
+ method_pin_map[fqn || ''].delete ref
484
+ method_pin_map[fqn || ''].push Solargraph::Pin::Method.new(ref.source, ref.node, ref.namespace, ref.scope, :private)
513
485
  end
514
486
  else
515
487
  inner_map_node c, tree, :private, :class, fqn, stack
@@ -520,10 +492,10 @@ module Solargraph
520
492
  cn = c.children[2].children[0].to_s
521
493
  ref = constant_pins.select{|p| p.name == cn}.first
522
494
  if ref.nil?
523
- ref = namespace_pins.select{|p| p.name == cn}.first
495
+ ref = namespace_pin_map.values.flatten.select{|p| p.name == cn and p.namespace == fqn}.last
524
496
  unless ref.nil?
525
- source.namespace_pins.delete ref
526
- source.namespace_pins.push Solargraph::Pin::Namespace.new(ref.source, ref.node, ref.namespace, :private)
497
+ namespace_pin_map[ref.path].delete ref
498
+ namespace_pin_map[ref.path].push Solargraph::Pin::Namespace.new(ref.source, ref.node, ref.namespace, :private, (ref.superclass_reference.nil? ? nil : ref.superclass_reference.name))
527
499
  end
528
500
  else
529
501
  source.constant_pins.delete ref
@@ -531,15 +503,22 @@ module Solargraph
531
503
  end
532
504
  end
533
505
  next
534
- elsif c.type == :send and c.children[1] == :include
535
- namespace_includes[fqn] ||= []
536
- c.children[2..-1].each do |i|
537
- namespace_includes[fqn].push unpack_name(i)
506
+ elsif c.type == :send and c.children[1] == :include and c.children[0].nil?
507
+ if @node_tree[0].nil? or @node_tree[0].type == :source or @node_tree[0].type == :class or @node_tree[0].type == :module or (@node_tree.length > 1 and @node_tree[0].type == :begin and (@node_tree[1].type == :class or @node_tree[1].type == :module))
508
+ if c.children[2].kind_of?(AST::Node) and c.children[2].type == :const
509
+ c.children[2..-1].each do |i|
510
+ namespace_pins(fqn || '').last.reference_include unpack_name(i)
511
+ end
512
+ end
538
513
  end
539
- elsif c.type == :send and c.children[1] == :extend
540
- namespace_extends[fqn] ||= []
541
- c.children[2..-1].each do |i|
542
- namespace_extends[fqn].push unpack_name(i)
514
+ elsif c.type == :send and c.children[1] == :extend and c.children[0].nil?
515
+ if @node_tree[0].nil? or @node_tree[0].type == :source or @node_tree[0].type == :class or @node_tree[0].type == :module or (@node_tree.length > 1 and @node_tree[0].type == :begin and (@node_tree[1].type == :class or @node_tree[1].type == :module))
516
+ if c.children[2].kind_of?(AST::Node) and c.children[2].type == :const
517
+ # namespace_extends[fqn || ''] ||= []
518
+ c.children[2..-1].each do |i|
519
+ namespace_pin_map[fqn || ''].last.reference_extend unpack_name(i)
520
+ end
521
+ end
543
522
  end
544
523
  elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
545
524
  c.children[2..-1].each do |a|
@@ -589,6 +568,16 @@ module Solargraph
589
568
  @node_object_ids ||= @all_nodes.map(&:object_id)
590
569
  end
591
570
 
571
+ # @return [Hash<String, Solargraph::Pin::Namespace>]
572
+ def namespace_pin_map
573
+ @namespace_pin_map ||= {}
574
+ end
575
+
576
+ # @return [Hash<String, Solargraph::Pin::Namespace>]
577
+ def method_pin_map
578
+ @method_pin_map ||= {}
579
+ end
580
+
592
581
  class << self
593
582
  # @return [Solargraph::Source]
594
583
  def load filename
@@ -596,65 +585,22 @@ module Solargraph
596
585
  Source.load_string(code, filename)
597
586
  end
598
587
 
599
- # @deprecated Use load_string instead
600
- def virtual code, filename = nil
601
- load_string code, filename
602
- end
603
-
604
588
  # @return [Solargraph::Source]
605
589
  def load_string code, filename = nil
606
- begin
607
- node, comments = parse(code, filename)
608
- Source.new(code, node, comments, filename)
609
- rescue Parser::SyntaxError => e
610
- tmp = code.gsub(/[^ \t\r\n]/, ' ')
611
- node, comments = parse(tmp, filename)
612
- Source.new(code, node, comments, filename)
613
- end
590
+ Source.new code, filename
614
591
  end
615
592
 
616
- # def get_position_at(code, offset)
617
- # cursor = 0
618
- # line = 0
619
- # col = nil
620
- # code.each_line do |l|
621
- # if cursor + l.length > offset
622
- # col = offset - cursor
623
- # break
624
- # end
625
- # if cursor + l.length == offset
626
- # if l.end_with?("\n")
627
- # col = 0
628
- # line += 1
629
- # break
630
- # else
631
- # col = l.length
632
- # break
633
- # end
634
- # end
635
- # # if cursor + l.length - 1 == offset and !l.end_with?("\n")
636
- # # col = l.length - 1
637
- # # break
638
- # # end
639
- # cursor += l.length
640
- # line += 1
641
- # end
642
- # raise "Invalid offset" if col.nil?
643
- # [line, col]
644
- # end
645
-
646
593
  def parse code, filename = nil
647
594
  parser = Parser::CurrentRuby.new(FlawedBuilder.new)
648
595
  parser.diagnostics.all_errors_are_fatal = true
649
596
  parser.diagnostics.ignore_warnings = true
650
597
  buffer = Parser::Source::Buffer.new(filename, 1)
651
- buffer.source = code
598
+ buffer.source = code.force_encoding(Encoding::UTF_8)
652
599
  parser.parse_with_comments(buffer)
653
- end
600
+ end
654
601
 
655
602
  def fix code, filename = nil, offset = nil
656
603
  tries = 0
657
- # code.gsub!(/\r/, '')
658
604
  offset = Source.get_offset(code, offset[0], offset[1]) if offset.kind_of?(Array)
659
605
  pos = nil
660
606
  pos = get_position_at(code, offset) unless offset.nil?