solargraph 0.13.3 → 0.14.0

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: 613c6ae706229464a6f918aef5f093a97e0ff569
4
- data.tar.gz: b68e4d8abbf2b884d78f9af364e34e5cbcde6f2f
3
+ metadata.gz: 0d9090bbc3094234313c93d9cbc44461426c9fd8
4
+ data.tar.gz: 802563c75b5edb831701442e15bb0e7715934b8a
5
5
  SHA512:
6
- metadata.gz: 843ff75f0ccf680f311a3e42ba4e5ff18810ff1beb048638503c3e7b794883b1bd419c2dd2b6bb3d56bc17a3a06e8e5a7d392f9abf458c57affe0f219ae2ad7a
7
- data.tar.gz: a3b5f6d57c62b1d35e940e29b6c8e9b70594a73f1f6f37021a31cfee11eefc3495cb1d09f13de70b1722a9d42bfde9ce827682df898198c6dad5b59918c76419
6
+ metadata.gz: f6d2eedfd1dafc0c280643b6f21401f61c4dbb2e3cd89273a6cc9892d25528412e04701a2501d63708535d5f2024d7a7b3773185dd03877dd957f938237db7d5
7
+ data.tar.gz: 4dca225b820a8ac799475936649673cff8f9d20bb389f719568ee9098f85fb68cfef83d215cd8ab2a84225162d1b2619bfffc71417a810ecfb2ac0d7d1975e38
data/bin/solargraph CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift '/home/fred/solargraph-ruby/lib'
4
3
  require 'solargraph'
5
4
 
6
5
  Solargraph::Shell.start(ARGV)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solargraph/plugin/process'
4
+
5
+ Solargraph::Plugin::Process.new.run
@@ -3,23 +3,44 @@ require 'yaml'
3
3
  module Solargraph
4
4
  class ApiMap
5
5
  class Config
6
+ # @return [String]
6
7
  attr_reader :workspace
7
8
  attr_reader :raw_data
8
9
 
10
+ # @return [Array<String>]
11
+ attr_reader :included
12
+
13
+ # @return [Array<String>]
14
+ attr_reader :excluded
15
+
16
+ # @return [Array<String>]
17
+ attr_reader :domains
18
+
9
19
  def initialize workspace = nil
10
20
  @workspace = workspace
11
21
  include_globs = ['**/*.rb']
12
22
  exclude_globs = ['spec/**/*', 'test/**/*']
23
+ @included = []
24
+ @excluded = []
25
+ @domains = []
13
26
  unless @workspace.nil?
27
+ include_globs = ['**/*.rb']
28
+ exclude_globs = ['spec/**/*', 'test/**/*']
14
29
  sfile = File.join(@workspace, '.solargraph.yml')
15
30
  if File.file?(sfile)
16
31
  @raw_data = YAML.load(File.read(sfile))
32
+ conf = YAML.load(File.read(sfile))
33
+ include_globs = conf['include'] || include_globs
34
+ exclude_globs = conf['exclude'] || []
35
+ @domains = conf['domains'] || []
17
36
  end
37
+ @included.concat process_globs(include_globs)
38
+ @excluded.concat process_globs(exclude_globs)
18
39
  end
19
40
  @raw_data ||= {}
20
41
  @raw_data['include'] = @raw_data['include'] || include_globs
21
42
  @raw_data['exclude'] = @raw_data['exclude'] || exclude_globs
22
- @raw_data['extensions'] = @raw_data['extensions'] || []
43
+ # @todo If the domains config goes stable, add it to @raw_data
23
44
  end
24
45
 
25
46
  def included
@@ -30,10 +51,6 @@ module Solargraph
30
51
  process_globs @raw_data['exclude']
31
52
  end
32
53
 
33
- def extensions
34
- @raw_data['extensions']
35
- end
36
-
37
54
  private
38
55
 
39
56
  def process_globs globs
@@ -44,7 +44,7 @@ module Solargraph
44
44
  attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :writer, docstring, "#{d.tag.name}=")
45
45
  end
46
46
  elsif d.tag.tag_name == 'method'
47
- gen_src = Source.virtual(filename, "def #{d.tag.name};end")
47
+ gen_src = Source.virtual("def #{d.tag.name};end", filename)
48
48
  gen_pin = gen_src.method_pins.first
49
49
  method_pins.push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name)
50
50
  else
@@ -298,17 +298,17 @@ module Solargraph
298
298
  # @return [Solargraph::ApiMap::Source]
299
299
  def load filename
300
300
  code = File.read(filename).gsub(/\r/, '')
301
- Source.virtual(filename, code)
301
+ Source.virtual(code, filename)
302
302
  end
303
303
 
304
304
  # @return [Solargraph::ApiMap::Source]
305
- def virtual filename, code
305
+ def virtual code, filename = nil
306
306
  node, comments = Parser::CurrentRuby.parse_with_comments(code)
307
307
  Source.new(code, node, comments, filename)
308
308
  end
309
309
 
310
310
  # @return [Solargraph::ApiMap::Source]
311
- def fix filename, code, cursor = nil
311
+ def fix code, filename = nil, cursor = nil
312
312
  tries = 0
313
313
  code.gsub!(/\r/, '')
314
314
  tmp = code
@@ -31,9 +31,6 @@ module Solargraph
31
31
  # @return [String]
32
32
  attr_reader :workspace
33
33
 
34
- # @return [Array<String>]
35
- attr_reader :required
36
-
37
34
  # @param workspace [String]
38
35
  def initialize workspace = nil
39
36
  @workspace = workspace.gsub(/\\/, '/') unless workspace.nil?
@@ -59,14 +56,19 @@ module Solargraph
59
56
  @virtual_source = nil
60
57
  @virtual_filename = nil
61
58
  @stale = true
62
- live_map
63
59
  refresh
60
+ yard_map
64
61
  end
65
62
 
66
63
  def config
67
64
  @config ||= ApiMap::Config.new(@workspace)
68
65
  end
69
66
 
67
+ # @return [Array<String>]
68
+ def required
69
+ @required ||= []
70
+ end
71
+
70
72
  # @return [Solargraph::YardMap]
71
73
  def yard_map
72
74
  refresh
@@ -78,24 +80,25 @@ module Solargraph
78
80
 
79
81
  # @return [Solargraph::LiveMap]
80
82
  def live_map
81
- @live_map ||= Solargraph::LiveMap.new(workspace)
83
+ @live_map ||= Solargraph::LiveMap.new(self)
82
84
  end
83
85
 
84
86
  # @return [Solargraph::ApiMap::Source]
85
- def virtualize filename, code, cursor = nil
87
+ def virtualize code, filename = nil, cursor = nil
86
88
  unless @virtual_source.nil? or @virtual_filename == filename or @workspace_files.include?(@virtual_filename)
87
89
  eliminate @virtual_filename
88
90
  end
89
- refresh
91
+ #refresh
90
92
  @virtual_filename = filename
91
- @virtual_source = Source.fix(filename, code, cursor)
93
+ @virtual_source = Source.fix(code, filename, cursor)
92
94
  process_virtual
95
+ #@stale = true
93
96
  @virtual_source
94
97
  end
95
98
 
96
99
  # @return [Solargraph::ApiMap::Source]
97
100
  def append_source code, filename
98
- virtualize filename, code
101
+ virtualize code, filename
99
102
  end
100
103
 
101
104
  def refresh force = false
@@ -133,6 +136,8 @@ module Solargraph
133
136
  result = []
134
137
  result += inner_namespaces_in(name, root, [])
135
138
  result += yard_map.get_constants name, root
139
+ strings = result.map(&:to_s)
140
+ result.concat live_map.get_constants(name, root)
136
141
  result
137
142
  end
138
143
 
@@ -152,7 +157,7 @@ module Solargraph
152
157
  result.push pin_to_suggestion(pin)
153
158
  end
154
159
  end
155
- result.concat yard_map.get_constants(namespace, root)
160
+ result.concat yard_map.get_constants(fqns)
156
161
  end
157
162
 
158
163
  # @return [String]
@@ -188,7 +193,11 @@ module Solargraph
188
193
  }
189
194
  end
190
195
  end
191
- yard_map.find_fully_qualified_namespace(name, root)
196
+ result = yard_map.find_fully_qualified_namespace(name, root)
197
+ if result.nil?
198
+ result = live_map.get_fqns(name, root)
199
+ end
200
+ result
192
201
  end
193
202
 
194
203
  def get_namespace_nodes(fqns)
@@ -354,13 +363,16 @@ module Solargraph
354
363
  result
355
364
  end
356
365
 
357
- def get_namespace_type namespace, root = ''
366
+ def get_namespace_type fqns
367
+ return nil if fqns.nil?
358
368
  type = nil
359
- fqns = find_fully_qualified_namespace(namespace, root)
360
369
  nodes = get_namespace_nodes(fqns)
361
370
  unless nodes.nil? or nodes.empty? or !nodes[0].kind_of?(AST::Node)
362
371
  type = nodes[0].type if [:class, :module].include?(nodes[0].type)
363
372
  end
373
+ if type.nil?
374
+ type = yard_map.get_namespace_type(fqns)
375
+ end
364
376
  type
365
377
  end
366
378
 
@@ -373,15 +385,16 @@ module Solargraph
373
385
  namespace = clean_namespace_string(namespace)
374
386
  fqns = find_fully_qualified_namespace(namespace, root)
375
387
  meths = []
376
- meths.concat inner_get_methods(namespace, root, []) #unless has_yardoc?
377
- yard_meths = yard_map.get_methods(namespace, root, visibility: visibility)
388
+ skip = []
389
+ meths.concat inner_get_methods(namespace, root, skip)
390
+ yard_meths = yard_map.get_methods(fqns, '', visibility: visibility)
378
391
  if yard_meths.any?
379
392
  meths.concat yard_meths
380
393
  else
381
- type = get_namespace_type(namespace, root)
394
+ type = get_namespace_type(fqns)
382
395
  if type == :class
383
396
  meths.concat yard_map.get_instance_methods('Class')
384
- elsif type == :module
397
+ else
385
398
  meths.concat yard_map.get_methods('Module')
386
399
  end
387
400
  end
@@ -395,12 +408,17 @@ module Solargraph
395
408
  end
396
409
  end
397
410
  end
411
+ if namespace == '' and root == ''
412
+ config.domains.each do |d|
413
+ meths.concat get_instance_methods(d)
414
+ end
415
+ end
398
416
  strings = meths.map(&:to_s)
399
- live_map.get_methods(namespace, root, visibility.include?(:private)).each do |m|
417
+ live_map.get_methods(fqns, '', 'class', visibility.include?(:private)).each do |m|
400
418
  next if strings.include?(m) or !m.match(/^[a-z]/i)
401
- meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
419
+ meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'), path: "#{fqns}.#{m}")
402
420
  end
403
- meths
421
+ meths
404
422
  end
405
423
 
406
424
  # Get an array of instance methods that are available in the specified
@@ -420,7 +438,7 @@ module Solargraph
420
438
  if yard_meths.any?
421
439
  meths.concat yard_meths
422
440
  else
423
- type = get_namespace_type(namespace, root)
441
+ type = get_namespace_type(fqns)
424
442
  if type == :class
425
443
  meths += yard_map.get_instance_methods('Object')
426
444
  elsif type == :module
@@ -428,9 +446,9 @@ module Solargraph
428
446
  end
429
447
  end
430
448
  strings = meths.map(&:to_s)
431
- live_map.get_instance_methods(namespace, root, visibility.include?(:private)).each do |m|
449
+ live_map.get_methods(namespace, root, 'instance', visibility.include?(:private)).each do |m|
432
450
  next if strings.include?(m) or !m.match(/^[a-z]/i)
433
- meths.push Suggestion.new(m, kind: Suggestion::METHOD)
451
+ meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'), path: "#{fqns}##{m}")
434
452
  end
435
453
  meths
436
454
  end
@@ -448,8 +466,10 @@ module Solargraph
448
466
  end
449
467
 
450
468
  def update filename
451
- @@source_cache[filename] ||= Source.load(filename)
452
- #cache.clear
469
+ filename.gsub!(/\\/, '/')
470
+ eliminate filename
471
+ @@source_cache[filename] = Source.load(filename)
472
+ rebuild_local_yardoc #if @workspace_files.include?(filename)
453
473
  @stale = true
454
474
  end
455
475
 
@@ -467,7 +487,7 @@ module Solargraph
467
487
  elsif path.include?('.')
468
488
  # It's a class method
469
489
  parts = path.split('.')
470
- result = get_instance_methods(parts[0], '', visibility: [:public, :private, :protected]).select{|s| s.label == parts[1]}
490
+ result = get_methods(parts[0], '', visibility: [:public, :private, :protected]).select{|s| s.label == parts[1]}
471
491
  else
472
492
  # It's a class or module
473
493
  get_namespace_nodes(path).each do |node|
@@ -496,19 +516,11 @@ module Solargraph
496
516
  @parent_stack = {}
497
517
  namespace_map.clear
498
518
  namespace_tree.clear
499
- @required = []
519
+ required.clear
500
520
  end
501
521
 
502
522
  def process_maps
503
- @sources.clear
504
- @workspace_files.each do |f|
505
- begin
506
- @@source_cache[f] ||= Source.load(f)
507
- @sources[f] = @@source_cache[f]
508
- rescue
509
- STDERR.puts "Failed to load #{f}"
510
- end
511
- end
523
+ process_workspace_files
512
524
  cache.clear
513
525
  @ivar_pins = {}
514
526
  @cvar_pins = {}
@@ -537,11 +549,30 @@ module Solargraph
537
549
  map_source s
538
550
  }
539
551
  @required.uniq!
540
- #live_map.update self
541
- live_map.reload
552
+ live_map.refresh
542
553
  @stale = false
543
554
  end
544
555
 
556
+ def rebuild_local_yardoc
557
+ return if workspace.nil? or !File.exist?(File.join(workspace, '.yardoc'))
558
+ STDERR.puts "Rebuilding local yardoc for #{workspace}"
559
+ Dir.chdir(workspace) { Process.spawn('yardoc') }
560
+ end
561
+
562
+ def process_workspace_files
563
+ @sources.clear
564
+ @workspace_files.each do |f|
565
+ if File.file?(f)
566
+ begin
567
+ @@source_cache[f] ||= Source.load(f)
568
+ @sources[f] = @@source_cache[f]
569
+ rescue
570
+ STDERR.puts "Failed to load #{f}"
571
+ end
572
+ end
573
+ end
574
+ end
575
+
545
576
  def process_virtual
546
577
  unless @virtual_source.nil?
547
578
  cache.clear
@@ -629,9 +660,9 @@ module Solargraph
629
660
  meths.concat inner_get_methods(sc, fqns, skip, visibility - [:private])
630
661
  meths.concat yard_map.get_methods(sc, fqns, visibility: visibility - [:private])
631
662
  strings = meths.map(&:to_s)
632
- live_map.get_methods(sc, fqns, false).each do |m|
663
+ live_map.get_methods(sc, fqns, 'class', false).each do |m|
633
664
  next if strings.include?(m) or !m.match(/^[a-z]/i)
634
- meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
665
+ meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'), path: "#{fqns}##{m}")
635
666
  end
636
667
  end
637
668
  end
@@ -661,7 +692,7 @@ module Solargraph
661
692
  meths.concat inner_get_instance_methods(sc, fqns, skip, visibility - [:private])
662
693
  meths.concat yard_map.get_instance_methods(sc, fqns, visibility: visibility - [:private])
663
694
  strings = meths.map(&:to_s)
664
- live_map.get_instance_methods(sc, fqns, false).each do |m|
695
+ live_map.get_methods(sc, fqns, 'instance', false).each do |m|
665
696
  next if strings.include?(m) or !m.match(/^[a-z]/i)
666
697
  meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
667
698
  end
@@ -690,7 +721,7 @@ module Solargraph
690
721
  }
691
722
  unless cursor.nil?
692
723
  cursor.keys.each { |k|
693
- type = get_namespace_type(k, fqns)
724
+ type = get_namespace_type("#{fqns == '' ? '' : fqns + '::'}#{k}")
694
725
  kind = nil
695
726
  detail = nil
696
727
  if type == :class
@@ -755,10 +786,12 @@ module Solargraph
755
786
  visibility = [:public]
756
787
  visibility.concat [:private, :protected] if top
757
788
  if scope == :instance || namespace == ''
758
- meth = get_instance_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
789
+ tmp = get_instance_methods(namespace, visibility: visibility)
759
790
  else
760
- meth = get_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
791
+ tmp = get_methods(namespace, visibility: visibility)
761
792
  end
793
+ tmp.concat get_instance_methods('Kernel', visibility: [:public]) if top
794
+ meth = tmp.select{|s| s.label == part}.first
762
795
  return nil if meth.nil? or meth.return_type.nil?
763
796
  type = meth.return_type
764
797
  scope = :instance
@@ -37,7 +37,7 @@ module Solargraph
37
37
  filename = filename.gsub(File::ALT_SEPARATOR, File::SEPARATOR) unless filename.nil? or File::ALT_SEPARATOR.nil?
38
38
  @filename = filename
39
39
  @api_map = api_map
40
- @source = self.api_map.virtualize filename, code, cursor
40
+ @source = self.api_map.virtualize code, filename, cursor
41
41
  @node = @source.node
42
42
  @code = @source.code
43
43
  @comments = @source.comments
@@ -229,8 +229,7 @@ module Solargraph
229
229
  else
230
230
  type = infer_literal_node_type(node_at(index - 2))
231
231
  if type.nil?
232
- current_namespace = namespace_at(index)
233
- parts = current_namespace.to_s.split('::')
232
+ parts = namespace.to_s.split('::')
234
233
  result += get_snippets_at(index) if with_snippets
235
234
  result += get_local_variables_and_methods_at(index)
236
235
  result += ApiMap.get_keywords
@@ -652,7 +651,7 @@ module Solargraph
652
651
  arr = []
653
652
  @source.local_variable_pins.select{|p| p.visible_from?(node) }.each do |pin|
654
653
  #arr.push Suggestion.new(pin.name, kind: Suggestion::VARIABLE, return_type: api_map.infer_assignment_node_type(pin.node, namespace))
655
- arr.push Suggestion.new(pin.name, kind: Suggestion::VARIABLE)
654
+ arr.push Suggestion.new(pin.name, kind: Suggestion::VARIABLE, location: pin.location)
656
655
  end
657
656
  arr
658
657
  end
@@ -3,7 +3,7 @@ module Solargraph
3
3
  class Cache
4
4
  def initialize
5
5
  @method_cache = {}
6
- @instance_method_cache = {}
6
+ @constant_cache = {}
7
7
  end
8
8
 
9
9
  def get_methods options
@@ -14,17 +14,17 @@ module Solargraph
14
14
  @method_cache[options] = values
15
15
  end
16
16
 
17
- def get_instance_methods options
18
- @instance_method_cache[options]
17
+ def get_constants namespace, root
18
+ @constant_cache[[namespace, root]]
19
19
  end
20
20
 
21
- def set_instance_methods options, values
22
- @instance_method_cache[options] = values
21
+ def set_constants namespace, root, values
22
+ @constant_cache[[namespace, root]] = values
23
23
  end
24
24
 
25
25
  def clear
26
26
  @method_cache.clear
27
- @instance_method_cache.clear
27
+ @constant_cache.clear
28
28
  end
29
29
  end
30
30
  end
@@ -2,95 +2,125 @@ module Solargraph
2
2
  # The LiveMap allows extensions to add their own completion suggestions.
3
3
  #
4
4
  class LiveMap
5
+ autoload :Cache, 'solargraph/live_map/cache'
6
+
5
7
  @@plugins = []
6
-
7
- attr_reader :workspace
8
8
 
9
- def initialize workspace
10
- @workspace = workspace
11
- @runners = []
12
- at_exit { stop }
9
+ # @return [Solargraph::ApiMap]
10
+ attr_reader :api_map
11
+
12
+ def initialize api_map
13
+ @api_map = api_map
14
+ runners
13
15
  end
14
16
 
15
- def start
16
- unless workspace.nil?
17
- @@plugins.each do |p|
18
- r = p.new(workspace)
19
- r.start
20
- @runners.push r
21
- end
17
+ def get_methods(namespace, root = '', scope = 'instance', with_private = false)
18
+ params = {
19
+ namespace: namespace, root: root, scope: scope, with_private: with_private
20
+ }
21
+ cached = cache.get_methods(params)
22
+ return cached unless cached.nil?
23
+ did_runtime = false
24
+ result = []
25
+ runners.each do |p|
26
+ next if did_runtime and p.runtime?
27
+ result.concat p.get_methods(namespace: namespace, root: root, scope: scope, with_private: with_private)
28
+ did_runtime = true if p.runtime?
22
29
  end
30
+ cache.set_methods(params, result)
31
+ result
23
32
  end
24
33
 
25
- def reload
26
- restart
34
+ # @return [Array<Solargraph::Suggestion>]
35
+ def get_constants(namespace, root = '')
36
+ cached = cache.get_constants(namespace, root)
37
+ return cached unless cached.nil?
38
+ did_runtime = false
39
+ result = []
40
+ runners.each do |p|
41
+ next if did_runtime and p.runtime?
42
+ result.concat p.get_constants(namespace, root)
43
+ did_runtime = true if p.runtime?
44
+ end
45
+ suggestions = []
46
+ result.uniq.each do |r|
47
+ kind = Suggestion::CONSTANT
48
+ if r['class'] == 'Class'
49
+ kind = Suggestion::CLASS
50
+ elsif r['class'] == 'Module'
51
+ kind = Suggestion::MODULE
52
+ end
53
+ suggestions.push(Suggestion.new(r['name'], kind: kind))
54
+ end
55
+ cache.set_constants(namespace, root, suggestions)
56
+ suggestions
27
57
  end
28
58
 
29
- def restart
30
- stop
31
- start
59
+ def get_fqns(namespace, root)
60
+ did_runtime = false
61
+ runners.each do |p|
62
+ next if did_runtime and p.runtime?
63
+ result = p.get_fqns(namespace, root)
64
+ return result unless result.nil?
65
+ did_runtime = true if p.runtime?
66
+ end
67
+ nil
32
68
  end
33
69
 
34
- def stop
35
- @runners.each do |p|
36
- p.stop
37
- end
38
- @runners.clear
70
+ # Register a plugin for LiveMap to use when generating suggestions.
71
+ #
72
+ # @param cls [Class<Solargraph::Plugin::Base>]
73
+ def self.install cls
74
+ @@plugins.push cls unless @@plugins.include?(cls)
39
75
  end
40
76
 
41
- def get_instance_methods(namespace, root = '', with_private = false)
42
- result = []
43
- @runners.each do |p|
44
- resp = p.get_methods(namespace: namespace, root: root, scope: 'instance', with_private: with_private)
45
- STDERR.puts resp.message unless resp.ok?
46
- result.concat(resp.data)
47
- end
48
- result
77
+ def self.uninstall cls
78
+ @@plugins.delete cls
49
79
  end
50
80
 
51
- def get_methods(namespace, root = '', with_private = false)
52
- result = []
53
- @runners.each do |p|
54
- resp = p.get_methods(namespace: namespace, root: root, scope: 'class', with_private: with_private)
55
- STDERR.puts resp.message unless resp.ok?
56
- result.concat(resp.data)
57
- end
58
- result
81
+ def self.plugins
82
+ @@plugins.clone
59
83
  end
60
84
 
61
- def self.install cls
62
- @@plugins.push cls
85
+ def refresh
86
+ changed = false
87
+ runners.each do |p|
88
+ changed ||= p.refresh
89
+ end
90
+ if changed
91
+ STDERR.puts "Resetting LiveMap cache"
92
+ cache.clear
93
+ get_constants('')
94
+ get_methods('', '', 'class')
95
+ get_methods('', '', 'instance')
96
+ get_methods('Kernel', '', 'class')
97
+ get_methods('Kernel', '', 'instance')
98
+ end
63
99
  end
64
100
 
65
101
  private
66
102
 
67
- def find_constant(namespace, root)
68
- result = nil
69
- parts = root.split('::')
70
- if parts.empty?
71
- result = inner_find_constant(namespace)
72
- else
73
- until parts.empty?
74
- result = inner_find_constant("#{parts.join('::')}::#{namespace}")
75
- break unless result.nil?
76
- parts.pop
77
- end
78
- end
79
- result
103
+ # @return [Solargraph::LiveMap::Cache]
104
+ def cache
105
+ @cache ||= Solargraph::LiveMap::Cache.new
80
106
  end
81
107
 
82
- def inner_find_constant(namespace)
83
- cursor = Object
84
- parts = namespace.split('::')
85
- until parts.empty?
86
- here = parts.shift
87
- begin
88
- cursor = cursor.const_get(here)
89
- rescue NameError
90
- return nil
91
- end
108
+ # @return [Array<Solargraph::Plugin::Base>]
109
+ def runners
110
+ @runners ||= load_runners
111
+ end
112
+
113
+ # @return [Array<Solargraph::Plugin::Base>]
114
+ def load_runners
115
+ result = []
116
+ has_runtime = false
117
+ @@plugins.each do |p|
118
+ r = p.new(api_map)
119
+ result.push r if !has_runtime or !r.runtime?
120
+ has_runtime = true if r.runtime?
92
121
  end
93
- cursor
122
+ result.push Solargraph::Plugin::Runtime.new(api_map) unless has_runtime
123
+ result
94
124
  end
95
125
  end
96
126
  end
@@ -60,6 +60,10 @@ module Solargraph
60
60
  def filename
61
61
  source.filename
62
62
  end
63
+
64
+ def location
65
+ "#{source.filename}:#{node.location.expression.begin_pos}"
66
+ end
63
67
  end
64
68
  end
65
69
  end