solargraph 0.38.0 → 0.38.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b51cc5aaad5a07e4b7a5f6d2678b3fa42ffba42e7eb5aef0a9dca1834fe3b32
4
- data.tar.gz: eef096fe46ea782d8d1b747f4bf1faa80c3cac9caf80b6f212face3ae8d45392
3
+ metadata.gz: 0dbf36f40f7b87b541abe48c7e624999b44730cd5165f53ca8e7878311da7dcd
4
+ data.tar.gz: 0c12fa0cc1008eaf172fb964e6fac8fbc0b46333247b273b0e4ea9d840a81862
5
5
  SHA512:
6
- metadata.gz: 47f9cdd2ef911ab8ace7de207503c53bc518aaa1b303bb2bc097b86cca229d73886ad8fa0bd7d502794cc8ec67c4c9a9077bd75b2c06e9e9bb39e3879a102eef
7
- data.tar.gz: 698d1343b2843767c9a51d7330f0af2c4202018b1e9cd3e78179f3dd709d1a4a48b5b01ada8d867b8107c4b297a5bc34305989f4adaa7e9057732f1298b54975
6
+ metadata.gz: b7d4bb938698bf682bbb418a6489b4544451ad91039d0fe0e0720339d8b2f9e6c394cc7d8354cc1b2cf6b5505867e93ca26071c177ecae69eab2cf5c1e2e601d
7
+ data.tar.gz: 368ad36e47cc109a9e3c428a743617771a69e14ce7730e4889bb7bab44c3c3aa13643608d6286497f7ea38b99c1f6da130a3401ae0a167a31cf07fb96197fac0
@@ -6,6 +6,7 @@ rvm:
6
6
  - 2.4
7
7
  - 2.5
8
8
  - 2.6
9
+ - 2.7
9
10
  - jruby-head
10
11
  matrix:
11
12
  include:
data/README.md CHANGED
@@ -61,6 +61,12 @@ The Solargraph gem ships with documentation for Ruby 2.2.2. You can download doc
61
61
  $ solargraph download-core # Install the best match for your Ruby version
62
62
  $ solargraph clear # Reset the documentation cache
63
63
 
64
+ ### The Documentation Cache
65
+
66
+ Solargraph uses a cache directory to store documentation for the Ruby core and customized documentation for certain gems. The default location is `~/.solargraph/cache`, e.g., `/home/<username>/.solargraph/cache` on Linux or `C:\Users\<username>\.solargraph` on Windows.
67
+
68
+ You can change the location of the cache directory with the `SOLARGRAPH_CACHE` environment variable. This can be useful if you want the cache to comply with the XDG Base Directory Specification.
69
+
64
70
  ### Solargraph and Bundler
65
71
 
66
72
  If you're using the language server with a project that uses Bundler, the most comprehensive way to use your bundled gems is to bundle Solargraph.
@@ -138,7 +138,7 @@ module Solargraph
138
138
  @implicit ||= Environ.new
139
139
  end
140
140
 
141
- # @return [Hash]
141
+ # @return [Hash{String => String}]
142
142
  def local_path_hash
143
143
  @local_paths ||= {}
144
144
  end
@@ -189,7 +189,7 @@ module Solargraph
189
189
 
190
190
  # An array of namespace names defined in the ApiMap.
191
191
  #
192
- # @return [Array<String>]
192
+ # @return [Set<String>]
193
193
  def namespaces
194
194
  store.namespaces
195
195
  end
@@ -513,9 +513,11 @@ module Solargraph
513
513
  # @return [Boolean]
514
514
  def super_and_sub?(sup, sub)
515
515
  fqsup = qualify(sup)
516
- cls = qualify(store.get_superclass(sub), sub)
517
- until cls.nil?
518
- return true if cls == fqsup
516
+ cls = qualify(sub)
517
+ until fqsup.nil? || cls.nil?
518
+ # @todo Classes in the workspace are not detected as subclasses of
519
+ # Object. The quick and dirty fix is to hardcode it here.
520
+ return true if fqsup == 'Object' || cls == fqsup
519
521
  cls = qualify(store.get_superclass(cls), cls)
520
522
  end
521
523
  false
@@ -627,7 +629,7 @@ module Solargraph
627
629
  # @param name [String]
628
630
  # @param root [String]
629
631
  # @param skip [Array<String>]
630
- # @return [String]
632
+ # @return [String, nil]
631
633
  def inner_qualify name, root, skip
632
634
  return nil if name.nil?
633
635
  return nil if skip.include?(root)
@@ -663,7 +665,7 @@ module Solargraph
663
665
  # Get the namespace's type (Class or Module).
664
666
  #
665
667
  # @param fqns [String] A fully qualified namespace
666
- # @return [Symbol] :class, :module, or nil
668
+ # @return [Symbol, nil] :class, :module, or nil
667
669
  def get_namespace_type fqns
668
670
  return nil if fqns.nil?
669
671
  # @type [Pin::Namespace, nil]
@@ -62,6 +62,11 @@ module Solargraph
62
62
  @return_single_parameter
63
63
  )),
64
64
 
65
+ Override.from_comment('BasicObject#==', %(
66
+ @param other [BasicObject]
67
+ @return [Boolean]
68
+ )),
69
+
65
70
  Override.method_return('Class#new', 'self'),
66
71
  Override.method_return('Class.new', 'Class<Object>'),
67
72
  Override.method_return('Class#allocate', 'self'),
@@ -75,10 +80,16 @@ module Solargraph
75
80
  @return_value_parameter
76
81
  )),
77
82
 
83
+ # @todo This override isn't robust enough. It needs to allow for
84
+ # parameterized Hash types, e.g., [Hash{Symbol => String}].
85
+ Override.from_comment('Hash#[]=', %(
86
+ @param_tuple
87
+ )),
88
+
78
89
  Override.method_return('Object#!', 'Boolean'),
79
90
  Override.method_return('Object#clone', 'self', delete: [:overload]),
80
91
  Override.method_return('Object#dup', 'self'),
81
- Override.method_return('Object#freeze', 'self'),
92
+ Override.method_return('Object#freeze', 'self', delete: [:overload]),
82
93
  Override.method_return('Object#taint', 'self'),
83
94
  Override.method_return('Object#to_s', 'String'),
84
95
  Override.method_return('Object#untaint', 'self'),
@@ -99,3 +110,4 @@ module Solargraph
99
110
  )
100
111
  end
101
112
  end
113
+
@@ -12,16 +12,23 @@ module Solargraph
12
12
 
13
13
  # @param word [String]
14
14
  # @param arguments [Array<Chain>]
15
- def initialize word, arguments = [], with_block = false
15
+ # @param with_block [Boolean] True if the chain is inside a block
16
+ # @param head [Boolean] True if the call is the start of its chain
17
+ def initialize word, arguments = [], with_block = false, head = false
16
18
  @word = word
17
19
  @arguments = arguments
18
20
  @with_block = with_block
21
+ @head = head
19
22
  end
20
23
 
21
24
  def with_block?
22
25
  @with_block
23
26
  end
24
27
 
28
+ def head?
29
+ @head
30
+ end
31
+
25
32
  # @param api_map [ApiMap]
26
33
  # @param name_pin [Pin::Base]
27
34
  # @param locals [Array<Pin::Base>]
@@ -29,6 +36,7 @@ module Solargraph
29
36
  found = locals.select{|p| p.name == word}
30
37
  return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
31
38
  pins = api_map.get_method_stack(name_pin.binder.namespace, word, scope: name_pin.binder.scope)
39
+ pins.concat api_map.get_method_stack('Kernel', word, scope: :instance) if head?
32
40
  return [] if pins.empty?
33
41
  inferred_pins(pins, api_map, name_pin.context, locals)
34
42
  end
@@ -108,6 +116,7 @@ module Solargraph
108
116
  # @param pin [Pin::Method]
109
117
  # @param api_map [ApiMap]
110
118
  # @param context [ComplexType]
119
+ # @param locals [Pin::Base]
111
120
  # @return [Pin::Base]
112
121
  def process_macro pin, api_map, context, locals
113
122
  pin.macros.each do |macro|
@@ -117,6 +126,11 @@ module Solargraph
117
126
  Pin::ProxyType.anonymous(ComplexType::UNDEFINED)
118
127
  end
119
128
 
129
+ # @param pin [Pin::Method]
130
+ # @param api_map [ApiMap]
131
+ # @param context [ComplexType]
132
+ # @param locals [Pin::Base]
133
+ # @return [Pin::ProxyType]
120
134
  def process_directive pin, api_map, context, locals
121
135
  pin.directives.each do |dir|
122
136
  macro = api_map.named_macro(dir.tag.name)
@@ -127,8 +141,12 @@ module Solargraph
127
141
  Pin::ProxyType.anonymous ComplexType::UNDEFINED
128
142
  end
129
143
 
130
- # @param api_map [ApiMap]
144
+ # @param pin [Pin]
131
145
  # @param macro [YARD::Tags::MacroDirective]
146
+ # @param api_map [ApiMap]
147
+ # @param context [ComplexType]
148
+ # @param locals [Array<Pin::Base>]
149
+ # @return [Pin::ProxyType]
132
150
  def inner_process_macro pin, macro, api_map, context, locals
133
151
  vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
134
152
  txt = macro.tag.text.clone
@@ -151,17 +169,19 @@ module Solargraph
151
169
 
152
170
  # @param docstring [YARD::Docstring]
153
171
  # @param context [ComplexType]
172
+ # @return [ComplexType]
154
173
  def extra_return_type docstring, context
155
174
  if docstring.has_tag?(:return_single_parameter) && context.subtypes.one?
156
175
  return context.subtypes.first
157
176
  elsif docstring.has_tag?(:return_value_parameter) && context.value_types.one?
158
177
  return context.value_types.first
159
- # elsif docstring.has_tag?(:return) && docstring.tag(:return).types && !docstring.tag(:return).types.empty?
160
- # return ComplexType.try_parse(*docstring.tag(:return).types)
161
178
  end
162
179
  nil
163
180
  end
164
181
 
182
+ # @param arguments [Array<Chain>]
183
+ # @param parameters [Array<String>]
184
+ # @return [Boolean]
165
185
  def arguments_match arguments, parameters
166
186
  argcount = arguments.length
167
187
  # argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
@@ -58,13 +58,13 @@ module Solargraph
58
58
  n.children[2..-1].each do |c|
59
59
  args.push NodeChainer.chain(c)
60
60
  end
61
- result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
61
+ result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n), result.length.zero?)
62
62
  elsif n.children[0].nil?
63
63
  args = []
64
64
  n.children[2..-1].each do |c|
65
65
  args.push NodeChainer.chain(c)
66
66
  end
67
- result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n))
67
+ result.push Chain::Call.new(n.children[1].to_s, args, @in_block || block_passed?(n), result.length.zero?)
68
68
  else
69
69
  raise "No idea what to do with #{n}"
70
70
  end
@@ -70,6 +70,8 @@ module Solargraph
70
70
  return '::Regexp'
71
71
  elsif node.type == :irange
72
72
  return '::Range'
73
+ elsif node.type == :true || node.type == :false
74
+ return '::Boolean'
73
75
  # @todo Support `nil` keyword in types
74
76
  # elsif node.type == :nil
75
77
  # return 'NilClass'
@@ -177,9 +177,33 @@ module Solargraph
177
177
  else
178
178
  pin = pins.first
179
179
  ptypes = ParamDef.from(pin)
180
- params = param_tags_from(pin)
180
+ params = first_param_tags_from(pins)
181
181
  cursor = 0
182
182
  curtype = nil
183
+ # The @param_tuple tag marks exceptional cases for handling, e.g., the Hash#[]= method.
184
+ if pin.docstring.tag(:param_tuple)
185
+ if node.children[2..-1].length > 2
186
+ result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong number of arguments to #{pin.path}")
187
+ else
188
+ base = chain.base.infer(api_map, block, locals)
189
+ # @todo Don't just use the first key/value type
190
+ k = base.key_types.first || ComplexType.parse('Object')
191
+ v = base.value_types.first || ComplexType.parse('Object')
192
+ tuple = [
193
+ ParamDef.new('key', k),
194
+ ParamDef.new('value', v)
195
+ ]
196
+ node.children[2..-1].each_with_index do |arg, index|
197
+ chain = Solargraph::Source::NodeChainer.chain(arg, filename)
198
+ argtype = chain.infer(api_map, block, locals)
199
+ partype = tuple[index].type
200
+ if argtype.tag != partype.tag && !api_map.super_and_sub?(partype.tag.to_s, argtype.tag.to_s)
201
+ result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong parameter type for #{pin.path}: #{tuple[index].name} expected #{partype.tag}, received #{argtype.tag}")
202
+ end
203
+ end
204
+ end
205
+ return result
206
+ end
183
207
  node.children[2..-1].each_with_index do |arg, index|
184
208
  if pin.is_a?(Pin::Attribute)
185
209
  curtype = ParamDef.new('value', :arg)
@@ -188,8 +212,20 @@ module Solargraph
188
212
  end
189
213
  if curtype.nil?
190
214
  if pin.parameters[index].nil?
191
- result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Not enough arguments sent to #{pin.path}")
192
- break
215
+ if params.values[index]
216
+ # Allow for methods that have named parameters but no
217
+ # arguments in their definitions. This is common in the Ruby
218
+ # core, e.g., the Hash#[]= method.
219
+ chain = Solargraph::Source::NodeChainer.chain(arg, filename)
220
+ argtype = chain.infer(api_map, block, locals)
221
+ partype = params.values[index]
222
+ if argtype.tag != partype.tag && !api_map.super_and_sub?(partype.tag.to_s, argtype.tag.to_s)
223
+ result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong parameter type for #{pin.path}: #{params.keys[index]} expected #{partype.tag}, received #{argtype.tag}")
224
+ end
225
+ else
226
+ result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Not enough arguments sent to #{pin.path}")
227
+ break
228
+ end
193
229
  end
194
230
  else
195
231
  # @todo This should also detect when the last parameter is a hash
@@ -300,6 +336,14 @@ module Solargraph
300
336
  result
301
337
  end
302
338
 
339
+ def first_param_tags_from pins
340
+ pins.each do |pin|
341
+ result = param_tags_from(pin)
342
+ return result unless result.empty?
343
+ end
344
+ {}
345
+ end
346
+
303
347
  # @param location [Location, nil]
304
348
  def report_location? location
305
349
  return false if location.nil?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.38.0'
4
+ VERSION = '0.38.1'
5
5
  end
@@ -22,6 +22,8 @@ YARD::Tags::Library.define_tag('ReturnSingleParameter', :return_single_parameter
22
22
  YARD::Tags::Library.define_tag('YieldparamSingleParameter', :yieldparam_single_parameter)
23
23
  # Define a @return_value_parameter tag for returning e.g. Hash values
24
24
  YARD::Tags::Library.define_tag('ReturnValueParameter', :return_value_parameter)
25
+ # Define a @param_tuple tag for e.g. Hash#[]= parameters
26
+ YARD::Tags::Library.define_tag('ParamTuple', :param_tuple)
25
27
  # Define a @!domain directive for documenting DSLs
26
28
  YARD::Tags::Library.define_directive("domain", :with_types, Solargraph::DomainDirective)
27
29
  # Define an @!override directive for overriding method tags
@@ -27,9 +27,12 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency 'parser', '~> 2.3'
28
28
  s.add_runtime_dependency 'reverse_markdown', '~> 1.0', '>= 1.0.5'
29
29
  s.add_runtime_dependency 'rubocop', '~> 0.52'
30
- s.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.4'
30
+ s.add_runtime_dependency 'thor', '~> 1.0'
31
31
  s.add_runtime_dependency 'tilt', '~> 2.0'
32
32
  s.add_runtime_dependency 'yard', '~> 0.9'
33
+ s.add_runtime_dependency 'e2mmap'
34
+ s.add_runtime_dependency 'irb', '<= 1.1.0'
35
+ s.add_runtime_dependency 'benchmark'
33
36
 
34
37
  s.add_development_dependency 'pry', '~> 0.11.3'
35
38
  s.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
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.38.0
4
+ version: 0.38.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-22 00:00:00.000000000 Z
11
+ date: 2020-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -146,20 +146,14 @@ dependencies:
146
146
  requirements:
147
147
  - - "~>"
148
148
  - !ruby/object:Gem::Version
149
- version: '0.19'
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: 0.19.4
149
+ version: '1.0'
153
150
  type: :runtime
154
151
  prerelease: false
155
152
  version_requirements: !ruby/object:Gem::Requirement
156
153
  requirements:
157
154
  - - "~>"
158
155
  - !ruby/object:Gem::Version
159
- version: '0.19'
160
- - - ">="
161
- - !ruby/object:Gem::Version
162
- version: 0.19.4
156
+ version: '1.0'
163
157
  - !ruby/object:Gem::Dependency
164
158
  name: tilt
165
159
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +182,48 @@ dependencies:
188
182
  - - "~>"
189
183
  - !ruby/object:Gem::Version
190
184
  version: '0.9'
185
+ - !ruby/object:Gem::Dependency
186
+ name: e2mmap
187
+ requirement: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ type: :runtime
193
+ prerelease: false
194
+ version_requirements: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
199
+ - !ruby/object:Gem::Dependency
200
+ name: irb
201
+ requirement: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - "<="
204
+ - !ruby/object:Gem::Version
205
+ version: 1.1.0
206
+ type: :runtime
207
+ prerelease: false
208
+ version_requirements: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - "<="
211
+ - !ruby/object:Gem::Version
212
+ version: 1.1.0
213
+ - !ruby/object:Gem::Dependency
214
+ name: benchmark
215
+ requirement: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ type: :runtime
221
+ prerelease: false
222
+ version_requirements: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - ">="
225
+ - !ruby/object:Gem::Version
226
+ version: '0'
191
227
  - !ruby/object:Gem::Dependency
192
228
  name: pry
193
229
  requirement: !ruby/object:Gem::Requirement