solargraph 0.9.0 → 0.9.1

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: 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