solargraph 0.10.1 → 0.10.3

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