solargraph 0.48.0 → 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
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