solargraph 0.38.0 → 0.38.1

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