solargraph 0.13.2 → 0.13.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: ed95e7c0676d9b744be9c8c006104ae42fdce15f
4
- data.tar.gz: b67a658208dd50359c7b0aa0118c646b89696f93
3
+ metadata.gz: 613c6ae706229464a6f918aef5f093a97e0ff569
4
+ data.tar.gz: b68e4d8abbf2b884d78f9af364e34e5cbcde6f2f
5
5
  SHA512:
6
- metadata.gz: b28a0447fd5d9f555ab0a94fbabb0e08df008107f882e1f6d993de857012d3b8c243d0c34fdbb133f9c3e20393534c683dfd10be485beb32d068f18c7a654c77
7
- data.tar.gz: ee15faa36e173dfd9ca12f0b2eddc5225cf420136db7831adafea1303e585e49786b6e3b74ddc0618a22f6837381e93049a5319b1a14b1ec6e9e1f4dd089b3a7
6
+ metadata.gz: 843ff75f0ccf680f311a3e42ba4e5ff18810ff1beb048638503c3e7b794883b1bd419c2dd2b6bb3d56bc17a3a06e8e5a7d392f9abf458c57affe0f219ae2ad7a
7
+ data.tar.gz: a3b5f6d57c62b1d35e940e29b6c8e9b70594a73f1f6f37021a31cfee11eefc3495cb1d09f13de70b1722a9d42bfde9ce827682df898198c6dad5b59918c76419
@@ -4,33 +4,44 @@ module Solargraph
4
4
  class ApiMap
5
5
  class Config
6
6
  attr_reader :workspace
7
- attr_reader :included
8
- attr_reader :excluded
7
+ attr_reader :raw_data
9
8
 
10
9
  def initialize workspace = nil
11
10
  @workspace = workspace
12
- @included = []
13
- @excluded = []
14
11
  include_globs = ['**/*.rb']
15
12
  exclude_globs = ['spec/**/*', 'test/**/*']
16
13
  unless @workspace.nil?
17
14
  sfile = File.join(@workspace, '.solargraph.yml')
18
15
  if File.file?(sfile)
19
- conf = YAML.load(File.read(sfile))
20
- include_globs = conf['include'] || include_globs
21
- exclude_globs = conf['exclude'] || []
16
+ @raw_data = YAML.load(File.read(sfile))
22
17
  end
23
18
  end
24
- include_globs.each { |g| @included.concat process_glob(g) }
25
- exclude_globs.each { |g| @excluded.concat process_glob(g) }
19
+ @raw_data ||= {}
20
+ @raw_data['include'] = @raw_data['include'] || include_globs
21
+ @raw_data['exclude'] = @raw_data['exclude'] || exclude_globs
22
+ @raw_data['extensions'] = @raw_data['extensions'] || []
23
+ end
24
+
25
+ def included
26
+ process_globs @raw_data['include']
27
+ end
28
+
29
+ def excluded
30
+ process_globs @raw_data['exclude']
31
+ end
32
+
33
+ def extensions
34
+ @raw_data['extensions']
26
35
  end
27
36
 
28
37
  private
29
38
 
30
- def process_glob glob
39
+ def process_globs globs
31
40
  result = []
32
- Dir[File.join workspace, glob].each do |f|
33
- result.push File.realdirpath(f)
41
+ globs.each do |glob|
42
+ Dir[File.join workspace, glob].each do |f|
43
+ result.push File.realdirpath(f)
44
+ end
34
45
  end
35
46
  result
36
47
  end
@@ -23,6 +23,7 @@ module Solargraph
23
23
  root = root.append node
24
24
  @node = root
25
25
  @comments = comments
26
+ @directives = {}
26
27
  @docstring_hash = associate_comments(node, comments)
27
28
  @filename = filename
28
29
  @namespace_nodes = {}
@@ -30,6 +31,27 @@ module Solargraph
30
31
  @node_stack = []
31
32
  @node_tree = {}
32
33
  inner_map_node @node
34
+ @directives.each_pair do |k, v|
35
+ v.each do |d|
36
+ ns = namespace_for(k.node)
37
+ docstring = YARD::Docstring.parser.parse(d.tag.text).to_docstring
38
+ if d.tag.tag_name == 'attribute'
39
+ t = (d.tag.types.nil? || d.tag.types.empty?) ? nil : d.tag.types.flatten.join('')
40
+ if t.nil? or t.include?('r')
41
+ attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :reader, docstring, d.tag.name)
42
+ end
43
+ if t.nil? or t.include?('w')
44
+ attribute_pins.push Solargraph::Pin::Directed::Attribute.new(self, k.node, ns, :writer, docstring, "#{d.tag.name}=")
45
+ end
46
+ elsif d.tag.tag_name == 'method'
47
+ gen_src = Source.virtual(filename, "def #{d.tag.name};end")
48
+ gen_pin = gen_src.method_pins.first
49
+ method_pins.push Solargraph::Pin::Directed::Method.new(gen_src, gen_pin.node, ns, :instance, :public, docstring, gen_pin.name)
50
+ else
51
+ STDERR.puts "Nothing to do for directive: #{d}"
52
+ end
53
+ end
54
+ end
33
55
  end
34
56
 
35
57
  def namespaces
@@ -99,6 +121,16 @@ module Solargraph
99
121
  @node_tree[node] || []
100
122
  end
101
123
 
124
+ def namespace_for node
125
+ parts = []
126
+ ([node] + (@node_tree[node] || [])).each do |n|
127
+ if n.type == :class or n.type == :module
128
+ parts.unshift unpack_name(n.children[0])
129
+ end
130
+ end
131
+ parts.join('::')
132
+ end
133
+
102
134
  def include? node
103
135
  @all_nodes.include? node
104
136
  end
@@ -126,7 +158,12 @@ module Solargraph
126
158
  ctxt += "#{p[num..-1]}\n"
127
159
  end
128
160
  }
129
- yard_hash[k] = YARD::Docstring.parser.parse(ctxt).to_docstring
161
+ parse = YARD::Docstring.parser.parse(ctxt)
162
+ unless parse.directives.empty?
163
+ @directives[k] ||= []
164
+ @directives[k].concat parse.directives
165
+ end
166
+ yard_hash[k] = parse.to_docstring
130
167
  }
131
168
  yard_hash
132
169
  end
@@ -204,14 +241,14 @@ module Solargraph
204
241
  elsif c.type == :casgn
205
242
  constant_pins.push Solargraph::Pin::Constant.new(self, c, fqn)
206
243
  else
207
- unless fqn.nil?
244
+ #unless fqn.nil?
208
245
  if c.kind_of?(AST::Node)
209
246
  if c.type == :def and c.children[0].to_s[0].match(/[a-z]/i)
210
- method_pins.push Solargraph::Pin::Method.new(source, c, fqn, scope, visibility)
247
+ method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', scope, visibility)
211
248
  #inner_map_node c, tree, visibility, scope, fqn, stack
212
249
  #next
213
250
  elsif c.type == :defs
214
- method_pins.push Solargraph::Pin::Method.new(source, c, fqn, :class, :public)
251
+ method_pins.push Solargraph::Pin::Method.new(source, c, fqn || '', :class, :public)
215
252
  inner_map_node c, tree, :public, :class, fqn, stack
216
253
  next
217
254
  elsif c.type == :send and [:public, :protected, :private].include?(c.children[1])
@@ -224,18 +261,18 @@ module Solargraph
224
261
  elsif c.type == :send and [:attr_reader, :attr_writer, :attr_accessor].include?(c.children[1])
225
262
  c.children[2..-1].each do |a|
226
263
  if c.children[1] == :attr_reader or c.children[1] == :attr_accessor
227
- attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :reader, docstring_for(c)) #AttrPin.new(c)
264
+ attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :reader, docstring_for(c)) #AttrPin.new(c)
228
265
  end
229
266
  if c.children[1] == :attr_writer or c.children[1] == :attr_accessor
230
- attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn, :writer, docstring_for(c)) #AttrPin.new(c)
267
+ attribute_pins.push Solargraph::Pin::Attribute.new(self, a, fqn || '', :writer, docstring_for(c)) #AttrPin.new(c)
231
268
  end
232
269
  end
233
270
  elsif c.type == :sclass and c.children[0].type == :self
234
- inner_map_node c, tree, :public, :class, fqn, stack
271
+ inner_map_node c, tree, :public, :class, fqn || '', stack
235
272
  next
236
273
  end
237
274
  end
238
- end
275
+ #end
239
276
  if c.type == :send and c.children[1] == :require
240
277
  if c.children[2].kind_of?(AST::Node) and c.children[2].type == :str
241
278
  required.push c.children[2].children[0].to_s
@@ -38,10 +38,15 @@ module Solargraph
38
38
  def initialize workspace = nil
39
39
  @workspace = workspace.gsub(/\\/, '/') unless workspace.nil?
40
40
  clear
41
+ # @todo Instead of requiring extensions to be listed in the config,
42
+ # we're experimenting with automatically loading them.
43
+ #self.config.extensions.each do |ext|
44
+ # require ext
45
+ #end
46
+ require_extensions
41
47
  @workspace_files = []
42
48
  unless @workspace.nil?
43
- config = ApiMap::Config.new(@workspace)
44
- @workspace_files.concat (config.included - config.excluded)
49
+ @workspace_files.concat (self.config.included - self.config.excluded)
45
50
  @workspace_files.each do |wf|
46
51
  begin
47
52
  @@source_cache[wf] ||= Source.load(wf)
@@ -54,9 +59,14 @@ module Solargraph
54
59
  @virtual_source = nil
55
60
  @virtual_filename = nil
56
61
  @stale = true
62
+ live_map
57
63
  refresh
58
64
  end
59
65
 
66
+ def config
67
+ @config ||= ApiMap::Config.new(@workspace)
68
+ end
69
+
60
70
  # @return [Solargraph::YardMap]
61
71
  def yard_map
62
72
  refresh
@@ -66,6 +76,11 @@ module Solargraph
66
76
  @yard_map
67
77
  end
68
78
 
79
+ # @return [Solargraph::LiveMap]
80
+ def live_map
81
+ @live_map ||= Solargraph::LiveMap.new(workspace)
82
+ end
83
+
69
84
  # @return [Solargraph::ApiMap::Source]
70
85
  def virtualize filename, code, cursor = nil
71
86
  unless @virtual_source.nil? or @virtual_filename == filename or @workspace_files.include?(@virtual_filename)
@@ -356,6 +371,7 @@ module Solargraph
356
371
  def get_methods(namespace, root = '', visibility: [:public])
357
372
  refresh
358
373
  namespace = clean_namespace_string(namespace)
374
+ fqns = find_fully_qualified_namespace(namespace, root)
359
375
  meths = []
360
376
  meths.concat inner_get_methods(namespace, root, []) #unless has_yardoc?
361
377
  yard_meths = yard_map.get_methods(namespace, root, visibility: visibility)
@@ -371,7 +387,6 @@ module Solargraph
371
387
  end
372
388
  news = meths.select{|s| s.label == 'new'}
373
389
  unless news.empty?
374
- fqns = find_fully_qualified_namespace(namespace, root)
375
390
  if @method_pins[fqns]
376
391
  inits = @method_pins[fqns].select{|p| p.name == 'initialize'}
377
392
  meths -= news unless inits.empty?
@@ -380,7 +395,12 @@ module Solargraph
380
395
  end
381
396
  end
382
397
  end
383
- meths
398
+ strings = meths.map(&:to_s)
399
+ live_map.get_methods(namespace, root, visibility.include?(:private)).each do |m|
400
+ 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)'))
402
+ end
403
+ meths
384
404
  end
385
405
 
386
406
  # Get an array of instance methods that are available in the specified
@@ -407,6 +427,11 @@ module Solargraph
407
427
  meths += yard_map.get_instance_methods('Module')
408
428
  end
409
429
  end
430
+ strings = meths.map(&:to_s)
431
+ live_map.get_instance_methods(namespace, root, visibility.include?(:private)).each do |m|
432
+ next if strings.include?(m) or !m.match(/^[a-z]/i)
433
+ meths.push Suggestion.new(m, kind: Suggestion::METHOD)
434
+ end
410
435
  meths
411
436
  end
412
437
 
@@ -424,7 +449,8 @@ module Solargraph
424
449
 
425
450
  def update filename
426
451
  @@source_cache[filename] ||= Source.load(filename)
427
- cache.clear
452
+ #cache.clear
453
+ @stale = true
428
454
  end
429
455
 
430
456
  def sources
@@ -511,6 +537,8 @@ module Solargraph
511
537
  map_source s
512
538
  }
513
539
  @required.uniq!
540
+ #live_map.update self
541
+ live_map.reload
514
542
  @stale = false
515
543
  end
516
544
 
@@ -600,6 +628,11 @@ module Solargraph
600
628
  unless sc.nil?
601
629
  meths.concat inner_get_methods(sc, fqns, skip, visibility - [:private])
602
630
  meths.concat yard_map.get_methods(sc, fqns, visibility: visibility - [:private])
631
+ strings = meths.map(&:to_s)
632
+ live_map.get_methods(sc, fqns, false).each do |m|
633
+ 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)'))
635
+ end
603
636
  end
604
637
  end
605
638
  meths.uniq
@@ -627,6 +660,11 @@ module Solargraph
627
660
  unless sc.nil?
628
661
  meths.concat inner_get_instance_methods(sc, fqns, skip, visibility - [:private])
629
662
  meths.concat yard_map.get_instance_methods(sc, fqns, visibility: visibility - [:private])
663
+ strings = meths.map(&:to_s)
664
+ live_map.get_instance_methods(sc, fqns, false).each do |m|
665
+ next if strings.include?(m) or !m.match(/^[a-z]/i)
666
+ meths.push Suggestion.new(m, kind: Suggestion::METHOD, docstring: YARD::Docstring.new('(defined at runtime)'))
667
+ end
630
668
  end
631
669
  end
632
670
  im = @namespace_includes[fqns]
@@ -716,7 +754,7 @@ module Solargraph
716
754
  elsif !METHODS_RETURNING_SELF.include?(part)
717
755
  visibility = [:public]
718
756
  visibility.concat [:private, :protected] if top
719
- if scope == :instance
757
+ if scope == :instance || namespace == ''
720
758
  meth = get_instance_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
721
759
  else
722
760
  meth = get_methods(namespace, visibility: visibility).select{|s| s.label == part}.first
@@ -759,5 +797,12 @@ module Solargraph
759
797
  def pin_to_suggestion pin
760
798
  @pin_suggestions[pin] ||= Suggestion.pull(pin)
761
799
  end
800
+
801
+ def require_extensions
802
+ Gem::Specification.all_names.select{|n| n.match(/^solargraph\-[a-z0-9_\-]*?\-ext\-[0-9\.]*$/)}.each do |n|
803
+ STDERR.puts "Loading extension #{n}"
804
+ require n.match(/^(solargraph\-[a-z0-9_\-]*?\-ext)\-[0-9\.]*$/)[1]
805
+ end
806
+ end
762
807
  end
763
808
  end
@@ -13,6 +13,11 @@ module Solargraph
13
13
  # @return [String]
14
14
  attr_reader :code
15
15
 
16
+ # The source object generated from the code.
17
+ #
18
+ # @return [Solargraph::ApiMap::Source]
19
+ attr_reader :source
20
+
16
21
  # The filename for the source code.
17
22
  #
18
23
  # @return [String]
@@ -236,6 +241,8 @@ module Solargraph
236
241
  end
237
242
  result += api_map.namespaces_in('')
238
243
  result += api_map.get_instance_methods('Kernel')
244
+ result += api_map.get_methods('')
245
+ result += api_map.get_instance_methods('')
239
246
  else
240
247
  result.concat api_map.get_instance_methods(type)
241
248
  end
@@ -0,0 +1,31 @@
1
+ module Solargraph
2
+ class LiveMap
3
+ class Cache
4
+ def initialize
5
+ @method_cache = {}
6
+ @instance_method_cache = {}
7
+ end
8
+
9
+ def get_methods options
10
+ @method_cache[options]
11
+ end
12
+
13
+ def set_methods options, values
14
+ @method_cache[options] = values
15
+ end
16
+
17
+ def get_instance_methods options
18
+ @instance_method_cache[options]
19
+ end
20
+
21
+ def set_instance_methods options, values
22
+ @instance_method_cache[options] = values
23
+ end
24
+
25
+ def clear
26
+ @method_cache.clear
27
+ @instance_method_cache.clear
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,96 @@
1
+ module Solargraph
2
+ # The LiveMap allows extensions to add their own completion suggestions.
3
+ #
4
+ class LiveMap
5
+ @@plugins = []
6
+
7
+ attr_reader :workspace
8
+
9
+ def initialize workspace
10
+ @workspace = workspace
11
+ @runners = []
12
+ at_exit { stop }
13
+ end
14
+
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
22
+ end
23
+ end
24
+
25
+ def reload
26
+ restart
27
+ end
28
+
29
+ def restart
30
+ stop
31
+ start
32
+ end
33
+
34
+ def stop
35
+ @runners.each do |p|
36
+ p.stop
37
+ end
38
+ @runners.clear
39
+ end
40
+
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
49
+ end
50
+
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
59
+ end
60
+
61
+ def self.install cls
62
+ @@plugins.push cls
63
+ end
64
+
65
+ private
66
+
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
80
+ end
81
+
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
92
+ end
93
+ cursor
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,16 @@
1
+ module Solargraph
2
+ module Pin
3
+ module Directed
4
+ class Attribute < Solargraph::Pin::Attribute
5
+ def initialize source, node, namespace, access, docstring, name
6
+ super(source, node, namespace, access, docstring)
7
+ @name = name
8
+ end
9
+
10
+ def name
11
+ @name
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Solargraph
2
+ module Pin
3
+ module Directed
4
+ class Method < Solargraph::Pin::Method
5
+ def initialize source, node, namespace, scope, visibility, docstring, name
6
+ super(source, node, namespace, scope, visibility)
7
+ @docstring = docstring
8
+ @name = name
9
+ end
10
+
11
+ def name
12
+ @name
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Solargraph
2
+ module Pin
3
+ # Directed pins are defined by YARD directives instead of code.
4
+ module Directed
5
+ autoload :Attribute, 'solargraph/pin/directed/attribute'
6
+ autoload :Method, 'solargraph/pin/directed/method'
7
+ end
8
+ end
9
+ end
@@ -10,5 +10,6 @@ module Solargraph
10
10
  autoload :GlobalVariable, 'solargraph/pin/global_variable'
11
11
  autoload :Constant, 'solargraph/pin/constant'
12
12
  autoload :Symbol, 'solargraph/pin/symbol'
13
+ autoload :Directed, 'solargraph/pin/directed'
13
14
  end
14
15
  end
@@ -0,0 +1,38 @@
1
+ module Solargraph
2
+ module Plugin
3
+ class Base
4
+
5
+ def initialize workspace
6
+ # @!attribute [r] workspace
7
+ # @return [String]
8
+ define_singleton_method(:workspace) { workspace }
9
+ post_initialize
10
+ end
11
+
12
+ def post_initialize
13
+ end
14
+
15
+ def start
16
+ raise "#{self.class} needs to implement the start method"
17
+ end
18
+
19
+ def stop
20
+ raise "#{self.class} needs to implement the stop method"
21
+ end
22
+
23
+ def get_methods namespace:, root:, scope:, with_private: false
24
+ raise "#{self.class} needs to implement the get_methods method"
25
+ end
26
+
27
+ protected
28
+
29
+ def respond_ok data
30
+ Solargraph::Plugin::Response.new('ok', data)
31
+ end
32
+
33
+ def respond_err exception
34
+ Solargraph::Plugin::Response.new('err', [], exception.message)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ module Solargraph
2
+ module Plugin
3
+ class Response
4
+ attr_reader :status
5
+ attr_reader :data
6
+ attr_reader :message
7
+
8
+ def initialize status = 'ok', data = [], message = nil
9
+ @status = status
10
+ @data = data
11
+ @message = message
12
+ end
13
+
14
+ def ok?
15
+ status == 'ok'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Solargraph
2
+ module Plugin
3
+ class Runtime < Base
4
+ def start
5
+ end
6
+
7
+ def stop
8
+ end
9
+
10
+ def get_methods namespace:, root:, scope:, with_private: false
11
+ raise "#{self.class} needs to implement the get_methods method"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Solargraph
2
+ module Plugin
3
+ autoload :Base, 'solargraph/plugin/base'
4
+ autoload :Runtime, 'solargraph/plugin/runtime'
5
+ autoload :Response, 'solargraph/plugin/response'
6
+ end
7
+ end
@@ -50,7 +50,7 @@ module Solargraph
50
50
  code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: api_map, cursor: [params['line'].to_i, params['column'].to_i])
51
51
  offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
52
52
  sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false, filtered: true)
53
- { "status" => "ok", "suggestions" => sugg }.to_json
53
+ JSON.generate({ "status" => "ok", "suggestions" => sugg.map(&:as_json) })
54
54
  rescue Exception => e
55
55
  STDERR.puts e
56
56
  STDERR.puts e.backtrace.join("\n")
@@ -0,0 +1,11 @@
1
+ module Solargraph
2
+ module ServerMethods
3
+ def available_port
4
+ socket = Socket.new(:INET, :STREAM, 0)
5
+ socket.bind(Addrinfo.tcp("127.0.0.1", 0))
6
+ port = socket.local_address.ip_port
7
+ socket.close
8
+ port
9
+ end
10
+ end
11
+ end
@@ -5,9 +5,12 @@ require 'rubygems/package'
5
5
  require 'zlib'
6
6
  require 'net/http'
7
7
  require 'socket'
8
+ require 'bundler'
8
9
 
9
10
  module Solargraph
10
11
  class Shell < Thor
12
+ include Solargraph::ServerMethods
13
+
11
14
  map %w[--version -v] => :version
12
15
 
13
16
  desc "--version, -v", "Print the version"
@@ -93,25 +96,28 @@ module Solargraph
93
96
  end
94
97
 
95
98
  desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
99
+ option :extensions, type: :boolean, aliases: :e, desc: 'Add installed extensions', default: true
96
100
  def config(directory = '.')
101
+ matches = []
102
+ if options[:extensions]
103
+ Gem::Specification.each do |g|
104
+ puts g.name
105
+ if g.name.match(/^solargraph\-[A-Za-z0-9_\-]*?\-ext/)
106
+ require g.name
107
+ matches.push g.name
108
+ end
109
+ end
110
+ end
111
+ conf = Solargraph::ApiMap::Config.new.raw_data
112
+ unless matches.empty?
113
+ matches.each do |m|
114
+ conf['extensions'].push m
115
+ end
116
+ end
97
117
  File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
98
- file.puts "include:",
99
- " - ./**/*.rb",
100
- "exclude:",
101
- " - spec/**/*",
102
- " - test/**/*"
118
+ file.puts conf.to_yaml
103
119
  end
104
120
  STDOUT.puts "Configuration file initialized."
105
121
  end
106
-
107
- private
108
-
109
- def available_port
110
- socket = Socket.new(:INET, :STREAM, 0)
111
- socket.bind(Addrinfo.tcp("127.0.0.1", 0))
112
- port = socket.local_address.ip_port
113
- socket.close
114
- port
115
- end
116
122
  end
117
123
  end
@@ -61,7 +61,8 @@ module Solargraph
61
61
  # @return [String]
62
62
  def return_type
63
63
  if @return_type.nil? and !docstring.nil?
64
- t = docstring.tag(:overload)&.tag(:return) || docstring.tag(:return)
64
+ ol = docstring.tag(:overload)
65
+ t = ol.nil? ? docstring.tag(:return) : ol.tag(:return)
65
66
  @return_type = t.types[0] unless t.nil? or t.types.nil?
66
67
  end
67
68
  @return_type
@@ -69,7 +70,7 @@ module Solargraph
69
70
 
70
71
  # @return [YARD::Docstring]
71
72
  def docstring
72
- @docstring ||= @code_object&.docstring
73
+ @docstring ||= @code_object.nil? ? nil : @code_object.docstring
73
74
  end
74
75
 
75
76
  # @return [String]
@@ -95,8 +96,8 @@ module Solargraph
95
96
  @params
96
97
  end
97
98
 
98
- def to_json args={}
99
- obj = {
99
+ def as_json args = {}
100
+ {
100
101
  label: @label,
101
102
  kind: @kind,
102
103
  insert: @insert,
@@ -108,7 +109,10 @@ module Solargraph
108
109
  return_type: return_type,
109
110
  documentation: documentation
110
111
  }
111
- obj.to_json(args)
112
+ end
113
+
114
+ def to_json args = {}
115
+ as_json.to_json(args)
112
116
  end
113
117
 
114
118
  def self.pull pin, return_type = nil
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.13.2'
2
+ VERSION = '0.13.3'
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require 'parser/current'
2
2
  require 'yard'
3
- require 'bundler'
4
3
 
5
4
  module Solargraph
6
5
 
@@ -27,7 +26,7 @@ module Solargraph
27
26
  if gy.nil?
28
27
  STDERR.puts "Required path not found: #{r}"
29
28
  else
30
- STDERR.puts "Adding #{gy}"
29
+ #STDERR.puts "Adding #{gy}"
31
30
  yardocs.unshift gy
32
31
  add_gem_dependencies g
33
32
  end
@@ -47,6 +46,11 @@ module Solargraph
47
46
  #cache_core
48
47
  end
49
48
 
49
+ # @return [Solargraph::LiveMap]
50
+ def live_map
51
+ @live_map ||= Solargraph::LiveMap.new
52
+ end
53
+
50
54
  # @return [Array<String>]
51
55
  def yardocs
52
56
  @yardocs ||= []
@@ -255,15 +259,28 @@ module Solargraph
255
259
  def bundled_gem_yardocs
256
260
  result = []
257
261
  unless workspace.nil?
258
- gl = File.join(workspace, 'Gemfile.lock')
259
- if File.file?(gl)
260
- lockfile = Bundler::LockfileParser.new(Bundler.read_file(gl))
261
- lockfile.specs.each do |s|
262
- y = YARD::Registry.yardoc_file_for_gem(s.name, s.version.to_s)
263
- if y.nil?
264
- STDERR.puts "Bundled gem not found: #{s.name} #{s.version}"
265
- else
266
- result.push y
262
+ Bundler.with_clean_env do
263
+ Bundler.environment.chdir(workspace) do
264
+ glfn = File.join(workspace, 'Gemfile.lock')
265
+ spec_versions = {}
266
+ if File.file?(glfn)
267
+ lockfile = Bundler::LockfileParser.new(Bundler.read_file(glfn))
268
+ lockfile.specs.each do |s|
269
+ spec_versions[s.name] = s.version.to_s
270
+ end
271
+ end
272
+ Bundler.environment.dependencies.each do |s|
273
+ if s.type == :runtime
274
+ ver = spec_versions[s.name]
275
+ y = YARD::Registry.yardoc_file_for_gem(s.name, ver)
276
+ if y.nil?
277
+ STDERR.puts "Bundled gem not found: #{s.name}, #{ver}"
278
+ else
279
+ #STDERR.puts "Adding #{y}"
280
+ result.push y
281
+ add_gem_dependencies(s.name)
282
+ end
283
+ end
267
284
  end
268
285
  end
269
286
  end
@@ -325,7 +342,7 @@ module Solargraph
325
342
  if gy.nil?
326
343
  STDERR.puts "Required path not found: #{r}"
327
344
  else
328
- STDERR.puts "Adding #{gy}"
345
+ #STDERR.puts "Adding #{gy}"
329
346
  yardocs.unshift gy
330
347
  end
331
348
  end
data/lib/solargraph.rb CHANGED
@@ -3,18 +3,21 @@ require 'rubygems/package'
3
3
  require 'yard-solargraph'
4
4
 
5
5
  module Solargraph
6
- autoload :Analyzer, 'solargraph/analyzer'
7
- autoload :Shell, 'solargraph/shell'
8
- autoload :LiveParser, 'solargraph/live_parser'
9
- autoload :ApiMap, 'solargraph/api_map'
10
- autoload :CodeMap, 'solargraph/code_map'
11
- autoload :NodeMethods, 'solargraph/node_methods'
12
- autoload :Suggestion, 'solargraph/suggestion'
13
- autoload :Snippets, 'solargraph/snippets'
14
- autoload :Server, 'solargraph/server'
15
- autoload :YardMap, 'solargraph/yard_map'
16
- autoload :YardMethods, 'solargraph/yard_methods'
17
- autoload :Pin, 'solargraph/pin'
6
+ autoload :Analyzer, 'solargraph/analyzer'
7
+ autoload :Shell, 'solargraph/shell'
8
+ autoload :LiveParser, 'solargraph/live_parser'
9
+ autoload :ApiMap, 'solargraph/api_map'
10
+ autoload :CodeMap, 'solargraph/code_map'
11
+ autoload :NodeMethods, 'solargraph/node_methods'
12
+ autoload :Suggestion, 'solargraph/suggestion'
13
+ autoload :Snippets, 'solargraph/snippets'
14
+ autoload :Server, 'solargraph/server'
15
+ autoload :YardMap, 'solargraph/yard_map'
16
+ autoload :YardMethods, 'solargraph/yard_methods'
17
+ autoload :Pin, 'solargraph/pin'
18
+ autoload :LiveMap, 'solargraph/live_map'
19
+ autoload :ServerMethods, 'solargraph/server_methods'
20
+ autoload :Plugin, 'solargraph/plugin'
18
21
 
19
22
  YARDOC_PATH = File.join(File.realpath(File.dirname(__FILE__)), '..', 'yardoc')
20
23
  YARD_EXTENSION_FILE = File.join(File.realpath(File.dirname(__FILE__)), 'yard-solargraph.rb')
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.13.2
4
+ version: 0.13.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-11-01 00:00:00.000000000 Z
11
+ date: 2017-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -76,30 +76,30 @@ dependencies:
76
76
  name: bundler
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ">="
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: '1.14'
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ">="
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '0'
88
+ version: '1.14'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: puma
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - ">="
93
+ - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '0'
95
+ version: '3.8'
96
96
  type: :runtime
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - ">="
100
+ - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '0'
102
+ version: '3.8'
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: rspec
105
105
  requirement: !ruby/object:Gem::Requirement
@@ -190,6 +190,8 @@ files:
190
190
  - lib/solargraph/api_map/config.rb
191
191
  - lib/solargraph/api_map/source.rb
192
192
  - lib/solargraph/code_map.rb
193
+ - lib/solargraph/live_map.rb
194
+ - lib/solargraph/live_map/cache.rb
193
195
  - lib/solargraph/node_methods.rb
194
196
  - lib/solargraph/pin.rb
195
197
  - lib/solargraph/pin/attribute.rb
@@ -197,12 +199,20 @@ files:
197
199
  - lib/solargraph/pin/base_variable.rb
198
200
  - lib/solargraph/pin/class_variable.rb
199
201
  - lib/solargraph/pin/constant.rb
202
+ - lib/solargraph/pin/directed.rb
203
+ - lib/solargraph/pin/directed/attribute.rb
204
+ - lib/solargraph/pin/directed/method.rb
200
205
  - lib/solargraph/pin/global_variable.rb
201
206
  - lib/solargraph/pin/instance_variable.rb
202
207
  - lib/solargraph/pin/local_variable.rb
203
208
  - lib/solargraph/pin/method.rb
204
209
  - lib/solargraph/pin/symbol.rb
210
+ - lib/solargraph/plugin.rb
211
+ - lib/solargraph/plugin/base.rb
212
+ - lib/solargraph/plugin/response.rb
213
+ - lib/solargraph/plugin/runtime.rb
205
214
  - lib/solargraph/server.rb
215
+ - lib/solargraph/server_methods.rb
206
216
  - lib/solargraph/shell.rb
207
217
  - lib/solargraph/snippets.rb
208
218
  - lib/solargraph/suggestion.rb
@@ -237,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
247
  version: '0'
238
248
  requirements: []
239
249
  rubyforge_project:
240
- rubygems_version: 2.5.1
250
+ rubygems_version: 2.4.5
241
251
  signing_key:
242
252
  specification_version: 4
243
253
  summary: Solargraph for Ruby