solargraph 0.48.0 → 0.49.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/rspec.yml +1 -1
  4. data/CHANGELOG.md +9 -0
  5. data/LICENSE +1 -1
  6. data/SPONSORS.md +2 -4
  7. data/lib/solargraph/api_map/store.rb +13 -1
  8. data/lib/solargraph/api_map.rb +30 -12
  9. data/lib/solargraph/cache.rb +51 -0
  10. data/lib/solargraph/complex_type/type_methods.rb +3 -6
  11. data/lib/solargraph/complex_type/unique_type.rb +57 -0
  12. data/lib/solargraph/complex_type.rb +20 -1
  13. data/lib/solargraph/convention/rakefile.rb +17 -0
  14. data/lib/solargraph/convention.rb +2 -0
  15. data/lib/solargraph/diagnostics/rubocop.rb +15 -2
  16. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
  17. data/lib/solargraph/language_server/host.rb +22 -18
  18. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  19. data/lib/solargraph/language_server/message/initialize.rb +2 -0
  20. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
  21. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  22. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  23. data/lib/solargraph/library.rb +21 -20
  24. data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
  25. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
  26. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
  27. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
  28. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  29. data/lib/solargraph/pin/base.rb +5 -2
  30. data/lib/solargraph/pin/conversions.rb +2 -6
  31. data/lib/solargraph/pin/method.rb +84 -10
  32. data/lib/solargraph/pin/namespace.rb +4 -1
  33. data/lib/solargraph/pin/parameter.rb +8 -3
  34. data/lib/solargraph/pin/signature.rb +23 -0
  35. data/lib/solargraph/pin.rb +1 -0
  36. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  37. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  38. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  39. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  40. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  41. data/lib/solargraph/rbs_map.rb +73 -0
  42. data/lib/solargraph/shell.rb +38 -30
  43. data/lib/solargraph/source/chain/call.rb +30 -22
  44. data/lib/solargraph/source/chain.rb +21 -6
  45. data/lib/solargraph/source_map/clip.rb +5 -0
  46. data/lib/solargraph/source_map/mapper.rb +2 -0
  47. data/lib/solargraph/type_checker.rb +71 -65
  48. data/lib/solargraph/version.rb +1 -1
  49. data/lib/solargraph/views/environment.erb +2 -2
  50. data/lib/solargraph/workspace.rb +11 -14
  51. data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
  52. data/lib/solargraph/yard_map.rb +7 -148
  53. data/lib/solargraph.rb +2 -2
  54. data/solargraph.gemspec +8 -6
  55. metadata +43 -36
  56. data/lib/solargraph/compat.rb +0 -37
  57. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  58. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  59. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  60. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -143
  61. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  62. data/yardoc/2.2.2.tar.gz +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7531e9e085d6b9645a2d44a9aa020d661769a05ebe9b15377d91d0217f1cebd1
4
- data.tar.gz: 63d27c2e39cac69742d77866ba7c5ef49634d8598cc10aa8427ec150bf70d12b
3
+ metadata.gz: b0b66abd5cf5a0376d5521532dda16db328592eb38bac6acd84f997b19cb328c
4
+ data.tar.gz: 51e038df27bae1457393c7ff023c9951b0f8919267678e29aab2e21efeb2b1a8
5
5
  SHA512:
6
- metadata.gz: 38929be15a4be6b9995f7b471a9fed4f51541027822bd92b78b2f6ca426a9b42477491c324066ea312f31ebeb43a73a373a457454edc8c14390ab25f403c727d
7
- data.tar.gz: 1c16b8046376cde3f1a1393ca12b060b708b4c5be1c1e9ee4f2be0f03b2443c6dcbc77bce3190ce47cff7fe2f7726e0963a3f05e00956dadd5628c2a437aeab3
6
+ metadata.gz: 9b8310748d4754c27fd62763ce1bd8759fc43fc825b1b40353d4537130f2b6143cdb59101da679a8b4a7fb0778430eeac2eccbb845f7a9a5ac11f402b3a71461
7
+ data.tar.gz: 1b2f79f5396a3c056d0b2acbcb49d6c1385b02a49b33edbe1a3e452a7b451b9b87547b8b8d5974a17e25ea2f5c21db8dd315d2b3d856fb3c7ce2d300a4595c70
@@ -0,0 +1 @@
1
+ patreon: castwide
@@ -22,7 +22,7 @@ jobs:
22
22
  runs-on: ubuntu-latest
23
23
  strategy:
24
24
  matrix:
25
- ruby-version: ['2.4', '2.5', '2.6', '2.7', '3.0']
25
+ ruby-version: ['2.6', '2.7', '3.0', '3.1']
26
26
 
27
27
  steps:
28
28
  - uses: actions/checkout@v3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.49.0 - April 9, 2023
2
+ - Better union type handling
3
+ - First version of RBS support
4
+ - Dependency updates
5
+ - Update RuboCop config options
6
+ - RBS core and stdlib mapping
7
+ - Anonymous splats and multisig arity
8
+ - Infinite loop when checking if a class is a superclass (#641)
9
+
1
10
  ## 0.48.0 - December 19, 2022
2
11
  - Add Sublime Text to README (#604)
3
12
  - Map nested constant assignments
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017-2019 by Fred Snyder for Castwide Technologies
3
+ Copyright (c) 2017-2023 by Fred Snyder for Castwide Technologies
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/SPONSORS.md CHANGED
@@ -10,8 +10,6 @@ The following people and organizations provide funding or other resources. [Beco
10
10
 
11
11
  ## Named Sponsors
12
12
 
13
- - Tom de Grunt
14
13
  - Akira Yamada
15
- - Erlend Finvåg
16
- - Matt Massicotte
17
- - Oscar Rivas
14
+ - Joel Drapper
15
+ - Yutaka Tachibana
@@ -247,10 +247,22 @@ module Solargraph
247
247
  end
248
248
  ovr.tags.each do |tag|
249
249
  pin.docstring.add_tag(tag)
250
- new_pin.docstring.add_tag(tag) if new_pin
250
+ redefine_return_type pin, tag
251
+ if new_pin
252
+ new_pin.docstring.add_tag(tag)
253
+ redefine_return_type new_pin, tag
254
+ end
251
255
  end
252
256
  end
253
257
  end
258
+
259
+ def redefine_return_type pin, tag
260
+ return unless pin && tag.tag_name == 'return'
261
+ pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
262
+ pin.signatures.each do |sig|
263
+ sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
264
+ end
265
+ end
254
266
  end
255
267
  end
256
268
  end
@@ -21,6 +21,8 @@ module Solargraph
21
21
  # @return [Array<String>]
22
22
  attr_reader :unresolved_requires
23
23
 
24
+ @@core_map = RbsMap::CoreMap.new
25
+
24
26
  # @return [Array<String>]
25
27
  attr_reader :missing_docs
26
28
 
@@ -40,7 +42,7 @@ module Solargraph
40
42
  @source_map_hash = {}
41
43
  implicit.clear
42
44
  cache.clear
43
- @store = Store.new(yard_map.pins + pins)
45
+ @store = Store.new(@@core_map.pins + pins)
44
46
  self
45
47
  end
46
48
 
@@ -68,8 +70,10 @@ module Solargraph
68
70
  end
69
71
  external_requires.merge implicit.requires
70
72
  external_requires.merge bench.workspace.config.required
71
- yard_map.change(external_requires, bench.workspace.directory, bench.workspace.source_gems)
72
- @store = Store.new(yard_map.pins + implicit.pins + pins)
73
+ @rbs_maps = external_requires.map { |r| load_rbs_map(r) }
74
+ unresolved_requires = @rbs_maps.reject(&:resolved?).map(&:library)
75
+ yard_map.change(unresolved_requires, bench.workspace.directory, bench.workspace.source_gems)
76
+ @store = Store.new(@@core_map.pins + @rbs_maps.flat_map(&:pins) + yard_map.pins + implicit.pins + pins)
73
77
  @unresolved_requires = yard_map.unresolved_requires
74
78
  @missing_docs = yard_map.missing_docs
75
79
  @rebindable_method_names = nil
@@ -77,6 +81,14 @@ module Solargraph
77
81
  self
78
82
  end
79
83
 
84
+ def core_pins
85
+ @@core_map.pins
86
+ end
87
+
88
+ def yard_map
89
+ @yard_map ||= YardMap.new
90
+ end
91
+
80
92
  # @param name [String]
81
93
  # @return [YARD::Tags::MacroDirective, nil]
82
94
  def named_macro name
@@ -132,7 +144,8 @@ module Solargraph
132
144
 
133
145
  def rebindable_method_names
134
146
  @rebindable_method_names ||= begin
135
- result = yard_map.rebindable_method_names
147
+ # result = yard_map.rebindable_method_names
148
+ result = ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'].to_set
136
149
  source_maps.each do |map|
137
150
  result.merge map.rebindable_method_names
138
151
  end
@@ -191,7 +204,7 @@ module Solargraph
191
204
  #
192
205
  # @param namespace [String, nil] The namespace to match
193
206
  # @param context [String] The context to search
194
- # @return [String]
207
+ # @return [String, nil]
195
208
  def qualify namespace, context = ''
196
209
  return namespace if ['self', nil].include?(namespace)
197
210
  cached = cache.get_qualified_namespace(namespace, context)
@@ -447,18 +460,15 @@ module Solargraph
447
460
  def super_and_sub?(sup, sub)
448
461
  fqsup = qualify(sup)
449
462
  cls = qualify(sub)
450
- until fqsup.nil? || cls.nil?
463
+ tested = []
464
+ until fqsup.nil? || cls.nil? || tested.include?(cls)
451
465
  return true if cls == fqsup
466
+ tested.push cls
452
467
  cls = qualify_superclass(cls)
453
468
  end
454
469
  false
455
470
  end
456
471
 
457
- # @return [YardMap]
458
- def yard_map
459
- @yard_map ||= YardMap.new
460
- end
461
-
462
472
  # Check if the host class includes the specified module.
463
473
  #
464
474
  # @param host [String] The class
@@ -475,6 +485,14 @@ module Solargraph
475
485
  # @return [Hash{String => SourceMap}]
476
486
  attr_reader :source_map_hash
477
487
 
488
+ # @param library [String]
489
+ # @return [RbsMap]
490
+ def load_rbs_map library
491
+ # map = RbsMap.load(library)
492
+ # return map if map.resolved?
493
+ RbsMap::StdlibMap.load(library)
494
+ end
495
+
478
496
  # @return [ApiMap::Store]
479
497
  def store
480
498
  @store ||= Store.new
@@ -677,7 +695,7 @@ module Solargraph
677
695
  comments: origin.comments,
678
696
  scope: origin.scope,
679
697
  visibility: origin.visibility,
680
- parameters: origin.parameters,
698
+ signatures: origin.signatures,
681
699
  attribute: origin.attribute?
682
700
  }
683
701
  Pin::Method.new **args
@@ -0,0 +1,51 @@
1
+ require 'fileutils'
2
+
3
+ module Solargraph
4
+ module Cache
5
+ class << self
6
+ # The base directory where cached documentation is installed.
7
+ #
8
+ # @return [String]
9
+ def base_dir
10
+ # The directory is not stored in a variable so it can be overridden
11
+ # in specs.
12
+ ENV['SOLARGRAPH_CACHE'] || File.join(Dir.home, '.solargraph', 'cache')
13
+ end
14
+
15
+ # The working directory for the current Ruby and Solargraph versions.
16
+ #
17
+ # @return [String]
18
+ def work_dir
19
+ # The directory is not stored in a variable so it can be overridden
20
+ # in specs.
21
+ File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
22
+ end
23
+
24
+ # @return [Array<Solargraph::Pin::Base>, nil]
25
+ def load *path
26
+ file = File.join(work_dir, *path)
27
+ return nil unless File.file?(file)
28
+ Marshal.load(File.read(file, mode: 'rb'))
29
+ rescue StandardError => e
30
+ Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
31
+ FileUtils.rm_f file
32
+ nil
33
+ end
34
+
35
+ # @return [Boolean]
36
+ def save *path, pins
37
+ return false if pins.empty?
38
+ file = File.join(work_dir, *path)
39
+ base = File.dirname(file)
40
+ FileUtils.mkdir_p base unless File.directory?(base)
41
+ ser = Marshal.dump(pins)
42
+ File.write file, ser, mode: 'wb'
43
+ true
44
+ end
45
+
46
+ def clear
47
+ FileUtils.rm_rf base_dir, secure: true
48
+ end
49
+ end
50
+ end
51
+ end
@@ -101,6 +101,7 @@ module Solargraph
101
101
  # @param context [String] The namespace from which to resolve names
102
102
  # @return [ComplexType] The generated ComplexType
103
103
  def qualify api_map, context = ''
104
+ return self if name == 'param'
104
105
  return ComplexType.new([self]) if duck_type? || void? || undefined?
105
106
  recon = (rooted? ? '' : context)
106
107
  fqns = api_map.qualify(name, recon)
@@ -109,12 +110,8 @@ module Solargraph
109
110
  return UniqueType::UNDEFINED
110
111
  end
111
112
  fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
112
- ltypes = key_types.map do |t|
113
- t.qualify api_map, context
114
- end
115
- rtypes = value_types.map do |t|
116
- t.qualify api_map, context
117
- end
113
+ ltypes = key_types.map { |t| t.qualify api_map, context }.uniq
114
+ rtypes = value_types.map { |t| t.qualify api_map, context }.uniq
118
115
  if list_parameters?
119
116
  Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
120
117
  elsif fixed_parameters?
@@ -8,6 +8,8 @@ module Solargraph
8
8
  class UniqueType
9
9
  include TypeMethods
10
10
 
11
+ attr_reader :all_params
12
+
11
13
  # Create a UniqueType with the specified name and an optional substring.
12
14
  # The substring is the parameter section of a parametrized type, e.g.,
13
15
  # for the type `Array<String>`, the name is `Array` and the substring is
@@ -27,6 +29,7 @@ module Solargraph
27
29
  @tag = @name + substring
28
30
  @key_types = []
29
31
  @subtypes = []
32
+ @all_params = []
30
33
  return unless parameters?
31
34
  if @substring.start_with?('<(') && @substring.end_with?(')>')
32
35
  subs = ComplexType.parse(substring[2..-3], partial: true)
@@ -40,12 +43,66 @@ module Solargraph
40
43
  else
41
44
  @subtypes.concat subs
42
45
  end
46
+ @all_params.concat @key_types
47
+ @all_params.concat @subtypes
43
48
  end
44
49
 
45
50
  def to_s
46
51
  tag
47
52
  end
48
53
 
54
+ def to_rbs
55
+ "#{namespace}#{parameters? ? "[#{subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
56
+ end
57
+
58
+ def parameterized?
59
+ name == 'param' || all_params.any?(&:parameterized?)
60
+ end
61
+
62
+ def resolve_parameters definitions, context
63
+ new_name = if name == 'param'
64
+ idx = definitions.parameters.index(subtypes.first.name)
65
+ return ComplexType::UNDEFINED if idx.nil?
66
+ param_type = context.return_type.all_params[idx]
67
+ return ComplexType::UNDEFINED unless param_type
68
+ param_type.to_s
69
+ else
70
+ name
71
+ end
72
+ new_key_types = if name != 'param'
73
+ @key_types.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
74
+ else
75
+ []
76
+ end
77
+ new_subtypes = if name != 'param'
78
+ @subtypes.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
79
+ else
80
+ []
81
+ end
82
+ if name != 'param' && !(new_key_types.empty? && new_subtypes.empty?)
83
+ if hash_parameters?
84
+ UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
85
+ elsif parameters?
86
+ if @substring.start_with?'<('
87
+ UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
88
+ else
89
+ UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
90
+ end
91
+ else
92
+ UniqueType.new(new_name)
93
+ end
94
+ else
95
+ UniqueType.new(new_name)
96
+ end
97
+
98
+ # idx = definitions.parameters.index(subtypes.first.name)
99
+ # STDERR.puts "Index: #{idx}"
100
+ # return ComplexType::UNDEFINED if idx.nil?
101
+ # param_type = context.return_type.all_params[idx]
102
+ # return ComplexType::UNDEFINED unless param_type
103
+ # ComplexType.try_parse(param_type.to_s)
104
+ end
105
+
49
106
  def self_to dst
50
107
  return self unless selfy?
51
108
  new_name = (@name == 'self' ? dst : @name)
@@ -30,6 +30,12 @@ module Solargraph
30
30
  @items.first
31
31
  end
32
32
 
33
+ def to_rbs
34
+ ((@items.length > 1 ? '(' : '') + @items.map do |item|
35
+ "#{item.namespace}#{item.parameters? ? "[#{item.subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
36
+ end.join(' | ') + (@items.length > 1 ? ')' : '')).gsub(/undefined/, 'untyped')
37
+ end
38
+
33
39
  def map &block
34
40
  @items.map &block
35
41
  end
@@ -85,13 +91,22 @@ module Solargraph
85
91
  end
86
92
 
87
93
  def any? &block
88
- @items.any? &block
94
+ @items.compact.any? &block
89
95
  end
90
96
 
91
97
  def selfy?
92
98
  @items.any?(&:selfy?)
93
99
  end
94
100
 
101
+ def parameterized?
102
+ any?(&:parameterized?)
103
+ end
104
+
105
+ def resolve_parameters definitions, context
106
+ result = @items.map { |i| i.resolve_parameters(definitions, context) }
107
+ ComplexType.parse(*result.map(&:tag))
108
+ end
109
+
95
110
  # @param dst [String]
96
111
  # @return [ComplexType]
97
112
  def self_to dst
@@ -105,6 +120,10 @@ module Solargraph
105
120
  @items.any?(&:nil_type?)
106
121
  end
107
122
 
123
+ def all_params
124
+ @items.first.all_params || []
125
+ end
126
+
108
127
  private
109
128
 
110
129
  # @todo This is a quick and dirty hack that forces `self` keywords
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ class Rakefile < Base
6
+ def local source_map
7
+ basename = File.basename(source_map.filename)
8
+ return EMPTY_ENVIRON unless basename.end_with?('.rake') || basename == 'Rakefile'
9
+
10
+ @environ ||= Environ.new(
11
+ requires: ['rake'],
12
+ domains: ['Rake::DSL']
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  autoload :Gemfile, 'solargraph/convention/gemfile'
12
12
  autoload :Rspec, 'solargraph/convention/rspec'
13
13
  autoload :Gemspec, 'solargraph/convention/gemspec'
14
+ autoload :Rakefile, 'solargraph/convention/rakefile'
14
15
 
15
16
  @@conventions = Set.new
16
17
 
@@ -43,5 +44,6 @@ module Solargraph
43
44
  register Gemfile
44
45
  register Gemspec
45
46
  register Rspec
47
+ register Rakefile
46
48
  end
47
49
  end
@@ -23,15 +23,19 @@ module Solargraph
23
23
  # @param _api_map [Solargraph::ApiMap]
24
24
  # @return [Array<Hash>]
25
25
  def diagnose source, _api_map
26
+ @source = source
26
27
  require_rubocop(rubocop_version)
27
28
  options, paths = generate_options(source.filename, source.code)
28
29
  store = RuboCop::ConfigStore.new
29
30
  runner = RuboCop::Runner.new(options, store)
30
31
  result = redirect_stdout{ runner.run(paths) }
32
+
33
+ return [] if result.empty?
34
+
31
35
  make_array JSON.parse(result)
32
36
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
33
37
  raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
34
- rescue JSON::ParserError
38
+ rescue JSON::ParserError => e
35
39
  raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
36
40
  end
37
41
 
@@ -89,8 +93,17 @@ module Solargraph
89
93
  if off['location']['start_line'] != off['location']['last_line']
90
94
  Position.new(off['location']['start_line'], 0)
91
95
  else
96
+ start_line = off['location']['start_line'] - 1
97
+ last_column = off['location']['last_column']
98
+ line = @source.code.lines[start_line]
99
+ col_off = if line.nil? || line.empty?
100
+ 1
101
+ else
102
+ 0
103
+ end
104
+
92
105
  Position.new(
93
- off['location']['start_line'] - 1, off['location']['last_column'] - 1
106
+ start_line, last_column - col_off
94
107
  )
95
108
  end
96
109
  end
@@ -10,13 +10,15 @@ module Solargraph
10
10
  # Requires a specific version of rubocop, or the latest installed version
11
11
  # if _version_ is `nil`.
12
12
  #
13
- # @param version [String]
13
+ # @param version [String, nil]
14
14
  # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
15
  def require_rubocop(version = nil)
16
16
  begin
17
17
  gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
18
18
  gem_lib_path = File.join(gem_path, 'lib')
19
19
  $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
20
+ # @todo Gem::MissingSpecVersionError is undocumented for some reason
21
+ # @sg-ignore
20
22
  rescue Gem::MissingSpecVersionError => e
21
23
  raise InvalidRubocopVersionError,
22
24
  "could not find '#{e.name}' (#{e.requirement}) - "\
@@ -130,35 +130,39 @@ module Solargraph
130
130
  end
131
131
  end
132
132
 
133
- # Respond to a notification that a file was created in the workspace.
134
- # The libraries will determine whether the file should be merged; see
133
+ # Respond to a notification that files were created in the workspace.
134
+ # The libraries will determine whether the files should be merged; see
135
135
  # Solargraph::Library#create_from_disk.
136
136
  #
137
- # @param uri [String] The file uri.
138
- # @return [Boolean] True if a library accepted the file.
139
- def create uri
140
- filename = uri_to_file(uri)
137
+ # @param uris [Array<String>] The URIs of the files.
138
+ # @return [Boolean] True if at least one library accepted at least one file.
139
+ def create *uris
140
+ filenames = uris.map { |uri| uri_to_file(uri) }
141
141
  result = false
142
142
  libraries.each do |lib|
143
- result = true if lib.create_from_disk(filename)
143
+ result = true if lib.create_from_disk(*filenames)
144
+ end
145
+ uris.each do |uri|
146
+ diagnoser.schedule uri if open?(uri)
144
147
  end
145
- diagnoser.schedule uri if open?(uri)
146
148
  result
147
149
  end
148
150
 
149
- # Delete the specified file from the library.
151
+ # Delete the specified files from the library.
150
152
  #
151
- # @param uri [String] The file uri.
153
+ # @param uris [Array<String>] The file uris.
152
154
  # @return [void]
153
- def delete uri
154
- filename = uri_to_file(uri)
155
+ def delete *uris
156
+ filenames = uris.map { |uri| uri_to_file(uri) }
155
157
  libraries.each do |lib|
156
- lib.delete(filename)
158
+ lib.delete(*filenames)
159
+ end
160
+ uris.each do |uri|
161
+ send_notification "textDocument/publishDiagnostics", {
162
+ uri: uri,
163
+ diagnostics: []
164
+ }
157
165
  end
158
- send_notification "textDocument/publishDiagnostics", {
159
- uri: uri,
160
- diagnostics: []
161
- }
162
166
  end
163
167
 
164
168
  # Open the specified file in the library.
@@ -692,7 +696,7 @@ module Solargraph
692
696
  params['contentChanges'].each do |recvd|
693
697
  chng = check_diff(params['textDocument']['uri'], recvd)
694
698
  changes.push Solargraph::Source::Change.new(
695
- (chng['range'].nil? ?
699
+ (chng['range'].nil? ?
696
700
  nil :
697
701
  Solargraph::Range.from_to(chng['range']['start']['line'], chng['range']['start']['character'], chng['range']['end']['line'], chng['range']['end']['character'])
698
702
  ),
@@ -10,11 +10,7 @@ module Solargraph
10
10
  #
11
11
  class DownloadCore < Base
12
12
  def process
13
- ver = Solargraph::YardMap::CoreDocs.best_download
14
- Solargraph::YardMap::CoreDocs.download ver
15
- host.show_message "Downloaded documentation for Ruby #{ver}.", LanguageServer::MessageTypes::INFO
16
- rescue StandardError => e
17
- host.show_message "An error occurred while downloading documentation: [#{e.class}] #{e.message}", LanguageServer::MessageTypes::ERROR
13
+ host.show_message "Downloading cores is deprecated. Solargraph currently uses RBS for core and stdlib documentation", LanguageServer::MessageTypes::INFO
18
14
  end
19
15
  end
20
16
  end
@@ -25,6 +25,8 @@ module Solargraph
25
25
  }
26
26
  }
27
27
  }
28
+ # FIXME: lsp default is utf-16, may have different position
29
+ result[:capabilities][:positionEncoding] = "utf-32" if params.dig("capabilities", "general", "positionEncodings")&.include?("utf-32")
28
30
  result[:capabilities].merge! static_completion unless dynamic_registration_for?('textDocument', 'completion')
29
31
  result[:capabilities].merge! static_signature_help unless dynamic_registration_for?('textDocument', 'signatureHelp')
30
32
  # result[:capabilities].merge! static_on_type_formatting unless dynamic_registration_for?('textDocument', 'onTypeFormatting')
@@ -54,7 +54,7 @@ module Solargraph
54
54
  def cli_args file_uri, config
55
55
  file = UriHelpers.uri_to_file(file_uri)
56
56
  args = [
57
- config['cops'] == 'all' ? '--auto-correct-all' : '--auto-correct',
57
+ config['cops'] == 'all' ? '--autocorrect-all' : '--autocorrect',
58
58
  '--cache', 'false',
59
59
  '--format', formatter_class(config).name,
60
60
  ]
@@ -9,13 +9,8 @@ module Solargraph
9
9
  line = params['position']['line']
10
10
  col = params['position']['character']
11
11
  suggestions = host.signatures_at(params['textDocument']['uri'], line, col)
12
- info = []
13
- suggestions.each do |pin|
14
- info.concat pin.overloads.map(&:signature_help)
15
- info.push pin.signature_help
16
- end
17
12
  set_result({
18
- signatures: info
13
+ signatures: suggestions.flat_map { |pin| pin.signature_help }
19
14
  })
20
15
  rescue FileNotFoundError => e
21
16
  Logging.logger.warn "[#{e.class}] #{e.message}"
@@ -10,22 +10,29 @@ module Solargraph::LanguageServer::Message::Workspace
10
10
 
11
11
  def process
12
12
  need_catalog = false
13
+ to_create = []
14
+ to_delete = []
15
+
13
16
  # @param change [Hash]
14
17
  params['changes'].each do |change|
15
18
  if change['type'] == CREATED
16
- host.create change['uri']
19
+ to_create << change['uri']
17
20
  need_catalog = true
18
21
  elsif change['type'] == CHANGED
19
22
  next if host.open?(change['uri'])
20
- host.create change['uri']
23
+ to_create << change['uri']
21
24
  need_catalog = true
22
25
  elsif change['type'] == DELETED
23
- host.delete change['uri']
26
+ to_delete << change['uri']
24
27
  need_catalog = true
25
28
  else
26
29
  set_error Solargraph::LanguageServer::ErrorCodes::INVALID_PARAMS, "Unknown change type ##{change['type']} for #{uri_to_file(change['uri'])}"
27
30
  end
28
31
  end
32
+
33
+ host.create *to_create
34
+ host.delete *to_delete
35
+
29
36
  # Force host to catalog libraries after file changes (see castwide/solargraph#139)
30
37
  host.catalog if need_catalog
31
38
  end