solargraph 0.39.15 → 0.40.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -8
- data/CHANGELOG.md +992 -0
- data/Rakefile +12 -1
- data/SPONSORS.md +1 -0
- data/lib/.rubocop.yml +2 -2
- data/lib/solargraph.rb +2 -4
- data/lib/solargraph/api_map.rb +75 -74
- data/lib/solargraph/api_map/cache.rb +2 -2
- data/lib/solargraph/api_map/store.rb +4 -8
- data/lib/solargraph/{bundle.rb → bench.rb} +6 -2
- data/lib/solargraph/compat.rb +14 -0
- data/lib/solargraph/complex_type.rb +2 -2
- data/lib/solargraph/convention.rb +13 -4
- data/lib/solargraph/convention/base.rb +16 -8
- data/lib/solargraph/convention/gemfile.rb +2 -5
- data/lib/solargraph/convention/gemspec.rb +3 -6
- data/lib/solargraph/convention/rspec.rb +3 -6
- data/lib/solargraph/environ.rb +11 -6
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +6 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +17 -19
- data/lib/solargraph/library.rb +6 -8
- data/lib/solargraph/parser/legacy/node_methods.rb +9 -0
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +36 -23
- data/lib/solargraph/parser/node_processor/base.rb +3 -0
- data/lib/solargraph/parser/rubyvm/node_methods.rb +18 -1
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +40 -29
- data/lib/solargraph/pin.rb +0 -3
- data/lib/solargraph/pin/common.rb +1 -1
- data/lib/solargraph/pin/conversions.rb +3 -4
- data/lib/solargraph/pin/documenting.rb +3 -9
- data/lib/solargraph/pin/method.rb +141 -7
- data/lib/solargraph/pin/method_alias.rb +1 -1
- data/lib/solargraph/position.rb +2 -14
- data/lib/solargraph/source.rb +10 -6
- data/lib/solargraph/source/chain.rb +18 -5
- data/lib/solargraph/source_map.rb +4 -1
- data/lib/solargraph/source_map/clip.rb +3 -2
- data/lib/solargraph/source_map/mapper.rb +10 -6
- data/lib/solargraph/type_checker.rb +27 -24
- data/lib/solargraph/type_checker/param_def.rb +1 -1
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +40 -47
- data/lib/solargraph/yard_map/core_fills.rb +185 -0
- data/lib/solargraph/yard_map/helpers.rb +16 -0
- data/lib/solargraph/yard_map/mapper.rb +14 -8
- data/lib/solargraph/{pin/yard_pin/constant.rb → yard_map/mapper/to_constant.rb} +6 -6
- data/lib/solargraph/yard_map/mapper/to_method.rb +78 -0
- data/lib/solargraph/{pin/yard_pin/namespace.rb → yard_map/mapper/to_namespace.rb} +6 -6
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +1 -1
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -0
- data/lib/solargraph/yard_map/to_method.rb +79 -0
- data/solargraph.gemspec +5 -5
- metadata +22 -36
- data/lib/solargraph/core_fills.rb +0 -160
- data/lib/solargraph/pin/attribute.rb +0 -49
- data/lib/solargraph/pin/base_method.rb +0 -141
- data/lib/solargraph/pin/yard_pin.rb +0 -12
- data/lib/solargraph/pin/yard_pin/method.rb +0 -80
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -20
- data/lib/solargraph/stdlib_fills.rb +0 -40
- data/travis-bundler.rb +0 -11
data/lib/solargraph/position.rb
CHANGED
@@ -40,20 +40,8 @@ module Solargraph
|
|
40
40
|
# @param position [Position]
|
41
41
|
# @return [Integer]
|
42
42
|
def self.to_offset text, position
|
43
|
-
|
44
|
-
|
45
|
-
line = position.line
|
46
|
-
column = position.character
|
47
|
-
text.lines.each do |l|
|
48
|
-
line_length = l.length
|
49
|
-
if feed == line
|
50
|
-
result += column
|
51
|
-
break
|
52
|
-
end
|
53
|
-
result += line_length
|
54
|
-
feed += 1
|
55
|
-
end
|
56
|
-
result
|
43
|
+
return 0 if text.empty?
|
44
|
+
text.lines[0...position.line].sum(&:length) + position.character
|
57
45
|
end
|
58
46
|
|
59
47
|
# Get a numeric offset for the specified text and a position identified
|
data/lib/solargraph/source.rb
CHANGED
@@ -284,7 +284,7 @@ module Solargraph
|
|
284
284
|
|
285
285
|
FOLDING_NODE_TYPES = if Parser.rubyvm?
|
286
286
|
%i[
|
287
|
-
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR
|
287
|
+
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR HASH ARRAY LIST
|
288
288
|
].freeze
|
289
289
|
else
|
290
290
|
%i[
|
@@ -345,18 +345,22 @@ module Solargraph
|
|
345
345
|
|
346
346
|
# @param top [Parser::AST::Node]
|
347
347
|
# @param result [Array<Range>]
|
348
|
+
# @param parent [Symbol]
|
348
349
|
# @return [void]
|
349
|
-
def inner_folding_ranges top, result = []
|
350
|
+
def inner_folding_ranges top, result = [], parent = nil
|
350
351
|
# return unless top.is_a?(::Parser::AST::Node)
|
351
352
|
return unless Parser.is_ast_node?(top)
|
352
353
|
if FOLDING_NODE_TYPES.include?(top.type)
|
353
|
-
|
354
|
-
|
355
|
-
|
354
|
+
# @todo Smelly exception for hash's first-level array in RubyVM
|
355
|
+
unless [:ARRAY, :LIST].include?(top.type) && parent == :HASH
|
356
|
+
range = Range.from_node(top)
|
357
|
+
if result.empty? || range.start.line > result.last.start.line
|
358
|
+
result.push range unless range.ending.line - range.start.line < 2
|
359
|
+
end
|
356
360
|
end
|
357
361
|
end
|
358
362
|
top.children.each do |child|
|
359
|
-
inner_folding_ranges(child, result)
|
363
|
+
inner_folding_ranges(child, result, top.type)
|
360
364
|
end
|
361
365
|
end
|
362
366
|
|
@@ -110,18 +110,21 @@ module Solargraph
|
|
110
110
|
# @param api_map [ApiMap]
|
111
111
|
# @return [ComplexType]
|
112
112
|
def infer_first_defined pins, context, api_map
|
113
|
-
|
113
|
+
possibles = []
|
114
114
|
pins.each do |pin|
|
115
115
|
# Avoid infinite recursion
|
116
116
|
next if @@inference_stack.include?(pin.identity)
|
117
117
|
@@inference_stack.push pin.identity
|
118
118
|
type = pin.typify(api_map)
|
119
119
|
@@inference_stack.pop
|
120
|
-
|
120
|
+
if type.defined?
|
121
|
+
possibles.push type
|
122
|
+
break if pin.is_a?(Pin::Method)
|
123
|
+
end
|
121
124
|
end
|
122
|
-
if
|
125
|
+
if possibles.empty?
|
123
126
|
# Limit method inference recursion
|
124
|
-
return
|
127
|
+
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
125
128
|
@@inference_depth += 1
|
126
129
|
pins.each do |pin|
|
127
130
|
# Avoid infinite recursion
|
@@ -129,10 +132,20 @@ module Solargraph
|
|
129
132
|
@@inference_stack.push pin.identity
|
130
133
|
type = pin.probe(api_map)
|
131
134
|
@@inference_stack.pop
|
132
|
-
|
135
|
+
if type.defined?
|
136
|
+
possibles.push type
|
137
|
+
break if pin.is_a?(Pin::Method)
|
138
|
+
end
|
133
139
|
end
|
134
140
|
@@inference_depth -= 1
|
135
141
|
end
|
142
|
+
return ComplexType::UNDEFINED if possibles.empty?
|
143
|
+
type = if possibles.length > 1
|
144
|
+
sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
|
145
|
+
ComplexType.parse(*sorted)
|
146
|
+
else
|
147
|
+
possibles.first
|
148
|
+
end
|
136
149
|
return type if context.nil? || context.return_type.undefined?
|
137
150
|
type.self_to(context.return_type.namespace)
|
138
151
|
end
|
@@ -30,7 +30,7 @@ module Solargraph
|
|
30
30
|
@source = source.dup
|
31
31
|
@pins = pins
|
32
32
|
@locals = locals
|
33
|
-
environ.merge Convention.
|
33
|
+
environ.merge Convention.for_local(self) unless filename.nil?
|
34
34
|
@pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
|
35
35
|
@pin_select_cache = {}
|
36
36
|
end
|
@@ -168,6 +168,9 @@ module Solargraph
|
|
168
168
|
position = Position.new(line, character)
|
169
169
|
found = nil
|
170
170
|
pins.each do |pin|
|
171
|
+
# @todo Attribute pins should not be treated like closures, but
|
172
|
+
# there's probably a better way to handle it
|
173
|
+
next if pin.is_a?(Pin::Method) && pin.attribute?
|
171
174
|
found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
|
172
175
|
break if pin.location.range.start.line > line
|
173
176
|
end
|
@@ -149,7 +149,7 @@ module Solargraph
|
|
149
149
|
frag_start = cursor.start_of_word.to_s.downcase
|
150
150
|
filtered = result.uniq(&:name).select { |s|
|
151
151
|
s.name.downcase.start_with?(frag_start) &&
|
152
|
-
(!s.is_a?(Pin::
|
152
|
+
(!s.is_a?(Pin::Method) || s.name.match(/^[a-z0-9_]+(\!|\?|=)?$/i))
|
153
153
|
}
|
154
154
|
Completion.new(filtered, cursor.range)
|
155
155
|
end
|
@@ -212,7 +212,8 @@ module Solargraph
|
|
212
212
|
result.concat api_map.get_constants(context_pin.context.namespace, *gates)
|
213
213
|
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
214
214
|
result.concat api_map.get_methods('Kernel')
|
215
|
-
result.concat ApiMap.keywords
|
215
|
+
# result.concat ApiMap.keywords
|
216
|
+
result.concat api_map.keyword_pins
|
216
217
|
result.concat yielded_self_pins
|
217
218
|
end
|
218
219
|
end
|
@@ -126,27 +126,31 @@ module Solargraph
|
|
126
126
|
namespace = closure_at(source_position)
|
127
127
|
t = (directive.tag.types.nil? || directive.tag.types.empty?) ? nil : directive.tag.types.flatten.join('')
|
128
128
|
if t.nil? || t.include?('r')
|
129
|
-
pins.push Solargraph::Pin::
|
129
|
+
pins.push Solargraph::Pin::Method.new(
|
130
130
|
location: location,
|
131
131
|
closure: namespace,
|
132
132
|
name: directive.tag.name,
|
133
133
|
comments: docstring.all.to_s,
|
134
|
-
access: :reader,
|
135
134
|
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
136
135
|
visibility: :public,
|
137
|
-
explicit: false
|
136
|
+
explicit: false,
|
137
|
+
attribute: true
|
138
138
|
)
|
139
139
|
end
|
140
140
|
if t.nil? || t.include?('w')
|
141
|
-
pins.push Solargraph::Pin::
|
141
|
+
pins.push Solargraph::Pin::Method.new(
|
142
142
|
location: location,
|
143
143
|
closure: namespace,
|
144
144
|
name: "#{directive.tag.name}=",
|
145
145
|
comments: docstring.all.to_s,
|
146
|
-
access: :writer,
|
147
146
|
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
148
|
-
visibility: :public
|
147
|
+
visibility: :public,
|
148
|
+
attribute: true
|
149
149
|
)
|
150
|
+
pins.last.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last)
|
151
|
+
if pins.last.return_type.defined?
|
152
|
+
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '), 'value')
|
153
|
+
end
|
150
154
|
end
|
151
155
|
when 'parse'
|
152
156
|
begin
|
@@ -73,15 +73,15 @@ module Solargraph
|
|
73
73
|
# @return [Array<Problem>]
|
74
74
|
def method_tag_problems
|
75
75
|
result = []
|
76
|
-
# @param pin [Pin::
|
77
|
-
source_map.pins_by_class(Pin::
|
76
|
+
# @param pin [Pin::Method]
|
77
|
+
source_map.pins_by_class(Pin::Method).each do |pin|
|
78
78
|
result.concat method_return_type_problems_for(pin)
|
79
79
|
result.concat method_param_type_problems_for(pin)
|
80
80
|
end
|
81
81
|
result
|
82
82
|
end
|
83
83
|
|
84
|
-
# @param pin [Pin::
|
84
|
+
# @param pin [Pin::Method]
|
85
85
|
# @return [Array<Problem>]
|
86
86
|
def method_return_type_problems_for pin
|
87
87
|
result = []
|
@@ -115,7 +115,7 @@ module Solargraph
|
|
115
115
|
pin.location && source_map.source.comment_at?(pin.location.range.ending)
|
116
116
|
end
|
117
117
|
|
118
|
-
# @param pin [Pin::
|
118
|
+
# @param pin [Pin::Method]
|
119
119
|
# @return [Array<Problem>]
|
120
120
|
def method_param_type_problems_for pin
|
121
121
|
stack = api_map.get_method_stack(pin.namespace, pin.name, scope: pin.scope)
|
@@ -147,14 +147,12 @@ module Solargraph
|
|
147
147
|
result = []
|
148
148
|
all_variables.each do |pin|
|
149
149
|
if pin.return_type.defined?
|
150
|
-
# @todo Somwhere in here we still need to determine if the variable is defined by an external call
|
151
150
|
declared = pin.typify(api_map)
|
152
151
|
if declared.defined?
|
153
152
|
if rules.validate_tags?
|
154
153
|
inferred = pin.probe(api_map)
|
155
154
|
if inferred.undefined?
|
156
155
|
next if rules.ignore_all_undefined?
|
157
|
-
# next unless internal?(pin) # @todo This might be redundant for variables
|
158
156
|
if declared_externally?(pin)
|
159
157
|
ignored_pins.push pin
|
160
158
|
else
|
@@ -172,7 +170,6 @@ module Solargraph
|
|
172
170
|
result.push Problem.new(pin.location, "Unresolved type #{pin.return_type} for variable #{pin.name}", pin: pin)
|
173
171
|
end
|
174
172
|
else
|
175
|
-
# @todo Check if the variable is defined by an external call
|
176
173
|
inferred = pin.probe(api_map)
|
177
174
|
if inferred.undefined? && declared_externally?(pin)
|
178
175
|
ignored_pins.push pin
|
@@ -227,7 +224,7 @@ module Solargraph
|
|
227
224
|
base = base.base
|
228
225
|
end
|
229
226
|
closest = found.typify(api_map) if found
|
230
|
-
if !found || closest.defined?
|
227
|
+
if !found || (closest.defined? && internal_or_core?(found))
|
231
228
|
unless ignored_pins.include?(found)
|
232
229
|
result.push Problem.new(location, "Unresolved call to #{missing.links.last.word}")
|
233
230
|
@marked_ranges.push rng
|
@@ -244,8 +241,8 @@ module Solargraph
|
|
244
241
|
base = chain
|
245
242
|
until base.links.length == 1 && base.undefined?
|
246
243
|
pins = base.define(api_map, block_pin, locals)
|
247
|
-
if pins.first.is_a?(Pin::
|
248
|
-
# @type [Pin::
|
244
|
+
if pins.first.is_a?(Pin::Method)
|
245
|
+
# @type [Pin::Method]
|
249
246
|
pin = pins.first
|
250
247
|
ap = if base.links.last.is_a?(Solargraph::Source::Chain::ZSuper)
|
251
248
|
arity_problems_for(pin, fake_args_for(block_pin), location)
|
@@ -313,7 +310,6 @@ module Solargraph
|
|
313
310
|
end
|
314
311
|
else
|
315
312
|
if par.decl == :kwarg
|
316
|
-
# @todo Problem: missing required keyword argument
|
317
313
|
result.push Problem.new(location, "Call to #{pin.path} is missing keyword argument #{par.name}")
|
318
314
|
end
|
319
315
|
end
|
@@ -338,6 +334,8 @@ module Solargraph
|
|
338
334
|
result
|
339
335
|
end
|
340
336
|
|
337
|
+
# @param [Pin::Method]
|
338
|
+
# @return [Hash]
|
341
339
|
def param_hash(pin)
|
342
340
|
tags = pin.docstring.tags(:param)
|
343
341
|
return {} if tags.empty?
|
@@ -350,6 +348,7 @@ module Solargraph
|
|
350
348
|
end
|
351
349
|
|
352
350
|
# @param [Array<Pin::Method>]
|
351
|
+
# @return [Hash]
|
353
352
|
def first_param_hash(pins)
|
354
353
|
pins.each do |pin|
|
355
354
|
result = param_hash(pin)
|
@@ -360,9 +359,14 @@ module Solargraph
|
|
360
359
|
|
361
360
|
# @param pin [Pin::Base]
|
362
361
|
def internal? pin
|
362
|
+
return false if pin.nil?
|
363
363
|
pin.location && api_map.bundled?(pin.location.filename)
|
364
364
|
end
|
365
365
|
|
366
|
+
def internal_or_core? pin
|
367
|
+
internal?(pin) || api_map.yard_map.core_pins.include?(pin) || api_map.yard_map.stdlib_pins.include?(pin)
|
368
|
+
end
|
369
|
+
|
366
370
|
# @param pin [Pin::Base]
|
367
371
|
def external? pin
|
368
372
|
!internal? pin
|
@@ -395,7 +399,7 @@ module Solargraph
|
|
395
399
|
true
|
396
400
|
end
|
397
401
|
|
398
|
-
# @param pin [Pin::
|
402
|
+
# @param pin [Pin::Method]
|
399
403
|
def arity_problems_for(pin, arguments, location)
|
400
404
|
return [] unless pin.explicit?
|
401
405
|
return [] if pin.parameters.empty? && arguments.empty?
|
@@ -410,9 +414,12 @@ module Solargraph
|
|
410
414
|
if unchecked.empty? && pin.parameters.any? { |param| param.decl == :kwarg }
|
411
415
|
return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
|
412
416
|
end
|
417
|
+
settled_kwargs = 0
|
413
418
|
unless unchecked.empty?
|
414
|
-
|
415
|
-
|
419
|
+
if Parser.is_ast_node?(unchecked.last.node) && splatted_call?(unchecked.last.node)
|
420
|
+
settled_kwargs = pin.parameters.count(&:keyword?)
|
421
|
+
else
|
422
|
+
kwargs = convert_hash(unchecked.last.node)
|
416
423
|
if pin.parameters.any? { |param| [:kwarg, :kwoptarg].include?(param.decl) || param.kwrestarg? }
|
417
424
|
if kwargs.empty?
|
418
425
|
add_params += 1
|
@@ -422,6 +429,7 @@ module Solargraph
|
|
422
429
|
next unless param.keyword?
|
423
430
|
if kwargs.key?(param.name.to_sym)
|
424
431
|
kwargs.delete param.name.to_sym
|
432
|
+
settled_kwargs += 1
|
425
433
|
elsif param.decl == :kwarg
|
426
434
|
return [Problem.new(location, "Missing keyword argument #{param.name} to #{pin.path}")]
|
427
435
|
end
|
@@ -432,7 +440,7 @@ module Solargraph
|
|
432
440
|
end
|
433
441
|
end
|
434
442
|
end
|
435
|
-
|
443
|
+
end
|
436
444
|
end
|
437
445
|
req = required_param_count(pin)
|
438
446
|
if req + add_params < unchecked.length
|
@@ -443,23 +451,18 @@ module Solargraph
|
|
443
451
|
return []
|
444
452
|
end
|
445
453
|
return [Problem.new(location, "Too many arguments to #{pin.path}")]
|
446
|
-
elsif unchecked.length < req && (arguments.empty? || !arguments.last.splat?)
|
454
|
+
elsif unchecked.length < req - settled_kwargs && (arguments.empty? || !arguments.last.splat?)
|
447
455
|
return [Problem.new(location, "Not enough arguments to #{pin.path}")]
|
448
456
|
end
|
449
457
|
[]
|
450
458
|
end
|
451
459
|
|
452
|
-
# @param pin [Pin::
|
460
|
+
# @param pin [Pin::Method]
|
453
461
|
def required_param_count(pin)
|
454
|
-
|
455
|
-
pin.parameters.each do |param|
|
456
|
-
break unless param.decl == :arg
|
457
|
-
count += 1
|
458
|
-
end
|
459
|
-
count
|
462
|
+
pin.parameters.sum { |param| %i[arg kwarg].include?(param.decl) ? 1 : 0 }
|
460
463
|
end
|
461
464
|
|
462
|
-
# @param pin [Pin::
|
465
|
+
# @param pin [Pin::Method]
|
463
466
|
def optional_param_count(pin)
|
464
467
|
count = 0
|
465
468
|
pin.parameters.each do |param|
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -10,11 +10,15 @@ module Solargraph
|
|
10
10
|
# stdlib, and gems.
|
11
11
|
#
|
12
12
|
class YardMap
|
13
|
-
autoload :Cache,
|
14
|
-
autoload :CoreDocs,
|
15
|
-
autoload :CoreGen,
|
16
|
-
autoload :Mapper,
|
17
|
-
autoload :RdocToYard,
|
13
|
+
autoload :Cache, 'solargraph/yard_map/cache'
|
14
|
+
autoload :CoreDocs, 'solargraph/yard_map/core_docs'
|
15
|
+
autoload :CoreGen, 'solargraph/yard_map/core_gen'
|
16
|
+
autoload :Mapper, 'solargraph/yard_map/mapper'
|
17
|
+
autoload :RdocToYard, 'solargraph/yard_map/rdoc_to_yard'
|
18
|
+
autoload :CoreFills, 'solargraph/yard_map/core_fills'
|
19
|
+
autoload :StdlibFills, 'solargraph/yard_map/stdlib_fills'
|
20
|
+
autoload :Helpers, 'solargraph/yard_map/helpers'
|
21
|
+
autoload :ToMethod, 'solargraph/yard_map/to_method'
|
18
22
|
|
19
23
|
CoreDocs.require_minimum
|
20
24
|
|
@@ -50,6 +54,8 @@ module Solargraph
|
|
50
54
|
def initialize(required: [], gemset: {}, with_dependencies: true)
|
51
55
|
# HACK: YardMap needs its own copy of this array
|
52
56
|
@required = required.clone
|
57
|
+
# HACK: Hardcoded YAML handling
|
58
|
+
@required.push 'psych' if @required.include?('yaml')
|
53
59
|
@with_dependencies = with_dependencies
|
54
60
|
@gem_paths = {}
|
55
61
|
@stdlib_namespaces = []
|
@@ -74,6 +80,8 @@ module Solargraph
|
|
74
80
|
# @param new_gemset [Hash{String => String}]
|
75
81
|
# @return [Boolean]
|
76
82
|
def change new_requires, new_gemset, source_gems = []
|
83
|
+
# HACK: Hardcoded YAML handling
|
84
|
+
new_requires.push 'psych' if new_requires.include?('yaml')
|
77
85
|
if new_requires.uniq.sort == required.uniq.sort && new_gemset == gemset && @source_gems.uniq.sort == source_gems.uniq.sort
|
78
86
|
false
|
79
87
|
else
|
@@ -131,7 +139,7 @@ module Solargraph
|
|
131
139
|
# @param path [String]
|
132
140
|
# @return [Pin::Base]
|
133
141
|
def path_pin path
|
134
|
-
pins.select{ |p| p.path == path }.first
|
142
|
+
pins.select { |p| p.path == path }.first
|
135
143
|
end
|
136
144
|
|
137
145
|
# Get the location of a file referenced by a require path.
|
@@ -151,6 +159,10 @@ module Solargraph
|
|
151
159
|
nil
|
152
160
|
end
|
153
161
|
|
162
|
+
def stdlib_pins
|
163
|
+
@stdlib_pins ||= []
|
164
|
+
end
|
165
|
+
|
154
166
|
private
|
155
167
|
|
156
168
|
# @return [YardMap::Cache]
|
@@ -158,10 +170,12 @@ module Solargraph
|
|
158
170
|
@cache ||= YardMap::Cache.new
|
159
171
|
end
|
160
172
|
|
173
|
+
# @return [Hash]
|
161
174
|
def pin_class_hash
|
162
175
|
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
163
176
|
end
|
164
177
|
|
178
|
+
# @return [Array<Pin::Base>]
|
165
179
|
def pins_by_class klass
|
166
180
|
@pin_select_cache[klass] ||= pin_class_hash.select { |key, _| key <= klass }.values.flatten
|
167
181
|
end
|
@@ -179,12 +193,13 @@ module Solargraph
|
|
179
193
|
|
180
194
|
# @return [void]
|
181
195
|
def process_requires
|
182
|
-
pins.
|
196
|
+
pins.replace core_pins
|
183
197
|
unresolved_requires.clear
|
184
|
-
|
198
|
+
stdlib_pins.clear
|
199
|
+
environ = Convention.for_global(self)
|
185
200
|
done = []
|
186
201
|
from_std = []
|
187
|
-
required.each do |r|
|
202
|
+
(required + environ.requires).each do |r|
|
188
203
|
next if r.nil? || r.empty? || done.include?(r)
|
189
204
|
done.push r
|
190
205
|
cached = cache.get_path_pins(r)
|
@@ -209,7 +224,6 @@ module Solargraph
|
|
209
224
|
yardocs.unshift yd
|
210
225
|
result.concat process_yardoc yd, spec
|
211
226
|
result.concat add_gem_dependencies(spec) if with_dependencies?
|
212
|
-
stdlib_fill r, result
|
213
227
|
end
|
214
228
|
rescue Gem::LoadError => e
|
215
229
|
base = r.split('/').first
|
@@ -219,7 +233,7 @@ module Solargraph
|
|
219
233
|
if stdtmp.empty?
|
220
234
|
unresolved_requires.push r
|
221
235
|
else
|
222
|
-
|
236
|
+
stdlib_pins.concat stdtmp
|
223
237
|
result.concat stdtmp
|
224
238
|
end
|
225
239
|
end
|
@@ -229,7 +243,13 @@ module Solargraph
|
|
229
243
|
pins.concat result
|
230
244
|
end
|
231
245
|
end
|
232
|
-
|
246
|
+
if required.include?('yaml') && required.include?('psych')
|
247
|
+
# HACK: Hardcoded YAML handling
|
248
|
+
# @todo Why can't this be handled with an override or a virtual pin?
|
249
|
+
pin = path_pin('YAML')
|
250
|
+
pin.instance_variable_set(:@return_type, ComplexType.parse('Module<Psych>')) unless pin.nil?
|
251
|
+
end
|
252
|
+
pins.concat environ.pins
|
233
253
|
end
|
234
254
|
|
235
255
|
# @param spec [Gem::Specification]
|
@@ -327,22 +347,6 @@ module Solargraph
|
|
327
347
|
spec
|
328
348
|
end
|
329
349
|
|
330
|
-
# @param path [String]
|
331
|
-
# @param pins [Array<Pin::Base>]
|
332
|
-
# @return [void]
|
333
|
-
def stdlib_fill path, pins
|
334
|
-
StdlibFills.get(path).each do |ovr|
|
335
|
-
pin = pins.select { |p| p.path == ovr.name }.first
|
336
|
-
next if pin.nil?
|
337
|
-
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
338
|
-
pin.docstring.delete_tags tag.to_sym
|
339
|
-
end
|
340
|
-
ovr.tags.each do |tag|
|
341
|
-
pin.docstring.add_tag(tag)
|
342
|
-
end
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
350
|
def load_core_pins
|
347
351
|
yd = CoreDocs.yardoc_file
|
348
352
|
ser = File.join(File.dirname(yd), 'core.ser')
|
@@ -360,23 +364,7 @@ module Solargraph
|
|
360
364
|
else
|
361
365
|
read_core_and_save_cache(yd, ser)
|
362
366
|
end
|
363
|
-
|
364
|
-
errno = result.select{ |pin| pin.path == 'Errno' }.first
|
365
|
-
Errno.constants.each do |const|
|
366
|
-
result.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno)
|
367
|
-
result.push Solargraph::Pin::Reference::Superclass.new(closure: result.last, name: 'SystemCallError')
|
368
|
-
end
|
369
|
-
CoreFills::OVERRIDES.each do |ovr|
|
370
|
-
pin = result.select { |p| p.path == ovr.name }.first
|
371
|
-
next if pin.nil?
|
372
|
-
(ovr.tags.map(&:tag_name) + ovr.delete).uniq.each do |tag|
|
373
|
-
pin.docstring.delete_tags tag.to_sym
|
374
|
-
end
|
375
|
-
ovr.tags.each do |tag|
|
376
|
-
pin.docstring.add_tag(tag)
|
377
|
-
end
|
378
|
-
end
|
379
|
-
result
|
367
|
+
ApiMap::Store.new(result + CoreFills::ALL).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
|
380
368
|
end
|
381
369
|
|
382
370
|
def read_core_and_save_cache yd, ser
|
@@ -384,7 +372,7 @@ module Solargraph
|
|
384
372
|
load_yardoc yd
|
385
373
|
result.concat Mapper.new(YARD::Registry.all).map
|
386
374
|
# HACK: Assume core methods with a single `args` parameter accept restarg
|
387
|
-
result.select { |pin| pin.is_a?(Solargraph::Pin::
|
375
|
+
result.select { |pin| pin.is_a?(Solargraph::Pin::Method )}.each do |pin|
|
388
376
|
if pin.parameters.length == 1 && pin.parameters.first.name == 'args' && pin.parameters.first.decl == :arg
|
389
377
|
# @todo Smelly instance variable access
|
390
378
|
pin.parameters.first.instance_variable_set(:@decl, :restarg)
|
@@ -403,7 +391,7 @@ module Solargraph
|
|
403
391
|
|
404
392
|
def load_stdlib_pins base
|
405
393
|
ser = File.join(File.dirname(CoreDocs.yardoc_stdlib_file), "#{base}.ser")
|
406
|
-
if File.file?(ser)
|
394
|
+
result = if File.file?(ser)
|
407
395
|
Solargraph.logger.info "Loading #{base} stdlib from cache"
|
408
396
|
file = File.open(ser, 'rb')
|
409
397
|
dump = file.read
|
@@ -418,6 +406,11 @@ module Solargraph
|
|
418
406
|
else
|
419
407
|
read_stdlib_and_save_cache(base, ser)
|
420
408
|
end
|
409
|
+
fills = StdlibFills.get(base)
|
410
|
+
unless fills.empty?
|
411
|
+
result = ApiMap::Store.new(result + fills).pins.reject { |pin| pin.is_a?(Pin::Reference::Override) }
|
412
|
+
end
|
413
|
+
result
|
421
414
|
end
|
422
415
|
|
423
416
|
def read_stdlib_and_save_cache base, ser
|