solargraph 0.34.2 → 0.34.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -1
- data/lib/solargraph/complex_type.rb +8 -8
- data/lib/solargraph/complex_type/type_methods.rb +2 -1
- data/lib/solargraph/core_fills.rb +9 -2
- data/lib/solargraph/language_server/host.rb +30 -16
- data/lib/solargraph/language_server/host/sources.rb +4 -2
- data/lib/solargraph/language_server/message/initialize.rb +1 -0
- data/lib/solargraph/pin/base.rb +4 -0
- data/lib/solargraph/pin/base_method.rb +1 -1
- data/lib/solargraph/pin/constant.rb +1 -2
- data/lib/solargraph/pin/method.rb +1 -2
- data/lib/solargraph/pin/parameter.rb +9 -3
- data/lib/solargraph/pin/yard_pin/namespace.rb +3 -4
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +7 -13
- data/lib/solargraph/shell.rb +3 -1
- data/lib/solargraph/source/chain.rb +16 -1
- data/lib/solargraph/source/chain/call.rb +18 -4
- data/lib/solargraph/source/node_chainer.rb +6 -5
- data/lib/solargraph/source/source_chainer.rb +6 -5
- data/lib/solargraph/source_map/mapper.rb +16 -3
- data/lib/solargraph/type_checker.rb +30 -3
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +0 -2
- data/lib/solargraph/yard_map/mapper.rb +1 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19d601d06fae9aedf33e93d09172bb9257757aaf7323f6f6a355c82fc7b67223
|
4
|
+
data.tar.gz: 5a5d073284cd8034b710dbb22169a30478e490e8561b4e2be56b59a52c79b757
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0071a0c809fae4043ea2ffa35ef811f575d1c9027f199c47d344692ce0e7a641a10f94af240220959a5ef924f92985511afebd8b502cc35ed023bbffe2b27a62
|
7
|
+
data.tar.gz: 0076f43c9ae828ead40ec6d64a6409fa96d3631a290673baf026aa65e8f72fbdc8103cd073a7f5919945cd8a7f598f233889ef38ea173f3e58cd27cbb03f8812
|
data/.travis.yml
CHANGED
@@ -6,11 +6,15 @@ rvm:
|
|
6
6
|
- 2.4
|
7
7
|
- 2.5
|
8
8
|
- 2.6
|
9
|
-
- jruby-
|
9
|
+
- jruby-head
|
10
10
|
matrix:
|
11
11
|
include:
|
12
12
|
- rvm: 2.5
|
13
13
|
os: osx
|
14
|
+
- rvm: 2.6
|
15
|
+
os: osx
|
16
|
+
allow_failures:
|
17
|
+
- rvm: jruby-head
|
14
18
|
# Update RubyGems and Bundler due to error with Bundler 1.16.1 and RubyGems 2.7.3
|
15
19
|
# See https://github.com/travis-ci/travis-ci/issues/8978
|
16
20
|
before_install:
|
@@ -121,8 +121,8 @@ module Solargraph
|
|
121
121
|
point_stack = 0
|
122
122
|
curly_stack = 0
|
123
123
|
paren_stack = 0
|
124
|
-
base =
|
125
|
-
subtype_string =
|
124
|
+
base = String.new
|
125
|
+
subtype_string = String.new
|
126
126
|
type_string.each_char do |char|
|
127
127
|
if char == '='
|
128
128
|
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
@@ -137,8 +137,8 @@ module Solargraph
|
|
137
137
|
types.push UniqueType.new(base[0..-2].strip)
|
138
138
|
key_types = types
|
139
139
|
types = []
|
140
|
-
base
|
141
|
-
subtype_string
|
140
|
+
base.clear
|
141
|
+
subtype_string.clear
|
142
142
|
next
|
143
143
|
else
|
144
144
|
point_stack -= 1
|
@@ -163,14 +163,14 @@ module Solargraph
|
|
163
163
|
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
164
164
|
# types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
165
165
|
types.push UniqueType.new(base.strip, subtype_string.strip)
|
166
|
-
base
|
167
|
-
subtype_string
|
166
|
+
base.clear
|
167
|
+
subtype_string.clear
|
168
168
|
next
|
169
169
|
end
|
170
170
|
if point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
171
|
-
base
|
171
|
+
base.concat char
|
172
172
|
else
|
173
|
-
subtype_string
|
173
|
+
subtype_string.concat char
|
174
174
|
end
|
175
175
|
end
|
176
176
|
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
@@ -25,6 +25,13 @@ module Solargraph
|
|
25
25
|
Override.method_return('Array#reject', 'self'),
|
26
26
|
Override.method_return('Array#keep_if', 'self'),
|
27
27
|
Override.method_return('Array#delete_if', 'self'),
|
28
|
+
Override.method_return('Array#reverse', 'self', delete: ['overload']),
|
29
|
+
Override.from_comment('Array#select', %(
|
30
|
+
@overload select(&block)
|
31
|
+
@return [self]
|
32
|
+
@overload select()
|
33
|
+
@return [Enumerator]
|
34
|
+
)),
|
28
35
|
Override.from_comment('Array#[]', %(
|
29
36
|
@overload [](range)
|
30
37
|
@param range [Range]
|
@@ -50,7 +57,7 @@ module Solargraph
|
|
50
57
|
@return [self]
|
51
58
|
@return_single_parameter
|
52
59
|
)),
|
53
|
-
|
60
|
+
|
54
61
|
Override.method_return('Class#new', 'self'),
|
55
62
|
Override.method_return('Class.new', 'Class<Object>'),
|
56
63
|
Override.method_return('Class#allocate', 'self'),
|
@@ -63,7 +70,7 @@ module Solargraph
|
|
63
70
|
Override.from_comment('Hash#[]', %(
|
64
71
|
@return_value_parameter
|
65
72
|
)),
|
66
|
-
|
73
|
+
|
67
74
|
Override.method_return('Object#!', 'Boolean'),
|
68
75
|
Override.method_return('Object#clone', 'self', delete: [:overload]),
|
69
76
|
Override.method_return('Object#dup', 'self'),
|
@@ -20,6 +20,8 @@ module Solargraph
|
|
20
20
|
include Dispatch
|
21
21
|
include Observable
|
22
22
|
|
23
|
+
attr_writer :client_capabilities
|
24
|
+
|
23
25
|
def initialize
|
24
26
|
@cancel_semaphore = Mutex.new
|
25
27
|
@buffer_semaphore = Mutex.new
|
@@ -362,16 +364,18 @@ module Solargraph
|
|
362
364
|
# @return [void]
|
363
365
|
def register_capabilities methods
|
364
366
|
logger.debug "Registering capabilities: #{methods}"
|
367
|
+
registrations = methods.select{|m| can_register?(m) and !registered?(m)}.map { |m|
|
368
|
+
@registered_capabilities.add m
|
369
|
+
{
|
370
|
+
id: m,
|
371
|
+
method: m,
|
372
|
+
registerOptions: dynamic_capability_options[m]
|
373
|
+
}
|
374
|
+
}
|
375
|
+
return if registrations.empty?
|
365
376
|
@register_semaphore.synchronize do
|
366
377
|
send_request 'client/registerCapability', {
|
367
|
-
registrations:
|
368
|
-
@registered_capabilities.add m
|
369
|
-
{
|
370
|
-
id: m,
|
371
|
-
method: m,
|
372
|
-
registerOptions: dynamic_capability_options[m]
|
373
|
-
}
|
374
|
-
}
|
378
|
+
registrations: registrations
|
375
379
|
}
|
376
380
|
end
|
377
381
|
end
|
@@ -384,15 +388,17 @@ module Solargraph
|
|
384
388
|
# @return [void]
|
385
389
|
def unregister_capabilities methods
|
386
390
|
logger.debug "Unregistering capabilities: #{methods}"
|
391
|
+
unregisterations = methods.select{|m| registered?(m)}.map{ |m|
|
392
|
+
@registered_capabilities.delete m
|
393
|
+
{
|
394
|
+
id: m,
|
395
|
+
method: m
|
396
|
+
}
|
397
|
+
}
|
398
|
+
return if unregisterations.empty?
|
387
399
|
@register_semaphore.synchronize do
|
388
400
|
send_request 'client/unregisterCapability', {
|
389
|
-
unregisterations:
|
390
|
-
@registered_capabilities.delete m
|
391
|
-
{
|
392
|
-
id: m,
|
393
|
-
method: m
|
394
|
-
}
|
395
|
-
}
|
401
|
+
unregisterations: unregisterations
|
396
402
|
}
|
397
403
|
end
|
398
404
|
end
|
@@ -613,6 +619,10 @@ module Solargraph
|
|
613
619
|
libraries.each(&:catalog)
|
614
620
|
end
|
615
621
|
|
622
|
+
def client_capabilities
|
623
|
+
@client_capabilities ||= {}
|
624
|
+
end
|
625
|
+
|
616
626
|
private
|
617
627
|
|
618
628
|
# @return [Diagnoser]
|
@@ -693,7 +703,7 @@ module Solargraph
|
|
693
703
|
referencesProvider: true
|
694
704
|
},
|
695
705
|
'textDocument/rename' => {
|
696
|
-
renameProvider: {prepareProvider: true}
|
706
|
+
renameProvider: prepare_rename? ? { prepareProvider: true } : true
|
697
707
|
},
|
698
708
|
'textDocument/documentSymbol' => {
|
699
709
|
documentSymbolProvider: true
|
@@ -712,6 +722,10 @@ module Solargraph
|
|
712
722
|
}
|
713
723
|
}
|
714
724
|
end
|
725
|
+
|
726
|
+
def prepare_rename?
|
727
|
+
client_capabilities['rename'] && client_capabilities['rename']['prepareSupport']
|
728
|
+
end
|
715
729
|
end
|
716
730
|
end
|
717
731
|
end
|
@@ -85,8 +85,10 @@ module Solargraph
|
|
85
85
|
# @return [void]
|
86
86
|
def async_update uri, updater
|
87
87
|
src = find(uri)
|
88
|
-
mutex.synchronize
|
89
|
-
|
88
|
+
mutex.synchronize do
|
89
|
+
open_source_hash[uri] = src.start_synchronize(updater)
|
90
|
+
queue.push uri
|
91
|
+
end
|
90
92
|
changed
|
91
93
|
notify_observers uri
|
92
94
|
end
|
@@ -9,6 +9,7 @@ module Solargraph
|
|
9
9
|
def process
|
10
10
|
bm = Benchmark.measure {
|
11
11
|
host.configure params['initializationOptions']
|
12
|
+
host.client_capabilities = params['capabilities']
|
12
13
|
if support_workspace_folders?
|
13
14
|
host.prepare_folders params['workspaceFolders']
|
14
15
|
elsif params['rootUri']
|
data/lib/solargraph/pin/base.rb
CHANGED
@@ -112,8 +112,7 @@ module Solargraph
|
|
112
112
|
location.filename,
|
113
113
|
[n.loc.expression.last_line, n.loc.expression.last_column]
|
114
114
|
)
|
115
|
-
|
116
|
-
type = chain.infer(api_map, self, clip.locals)
|
115
|
+
type = clip.infer
|
117
116
|
result.push type unless type.undefined?
|
118
117
|
end
|
119
118
|
end
|
@@ -44,6 +44,10 @@ module Solargraph
|
|
44
44
|
true
|
45
45
|
end
|
46
46
|
|
47
|
+
def probe api_map
|
48
|
+
typify api_map
|
49
|
+
end
|
50
|
+
|
47
51
|
private
|
48
52
|
|
49
53
|
# @return [YARD::Tags::Tag]
|
@@ -71,9 +75,11 @@ module Solargraph
|
|
71
75
|
meths = chain.define(api_map, closure, locals)
|
72
76
|
meths.each do |meth|
|
73
77
|
if meth.docstring.has_tag?(:yieldparam_single_parameter)
|
74
|
-
|
75
|
-
|
76
|
-
|
78
|
+
type = chain.base.infer(api_map, closure, locals)
|
79
|
+
if type.defined? && !type.subtypes.empty?
|
80
|
+
bmeth = chain.base.define(api_map, closure, locals).first
|
81
|
+
return type.subtypes.first.qualify(api_map, bmeth.context.namespace)
|
82
|
+
end
|
77
83
|
else
|
78
84
|
yps = meth.docstring.tags(:yieldparam)
|
79
85
|
unless yps[index].nil? or yps[index].types.nil? or yps[index].types.empty?
|
@@ -18,16 +18,15 @@ module Solargraph
|
|
18
18
|
location: location,
|
19
19
|
name: code_object.name.to_s,
|
20
20
|
comments: nil,
|
21
|
-
type: namespace_type
|
21
|
+
type: namespace_type,
|
22
22
|
visibility: code_object.visibility,
|
23
|
-
closure: closure
|
24
|
-
gates: split_to_gates(code_object.path)
|
23
|
+
closure: closure
|
25
24
|
)
|
26
25
|
end
|
27
26
|
|
28
27
|
private
|
29
28
|
|
30
|
-
def namespace_type
|
29
|
+
def namespace_type
|
31
30
|
code_object.is_a?(YARD::CodeObjects::ClassObject) ? :class : :module
|
32
31
|
end
|
33
32
|
end
|
@@ -15,25 +15,19 @@ module Solargraph
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def location
|
18
|
+
# Guarding with @located because nil locations are valid
|
18
19
|
return @location if @located
|
19
20
|
@located = true
|
20
|
-
@location =
|
21
|
+
@location = object_location
|
21
22
|
end
|
22
23
|
|
23
24
|
private
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
result.push parts.join('::')
|
31
|
-
parts.pop
|
32
|
-
end
|
33
|
-
result.push ''
|
34
|
-
@@gate_cache[namespace] = result.freeze
|
35
|
-
result
|
36
|
-
end
|
26
|
+
# @return [Solargraph::Location, nil]
|
27
|
+
def object_location
|
28
|
+
return nil if spec.nil? || code_object.nil? || code_object.file.nil? || code_object.line.nil?
|
29
|
+
file = File.join(spec.full_gem_path, code_object.file)
|
30
|
+
Solargraph::Location.new(file, Solargraph::Range.from_to(code_object.line - 1, 0, code_object.line - 1, 0))
|
37
31
|
end
|
38
32
|
end
|
39
33
|
end
|
data/lib/solargraph/shell.rb
CHANGED
@@ -198,7 +198,7 @@ module Solargraph
|
|
198
198
|
# @param pin [Solargraph::Pin::Base]
|
199
199
|
# @return [String]
|
200
200
|
def pin_description pin
|
201
|
-
if pin.path.nil? || pin.path.empty?
|
201
|
+
desc = if pin.path.nil? || pin.path.empty?
|
202
202
|
if pin.closure
|
203
203
|
"#{pin.closure.path} | #{pin.name}"
|
204
204
|
else
|
@@ -207,6 +207,8 @@ module Solargraph
|
|
207
207
|
else
|
208
208
|
pin.path
|
209
209
|
end
|
210
|
+
desc += " (#{pin.location.filename} #{pin.location.range.start.line})" if pin.location
|
211
|
+
desc
|
210
212
|
end
|
211
213
|
end
|
212
214
|
end
|
@@ -22,6 +22,8 @@ module Solargraph
|
|
22
22
|
|
23
23
|
@@inference_stack = []
|
24
24
|
@@inference_depth = 0
|
25
|
+
@@last_api_map = nil
|
26
|
+
@@pin_cache = {}
|
25
27
|
|
26
28
|
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
27
29
|
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
@@ -105,11 +107,18 @@ module Solargraph
|
|
105
107
|
# Limit method inference recursion
|
106
108
|
return type if @@inference_depth >= 2 && pins.first.is_a?(Pin::BaseMethod)
|
107
109
|
@@inference_depth += 1
|
110
|
+
name_count = {}
|
108
111
|
pins.each do |pin|
|
112
|
+
# Limit pin name hits for, e.g., variables with insane amounts of definitions
|
113
|
+
name_count[pin.identity] ||= 0
|
114
|
+
name_count[pin.identity] += 1
|
115
|
+
next if name_count[pin.identity] >= 10
|
109
116
|
# Avoid infinite recursion
|
110
117
|
next if @@inference_stack.include?(pin)
|
111
118
|
@@inference_stack.push pin
|
112
|
-
|
119
|
+
# puts " Inferring #{pin.class} | #{pin.path} | #{pin.name} | #{pin.location ? pin.location.to_hash : pin.location}"
|
120
|
+
# type = pin.probe(api_map)
|
121
|
+
type = remember_or_probe(pin, api_map)
|
113
122
|
@@inference_stack.pop
|
114
123
|
break if type.defined?
|
115
124
|
end
|
@@ -147,6 +156,12 @@ module Solargraph
|
|
147
156
|
end
|
148
157
|
end
|
149
158
|
end
|
159
|
+
|
160
|
+
def remember_or_probe pin, api_map
|
161
|
+
@@pin_cache.clear if @@last_api_map != api_map
|
162
|
+
@@last_api_map = api_map
|
163
|
+
@@pin_cache[pin] ||= pin.probe(api_map)
|
164
|
+
end
|
150
165
|
end
|
151
166
|
end
|
152
167
|
end
|
@@ -12,9 +12,14 @@ module Solargraph
|
|
12
12
|
|
13
13
|
# @param word [String]
|
14
14
|
# @param arguments [Array<Chain>]
|
15
|
-
def initialize word, arguments = []
|
15
|
+
def initialize word, arguments = [], with_block = false
|
16
16
|
@word = word
|
17
17
|
@arguments = arguments
|
18
|
+
@with_block = with_block
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_block?
|
22
|
+
@with_block
|
18
23
|
end
|
19
24
|
|
20
25
|
# @param api_map [ApiMap]
|
@@ -42,8 +47,8 @@ module Solargraph
|
|
42
47
|
type = ComplexType::UNDEFINED
|
43
48
|
# @param [YARD::Tags::OverloadTag]
|
44
49
|
overloads.each do |ol|
|
45
|
-
next
|
46
|
-
|
50
|
+
next unless arguments_match(arguments, ol.parameters)
|
51
|
+
next if ol.parameters.last && ol.parameters.last.first.start_with?('&') && ol.parameters.last.last.nil? && !with_block?
|
47
52
|
match = true
|
48
53
|
arguments.each_with_index do |arg, idx|
|
49
54
|
achain = arguments[idx]
|
@@ -95,7 +100,7 @@ module Solargraph
|
|
95
100
|
end
|
96
101
|
result.map do |pin|
|
97
102
|
next pin if pin.return_type.undefined?
|
98
|
-
selfy = pin.return_type.self_to(context.
|
103
|
+
selfy = pin.return_type.self_to(context.tag)
|
99
104
|
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
100
105
|
end
|
101
106
|
end
|
@@ -156,6 +161,15 @@ module Solargraph
|
|
156
161
|
end
|
157
162
|
nil
|
158
163
|
end
|
164
|
+
|
165
|
+
def arguments_match arguments, parameters
|
166
|
+
argcount = arguments.length
|
167
|
+
# argcount -= 1 if !arguments.empty? && arguments.last.links.first.word.start_with?('&')
|
168
|
+
parcount = parameters.length
|
169
|
+
parcount -= 1 if !parameters.empty? && parameters.last.first.start_with?('&')
|
170
|
+
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.first.start_with?('*'))
|
171
|
+
true
|
172
|
+
end
|
159
173
|
end
|
160
174
|
end
|
161
175
|
end
|
@@ -9,9 +9,10 @@ module Solargraph
|
|
9
9
|
|
10
10
|
# @param node [Parser::AST::Node]
|
11
11
|
# @param filename [String]
|
12
|
-
def initialize node, filename = nil
|
12
|
+
def initialize node, filename = nil, in_block = false
|
13
13
|
@node = node
|
14
14
|
@filename = filename
|
15
|
+
@in_block = in_block
|
15
16
|
end
|
16
17
|
|
17
18
|
# @return [Source::Chain]
|
@@ -24,8 +25,8 @@ module Solargraph
|
|
24
25
|
# @param node [Parser::AST::Node]
|
25
26
|
# @param filename [String]
|
26
27
|
# @return [Chain]
|
27
|
-
def chain node, filename = nil
|
28
|
-
NodeChainer.new(node, filename).chain
|
28
|
+
def chain node, filename = nil, in_block = false
|
29
|
+
NodeChainer.new(node, filename, in_block).chain
|
29
30
|
end
|
30
31
|
|
31
32
|
# @param code [String]
|
@@ -55,13 +56,13 @@ module Solargraph
|
|
55
56
|
n.children[2..-1].each do |c|
|
56
57
|
args.push NodeChainer.chain(c)
|
57
58
|
end
|
58
|
-
result.push Chain::Call.new(n.children[1].to_s, args)
|
59
|
+
result.push Chain::Call.new(n.children[1].to_s, args, @in_block)
|
59
60
|
elsif n.children[0].nil?
|
60
61
|
args = []
|
61
62
|
n.children[2..-1].each do |c|
|
62
63
|
args.push NodeChainer.chain(c)
|
63
64
|
end
|
64
|
-
result.push Chain::Call.new(n.children[1].to_s, args)
|
65
|
+
result.push Chain::Call.new(n.children[1].to_s, args, @in_block)
|
65
66
|
else
|
66
67
|
raise "No idea what to do with #{n}"
|
67
68
|
end
|
@@ -35,13 +35,14 @@ module Solargraph
|
|
35
35
|
return Chain.new([Chain::Literal.new('Symbol')]) if phrase.start_with?(':') && !phrase.start_with?('::')
|
36
36
|
begin
|
37
37
|
return Chain.new([]) if phrase.end_with?('..')
|
38
|
+
node = nil
|
39
|
+
parent = nil
|
38
40
|
if !source.repaired? && source.parsed? && source.synchronized?
|
39
|
-
node = source.
|
41
|
+
node, parent = source.tree_at(position.line, position.column)[0..2]
|
40
42
|
elsif source.parsed? && source.repaired? && end_of_phrase == '.'
|
41
|
-
node = source.
|
43
|
+
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
|
42
44
|
else
|
43
|
-
node = nil
|
44
|
-
node = source.node_at(fixed_position.line, fixed_position.column) unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)}
|
45
|
+
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2] unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)}
|
45
46
|
# Exception for positions that chain literal nodes in unsynchronized sources
|
46
47
|
node = nil unless source.synchronized? || !infer_literal_node_type(node).nil?
|
47
48
|
node = Source.parse(fixed_phrase) if node.nil?
|
@@ -50,7 +51,7 @@ module Solargraph
|
|
50
51
|
return Chain.new([Chain::UNDEFINED_CALL])
|
51
52
|
end
|
52
53
|
return Chain.new([Chain::UNDEFINED_CALL]) if node.nil? || (node.type == :sym && !phrase.start_with?(':'))
|
53
|
-
chain = NodeChainer.chain(node, source.filename)
|
54
|
+
chain = NodeChainer.chain(node, source.filename, parent && parent.type == :block)
|
54
55
|
if source.repaired? || !source.parsed? || !source.synchronized?
|
55
56
|
if end_of_phrase.strip == '.'
|
56
57
|
chain.links.push Chain::UNDEFINED_CALL
|
@@ -12,7 +12,7 @@ module Solargraph
|
|
12
12
|
|
13
13
|
private_class_method :new
|
14
14
|
|
15
|
-
MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse)/.freeze
|
15
|
+
MACRO_REGEXP = /(@\!method|@\!attribute|@\!domain|@\!macro|@\!parse|@\!override)/.freeze
|
16
16
|
|
17
17
|
# Generate the data.
|
18
18
|
#
|
@@ -67,14 +67,27 @@ module Solargraph
|
|
67
67
|
last_line = 0
|
68
68
|
# @param d [YARD::Tags::Directive]
|
69
69
|
parse.directives.each do |d|
|
70
|
-
line_num = cmnt
|
71
|
-
line_num += last_line
|
70
|
+
line_num = find_directive_line_number(cmnt, d.tag.tag_name, last_line)
|
72
71
|
pos = Solargraph::Position.new(comment_position.line + line_num, comment_position.column)
|
73
72
|
process_directive(source_position, pos, d)
|
74
73
|
last_line = line_num + 1
|
74
|
+
# @todo The below call assumes the topmost comment line. The above
|
75
|
+
# process occasionally emits incorrect comment positions due to
|
76
|
+
# blank lines in comment blocks, but at least it processes all the
|
77
|
+
# directives.
|
78
|
+
# process_directive(source_position, comment_position, d)
|
75
79
|
end
|
76
80
|
end
|
77
81
|
|
82
|
+
def find_directive_line_number comment, tag, start
|
83
|
+
num = comment.lines[start..-1].find_index do |line|
|
84
|
+
# Legacy method directives might be `@method` instead of `@!method`
|
85
|
+
# @todo Legacy syntax should probably emit a warning
|
86
|
+
line.include?("@!#{tag}") || (tag == 'method' && line.include?("@#{tag}"))
|
87
|
+
end
|
88
|
+
num.to_i + start
|
89
|
+
end
|
90
|
+
|
78
91
|
# @param position [Position]
|
79
92
|
# @param directive [YARD::Tags::Directive]
|
80
93
|
def process_directive source_position, comment_position, directive
|
@@ -192,12 +192,21 @@ module Solargraph
|
|
192
192
|
break
|
193
193
|
end
|
194
194
|
else
|
195
|
-
# @todo
|
196
|
-
|
195
|
+
# @todo This should also detect when the last parameter is a hash
|
196
|
+
if curtype.type == :kwrestarg
|
197
|
+
if arg.type != :hash
|
198
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong parameter type for #{pin.path}: expected hash or keyword")
|
199
|
+
else
|
200
|
+
result.concat check_hash_params arg, params
|
201
|
+
end
|
202
|
+
# @todo Break here? Not sure about that
|
203
|
+
break
|
204
|
+
end
|
205
|
+
break if curtype.type == :restarg
|
197
206
|
if arg.is_a?(Parser::AST::Node) && arg.type == :hash
|
198
207
|
arg.children.each do |pair|
|
199
208
|
sym = pair.children[0].children[0].to_s
|
200
|
-
partype = params[
|
209
|
+
partype = params[sym]
|
201
210
|
if partype
|
202
211
|
chain = Solargraph::Source::NodeChainer.chain(pair.children[1], filename)
|
203
212
|
argtype = chain.infer(api_map, block, locals)
|
@@ -242,6 +251,24 @@ module Solargraph
|
|
242
251
|
result
|
243
252
|
end
|
244
253
|
|
254
|
+
def check_hash_params arg, params
|
255
|
+
result = []
|
256
|
+
keys = arg.children.map do |child|
|
257
|
+
child.children[0].children[0].to_s
|
258
|
+
end
|
259
|
+
keys.each do |key|
|
260
|
+
param = params[key]
|
261
|
+
if param
|
262
|
+
# @todo typecheck
|
263
|
+
else
|
264
|
+
# @todo This error might not be valid. If there's a splat in the
|
265
|
+
# method parameters, should the type checker let it pass?
|
266
|
+
result.push Problem.new(nil, "Keyword argument #{key} does not have a @param tag")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
result
|
270
|
+
end
|
271
|
+
|
245
272
|
def arg_to_duck arg, par
|
246
273
|
return false unless par.duck_type?
|
247
274
|
meths = api_map.get_complex_type_methods(arg).map(&:name)
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/yard_map.rb
CHANGED
@@ -171,8 +171,6 @@ module Solargraph
|
|
171
171
|
result = []
|
172
172
|
begin
|
173
173
|
spec = spec_for_require(r)
|
174
|
-
ver = spec.version.to_s
|
175
|
-
ver = ">= 0" if ver.empty?
|
176
174
|
yd = yardoc_file_for_spec(spec)
|
177
175
|
# YARD detects gems for certain libraries that do not have a yardoc
|
178
176
|
# but exist in the stdlib. `fileutils` is an example. Treat those
|
@@ -5,7 +5,7 @@ module Solargraph
|
|
5
5
|
class Mapper
|
6
6
|
@@object_file_cache = {}
|
7
7
|
|
8
|
-
# @param code_objects [Array<YARD::
|
8
|
+
# @param code_objects [Array<YARD::CodeObjects::Base>]
|
9
9
|
# @param spec [Gem::Specification]
|
10
10
|
def initialize code_objects, spec = nil
|
11
11
|
@code_objects = code_objects
|
@@ -65,22 +65,6 @@ module Solargraph
|
|
65
65
|
end
|
66
66
|
result
|
67
67
|
end
|
68
|
-
|
69
|
-
# @param obj [YARD::CodeObjects::Base]
|
70
|
-
# @return [Solargraph::Location, nil]
|
71
|
-
def self.object_location obj, spec = nil
|
72
|
-
return nil if spec.nil? || obj.file.nil? || obj.line.nil?
|
73
|
-
file = nil
|
74
|
-
if @@object_file_cache.key?(obj.file)
|
75
|
-
file = @@object_file_cache[obj.file]
|
76
|
-
else
|
77
|
-
tmp = File.join(spec.full_gem_path, obj.file)
|
78
|
-
file = tmp if File.exist?(tmp)
|
79
|
-
@@object_file_cache[obj.file] = file
|
80
|
-
end
|
81
|
-
return nil if file.nil?
|
82
|
-
Solargraph::Location.new(file, Solargraph::Range.from_to(obj.line - 1, 0, obj.line - 1, 0))
|
83
|
-
end
|
84
68
|
end
|
85
69
|
end
|
86
70
|
end
|
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.34.
|
4
|
+
version: 0.34.3
|
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-07-
|
11
|
+
date: 2019-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|