solargraph 0.19.1 → 0.20.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.
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