solargraph 0.19.1 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +1 -0
  3. data/lib/solargraph/api_map.rb +29 -4
  4. data/lib/solargraph/api_map/probe.rb +3 -3
  5. data/lib/solargraph/diagnostics.rb +8 -0
  6. data/lib/solargraph/diagnostics/base.rb +12 -0
  7. data/lib/solargraph/diagnostics/require_not_found.rb +23 -0
  8. data/lib/solargraph/diagnostics/rubocop.rb +17 -6
  9. data/lib/solargraph/diagnostics/severities.rb +13 -0
  10. data/lib/solargraph/language_server.rb +5 -4
  11. data/lib/solargraph/language_server/host.rb +113 -19
  12. data/lib/solargraph/language_server/message.rb +2 -0
  13. data/lib/solargraph/language_server/message/base.rb +1 -1
  14. data/lib/solargraph/language_server/message/extended.rb +2 -0
  15. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +38 -0
  16. data/lib/solargraph/language_server/message/extended/document_gems.rb +23 -0
  17. data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +6 -7
  18. data/lib/solargraph/language_server/request.rb +14 -0
  19. data/lib/solargraph/library.rb +37 -3
  20. data/lib/solargraph/page.rb +12 -13
  21. data/lib/solargraph/pin/helper.rb +9 -3
  22. data/lib/solargraph/pin/localized.rb +9 -2
  23. data/lib/solargraph/pin/yard_object.rb +2 -3
  24. data/lib/solargraph/shell.rb +6 -0
  25. data/lib/solargraph/source.rb +5 -2
  26. data/lib/solargraph/source/fragment.rb +8 -0
  27. data/lib/solargraph/source/mapper.rb +6 -11
  28. data/lib/solargraph/version.rb +1 -1
  29. data/lib/solargraph/workspace.rb +33 -0
  30. data/lib/solargraph/workspace/config.rb +12 -0
  31. data/lib/solargraph/yard_map.rb +27 -87
  32. data/lib/yard-solargraph.rb +1 -0
  33. metadata +11 -11
@@ -1,3 +1,3 @@
1
1
  module Solargraph
2
- VERSION = '0.19.1'
2
+ VERSION = '0.20.0'
3
3
  end
@@ -90,6 +90,26 @@ module Solargraph
90
90
  @stime = source_hash.values.sort{|a, b| a.stime <=> b.stime}.last.stime
91
91
  end
92
92
 
93
+ def require_paths
94
+ @require_paths ||= generate_require_paths
95
+ end
96
+
97
+ def would_require? path
98
+ require_paths.each do |rp|
99
+ return true if File.exist?(File.join(rp, "#{path}.rb"))
100
+ end
101
+ false
102
+ end
103
+
104
+ def gemspec?
105
+ return true unless gemspecs.empty?
106
+ end
107
+
108
+ def gemspecs
109
+ return [] if directory.nil?
110
+ @gemspecs ||= Dir[File.join(directory, '**/*.gemspec')]
111
+ end
112
+
93
113
  private
94
114
 
95
115
  # @return [Hash<String, Solargraph::Source>]
@@ -109,5 +129,18 @@ module Solargraph
109
129
  end
110
130
  @stime = Time.now
111
131
  end
132
+
133
+ def generate_require_paths
134
+ return [] if directory.nil?
135
+ return [File.join(directory, 'lib')] unless gemspec?
136
+ result = []
137
+ gemspecs.each do |file|
138
+ spec = Gem::Specification.load(file)
139
+ base = File.dirname(file)
140
+ result.concat spec.require_paths.map{ |path| File.join(base, path) } unless spec.nil?
141
+ end
142
+ result.push File.join(directory, 'lib') if result.empty?
143
+ result
144
+ end
112
145
  end
113
146
  end
@@ -26,6 +26,7 @@ module Solargraph
26
26
  @raw_data ||= {}
27
27
  @raw_data['include'] ||= include_globs
28
28
  @raw_data['exclude'] ||= exclude_globs
29
+ @raw_data['reporters'] ||= []
29
30
  @raw_data['domains'] ||= []
30
31
  @raw_data['required'] ||= []
31
32
  @raw_data['plugins'] ||= []
@@ -69,6 +70,14 @@ module Solargraph
69
70
  raw_data['plugins']
70
71
  end
71
72
 
73
+ def reporters
74
+ raw_data['reporters']
75
+ end
76
+
77
+ def require_paths
78
+ @require_paths ||= generate_require_paths
79
+ end
80
+
72
81
  private
73
82
 
74
83
  def process_globs globs
@@ -101,6 +110,9 @@ module Solargraph
101
110
  def glob_to_directory glob
102
111
  glob.gsub(/(\/\*|\/\*\*\/\*\*?)$/, '')
103
112
  end
113
+
114
+ def generate_require_paths
115
+ end
104
116
  end
105
117
  end
106
118
  end
@@ -45,6 +45,10 @@ module Solargraph
45
45
  @yardocs ||= []
46
46
  end
47
47
 
48
+ def unresolved_requires
49
+ @unresolved_requires ||= []
50
+ end
51
+
48
52
  def load_yardoc y
49
53
  begin
50
54
  if y.kind_of?(Array)
@@ -139,33 +143,15 @@ module Solargraph
139
143
  yard = load_yardoc(y)
140
144
  unless yard.nil?
141
145
  ns = nil
142
- ns = find_first_resolved_namespace(yard, namespace, scope)
146
+ ns = find_first_resolved_object(yard, namespace, scope)
143
147
  unless ns.nil?
144
148
  ns.meths(scope: :class, visibility: visibility).each { |m|
145
- n = m.to_s.split(/[\.#]/).last.gsub(/=$/, ' = ')
146
- label = "#{n}"
147
- args = get_method_args(m)
148
- kind = (m.is_attribute? ? Suggestion::FIELD : Suggestion::METHOD)
149
- # meths.push Suggestion.new(label, insert: n, kind: kind, docstring: m.docstring, code_object: m, detail: "#{ns}", location: object_location(m), arguments: args)
150
149
  meths.push Pin::YardObject.new(m, object_location(m))
151
150
  }
152
151
  # Collect superclass methods
153
152
  if ns.kind_of?(YARD::CodeObjects::ClassObject) and !ns.superclass.nil?
154
153
  meths += get_methods ns.superclass.to_s, '', visibility: [:public, :protected] unless ['Object', 'BasicObject', ''].include?(ns.superclass.to_s)
155
154
  end
156
- # if ns.kind_of?(YARD::CodeObjects::ClassObject) and namespace != 'Class'
157
- # meths += get_instance_methods('Class')
158
- # yard = load_yardoc(y)
159
- # i = yard.at("#{ns}#initialize")
160
- # unless i.nil?
161
- # meths.delete_if{|m| m.name == 'new'}
162
- # label = "#{i}"
163
- # args = get_method_args(i)
164
- # tmp = Solargraph::Pin::YardObject.new(i, object_location(i))
165
- # tmp.instance_variable_set(:@name, 'new')
166
- # meths.push tmp
167
- # end
168
- # end
169
155
  end
170
156
  end
171
157
  end
@@ -185,21 +171,13 @@ module Solargraph
185
171
  yard = load_yardoc(y)
186
172
  unless yard.nil?
187
173
  ns = nil
188
- ns = find_first_resolved_namespace(yard, namespace, scope)
174
+ ns = find_first_resolved_object(yard, namespace, scope)
189
175
  unless ns.nil?
190
176
  ns.meths(scope: :instance, visibility: visibility).each { |m|
191
177
  n = m.to_s.split(/[\.#]/).last
192
178
  # HACK: Special treatment for #initialize
193
179
  next if n == 'initialize' and !visibility.include?(:private)
194
180
  if (namespace == 'Kernel' or !m.to_s.start_with?('Kernel#')) and !m.docstring.to_s.include?(':nodoc:')
195
- label = "#{n}"
196
- args = get_method_args(m)
197
- kind = (m.is_attribute? ? Suggestion::FIELD : Suggestion::METHOD)
198
- rt = nil
199
- if Solargraph::CoreFills::CUSTOM_RETURN_TYPES.has_key?(m.path)
200
- rt = Solargraph::CoreFills::CUSTOM_RETURN_TYPES[m.path]
201
- end
202
- # meths.push Suggestion.new(label, insert: "#{n.gsub(/=$/, ' = ')}", kind: kind, docstring: m.docstring, code_object: m, detail: m.namespace, location: object_location(m), arguments: args, return_type: rt)
203
181
  meths.push Pin::YardObject.new(m, object_location(m))
204
182
  end
205
183
  }
@@ -242,26 +220,9 @@ module Solargraph
242
220
  yardocs.each { |y|
243
221
  yard = load_yardoc(y)
244
222
  unless yard.nil?
245
- obj = find_first_resolved_namespace(yard, path, space)
246
- if obj.nil? and path.include?('#')
247
- parts = path.split('#')
248
- obj = yard.at(parts[0])
249
- unless obj.nil?
250
- meths = obj.meths(scope: [:instance]).keep_if{|m| m.name.to_s == parts[1]}
251
- meths.each do |m|
252
- args = get_method_args(m)
253
- # result.push Solargraph::Suggestion.new(m.name, kind: 'Method', detail: m.path, code_object: m, arguments: args, location: object_location(m))
254
- result.push Pin::YardObject.new(m, object_location(m))
255
- end
256
- end
257
- else
258
- unless obj.nil?
259
- args = []
260
- args = get_method_args(obj) if obj.kind_of?(YARD::CodeObjects::MethodObject)
261
- kind = kind_of_object(obj)
262
- # result.push Solargraph::Suggestion.new(obj.name, kind: kind, detail: obj.path, code_object: obj, arguments: args, location: object_location(obj))
263
- result.push Pin::YardObject.new(obj, object_location(obj))
264
- end
223
+ obj = find_first_resolved_object(yard, path, space)
224
+ unless obj.nil?
225
+ result.push Pin::YardObject.new(obj, object_location(obj))
265
226
  end
266
227
  end
267
228
  }
@@ -290,20 +251,7 @@ module Solargraph
290
251
  @cache ||= Cache.new
291
252
  end
292
253
 
293
- def get_method_args meth
294
- args = []
295
- meth.parameters.each { |a|
296
- p = a[0]
297
- unless a[1].nil?
298
- p += ' =' unless p.end_with?(':')
299
- p += " #{a[1]}"
300
- end
301
- args.push p
302
- }
303
- args
304
- end
305
-
306
- def find_first_resolved_namespace yard, namespace, scope
254
+ def find_first_resolved_object yard, namespace, scope
307
255
  unless scope.nil?
308
256
  parts = scope.split('::')
309
257
  while parts.length > 0
@@ -319,30 +267,21 @@ module Solargraph
319
267
  get_constants '', ''
320
268
  end
321
269
 
322
- def kind_of_object obj
323
- if obj.kind_of?(YARD::CodeObjects::MethodObject)
324
- 'Method'
325
- elsif obj.kind_of?(YARD::CodeObjects::ClassObject)
326
- 'Class'
327
- elsif obj.kind_of?(YARD::CodeObjects::ModuleObject)
328
- 'Module'
329
- else
330
- nil
331
- end
332
- end
333
-
334
270
  def process_gem_paths
335
- if !has_bundle? or ENV['BUNDLE_GEMFILE'] == File.join(workspace.directory, 'Gemfile')
271
+ if !has_bundle? or workspace.nil? or ENV['BUNDLE_GEMFILE'] == File.join(workspace.directory, 'Gemfile')
272
+ # Trust the current environment if Bundler is not being used or the
273
+ # workspace's Gemfile was loaded
336
274
  process_requires
337
275
  else
276
+ # Temporarily load the workspace in a clean environment to identify
277
+ # its gems
338
278
  processed = false
339
279
  Bundler.with_clean_env do
340
280
  Bundler.environment.chdir(workspace.directory) do
341
281
  begin
342
282
  Bundler.reset!
343
- # Bundler.setup
344
- processed = true
345
283
  process_requires
284
+ processed = true
346
285
  rescue Exception => e
347
286
  STDERR.puts "#{e.class}: #{e.message}"
348
287
  end
@@ -355,24 +294,26 @@ module Solargraph
355
294
 
356
295
  def process_requires
357
296
  tried = []
297
+ unresolved_requires.clear
358
298
  required.each do |r|
359
- # @todo Ignoring requires in the workspace's lib directory handles a lot of common cases.
360
- next if !workspace.nil? and File.exist?(File.join(workspace.directory, "lib", "#{r}.rb"))
299
+ next if !workspace.nil? and workspace.would_require?(r)
361
300
  begin
362
301
  name = r.split('/').first
363
302
  next if name.nil?
364
- # @todo Ignoring requires that match the workspace's gem name handles a few more.
365
- next if !workspace.nil? and File.exist?(File.join(workspace.directory, "#{name}.gemspec"))
366
303
  spec = Gem::Specification.find_by_name(name)
367
- next if spec.nil?
304
+ if spec.nil?
305
+ unresolved_requires.push r
306
+ next
307
+ end
368
308
  ver = spec.version.to_s
369
309
  ver = ">= 0" if ver.empty?
370
310
  add_gem_dependencies spec
371
311
  yd = YARD::Registry.yardoc_file_for_gem(spec.name, ver)
372
312
  @gem_paths[spec.name] = spec.full_gem_path
313
+ unresolved_requires.push r if yd.nil?
373
314
  yardocs.unshift yd unless yd.nil? or yardocs.include?(yd)
374
315
  rescue Gem::LoadError => e
375
- STDERR.puts "Required path #{r} could not be found in the workspace or gems"
316
+ unresolved_requires.push r
376
317
  end
377
318
  end
378
319
  end
@@ -383,7 +324,7 @@ module Solargraph
383
324
  @gem_paths[spec.name] = spec.full_gem_path unless spec.nil?
384
325
  gy = YARD::Registry.yardoc_file_for_gem(dep.name)
385
326
  if gy.nil?
386
- STDERR.puts "Required path not found: #{dep.name}"
327
+ unresolved_requires.push dep.name
387
328
  else
388
329
  yardocs.unshift gy unless yardocs.include?(gy)
389
330
  end
@@ -414,13 +355,12 @@ module Solargraph
414
355
  end
415
356
 
416
357
  # @param obj [YARD::CodeObjects::Base]
358
+ # @return [Solargraph::Source::Location]
417
359
  def object_location obj
418
360
  return nil if obj.file.nil? or obj.line.nil?
419
361
  @gem_paths.values.each do |path|
420
362
  file = File.join(path, obj.file)
421
- if File.exist?(file)
422
- return "#{file}:#{obj.line - 1}:0"
423
- end
363
+ return Solargraph::Source::Location.new(file, Solargraph::Source::Range.from_to(obj.line - 1, 0, obj.line - 1, 0)) if File.exist?(file)
424
364
  end
425
365
  nil
426
366
  end
@@ -6,3 +6,4 @@ require 'yard/templates/helpers/html_helper'
6
6
  YARD::Tags::Library.define_tag("Type", :type, :with_types_and_name)
7
7
  # Define a @yieldself tag for documenting block contexts
8
8
  YARD::Tags::Library.define_tag("Yieldself", :yieldself, :with_types)
9
+ YARD::Tags::Library.define_directive("domain", YARD::Tags::MacroDirective)
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.19.1
4
+ version: 0.20.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: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -127,25 +127,19 @@ dependencies:
127
127
  - !ruby/object:Gem::Version
128
128
  version: 1.0.5
129
129
  - !ruby/object:Gem::Dependency
130
- name: redcarpet
130
+ name: kramdown
131
131
  requirement: !ruby/object:Gem::Requirement
132
132
  requirements:
133
- - - "~>"
134
- - !ruby/object:Gem::Version
135
- version: '3.2'
136
133
  - - ">="
137
134
  - !ruby/object:Gem::Version
138
- version: 3.2.3
135
+ version: '0'
139
136
  type: :runtime
140
137
  prerelease: false
141
138
  version_requirements: !ruby/object:Gem::Requirement
142
139
  requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '3.2'
146
140
  - - ">="
147
141
  - !ruby/object:Gem::Version
148
- version: 3.2.3
142
+ version: '0'
149
143
  - !ruby/object:Gem::Dependency
150
144
  name: htmlentities
151
145
  requirement: !ruby/object:Gem::Requirement
@@ -290,7 +284,10 @@ files:
290
284
  - lib/solargraph/api_map/store.rb
291
285
  - lib/solargraph/core_fills.rb
292
286
  - lib/solargraph/diagnostics.rb
287
+ - lib/solargraph/diagnostics/base.rb
288
+ - lib/solargraph/diagnostics/require_not_found.rb
293
289
  - lib/solargraph/diagnostics/rubocop.rb
290
+ - lib/solargraph/diagnostics/severities.rb
294
291
  - lib/solargraph/language_server.rb
295
292
  - lib/solargraph/language_server/completion_item_kinds.rb
296
293
  - lib/solargraph/language_server/error_codes.rb
@@ -304,7 +301,9 @@ files:
304
301
  - lib/solargraph/language_server/message/completion_item/resolve.rb
305
302
  - lib/solargraph/language_server/message/exit_notification.rb
306
303
  - lib/solargraph/language_server/message/extended.rb
304
+ - lib/solargraph/language_server/message/extended/check_gem_version.rb
307
305
  - lib/solargraph/language_server/message/extended/document.rb
306
+ - lib/solargraph/language_server/message/extended/document_gems.rb
308
307
  - lib/solargraph/language_server/message/extended/search.rb
309
308
  - lib/solargraph/language_server/message/initialize.rb
310
309
  - lib/solargraph/language_server/message/initialized.rb
@@ -329,6 +328,7 @@ files:
329
328
  - lib/solargraph/language_server/message/workspace/did_change_watched_files.rb
330
329
  - lib/solargraph/language_server/message/workspace/workspace_symbol.rb
331
330
  - lib/solargraph/language_server/message_types.rb
331
+ - lib/solargraph/language_server/request.rb
332
332
  - lib/solargraph/language_server/symbol_kinds.rb
333
333
  - lib/solargraph/language_server/transport.rb
334
334
  - lib/solargraph/language_server/transport/socket.rb