solargraph 0.13.2 → 0.13.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: 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