solargraph 0.10.1 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41e2a41af1ef29061e085cd34a1666aa8e962327
4
- data.tar.gz: 8f785cd7a3a8113b47633c07e5b3816f028e1618
3
+ metadata.gz: 7fca7cec06944baee613ea512c26052d002badf1
4
+ data.tar.gz: 56b786723a5f0b33ae2612d110977f74f1d4bb7f
5
5
  SHA512:
6
- metadata.gz: adcca5889793480021d29af723d2d83062b5578ccf083f36555b6bd311d620981d671999c6df52a57618a22fa18842ac7d5b0dacb3fd7880efd38c27a2752456
7
- data.tar.gz: 630beb7fabb5a5c7d59ab30da28f72863f36d1111eca3f7a4b6f65e5d2cd91d3573f495b669964e77e02bac67ae95bb741b9f37a6ac08f109c00e3f2812f594c
6
+ metadata.gz: 3e8e40663cd4629b55a4436a33d8c8606b1087dbabbdd21d0180f1ca8b4cb26b563bd2f4f8076701ccf1fa7148513df4d01a063a04366bbd137df8b6cac5dcf9
7
+ data.tar.gz: d7bf1113b69a08d74805319918a756f6894810c5397912f68340cf15fb050fac2e989a292b89efb8f7899f56fd5c5d2e502c8d3d35d7a4b042a905993b8dd7bf
@@ -5,6 +5,7 @@ require 'yaml'
5
5
  module Solargraph
6
6
  class ApiMap
7
7
  autoload :Config, 'solargraph/api_map/config'
8
+ autoload :Cache, 'solargraph/api_map/cache'
8
9
 
9
10
  KEYWORDS = [
10
11
  '__ENCODING__', '__LINE__', '__FILE__', 'BEGIN', 'END', 'alias', 'and',
@@ -179,7 +180,7 @@ module Solargraph
179
180
  nodes = get_namespace_nodes(namespace) || @file_nodes.values
180
181
  arr = []
181
182
  nodes.each { |n|
182
- arr += inner_get_instance_variables(n, scope)
183
+ arr += inner_get_instance_variables(n, namespace, scope)
183
184
  }
184
185
  arr
185
186
  end
@@ -188,7 +189,7 @@ module Solargraph
188
189
  nodes = get_namespace_nodes(namespace) || @file_nodes.values
189
190
  arr = []
190
191
  nodes.each { |n|
191
- arr += inner_get_class_variables(n)
192
+ arr += inner_get_class_variables(n, namespace)
192
193
  }
193
194
  arr
194
195
  end
@@ -314,27 +315,45 @@ module Solargraph
314
315
  end
315
316
 
316
317
  def infer_signature_type signature, namespace, scope: :class
318
+ cached = cache.get_signature_type(signature, namespace, scope)
319
+ return cached unless cached.nil?
317
320
  return nil if signature.nil? or signature.empty?
321
+ result = nil
318
322
  if namespace.end_with?('#class')
319
- return infer_signature_type signature, namespace[0..-7], scope: (scope == :class ? :instance : :class)
320
- end
321
- parts = signature.split('.', 2)
322
- if parts[0].start_with?('@@')
323
- type = infer_class_variable(parts[0], namespace)
324
- inner_infer_signature_type parts[1], type, scope: :instance
325
- elsif parts[0].start_with?('@')
326
- type = infer_instance_variable(parts[0], namespace, scope)
327
- inner_infer_signature_type parts[1], type, scope: :instance
323
+ result = infer_signature_type signature, namespace[0..-7], scope: (scope == :class ? :instance : :class)
328
324
  else
329
- type = find_fully_qualified_namespace(parts[0], namespace)
330
- if type.nil?
331
- # It's a method call
332
- type = inner_infer_signature_type(parts[0], namespace, scope: scope)
333
- inner_infer_signature_type(parts[1], type, scope: :instance)
325
+ parts = signature.split('.', 2)
326
+ if parts[0].start_with?('@@')
327
+ type = infer_class_variable(parts[0], namespace)
328
+ if type.nil? or parts.empty?
329
+ result = inner_infer_signature_type(parts[1], type, scope: :instance)
330
+ else
331
+ result = type
332
+ end
333
+ elsif parts[0].start_with?('@')
334
+ type = infer_instance_variable(parts[0], namespace, scope)
335
+ if type.nil? or parts.empty?
336
+ result = inner_infer_signature_type(parts[1], type, scope: :instance)
337
+ else
338
+ result = type
339
+ end
334
340
  else
335
- inner_infer_signature_type(parts[1], type, scope: :class)
341
+ type = find_fully_qualified_namespace(parts[0], namespace)
342
+ if type.nil?
343
+ # It's a method call
344
+ type = inner_infer_signature_type(parts[0], namespace, scope: scope)
345
+ if parts[1].nil?
346
+ result = type
347
+ else
348
+ result = inner_infer_signature_type(parts[1], type, scope: :instance)
349
+ end
350
+ else
351
+ result = inner_infer_signature_type(parts[1], type, scope: :class)
352
+ end
336
353
  end
337
354
  end
355
+ cache.set_signature_type signature, namespace, scope, result
356
+ result
338
357
  end
339
358
 
340
359
  def get_namespace_type namespace, root = ''
@@ -474,6 +493,10 @@ module Solargraph
474
493
 
475
494
  private
476
495
 
496
+ def cache
497
+ @cache ||= Cache.new
498
+ end
499
+
477
500
  def associate_comments node, comments
478
501
  comment_hash = Parser::Source::Comment.associate_locations(node, comments)
479
502
  yard_hash = {}
@@ -641,31 +664,59 @@ module Solargraph
641
664
  result
642
665
  end
643
666
 
644
- def inner_get_instance_variables(node, scope)
667
+ def inner_get_instance_variables(node, namespace, scope)
645
668
  arr = []
646
669
  if node.kind_of?(AST::Node)
647
670
  node.children.each { |c|
648
671
  if c.kind_of?(AST::Node)
649
672
  is_inst = !find_parent(c, :def).nil?
650
673
  if c.type == :ivasgn and c.children[0] and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
651
- arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: get_comment_for(c))
674
+ type = nil
675
+ cmnt = get_comment_for(c)
676
+ if cmnt.nil?
677
+ sig = resolve_node_signature(c.children[1])
678
+ type = infer_signature_type(sig, namespace)
679
+ else
680
+ t = cmnt.tag(:type)
681
+ if t.nil?
682
+ sig = resolve_node_signature(c.children[1])
683
+ type = infer_signature_type(sig, namespace)
684
+ else
685
+ type = t.types[0]
686
+ end
687
+ end
688
+ arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: cmnt, return_type: type)
652
689
  end
653
- arr += inner_get_instance_variables(c, scope) unless [:class, :module].include?(c.type)
690
+ arr += inner_get_instance_variables(c, namespace, scope) unless [:class, :module].include?(c.type)
654
691
  end
655
692
  }
656
693
  end
657
694
  arr
658
695
  end
659
696
 
660
- def inner_get_class_variables(node)
697
+ def inner_get_class_variables(node, namespace)
661
698
  arr = []
662
699
  if node.kind_of?(AST::Node)
663
700
  node.children.each { |c|
664
701
  next unless c.kind_of?(AST::Node)
665
702
  if c.type == :cvasgn
666
- arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: get_comment_for(c))
703
+ type = nil
704
+ cmnt = get_comment_for(c)
705
+ if cmnt.nil?
706
+ sig = resolve_node_signature(c.children[1])
707
+ type = infer_signature_type(sig, namespace)
708
+ else
709
+ t = cmnt.tag(:type)
710
+ if t.nil?
711
+ sig = resolve_node_signature(c.children[1])
712
+ type = infer_signature_type(sig, namespace)
713
+ else
714
+ type = t.types[0]
715
+ end
716
+ end
717
+ arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: cmnt, return_type: type)
667
718
  end
668
- arr += inner_get_class_variables(c) unless [:class, :module].include?(c.type)
719
+ arr += inner_get_class_variables(c, namespace) unless [:class, :module].include?(c.type)
669
720
  }
670
721
  end
671
722
  arr
@@ -678,6 +729,8 @@ module Solargraph
678
729
  # @return [String] The fully qualified namespace for the signature's type
679
730
  # or nil if a type could not be determined
680
731
  def inner_infer_signature_type signature, namespace, scope: :instance
732
+ return nil if signature.nil?
733
+ signature.gsub!(/\.$/, '')
681
734
  if signature.nil? or signature.empty?
682
735
  if scope == :class
683
736
  return "#{namespace}#class"
@@ -694,6 +747,7 @@ module Solargraph
694
747
  top = true
695
748
  while parts.length > 0 and !type.nil?
696
749
  p = parts.shift
750
+ next if p.empty?
697
751
  if top and scope == :class
698
752
  #next if p == 'new'
699
753
  if p == 'new'
@@ -0,0 +1,15 @@
1
+ module Solargraph
2
+ class ApiMap
3
+ class Cache
4
+ def initialize
5
+ @signature_types = {}
6
+ end
7
+ def get_signature_type signature, namespace, scope
8
+ @signature_types[[signature, namespace, scope]]
9
+ end
10
+ def set_signature_type signature, namespace, scope, value
11
+ @signature_types[[signature, namespace, scope]] = value
12
+ end
13
+ end
14
+ end
15
+ end
@@ -10,7 +10,7 @@ module Solargraph
10
10
 
11
11
  include NodeMethods
12
12
 
13
- def initialize code: '', filename: nil, workspace: nil, api_map: nil
13
+ def initialize code: '', filename: nil, workspace: nil, api_map: nil, cursor: nil
14
14
  @workspace = workspace
15
15
  # HACK: Adjust incoming filename's path separator for yardoc file comparisons
16
16
  filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
@@ -19,6 +19,8 @@ module Solargraph
19
19
  @code = code.gsub(/\r/, '')
20
20
  tries = 0
21
21
  tmp = @code
22
+ cursor = CodeMap.get_offset(@code, cursor[0], cursor[1]) if cursor.kind_of?(Array)
23
+ fixed_cursor = false
22
24
  begin
23
25
  # HACK: The current file is parsed with a trailing underscore to fix
24
26
  # incomplete trees resulting from short scripts (e.g., a lone variable
@@ -34,21 +36,27 @@ module Solargraph
34
36
  if tries == 10 and e.message.include?('token $end')
35
37
  tmp += "\nend"
36
38
  else
37
- spot = e.diagnostic.location.begin_pos
38
- repl = '_'
39
- if tmp[spot] == '@' or tmp[spot] == ':'
40
- # Stub unfinished instance variables and symbols
41
- spot -= 1
42
- elsif tmp[spot - 1] == '.'
43
- # Stub unfinished method calls
44
- repl = '#' if spot == tmp.length or tmp[spot] == '\n'
45
- spot -= 2
39
+ if !fixed_cursor and !cursor.nil? and e.message.include?('token $end') and cursor >= 2
40
+ fixed_cursor = true
41
+ spot = cursor - 2
42
+ repl = '_'
46
43
  else
47
- # Stub the whole line
48
- spot = beginning_of_line_from(tmp, spot)
49
- repl = '#'
50
- if tmp[spot+1..-1].rstrip == 'end'
51
- repl= 'end;end'
44
+ spot = e.diagnostic.location.begin_pos
45
+ repl = '_'
46
+ if tmp[spot] == '@' or tmp[spot] == ':'
47
+ # Stub unfinished instance variables and symbols
48
+ spot -= 1
49
+ elsif tmp[spot - 1] == '.'
50
+ # Stub unfinished method calls
51
+ repl = '#' if spot == tmp.length or tmp[spot] == '\n'
52
+ spot -= 2
53
+ else
54
+ # Stub the whole line
55
+ spot = beginning_of_line_from(tmp, spot)
56
+ repl = '#'
57
+ if tmp[spot+1..-1].rstrip == 'end'
58
+ repl= 'end;end'
59
+ end
52
60
  end
53
61
  end
54
62
  tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
@@ -75,13 +83,17 @@ module Solargraph
75
83
  # @param col [Integer]
76
84
  # @return [Integer]
77
85
  def get_offset line, col
86
+ CodeMap.get_offset @code, line, col
87
+ end
88
+
89
+ def self.get_offset text, line, col
78
90
  offset = 0
79
91
  if line > 0
80
- @code.lines[0..line - 1].each { |l|
92
+ text.lines[0..line - 1].each { |l|
81
93
  offset += l.length
82
94
  }
83
95
  end
84
- offset + col
96
+ offset + col
85
97
  end
86
98
 
87
99
  # Get an array of nodes containing the specified index, starting with the
@@ -358,7 +370,8 @@ module Solargraph
358
370
  if parts[1].nil? or parts[1].empty?
359
371
  result = yp.return_type
360
372
  else
361
- result = api_map.infer_signature_type(parts[1], yp.return_type, scope: :instance)
373
+ newsig = parts[1..-1].join('.')
374
+ result = api_map.infer_signature_type(newsig, yp.return_type, scope: :instance)
362
375
  end
363
376
  end
364
377
  end
@@ -382,9 +395,23 @@ module Solargraph
382
395
  start = parts[0]
383
396
  return nil if start.nil?
384
397
  remainder = parts[1..-1]
398
+ if start.start_with?('@@')
399
+ type = api_map.infer_class_variable(start, ns_here)
400
+ return nil if type.nil?
401
+ return type if remainder.empty?
402
+ return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
403
+ elsif start.start_with?('@')
404
+ scope = (node.type == :def ? :instance : :scope)
405
+ type = api_map.infer_instance_variable(start, ns_here, scope: :instance)
406
+ return nil if type.nil?
407
+ return type if remainder.empty?
408
+ return api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
409
+ end
385
410
  var = find_local_variable_node(start, node)
386
411
  if var.nil?
387
- return api_map.infer_signature_type(signature, ns_here)
412
+ scope = (node.type == :def ? :instance : :class)
413
+ type = api_map.infer_signature_type(signature, ns_here, scope: scope)
414
+ return type unless type.nil?
388
415
  else
389
416
  # Signature starts with a local variable
390
417
  type = get_type_comment(var)
@@ -395,7 +422,14 @@ module Solargraph
395
422
  end
396
423
  end
397
424
  unless type.nil?
398
- if remainder.empty?
425
+ if remainder[0] == 'new'
426
+ remainder.shift
427
+ if remainder.empty?
428
+ inferred = type
429
+ else
430
+ inferred = api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
431
+ end
432
+ elsif remainder.empty?
399
433
  inferred = type
400
434
  else
401
435
  inferred = api_map.infer_signature_type(remainder.join('.'), type, scope: :instance)
@@ -572,7 +606,9 @@ module Solargraph
572
606
  tmp = resolve_node_signature(lvarnode.children[1])
573
607
  sig = infer_signature_from_node tmp, scope_node
574
608
  end
575
- meth = api_map.get_instance_methods(sig, fqns).keep_if{ |s| s.to_s == block_node.children[0].children[1].to_s }.first
609
+ meths = api_map.get_instance_methods(sig, fqns)
610
+ meths += api_map.get_methods('')
611
+ meth = meths.keep_if{ |s| s.to_s == block_node.children[0].children[1].to_s }.first
576
612
  yps = []
577
613
  unless meth.nil? or meth.documentation.nil?
578
614
  yps = meth.documentation.tags(:yieldparam) || []
@@ -65,7 +65,7 @@ module Solargraph
65
65
  workspace = params['workspace'] || nil
66
66
  Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
67
67
  @@semaphore.synchronize {
68
- code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
68
+ code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace], cursor: [params['line'].to_i, params['column'].to_i])
69
69
  offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
70
70
  sugg = code_map.resolve_object_at(offset)
71
71
  }
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.10.1'
2
+ VERSION = '0.10.3'
3
3
  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.10.1
4
+ version: 0.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-11 00:00:00.000000000 Z
11
+ date: 2017-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -130,6 +130,7 @@ files:
130
130
  - bin/solargraph
131
131
  - lib/solargraph.rb
132
132
  - lib/solargraph/api_map.rb
133
+ - lib/solargraph/api_map/cache.rb
133
134
  - lib/solargraph/api_map/config.rb
134
135
  - lib/solargraph/code_map.rb
135
136
  - lib/solargraph/mapper.rb