solargraph 0.9.0 → 0.9.1

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: de6f8c27644254cbf44fabf999b5e7d9c54361d5
4
- data.tar.gz: e823050e40e151659b89be427a8039165c5a315c
3
+ metadata.gz: 3993f33469901ac1b7d51659d9452a48adcd0e3f
4
+ data.tar.gz: de8f13ed8c39b332b7837fca4bcdfd8516ca8c1f
5
5
  SHA512:
6
- metadata.gz: 1312f30cabb2d18635ea4e48900226318476ac7d53022b46b72afcc2696451154e9fc9718b1f74026ceb2cae6c4afc04b2904f28d3b9c02d555ef410904c53d2
7
- data.tar.gz: 2c05df4a956bdb87868e6d624c72fc232a35599d0abd8763286b0db389f559e4b160747f6c6a3c43b1a2c2d7d8659b840ddd00465a69e57f327e2b0858dd4663
6
+ metadata.gz: 0fdcec41d5a9b6920596d30f16a719948e74b3432b53584a0621b05f7c6d815e5bc5e69748737ef4c415db67061682babefeac0cf28c4cc73e69b8927b86b768
7
+ data.tar.gz: f6daf69d9d06dba1b7fea6e29ed5a2d8c336cfccbe3c33ab29cbb2fa05c79eca886f1e1474ed92ba5cc11a7eeb71ed6fbdedc5de96fc8ecd52c634fe91417209
@@ -24,6 +24,7 @@ module Solargraph
24
24
  attr_reader :workspace
25
25
  attr_reader :required
26
26
 
27
+ # @param workspace [String]
27
28
  def initialize workspace = nil
28
29
  @workspace = workspace.gsub(/\\/, '/') unless workspace.nil?
29
30
  clear
@@ -38,6 +39,7 @@ module Solargraph
38
39
  end
39
40
 
40
41
  def clear
42
+ @file_source = {}
41
43
  @file_nodes = {}
42
44
  @file_comments = {}
43
45
  @parent_stack = {}
@@ -46,15 +48,20 @@ module Solargraph
46
48
  @required = []
47
49
  end
48
50
 
51
+ # @return [Solargraph::YardMap]
49
52
  def yard_map
50
53
  @yard_map ||= YardMap.new(required: required, workspace: workspace)
51
54
  end
52
55
 
56
+ # @param filename [String]
53
57
  def append_file filename
54
58
  append_source File.read(filename), filename
55
59
  end
56
60
 
61
+ # @param text [String]
62
+ # @param filename [String]
57
63
  def append_source text, filename = nil
64
+ @file_source[filename] = text
58
65
  begin
59
66
  node, comments = Parser::CurrentRuby.parse_with_comments(text)
60
67
  append_node(node, comments, filename)
@@ -107,7 +114,6 @@ module Solargraph
107
114
  @file_comments[filename][node.loc]
108
115
  end
109
116
 
110
-
111
117
  def self.get_keywords
112
118
  result = []
113
119
  keywords = KEYWORDS + ['attr_reader', 'attr_writer', 'attr_accessor', 'private', 'public', 'protected']
@@ -149,45 +155,6 @@ module Solargraph
149
155
  result
150
156
  end
151
157
 
152
- def inner_namespaces_in name, root, skip
153
- result = []
154
- fqns = find_fully_qualified_namespace(name, root)
155
- unless fqns.nil? or skip.include?(fqns)
156
- skip.push fqns
157
- nodes = get_namespace_nodes(fqns)
158
- nodes.delete_if { |n| yardoc_has_file?(get_filename_for(n))}
159
- unless nodes.empty?
160
- cursor = @namespace_tree
161
- parts = fqns.split('::')
162
- parts.each { |p|
163
- cursor = cursor[p]
164
- }
165
- unless cursor.nil?
166
- cursor.keys.each { |k|
167
- type = get_namespace_type(k, fqns)
168
- kind = nil
169
- detail = nil
170
- if type == :class
171
- kind = Suggestion::CLASS
172
- detail = 'Class'
173
- elsif type == :module
174
- kind = Suggestion::MODULE
175
- detail = 'Module'
176
- end
177
- result.push Suggestion.new(k, kind: kind, detail: detail)
178
- }
179
- nodes = get_namespace_nodes(fqns)
180
- nodes.each { |n|
181
- get_include_strings_from(n).each { |i|
182
- result += inner_namespaces_in(i, fqns, skip)
183
- }
184
- }
185
- end
186
- end
187
- end
188
- result
189
- end
190
-
191
158
  def find_fully_qualified_namespace name, root = '', skip = []
192
159
  return nil if skip.include?(root)
193
160
  skip.push root
@@ -269,22 +236,6 @@ module Solargraph
269
236
  @yardoc_files.include?(file)
270
237
  end
271
238
 
272
- def inner_get_instance_variables(node, scope)
273
- arr = []
274
- if node.kind_of?(AST::Node)
275
- node.children.each { |c|
276
- if c.kind_of?(AST::Node)
277
- is_inst = !find_parent(c, :def).nil?
278
- if c.type == :ivasgn and c.children[0] and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
279
- arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: get_comment_for(c))
280
- end
281
- arr += inner_get_instance_variables(c, scope) unless [:class, :module].include?(c.type)
282
- end
283
- }
284
- end
285
- arr
286
- end
287
-
288
239
  def infer_instance_variable(var, namespace, scope = :instance)
289
240
  result = nil
290
241
  vn = nil
@@ -418,11 +369,11 @@ module Solargraph
418
369
  if c.type == :arg
419
370
  args.push c.children[0]
420
371
  elsif c.type == :optarg
421
- args.push "#{c.children[0]} = _"
372
+ args.push "#{c.children[0]} = #{code_for(c.children[1])}"
422
373
  elsif c.type == :kwarg
423
374
  args.push "#{c.children[0]}:"
424
375
  elsif c.type == :kwoptarg
425
- args.push "#{c.children[0]}: _"
376
+ args.push "#{c.children[0]}: #{code_for(c.children[1])}"
426
377
  end
427
378
  }
428
379
  args
@@ -607,6 +558,61 @@ module Solargraph
607
558
  meths.uniq
608
559
  end
609
560
 
561
+ def inner_namespaces_in name, root, skip
562
+ result = []
563
+ fqns = find_fully_qualified_namespace(name, root)
564
+ unless fqns.nil? or skip.include?(fqns)
565
+ skip.push fqns
566
+ nodes = get_namespace_nodes(fqns)
567
+ nodes.delete_if { |n| yardoc_has_file?(get_filename_for(n))}
568
+ unless nodes.empty?
569
+ cursor = @namespace_tree
570
+ parts = fqns.split('::')
571
+ parts.each { |p|
572
+ cursor = cursor[p]
573
+ }
574
+ unless cursor.nil?
575
+ cursor.keys.each { |k|
576
+ type = get_namespace_type(k, fqns)
577
+ kind = nil
578
+ detail = nil
579
+ if type == :class
580
+ kind = Suggestion::CLASS
581
+ detail = 'Class'
582
+ elsif type == :module
583
+ kind = Suggestion::MODULE
584
+ detail = 'Module'
585
+ end
586
+ result.push Suggestion.new(k, kind: kind, detail: detail)
587
+ }
588
+ nodes = get_namespace_nodes(fqns)
589
+ nodes.each { |n|
590
+ get_include_strings_from(n).each { |i|
591
+ result += inner_namespaces_in(i, fqns, skip)
592
+ }
593
+ }
594
+ end
595
+ end
596
+ end
597
+ result
598
+ end
599
+
600
+ def inner_get_instance_variables(node, scope)
601
+ arr = []
602
+ if node.kind_of?(AST::Node)
603
+ node.children.each { |c|
604
+ if c.kind_of?(AST::Node)
605
+ is_inst = !find_parent(c, :def).nil?
606
+ if c.type == :ivasgn and c.children[0] and ( (scope == :instance and is_inst) or (scope != :instance and !is_inst) )
607
+ arr.push Suggestion.new(c.children[0], kind: Suggestion::VARIABLE, documentation: get_comment_for(c))
608
+ end
609
+ arr += inner_get_instance_variables(c, scope) unless [:class, :module].include?(c.type)
610
+ end
611
+ }
612
+ end
613
+ arr
614
+ end
615
+
610
616
  def mappable?(node)
611
617
  return true if node.kind_of?(AST::Node) and [:array, :hash, :str, :int, :float].include?(node.type)
612
618
  # TODO Add node.type :casgn (constant assignment)
@@ -728,5 +734,13 @@ module Solargraph
728
734
  }
729
735
  end
730
736
  end
737
+
738
+ def code_for node
739
+ src = @file_source[get_filename_for(node)]
740
+ return nil if src.nil?
741
+ b = node.location.expression.begin.begin_pos
742
+ e = node.location.expression.end.end_pos
743
+ src[b..e].strip.gsub(/,$/, '')
744
+ end
731
745
  end
732
746
  end
@@ -23,8 +23,8 @@ module Solargraph
23
23
  # HACK: The current file is parsed with a trailing underscore to fix
24
24
  # incomplete trees resulting from short scripts (e.g., a lone variable
25
25
  # assignment).
26
- node, comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
27
- @node = self.api_map.append_node(node, comments, filename)
26
+ node, @comments = Parser::CurrentRuby.parse_with_comments(tmp + "\n_")
27
+ @node = self.api_map.append_node(node, @comments, filename)
28
28
  @parsed = tmp
29
29
  @code.freeze
30
30
  @parsed.freeze
@@ -99,6 +99,16 @@ module Solargraph
99
99
  n.kind_of?(AST::Node) and n.type == :str
100
100
  end
101
101
 
102
+ # Determine if the specified index is inside a comment.
103
+ #
104
+ # @return [Boolean]
105
+ def comment_at?(index)
106
+ @comments.each do |c|
107
+ return true if index > c.location.expression.begin_pos and index <= c.location.expression.end_pos
108
+ end
109
+ false
110
+ end
111
+
102
112
  def parent_node_from(index, *types)
103
113
  arr = tree_at(index)
104
114
  arr.each { |a|
@@ -178,7 +188,7 @@ module Solargraph
178
188
  #
179
189
  # @return [Array<Suggestions>] The completion suggestions
180
190
  def suggest_at index, filtered: false, with_snippets: false
181
- return [] if string_at?(index) or string_at?(index - 1)
191
+ return [] if string_at?(index) or string_at?(index - 1) or comment_at?(index)
182
192
  result = []
183
193
  phrase = phrase_at(index)
184
194
  signature = get_signature_at(index)
@@ -387,6 +397,7 @@ module Solargraph
387
397
  # @x.bar @x.bar
388
398
  # y.split(', ').length y.split.length
389
399
  #
400
+ # @param index [Integer]
390
401
  # @return [String]
391
402
  def get_signature_at index
392
403
  brackets = 0
@@ -478,15 +489,25 @@ module Solargraph
478
489
  private
479
490
 
480
491
  def get_method_arguments_from node
492
+ param_hash = {}
493
+ cmnt = api_map.get_comment_for(node)
494
+ unless cmnt.nil?
495
+ tags = cmnt.tags(:param)
496
+ tags.each do |tag|
497
+ param_hash[tag.name] = tag.types[0]
498
+ end
499
+ end
481
500
  result = []
482
501
  args = node.children[1]
483
502
  args.children.each do |arg|
484
503
  name = arg.children[0].to_s
485
- result.push Suggestion.new(name, kind: Suggestion::PROPERTY, insert: name)
504
+ result.push Suggestion.new(name, kind: Suggestion::PROPERTY, insert: name, return_type: param_hash[name])
486
505
  end
487
506
  result
488
507
  end
489
508
 
509
+ # @param suggestions [Array<Solargraph::Suggestion>]
510
+ # @param word [String]
490
511
  def reduce_starting_with(suggestions, word)
491
512
  suggestions.reject { |s|
492
513
  !s.label.start_with?(word)
@@ -132,12 +132,19 @@ module Solargraph
132
132
  end
133
133
 
134
134
  class Helpers
135
+ include YARD::Templates::Helpers::HtmlHelper
136
+
135
137
  attr_accessor :object
136
138
  attr_accessor :serializer
137
- include YARD::Templates::Helpers::HtmlHelper
139
+
140
+ def url_for(object)
141
+ '.'
142
+ end
143
+
138
144
  def options
139
145
  @options ||= YARD::Templates::TemplateOptions.new
140
146
  end
147
+
141
148
  # HACK: The linkify method just returns the arguments as plain text
142
149
  def linkify *args
143
150
  args.join(', ')
@@ -82,7 +82,7 @@ module Solargraph
82
82
 
83
83
  desc 'config [DIRECTORY]', 'Create or overwrite a default configuration file'
84
84
  def config(directory = '.')
85
- File.open(File.join(directory, '.solargraph'), 'w') do |file|
85
+ File.open(File.join(directory, '.solargraph.yml'), 'w') do |file|
86
86
  file.puts "include:",
87
87
  " - ./**/*.rb",
88
88
  "exclude:",
@@ -14,7 +14,7 @@ module Solargraph
14
14
 
15
15
  attr_reader :label, :kind, :insert, :detail, :documentation, :code_object, :location, :arguments
16
16
 
17
- def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil, arguments: []
17
+ def initialize label, kind: KEYWORD, insert: nil, detail: nil, documentation: nil, code_object: nil, location: nil, arguments: [], return_type: nil
18
18
  @helper = Server::Helpers.new
19
19
  @label = label.to_s
20
20
  @kind = kind
@@ -24,6 +24,7 @@ module Solargraph
24
24
  @documentation = documentation
25
25
  @location = location
26
26
  @arguments = arguments
27
+ @return_type = return_type
27
28
  end
28
29
 
29
30
  def path
@@ -35,27 +36,28 @@ module Solargraph
35
36
  end
36
37
 
37
38
  def return_type
38
- if code_object.nil?
39
- unless documentation.nil?
40
- if documentation.kind_of?(YARD::Docstring)
41
- t = documentation.tag(:return)
42
- return nil if t.nil?
43
- return t.types[0]
44
- else
45
- match = documentation.match(/@return \[([a-z0-9:_]*)/i)
46
- return match[1] unless match.nil?
39
+ if @return_type.nil?
40
+ if code_object.nil?
41
+ unless documentation.nil?
42
+ if documentation.kind_of?(YARD::Docstring)
43
+ t = documentation.tag(:return)
44
+ @return_type = t.types[0] unless t.nil? or t.types.nil?
45
+ else
46
+ match = documentation.match(/@return \[([a-z0-9:_]*)/i)
47
+ @return_type = match[1] unless match.nil?
48
+ end
47
49
  end
48
- end
49
- else
50
- o = code_object.tag(:overload)
51
- if o.nil?
52
- r = code_object.tag(:return)
53
50
  else
54
- r = o.tag(:return)
51
+ o = code_object.tag(:overload)
52
+ if o.nil?
53
+ r = code_object.tag(:return)
54
+ else
55
+ r = o.tag(:return)
56
+ end
57
+ @return_type = r.types[0] unless r.nil? or r.types.nil?
55
58
  end
56
- return r.types[0] unless r.nil?
57
59
  end
58
- nil
60
+ @return_type
59
61
  end
60
62
 
61
63
  def documentation
@@ -67,6 +69,23 @@ module Solargraph
67
69
  @documentation
68
70
  end
69
71
 
72
+ def params
73
+ if @params.nil?
74
+ @params = []
75
+ return @params if documentation.nil?
76
+ param_tags = documentation.tags(:param)
77
+ unless param_tags.empty?
78
+ param_tags.each do |t|
79
+ txt = t.name
80
+ txt += " [#{t.types.join(',')}]" unless t.types.nil? or t.types.empty?
81
+ txt += " #{t.text}" unless t.text.nil? or t.text.empty?
82
+ @params.push txt
83
+ end
84
+ end
85
+ end
86
+ @params
87
+ end
88
+
70
89
  def to_json args={}
71
90
  obj = {
72
91
  label: @label,
@@ -76,6 +95,7 @@ module Solargraph
76
95
  path: path,
77
96
  location: (@location.nil? ? nil : @location.to_s),
78
97
  arguments: @arguments,
98
+ params: params,
79
99
  return_type: return_type,
80
100
  documentation: @helper.html_markup_rdoc(documentation.to_s)
81
101
  }
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  end
@@ -1,13 +1,17 @@
1
1
  require 'rubygems'
2
2
  require 'parser/current'
3
3
  require 'yard'
4
+ require 'bundler'
4
5
 
5
6
  module Solargraph
6
7
 
7
8
  class YardMap
8
9
  autoload :Cache, 'solargraph/yard_map/cache'
9
10
 
10
- def initialize required: [], workspace: nil
11
+ attr_reader :workspace
12
+
13
+ def initialize required: [], workspace: nil, with_bundled: false
14
+ @workspace = workspace
11
15
  unless workspace.nil?
12
16
  wsy = File.join(workspace, '.yardoc')
13
17
  yardocs.push wsy if File.exist?(wsy)
@@ -22,16 +26,35 @@ module Solargraph
22
26
  if gy.nil?
23
27
  STDERR.puts "Required path not found: #{r}"
24
28
  else
25
- yardocs.push gy
29
+ STDERR.puts "Adding #{gy}"
30
+ yardocs.unshift gy
26
31
  end
27
32
  end
28
33
  end
29
34
  }
30
35
  yardocs.push File.join(Dir.home, '.solargraph', 'cache', '2.0.0', 'yardoc')
31
36
  yardocs.uniq!
37
+ include_bundled_gems if with_bundled
32
38
  cache_core
33
39
  end
34
40
 
41
+ def include_bundled_gems
42
+ return if workspace.nil?
43
+ lockfile = File.join(workspace, 'Gemfile.lock')
44
+ return unless File.file?(lockfile)
45
+ parser = Bundler::LockfileParser.new(Bundler.read_file(lockfile))
46
+ parser.specs.each do |s|
47
+ STDERR.puts "Specs include #{s.name}"
48
+ gy = YARD::Registry.yardoc_file_for_gem(s.name)
49
+ if gy.nil?
50
+ STDERR.puts "Bundled gem not found: #{s.name}"
51
+ else
52
+ yardocs.unshift gy unless yardocs.include?(gy)
53
+ end
54
+ end
55
+ end
56
+
57
+ # @return [Array<String>]
35
58
  def yardocs
36
59
  @yardocs ||= []
37
60
  end
@@ -50,6 +73,7 @@ module Solargraph
50
73
  end
51
74
  end
52
75
 
76
+ # @param query [String]
53
77
  def search query
54
78
  found = []
55
79
  yardocs.each { |y|
@@ -63,6 +87,7 @@ module Solargraph
63
87
  found.sort
64
88
  end
65
89
 
90
+ # @param query [String]
66
91
  def document query
67
92
  found = []
68
93
  yardocs.each { |y|
@@ -109,6 +134,7 @@ module Solargraph
109
134
  result
110
135
  end
111
136
 
137
+ # @param signature [String]
112
138
  def at signature
113
139
  yardocs.each { |y|
114
140
  yard = load_yardoc(y)
@@ -120,6 +146,8 @@ module Solargraph
120
146
  nil
121
147
  end
122
148
 
149
+ # @param signature [String]
150
+ # @param scope [String]
123
151
  def resolve signature, scope
124
152
  yardocs.each { |y|
125
153
  yard = load_yardoc(y)
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.9.0
4
+ version: 0.9.1
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-07-06 00:00:00.000000000 Z
11
+ date: 2017-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser