solargraph 0.45.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 (76) 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 +41 -0
  5. data/LICENSE +1 -1
  6. data/README.md +8 -0
  7. data/SPONSORS.md +2 -4
  8. data/lib/solargraph/api_map/store.rb +13 -1
  9. data/lib/solargraph/api_map.rb +55 -32
  10. data/lib/solargraph/cache.rb +51 -0
  11. data/lib/solargraph/complex_type/type_methods.rb +10 -6
  12. data/lib/solargraph/complex_type/unique_type.rb +57 -0
  13. data/lib/solargraph/complex_type.rb +35 -2
  14. data/lib/solargraph/convention/rakefile.rb +17 -0
  15. data/lib/solargraph/convention.rb +2 -0
  16. data/lib/solargraph/diagnostics/require_not_found.rb +16 -0
  17. data/lib/solargraph/diagnostics/rubocop.rb +17 -3
  18. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
  19. data/lib/solargraph/language_server/host.rb +22 -18
  20. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  21. data/lib/solargraph/language_server/message/initialize.rb +2 -0
  22. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
  23. data/lib/solargraph/language_server/message/text_document/hover.rb +16 -4
  24. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  25. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  26. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
  27. data/lib/solargraph/library.rb +21 -20
  28. data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
  29. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
  30. data/lib/solargraph/parser/rubyvm/class_methods.rb +7 -2
  31. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
  32. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -9
  33. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
  34. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +2 -2
  35. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
  36. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
  37. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  38. data/lib/solargraph/pin/base.rb +5 -2
  39. data/lib/solargraph/pin/block.rb +2 -1
  40. data/lib/solargraph/pin/conversions.rb +2 -6
  41. data/lib/solargraph/pin/method.rb +100 -10
  42. data/lib/solargraph/pin/namespace.rb +4 -1
  43. data/lib/solargraph/pin/parameter.rb +10 -7
  44. data/lib/solargraph/pin/search.rb +56 -0
  45. data/lib/solargraph/pin/signature.rb +23 -0
  46. data/lib/solargraph/pin.rb +2 -0
  47. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  48. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  49. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  50. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  51. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  52. data/lib/solargraph/rbs_map.rb +73 -0
  53. data/lib/solargraph/shell.rb +38 -30
  54. data/lib/solargraph/source/chain/call.rb +34 -23
  55. data/lib/solargraph/source/chain.rb +21 -6
  56. data/lib/solargraph/source.rb +1 -1
  57. data/lib/solargraph/source_map/clip.rb +5 -0
  58. data/lib/solargraph/source_map/mapper.rb +31 -2
  59. data/lib/solargraph/source_map.rb +1 -10
  60. data/lib/solargraph/type_checker/checks.rb +13 -0
  61. data/lib/solargraph/type_checker.rb +88 -68
  62. data/lib/solargraph/version.rb +1 -1
  63. data/lib/solargraph/views/environment.erb +2 -2
  64. data/lib/solargraph/workspace.rb +12 -14
  65. data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
  66. data/lib/solargraph/yard_map.rb +51 -195
  67. data/lib/solargraph.rb +2 -2
  68. data/solargraph.gemspec +8 -6
  69. metadata +44 -36
  70. data/lib/solargraph/compat.rb +0 -37
  71. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  72. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  73. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  74. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  75. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  76. data/yardoc/2.2.2.tar.gz +0 -0
@@ -8,6 +8,7 @@ module Solargraph
8
8
  # @return [Parser::AST::Node]
9
9
  attr_reader :receiver
10
10
 
11
+ # @param args [Array<Parameter>]
11
12
  def initialize receiver: nil, args: [], context: nil, **splat
12
13
  super(**splat)
13
14
  @receiver = receiver
@@ -25,7 +26,7 @@ module Solargraph
25
26
  @binder || closure.binder
26
27
  end
27
28
 
28
- # @return [Array<String>]
29
+ # @return [Array<Parameter>]
29
30
  def parameters
30
31
  @parameters ||= []
31
32
  end
@@ -34,12 +34,9 @@ module Solargraph
34
34
  end
35
35
  end
36
36
 
37
- # @return [Hash]
37
+ # @return [Array<Hash>]
38
38
  def signature_help
39
- @signature_help ||= {
40
- label: name + '(' + parameters.map(&:full).join(', ') + ')',
41
- documentation: documentation
42
- }
39
+ []
43
40
  end
44
41
 
45
42
  # @return [String]
@@ -47,7 +44,6 @@ module Solargraph
47
44
  # This property is not cached in an instance variable because it can
48
45
  # change when pins get proxied.
49
46
  detail = String.new
50
- detail += "(#{parameters.map(&:full).join(', ')}) " unless !is_a?(Pin::Method) || parameters.empty?
51
47
  detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
52
48
  detail.strip!
53
49
  return nil if detail.empty?
@@ -18,13 +18,18 @@ module Solargraph
18
18
 
19
19
  # @param visibility [::Symbol] :public, :protected, or :private
20
20
  # @param explicit [Boolean]
21
- def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, **splat
21
+ # @param parameters [Array<Pin::Parameter>]
22
+ # @param node [Parser::AST::Node, RubyVM::AbstractSyntaxTree::Node]
23
+ # @param attribute [Boolean]
24
+ def initialize visibility: :public, explicit: true, parameters: [], node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
22
25
  super(**splat)
23
26
  @visibility = visibility
24
27
  @explicit = explicit
25
28
  @parameters = parameters
26
29
  @node = node
27
30
  @attribute = attribute
31
+ @signatures = signatures
32
+ @anon_splat = anon_splat
28
33
  end
29
34
 
30
35
  # @return [Array<String>]
@@ -41,7 +46,45 @@ module Solargraph
41
46
  end
42
47
 
43
48
  def return_type
44
- @return_type ||= generate_complex_type
49
+ @return_type ||= ComplexType.try_parse(*signatures.map(&:return_type).map(&:to_s))
50
+ end
51
+
52
+ # @return [Array<Signature>]
53
+ def signatures
54
+ @signatures ||= begin
55
+ top_type = generate_complex_type
56
+ result = []
57
+ result.push Signature.new(parameters, top_type) if top_type.defined?
58
+ result.concat(overloads.map { |meth| Signature.new(meth.parameters, meth.return_type) })
59
+ result.push Signature.new(parameters, top_type) if result.empty?
60
+ result
61
+ end
62
+ end
63
+
64
+ # @return [String]
65
+ def detail
66
+ # This property is not cached in an instance variable because it can
67
+ # change when pins get proxied.
68
+ detail = String.new
69
+ detail += if signatures.length > 1
70
+ "(*) "
71
+ else
72
+ "(#{signatures.first.parameters.map(&:full).join(', ')}) " unless signatures.first.parameters.empty?
73
+ end.to_s
74
+ detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
75
+ detail.strip!
76
+ return nil if detail.empty?
77
+ detail
78
+ end
79
+
80
+ # @return [Array<Hash>]
81
+ def signature_help
82
+ @signature_help ||= signatures.map do |sig|
83
+ {
84
+ label: name + '(' + sig.parameters.map(&:full).join(', ') + ')',
85
+ documentation: documentation
86
+ }
87
+ end
45
88
  end
46
89
 
47
90
  def path
@@ -119,27 +162,60 @@ module Solargraph
119
162
  # @return [Array<Pin::Method>]
120
163
  def overloads
121
164
  @overloads ||= docstring.tags(:overload).map do |tag|
122
- Solargraph::Pin::Method.new(
123
- name: name,
124
- closure: self,
125
- # args: tag.parameters.map(&:first),
126
- parameters: tag.parameters.map do |src|
165
+ Pin::Signature.new(
166
+ tag.parameters.map do |src|
167
+ name, decl = parse_overload_param(src.first)
127
168
  Pin::Parameter.new(
128
169
  location: location,
129
170
  closure: self,
130
171
  comments: tag.docstring.all.to_s,
131
- name: src.first,
172
+ name: name,
173
+ decl: decl,
132
174
  presence: location ? location.range : nil,
133
- decl: :arg
175
+ return_type: param_type_from_name(tag, src.first)
134
176
  )
135
177
  end,
136
- comments: tag.docstring.all.to_s
178
+ ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
137
179
  )
138
180
  end
181
+ @overloads
182
+ end
183
+
184
+ def anon_splat?
185
+ @anon_splat
139
186
  end
140
187
 
141
188
  private
142
189
 
190
+ def select_decl name, asgn
191
+ if name.start_with?('**')
192
+ :kwrestarg
193
+ elsif name.start_with?('*')
194
+ :restarg
195
+ elsif name.start_with?('&')
196
+ :blockarg
197
+ elsif name.end_with?(':') && asgn
198
+ :kwoptarg
199
+ elsif name.end_with?(':')
200
+ :kwarg
201
+ elsif asgn
202
+ :optarg
203
+ else
204
+ :arg
205
+ end
206
+ end
207
+
208
+ def clean_param name
209
+ name.gsub(/[*&:]/, '')
210
+ end
211
+
212
+ # @param tag [YARD::Tags::OverloadTag]
213
+ def param_type_from_name(tag, name)
214
+ param = tag.tags(:param).select { |t| t.name == name }.first
215
+ return ComplexType::UNDEFINED unless param
216
+ ComplexType.try_parse(*param.types)
217
+ end
218
+
143
219
  # @return [ComplexType]
144
220
  def generate_complex_type
145
221
  tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
@@ -240,6 +316,20 @@ module Solargraph
240
316
  return ComplexType::UNDEFINED if types.empty?
241
317
  ComplexType.try_parse(*types.map(&:tag).uniq)
242
318
  end
319
+
320
+ # When YARD parses an overload tag, it includes rest modifiers in the parameters names.
321
+ #
322
+ # @param arg [String]
323
+ # @return [Array(String, Symbol)]
324
+ def parse_overload_param(name)
325
+ if name.start_with?('**')
326
+ [name[2..-1], :kwrestarg]
327
+ elsif name.start_with?('*')
328
+ [name[1..-1], :restarg]
329
+ else
330
+ [name, :arg]
331
+ end
332
+ end
243
333
  end
244
334
  end
245
335
  end
@@ -9,10 +9,12 @@ module Solargraph
9
9
  # @return [::Symbol] :class or :module
10
10
  attr_reader :type
11
11
 
12
+ attr_reader :parameters
13
+
12
14
  # @param type [::Symbol] :class or :module
13
15
  # @param visibility [::Symbol] :public or :private
14
16
  # @param gates [Array<String>]
15
- def initialize type: :class, visibility: :public, gates: [''], **splat
17
+ def initialize type: :class, visibility: :public, gates: [''], parameters: [], **splat
16
18
  # super(location, namespace, name, comments)
17
19
  super(**splat)
18
20
  @type = type
@@ -36,6 +38,7 @@ module Solargraph
36
38
  @closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
37
39
  @context = nil
38
40
  end
41
+ @parameters = parameters
39
42
  end
40
43
 
41
44
  def namespace
@@ -3,14 +3,17 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class Parameter < LocalVariable
6
+ # @return [Symbol]
6
7
  attr_reader :decl
7
8
 
9
+ # @return [String]
8
10
  attr_reader :asgn_code
9
11
 
10
- def initialize decl: :arg, asgn_code: nil, **splat
12
+ def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
11
13
  super(**splat)
12
14
  @asgn_code = asgn_code
13
15
  @decl = decl
16
+ @return_type = return_type
14
17
  end
15
18
 
16
19
  def keyword?
@@ -29,14 +32,18 @@ module Solargraph
29
32
  decl == :restarg || decl == :kwrestarg
30
33
  end
31
34
 
35
+ def block?
36
+ [:block, :blockarg].include?(decl)
37
+ end
38
+
32
39
  def full
33
40
  case decl
34
41
  when :optarg
35
- "#{name} = #{asgn_code}"
42
+ "#{name} = #{asgn_code || '?'}"
36
43
  when :kwarg
37
44
  "#{name}:"
38
45
  when :kwoptarg
39
- "#{name}: #{asgn_code}"
46
+ "#{name}: #{asgn_code || '?'}"
40
47
  when :restarg
41
48
  "*#{name}"
42
49
  when :kwrestarg
@@ -91,10 +98,6 @@ module Solargraph
91
98
  true
92
99
  end
93
100
 
94
- def probe api_map
95
- typify api_map
96
- end
97
-
98
101
  private
99
102
 
100
103
  # @return [YARD::Tags::Tag]
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jaro_winkler'
4
+
5
+ module Solargraph
6
+ module Pin
7
+ class Search
8
+ class Result
9
+ # @return [Float]
10
+ attr_reader :match
11
+
12
+ # @return [Pin::Base]
13
+ attr_reader :pin
14
+
15
+ def initialize match, pin
16
+ @match = match
17
+ @pin = pin
18
+ end
19
+ end
20
+
21
+ # @param pins [Array<Pin::Base>]
22
+ # @param query [String]
23
+ def initialize pins, query
24
+ @pins = pins
25
+ @query = query
26
+ end
27
+
28
+ # @return [Array<Pin::Base>]
29
+ def results
30
+ @results ||= do_query
31
+ end
32
+
33
+ private
34
+
35
+ # @return [Array<Pin::Base>]
36
+ def do_query
37
+ return @pins if @query.nil? || @query.empty?
38
+ @pins.map do |pin|
39
+ match = [fuzzy_string_match(pin.path, @query), fuzzy_string_match(pin.name, @query)].max
40
+ Result.new(match, pin) if match > 0.7
41
+ end
42
+ .compact
43
+ .sort { |a, b| b.match <=> a.match }
44
+ .map(&:pin)
45
+ end
46
+
47
+ # @param str1 [String]
48
+ # @param str2 [String]
49
+ # @return [Float]
50
+ def fuzzy_string_match str1, str2
51
+ return (1.0 + (str2.length.to_f / str1.length.to_f)) if str1.downcase.include?(str2.downcase)
52
+ JaroWinkler.distance(str1, str2, ignore_case: true)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,23 @@
1
+ module Solargraph
2
+ module Pin
3
+ class Signature
4
+ # @return [Array<Parameter>]
5
+ attr_reader :parameters
6
+
7
+ # @return [ComplexType]
8
+ attr_reader :return_type
9
+
10
+ attr_reader :block
11
+
12
+ def initialize parameters, return_type, block = nil
13
+ @parameters = parameters
14
+ @return_type = return_type
15
+ @block = block
16
+ end
17
+
18
+ def block?
19
+ !!@block
20
+ end
21
+ end
22
+ end
23
+ end
@@ -10,6 +10,7 @@ module Solargraph
10
10
  autoload :Conversions, 'solargraph/pin/conversions'
11
11
  autoload :Base, 'solargraph/pin/base'
12
12
  autoload :Method, 'solargraph/pin/method'
13
+ autoload :Signature, 'solargraph/pin/signature'
13
14
  autoload :MethodAlias, 'solargraph/pin/method_alias'
14
15
  autoload :BaseVariable, 'solargraph/pin/base_variable'
15
16
  autoload :InstanceVariable, 'solargraph/pin/instance_variable'
@@ -30,6 +31,7 @@ module Solargraph
30
31
  autoload :DuckMethod, 'solargraph/pin/duck_method'
31
32
  autoload :Singleton, 'solargraph/pin/singleton'
32
33
  autoload :KeywordParam, 'solargraph/pin/keyword_param'
34
+ autoload :Search, 'solargraph/pin/search'
33
35
 
34
36
  ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
35
37
  end