solargraph 0.18.2 → 0.18.3

Sign up to get free protection for your applications and to get access to all the features.
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?