solargraph 0.7.5 → 0.8.0

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: bc699f1c3abc5198bf2fde325bb4dfde8c6cb384
4
- data.tar.gz: 6f676543082c9943d647772d3c4c7f04ab4caefe
3
+ metadata.gz: a80ad72c101042120c5ec349dd3fb19a98e794e7
4
+ data.tar.gz: 99d562e48985d5fa6e3d8dbaf93edafd165490c4
5
5
  SHA512:
6
- metadata.gz: d519c282a68e56c063068d03a1d7067e98d544714e5b234b5f5da08c6b2e354fcc0067240bf6630eeeeb94b02cf57c1461715054b241febfe73217b53e6e3129
7
- data.tar.gz: 57e7b7388f4aca96e654a1997cd8d236227f9ebb76f7b4d118ca2fe5e3e015955c583889693e683e81f37e978b5d8c5781d218b2e18af17e6d88262f7bde5f12
6
+ metadata.gz: ee8a6a7d1d7cc1ec77727a81e7cd4db7e3da8c0d03baee7424ac2063d281bbc1ceb1863c37c489219f65735cc3adbb64f78b05b7a1ed29a9dfc2b73eb776c6ee
7
+ data.tar.gz: 34a309dcdb41c54a99ced46a8c51fe3b4372d8dc51a2620647f0b7d3f4331662f7fd3a263f4a99d6e45f3bfe899b965212e38adfb1e578daa89667914be50b98
@@ -15,7 +15,7 @@ module Solargraph
15
15
 
16
16
  MAPPABLE_METHODS = [
17
17
  :include, :extend, :require, :autoload, :attr_reader, :attr_writer, :attr_accessor, :private, :public, :protected
18
- ] # @todo Not including solargraph_include_public_methods (an experimental thing)
18
+ ]
19
19
 
20
20
  include NodeMethods
21
21
 
@@ -99,7 +99,7 @@ module Solargraph
99
99
 
100
100
  def self.get_keywords
101
101
  result = []
102
- keywords = KEYWORDS + MAPPABLE_METHODS
102
+ keywords = KEYWORDS + ['attr_reader', 'attr_writer', 'attr_accessor', 'private', 'public', 'protected']
103
103
  keywords.each { |k|
104
104
  result.push Suggestion.new(k, kind: Suggestion::KEYWORD, detail: 'Keyword')
105
105
  }
@@ -250,7 +250,6 @@ module Solargraph
250
250
  if @yardoc_files.nil?
251
251
  @yardoc_files = []
252
252
  yard_options[:include].each { |glob|
253
- #@yardoc_files.concat Dir[File.join workspace, glob]
254
253
  Dir[File.join workspace, glob].each { |f|
255
254
  @yardoc_files.push File.absolute_path(f)
256
255
  }
@@ -349,7 +348,6 @@ module Solargraph
349
348
  meths += get_methods('') if top or type.to_s == ''
350
349
  else
351
350
  meths = get_methods(type)
352
- #meths += get_methods('') if top
353
351
  end
354
352
  meths.delete_if{ |m| m.insert != p }
355
353
  return nil if meths.empty?
@@ -389,7 +387,7 @@ module Solargraph
389
387
  meths
390
388
  end
391
389
  end
392
-
390
+
393
391
  def get_method_args node
394
392
  list = nil
395
393
  args = []
@@ -466,12 +464,9 @@ module Solargraph
466
464
  STDERR.puts "No workspace specified for yardoc update."
467
465
  else
468
466
  Dir.chdir(workspace) do
469
- #YARD::Registry.load(yard_options[:include] - yard_options[:exclude], true)
470
- #YARD::Registry.save
471
467
  Thread.new {
472
468
  STDERR.puts "Updating the yardoc..."
473
469
  globs = yard_options[:include] - yard_options[:exclude]
474
- #cmd = "yardoc #{globs.join(' ')} -e #{Solargraph::YARD_EXTENSION_FILE} #{yard_options[:flags].join(' ')}"
475
470
  cmd = "yardoc -e #{Solargraph::YARD_EXTENSION_FILE}"
476
471
  STDERR.puts "Update yardoc with #{cmd}"
477
472
  STDERR.puts `#{cmd}`
@@ -514,16 +509,12 @@ module Solargraph
514
509
  docstring = get_comment_for(c)
515
510
  label = "#{c.children[1]}"
516
511
  args = get_method_args(c)
517
- label += " #{args.join(', ')}" unless args.empty?
518
- meths.push Suggestion.new(label, insert: c.children[1].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, detail: 'Method', documentation: docstring) if c.children[1].to_s[0].match(/[a-z_]/i) and c.children[1] != :def
512
+ meths.push Suggestion.new(label, insert: c.children[1].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, detail: 'Method', documentation: docstring, arguments: args) if c.children[1].to_s[0].match(/[a-z_]/i) and c.children[1] != :def
519
513
  elsif c.type == :send and c.children[1] == :include
520
514
  # TODO: This might not be right. Should we be getting singleton methods
521
515
  # from an include, or only from an extend?
522
516
  i = unpack_name(c.children[2])
523
517
  meths += inner_get_methods(i, root, skip) unless i == 'Kernel'
524
- #elsif c.type == :send and c.children[1] == :solargraph_include_public_methods
525
- # i = unpack_name(c.children[2])
526
- # meths += get_instance_methods(i, root, visibility: [:public])
527
518
  else
528
519
  meths += inner_get_methods_from_node(c, root, skip)
529
520
  end
@@ -559,8 +550,7 @@ module Solargraph
559
550
  cmnt = get_comment_for(c)
560
551
  label = "#{c.children[0]}"
561
552
  args = get_method_args(c)
562
- label += " #{args.join(', ')}" unless args.empty?
563
- meths.push Suggestion.new(label, insert: c.children[0].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, documentation: cmnt, detail: fqns) if c.children[0].to_s[0].match(/[a-z]/i)
553
+ meths.push Suggestion.new(label, insert: c.children[0].to_s.gsub(/=/, ' = '), kind: Suggestion::METHOD, documentation: cmnt, detail: fqns, arguments: args) if c.children[0].to_s[0].match(/[a-z]/i)
564
554
  elsif c.kind_of?(AST::Node) and c.type == :send and c.children[1] == :attr_reader
565
555
  c.children[2..-1].each { |x|
566
556
  meths.push Suggestion.new(x.children[0], kind: Suggestion::METHOD) if x.type == :sym
@@ -590,7 +580,7 @@ module Solargraph
590
580
  def mappable?(node)
591
581
  return true if node.kind_of?(AST::Node) and [:array, :hash, :str, :int, :float].include?(node.type)
592
582
  # TODO Add node.type :casgn (constant assignment)
593
- if node.kind_of?(AST::Node) and (node.type == :class or node.type == :module or node.type == :def or node.type == :defs or node.type == :ivasgn or node.type == :gvasgn or node.type == :lvasgn or node.type == :or_asgn)
583
+ if node.kind_of?(AST::Node) and (node.type == :class or node.type == :module or node.type == :def or node.type == :defs or node.type == :ivasgn or node.type == :gvasgn or node.type == :lvasgn or node.type == :or_asgn or node.type == :const or node.type == :lvar)
594
584
  true
595
585
  elsif node.kind_of?(AST::Node) and node.type == :send and node.children[0] == nil and MAPPABLE_METHODS.include?(node.children[1])
596
586
  true
@@ -627,6 +617,9 @@ module Solargraph
627
617
  if node.type == :class
628
618
  children += node.children[0, 2]
629
619
  children += get_mappable_nodes(node.children[2..-1], comment_hash)
620
+ #children += get_mappable_nodes(node.children, comment_hash)
621
+ elsif node.type == :const
622
+ children += node.children
630
623
  elsif node.type == :def
631
624
  children += node.children[0, 2]
632
625
  children += get_mappable_nodes(node.children[2..-1], comment_hash)
@@ -647,7 +640,7 @@ module Solargraph
647
640
  @required.push(node.children[3].children[0]) if node.children[3].children[0].kind_of?(String)
648
641
  type = :require
649
642
  children += node.children[1, 3]
650
- elsif node.type == :send
643
+ elsif node.type == :send or node.type == :lvar
651
644
  children += node.children
652
645
  elsif node.type == :or_asgn
653
646
  # TODO: The api_map should ignore local variables.
@@ -24,10 +24,6 @@ module Solargraph
24
24
  end
25
25
  @code = code.gsub(/\r/, '')
26
26
  tries = 0
27
- # Hide incomplete code to avoid syntax errors
28
- # @todo This might not be necessary given the corrected character
29
- # replacement in retries.
30
- #tmp = "#{@code}\nX".gsub(/[\.@]([\s])/, '#\1').gsub(/([\A\s]?)def([\s]*?[\n\Z])/, '\1#ef\2')
31
27
  tmp = @code
32
28
  begin
33
29
  node, comments = Parser::CurrentRuby.parse_with_comments(tmp)
@@ -41,10 +37,6 @@ module Solargraph
41
37
  STDERR.puts "Retrying..."
42
38
  tries += 1
43
39
  spot = e.diagnostic.location.begin_pos
44
- #STDERR.puts "CODE>>>>"
45
- #STDERR.puts tmp
46
- #STDERR.puts "<<<<CODE"
47
- #STDERR.puts "Spot #{spot}: #{tmp[spot]}"
48
40
  repl = '_'
49
41
  if tmp[spot] == '@' or tmp[spot] == ':'
50
42
  # Stub unfinished instance variables and symbols
@@ -61,14 +53,7 @@ module Solargraph
61
53
  repl= 'end;end'
62
54
  end
63
55
  end
64
- #if spot == 0
65
- # tmp = '#' + tmp[1..-1]
66
- #else
67
- tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
68
- #end
69
- #STDERR.puts "CHNG>>>>"
70
- #STDERR.puts tmp
71
- #STDERR.puts "<<<<CHNG"
56
+ tmp = tmp[0..spot] + repl + tmp[spot+repl.length+1..-1].to_s
72
57
  retry
73
58
  end
74
59
  raise e
@@ -136,12 +121,12 @@ module Solargraph
136
121
  def namespace_at(index)
137
122
  tree = tree_at(index)
138
123
  return nil if tree.length == 0
139
- node = parent_node_from(index, :module, :class)
140
- slice = tree[(tree.index(node) || 0)..-1]
124
+ slice = tree
141
125
  parts = []
142
126
  slice.reverse.each { |n|
143
127
  if n.type == :class or n.type == :module
144
- parts.push unpack_name(n.children[0])
128
+ c = const_from(n.children[0])
129
+ parts.push c
145
130
  end
146
131
  }
147
132
  parts.join("::")
@@ -179,7 +164,7 @@ module Solargraph
179
164
  @api_map.get_instance_variables(ns, (node.type == :def ? :instance : :class))
180
165
  end
181
166
 
182
- def suggest_at index, filtered: true, with_snippets: false
167
+ def suggest_at index, filtered: false, with_snippets: false
183
168
  node = node_at(index - 2)
184
169
  return [] if string_at?(index)
185
170
  result = []
@@ -240,10 +225,88 @@ module Solargraph
240
225
  end
241
226
  end
242
227
  end
243
- #result = reduce_starting_with(result, word_at(index)) if filtered
228
+ result = reduce_starting_with(result, word_at(index)) if filtered
244
229
  result.uniq{|s| s.path}
245
230
  end
246
231
 
232
+ def signatures_at index
233
+ sig = signature_index_before(index)
234
+ return [] if sig.nil?
235
+ word = word_at(sig)
236
+ suggest_at(sig).reject{|s| s.label != word}
237
+ end
238
+
239
+ def resolve_object_at index
240
+ signature = get_signature_at(index)
241
+ cursor = index
242
+ while @code[cursor] =~ /[a-z0-9_\?]/i
243
+ signature += @code[cursor]
244
+ cursor += 1
245
+ break if cursor >= @code.length
246
+ end
247
+ return [] if signature.to_s == ''
248
+ ns_here = namespace_at(index)
249
+ scope = parent_node_from(index, :class, :module, :def, :defs) || @node
250
+ parts = signature.split('.')
251
+ if parts.length > 1
252
+ beginner = parts[0..-2].join('.')
253
+ ender = parts.last
254
+ else
255
+ beginner = signature
256
+ ender = nil
257
+ end
258
+ var = find_local_variable_node(parts[0], scope)
259
+ if var.nil?
260
+ # It's not a local variable
261
+ fqns = @api_map.find_fully_qualified_namespace(beginner, ns_here)
262
+ if fqns.nil?
263
+ # It's a method call
264
+ if ender.nil?
265
+ return @api_map.yard_map.objects(beginner, ns_here)
266
+ else
267
+ sig_scope = (scope.type == :def ? :instance : :class)
268
+ type = @api_map.infer_signature_type(beginner, ns_here, scope: sig_scope)
269
+ return [] if type.nil?
270
+ path = type
271
+ path += "##{ender}" unless ender.nil?
272
+ return @api_map.yard_map.objects(path, ns_here)
273
+ end
274
+ else
275
+ path = beginner
276
+ path += "##{ender}" unless ender.nil?
277
+ return @api_map.yard_map.objects(path, ns_here)
278
+ end
279
+ else
280
+ # It's a local variable. Get the type from the node
281
+ type = get_type_comment(var)
282
+ type = infer(var.children[1]) if type.nil?
283
+ if type.nil?
284
+ vsig = resolve_node_signature(var.children[1])
285
+ vparts = vsig.split('.')
286
+ fqns = @api_map.find_fully_qualified_namespace(vparts[0], ns_here)
287
+ if fqns.nil?
288
+ vtype = @api_map.infer_signature_type(vsig, ns_here, scope: :instance)
289
+ else
290
+ vtype = @api_map.infer_signature_type(vparts[1..-1].join('.'), fqns, scope: :class)
291
+ end
292
+ return [] if vtype.nil?
293
+ fqns = @api_map.find_fully_qualified_namespace(vtype, ns_here)
294
+ if ender.nil?
295
+ signature = parts[1..-1].join('.')
296
+ else
297
+ signature = parts[1..-2].join('.')
298
+ end
299
+ type = @api_map.infer_signature_type(signature, fqns, scope: :instance)
300
+ end
301
+ unless type.nil?
302
+ path = type
303
+ path += "##{ender}" unless ender.nil?
304
+ return @api_map.yard_map.objects(path, ns_here)
305
+ end
306
+ end
307
+ return []
308
+ end
309
+
247
310
  # Find the signature at the specified index and get suggestions based
248
311
  # on its inferred type.
249
312
  #
@@ -274,23 +337,44 @@ module Solargraph
274
337
  # It's a local variable. Get the type from the node
275
338
  type = get_type_comment(var)
276
339
  type = infer(var.children[1]) if type.nil?
340
+ skipdat = false
277
341
  if type.nil?
278
342
  vsig = resolve_node_signature(var.children[1])
279
343
  vparts = vsig.split('.')
280
344
  fqns = @api_map.find_fully_qualified_namespace(vparts[0], ns_here)
281
345
  if fqns.nil?
282
- vtype = @api_map.infer_signature_type(vsig, ns_here, scope: :instance)
346
+ lvar = find_local_variable_node(vparts[0], scope)
347
+ if lvar.nil?
348
+ vtype = @api_map.infer_signature_type(vsig, ns_here, scope: :instance)
349
+ else
350
+ type = get_type_comment(lvar)
351
+ type = infer(lvar.children[1]) if type.nil?
352
+ if type.nil?
353
+ type = @api_map.infer_signature_type(resolve_node_signature(lvar.children[1]), ns_here, scope: :class)
354
+ end
355
+ unless type.nil?
356
+ signature = "#{vparts[1..-1].join('.')}"
357
+ skipdat = true
358
+ end
359
+ end
283
360
  else
284
361
  vtype = @api_map.infer_signature_type(vparts[1..-1].join('.'), fqns, scope: :class)
362
+ type = fqns
363
+ signature = parts[1..-1].join('.')
364
+ skipdat = true
285
365
  end
286
- fqns = @api_map.find_fully_qualified_namespace(vtype, ns_here)
287
- signature = parts[1..-1].join('.')
288
- type = @api_map.infer_signature_type(signature, fqns, scope: :instance)
366
+ unless skipdat
367
+ fqns = @api_map.find_fully_qualified_namespace(vtype, ns_here)
368
+ signature = parts[1..-1].join('.')
369
+ type = @api_map.infer_signature_type(signature, fqns, scope: :instance)
370
+ end
371
+ else
372
+ signature = signature.split('.')[1..-1].join('.')
289
373
  end
290
374
  unless type.nil?
291
375
  lparts = signature.split('.')
292
- if lparts.length > 1
293
- lsig = lparts[1..-1].join('.')
376
+ if lparts.length >= 1
377
+ lsig = signature
294
378
  ltype = @api_map.infer_signature_type(lsig, type, scope: :instance)
295
379
  result.concat @api_map.get_instance_methods(ltype) unless ltype.nil?
296
380
  else
@@ -454,5 +538,22 @@ module Solargraph
454
538
  end
455
539
  i
456
540
  end
541
+
542
+ def signature_index_before index
543
+ open_parens = 0
544
+ cursor = index - 1
545
+ while cursor >= 0
546
+ break if cursor < 0
547
+ if @code[cursor] == ')'
548
+ open_parens -= 1
549
+ elsif @code[cursor] == '('
550
+ open_parens += 1
551
+ end
552
+ break if open_parens == 1
553
+ cursor -= 1
554
+ end
555
+ cursor = nil if cursor < 0
556
+ cursor
557
+ end
457
558
  end
458
559
  end
@@ -22,6 +22,44 @@ module Solargraph
22
22
  parts
23
23
  end
24
24
 
25
+ def const_from node
26
+ if node.kind_of?(AST::Node) and node.type == :const
27
+ result = ''
28
+ unless node.children[0].nil?
29
+ result = const_from(node.children[0])
30
+ end
31
+ if result == ''
32
+ result = node.children[1].to_s
33
+ else
34
+ result = result + '::' + node.children[1].to_s
35
+ end
36
+ result
37
+ else
38
+ nil
39
+ end
40
+ end
41
+
42
+ def drill_signature node, signature
43
+ return signature unless node.kind_of?(AST::Node)
44
+ if node.type == :const or node.type == :cbase
45
+ unless node.children[0].nil?
46
+ signature += drill_signature(node.children[0], signature)
47
+ end
48
+ signature += '::' unless signature.empty?
49
+ signature += node.children[1].to_s
50
+ elsif node.type == :lvar
51
+ signature += '.' unless signature.empty?
52
+ signature += node.children[0].to_s
53
+ elsif node.type == :send
54
+ unless node.children[0].nil?
55
+ signature += drill_signature(node.children[0], signature)
56
+ end
57
+ signature += '.' unless signature.empty?
58
+ signature += node.children[1].to_s
59
+ end
60
+ signature
61
+ end
62
+
25
63
  def infer node
26
64
  if node.type == :str
27
65
  return 'String'
@@ -43,7 +81,8 @@ module Solargraph
43
81
  #
44
82
  # @return [String]
45
83
  def resolve_node_signature node
46
- stack_node_signature(node).join('.')
84
+ #stack_node_signature(node).join('.')
85
+ drill_signature node, ''
47
86
  end
48
87
 
49
88
  def stack_node_signature node
@@ -24,7 +24,45 @@ module Solargraph
24
24
  @@semaphore.synchronize {
25
25
  code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
26
26
  offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
27
- sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false, filtered: true)
27
+ sugg = code_map.suggest_at(offset, with_snippets: params['with_snippets'] == '1' ? true : false)
28
+ }
29
+ { "status" => "ok", "suggestions" => sugg }.to_json
30
+ rescue Exception => e
31
+ STDERR.puts e
32
+ STDERR.puts e.backtrace.join("\n")
33
+ { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
34
+ end
35
+ end
36
+
37
+ post '/signify' do
38
+ content_type :json
39
+ begin
40
+ sugg = []
41
+ workspace = params['workspace'] || CodeMap.find_workspace(params['filename'])
42
+ Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
43
+ @@semaphore.synchronize {
44
+ code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
45
+ offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
46
+ sugg = code_map.signatures_at(offset)
47
+ }
48
+ { "status" => "ok", "suggestions" => sugg }.to_json
49
+ rescue Exception => e
50
+ STDERR.puts e
51
+ STDERR.puts e.backtrace.join("\n")
52
+ { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
53
+ end
54
+ end
55
+
56
+ post '/hover' do
57
+ content_type :json
58
+ begin
59
+ sugg = []
60
+ workspace = params['workspace'] || CodeMap.find_workspace(params['filename'])
61
+ Server.prepare_workspace workspace unless @@api_hash.has_key?(workspace)
62
+ @@semaphore.synchronize {
63
+ code_map = CodeMap.new(code: params['text'], filename: params['filename'], api_map: @@api_hash[workspace])
64
+ offset = code_map.get_offset(params['line'].to_i, params['column'].to_i)
65
+ sugg = code_map.resolve_object_at(offset)
28
66
  }
29
67
  { "status" => "ok", "suggestions" => sugg }.to_json
30
68
  rescue Exception => e
@@ -58,15 +96,22 @@ module Solargraph
58
96
  erb :document
59
97
  end
60
98
 
61
- def htmlify object
99
+ def htmlify text
100
+ rdoc_to_html text
101
+ end
102
+
103
+ def rdoc_to_html text
104
+ h = Helpers.new
105
+ h.html_markup_rdoc(text)
106
+ end
107
+
108
+ def ruby_to_html code
62
109
  h = Helpers.new
63
- h.object = object
64
- h.htmlify object.docstring.all, :rdoc
110
+ h.html_markup_ruby(code)
65
111
  end
66
112
 
67
113
  class << self
68
114
  def run!
69
- #constant_updates
70
115
  super
71
116
  end
72
117
 
@@ -75,22 +120,8 @@ module Solargraph
75
120
  @@semaphore.synchronize {
76
121
  @@api_hash[directory] = api_map
77
122
  }
78
- #Thread.new {
79
- api_map.update_yardoc
80
- #}
81
- end
82
-
83
- def constant_updates
84
123
  Thread.new {
85
- loop do
86
- @@api_hash.keys.each { |k|
87
- update = Solargraph::ApiMap.new(k)
88
- @@semaphore.synchronize {
89
- @@api_hash[k] = update
90
- }
91
- }
92
- sleep 10
93
- end
124
+ api_map.update_yardoc
94
125
  }
95
126
  end
96
127
  end
@@ -75,7 +75,6 @@ module Solargraph
75
75
  rescue Exception => e
76
76
  STDERR.puts e
77
77
  STDERR.puts e.backtrace.join("\n")
78
- #result = { "status" => "err", "message" => e.message }.to_json
79
78
  result = { "status" => "err", "message" => e.message + "\n" + e.backtrace.join("\n") }.to_json
80
79
  STDOUT.puts result
81
80
  end
@@ -10,9 +10,9 @@ module Solargraph
10
10
  VARIABLE = 'Variable'
11
11
  SNIPPET = 'Snippet'
12
12
 
13
- attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location
13
+ attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location, :arguments
14
14
 
15
- def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil
15
+ def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil, arguments: []
16
16
  @label = label.to_s
17
17
  @kind = kind
18
18
  @insert = insert || @label
@@ -20,6 +20,7 @@ module Solargraph
20
20
  @code_object = code_object
21
21
  @documentation = documentation
22
22
  @location = location
23
+ @arguments = arguments
23
24
  end
24
25
 
25
26
  def path
@@ -55,12 +56,13 @@ module Solargraph
55
56
  insert: @insert,
56
57
  detail: @detail,
57
58
  path: path,
58
- location: (@location.nil? ? nil : @location.to_s)
59
+ location: (@location.nil? ? nil : @location.to_s),
60
+ arguments: @arguments
59
61
  }
60
62
  if @code_object.nil?
61
- obj[:documentation] = @documentation.all unless @documentation.nil?
63
+ obj[:documentation] = @documentation.to_s unless @documentation.nil?
62
64
  else
63
- obj[:documentation] = @code_object.docstring.all unless @code_object.docstring.nil?
65
+ obj[:documentation] = @code_object.docstring.to_s unless @code_object.docstring.nil?
64
66
  end
65
67
  obj.to_json(args)
66
68
  end
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.7.5'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -11,8 +11,6 @@ module Solargraph
11
11
  unless workspace.nil?
12
12
  wsy = File.join(workspace, '.yardoc')
13
13
  yardocs.push wsy if File.exist?(wsy)
14
- #wsy = Dir[File.join workspace, '**/*.rb']
15
- #yardocs.push(wsy)
16
14
  end
17
15
  used = []
18
16
  required.each { |r|
@@ -29,16 +27,7 @@ module Solargraph
29
27
  end
30
28
  end
31
29
  }
32
- # TODO: Experimental loading of all gems
33
- #Bundler.load.specs.each { |s|
34
- # unless used.include?(s.name)
35
- # used.push s.name
36
- # gy = YARD::Registry.yardoc_file_for_gem(s.name)
37
- # yardocs.push gy unless gy.nil?
38
- # end
39
- #}
40
30
  yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc')
41
- #yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc-stdlib')
42
31
  yardocs.uniq!
43
32
  cache_core
44
33
  end
@@ -159,8 +148,7 @@ module Solargraph
159
148
  n = m.to_s.split(/[\.#]/).last.gsub(/=/, ' = ')
160
149
  label = "#{n}"
161
150
  args = get_method_args(m)
162
- label += " #{args.join(', ')}" unless args.empty?
163
- meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
151
+ meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}", arguments: args)
164
152
  }
165
153
  # Collect superclass methods
166
154
  if ns.kind_of?(YARD::CodeObjects::ClassObject) and !ns.superclass.nil?
@@ -168,6 +156,14 @@ module Solargraph
168
156
  end
169
157
  if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Class'
170
158
  meths += get_instance_methods('Class')
159
+ yard = load_yardoc(y)
160
+ i = yard.at("#{ns}#initialize")
161
+ unless i.nil?
162
+ meths.delete_if{|m| m.label == 'new'}
163
+ label = "#{i}"
164
+ args = get_method_args(i)
165
+ meths.push Suggestion.new('new', kind: Suggestion::METHOD, documentation: i.docstring, code_object: i, detail: "#{ns}", location: "#{i.file}:#{i.line}", arguments: args)
166
+ end
171
167
  end
172
168
  end
173
169
  end
@@ -195,8 +191,7 @@ module Solargraph
195
191
  if n.to_s.match(/^[a-z]/i) and (namespace == 'Kernel' or !m.to_s.start_with?('Kernel#')) and !m.docstring.to_s.include?(':nodoc:')
196
192
  label = "#{n}"
197
193
  args = get_method_args(m)
198
- label += " #{args.join(', ')}" unless args.empty?
199
- meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: "#{ns}", location: "#{m.file}:#{m.line}")
194
+ meths.push Suggestion.new(label, insert: "#{n.gsub(/=/, ' = ')}", kind: Suggestion::METHOD, documentation: m.docstring, code_object: m, detail: m.namespace, location: "#{m.file}:#{m.line}", arguments: args)
200
195
  end
201
196
  }
202
197
  if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Object'
@@ -226,6 +221,35 @@ module Solargraph
226
221
  nil
227
222
  end
228
223
 
224
+ def objects path, space = ''
225
+ result = []
226
+ yardocs.each { |y|
227
+ yard = load_yardoc(y)
228
+ unless yard.nil?
229
+ obj = find_first_resolved_namespace(yard, path, space)
230
+ if obj.nil? and path.include?('#')
231
+ parts = path.split('#')
232
+ obj = yard.at(parts[0])
233
+ unless obj.nil?
234
+ meths = obj.meths(scope: [:instance]).keep_if{|m| m.name.to_s == parts[1]}
235
+ meths.each { |m|
236
+ args = get_method_args(m)
237
+ result.push Solargraph::Suggestion.new(m.name, kind: 'Method', detail: m.path, code_object: m, arguments: args)
238
+ }
239
+ end
240
+ else
241
+ unless obj.nil?
242
+ args = []
243
+ args = get_method_args(obj) if obj.kind_of?(YARD::CodeObjects::MethodObject)
244
+ kind = kind_of_object(obj)
245
+ result.push Solargraph::Suggestion.new(obj.name, kind: kind, detail: obj.path, code_object: obj, arguments: args)
246
+ end
247
+ end
248
+ end
249
+ }
250
+ result
251
+ end
252
+
229
253
  private
230
254
 
231
255
  def cache
@@ -257,10 +281,18 @@ module Solargraph
257
281
 
258
282
  def cache_core
259
283
  c = get_constants '', ''
260
- c.each { |n|
261
- #get_methods n.label, visibility: :public
262
- #get_instance_methods n.label, visibility: :public
263
- }
284
+ end
285
+
286
+ def kind_of_object obj
287
+ if obj.kind_of?(YARD::CodeObjects::MethodObject)
288
+ 'Method'
289
+ elsif obj.kind_of?(YARD::CodeObjects::ClassObject)
290
+ 'Class'
291
+ elsif obj.kind_of?(YARD::CodeObjects::ModuleObject)
292
+ 'Module'
293
+ else
294
+ nil
295
+ end
264
296
  end
265
297
  end
266
298
 
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.7.5
4
+ version: 0.8.0
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-05-16 00:00:00.000000000 Z
11
+ date: 2017-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser