solargraph 0.23.6 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/solargraph.rb +1 -0
- data/lib/solargraph/api_map.rb +30 -7
- data/lib/solargraph/api_map/probe.rb +15 -2
- data/lib/solargraph/complex_type.rb +90 -0
- data/lib/solargraph/diagnostics.rb +2 -0
- data/lib/solargraph/diagnostics/base.rb +5 -2
- data/lib/solargraph/diagnostics/type_not_defined.rb +110 -0
- data/lib/solargraph/language_server/host.rb +9 -3
- data/lib/solargraph/language_server/message/exit_notification.rb +0 -1
- data/lib/solargraph/language_server/message/shutdown.rb +1 -1
- data/lib/solargraph/library.rb +12 -3
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/pin/attribute.rb +12 -5
- data/lib/solargraph/pin/base.rb +47 -3
- data/lib/solargraph/pin/base_variable.rb +25 -4
- data/lib/solargraph/pin/block_parameter.rb +20 -11
- data/lib/solargraph/pin/duck_method.rb +15 -0
- data/lib/solargraph/pin/method.rb +16 -26
- data/lib/solargraph/pin/method_parameter.rb +12 -9
- data/lib/solargraph/pin/namespace.rb +2 -2
- data/lib/solargraph/pin/proxy_method.rb +5 -6
- data/lib/solargraph/pin/yard_object.rb +6 -2
- data/lib/solargraph/source.rb +26 -3
- data/lib/solargraph/source/change.rb +6 -0
- data/lib/solargraph/source/fragment.rb +31 -7
- data/lib/solargraph/source/location.rb +7 -0
- data/lib/solargraph/source/mapper.rb +28 -3
- data/lib/solargraph/source/position.rb +5 -0
- data/lib/solargraph/source/range.rb +5 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +26 -0
- metadata +5 -2
data/lib/solargraph/pin.rb
CHANGED
@@ -22,6 +22,7 @@ module Solargraph
|
|
22
22
|
autoload :Block, 'solargraph/pin/block'
|
23
23
|
autoload :Localized, 'solargraph/pin/localized'
|
24
24
|
autoload :ProxyMethod, 'solargraph/pin/proxy_method'
|
25
|
+
autoload :DuckMethod, 'solargraph/pin/duck_method'
|
25
26
|
|
26
27
|
ATTRIBUTE = 1
|
27
28
|
CLASS_VARIABLE = 2
|
@@ -30,12 +30,15 @@ module Solargraph
|
|
30
30
|
@path ||= namespace + (scope == :instance ? '#' : '.') + name
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
if @
|
35
|
-
|
36
|
-
|
33
|
+
def return_complex_types
|
34
|
+
if @return_complex_types.nil?
|
35
|
+
@return_complex_types = []
|
36
|
+
unless docstring.nil?
|
37
|
+
tag = docstring.tag(:return)
|
38
|
+
@return_complex_types.concat ComplexType.parse(*tag.types) unless tag.nil?
|
39
|
+
end
|
37
40
|
end
|
38
|
-
@
|
41
|
+
@return_complex_types
|
39
42
|
end
|
40
43
|
|
41
44
|
def visibility
|
@@ -48,6 +51,10 @@ module Solargraph
|
|
48
51
|
# them as methods without parameters
|
49
52
|
[]
|
50
53
|
end
|
54
|
+
|
55
|
+
def parameter_names
|
56
|
+
[]
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
data/lib/solargraph/pin/base.rb
CHANGED
@@ -18,15 +18,16 @@ module Solargraph
|
|
18
18
|
# @return [YARD::Docstring]
|
19
19
|
attr_reader :docstring
|
20
20
|
|
21
|
-
# @return [String]
|
22
|
-
attr_reader :return_type
|
23
|
-
|
24
21
|
# @return [Integer]
|
25
22
|
attr_reader :kind
|
26
23
|
|
27
24
|
# @return [String]
|
28
25
|
attr_reader :path
|
29
26
|
|
27
|
+
# @param location [Solargraph::Source::Location]
|
28
|
+
# @param namespace [String]
|
29
|
+
# @param name [String]
|
30
|
+
# @param docstring [YARD::Docstring]
|
30
31
|
def initialize location, namespace, name, docstring
|
31
32
|
@location = location
|
32
33
|
@namespace = namespace
|
@@ -58,6 +59,7 @@ module Solargraph
|
|
58
59
|
@identifier ||= "#{path}|#{name}"
|
59
60
|
end
|
60
61
|
|
62
|
+
# @return [Boolean]
|
61
63
|
def variable?
|
62
64
|
false
|
63
65
|
end
|
@@ -66,6 +68,48 @@ module Solargraph
|
|
66
68
|
def named_context
|
67
69
|
namespace
|
68
70
|
end
|
71
|
+
|
72
|
+
def == other
|
73
|
+
return false unless self.class == other.class
|
74
|
+
location == other.location and
|
75
|
+
namespace == other.namespace and
|
76
|
+
name == other.name and
|
77
|
+
( (docstring.nil? and other.docstring.nil?) or (docstring == other.docstring and docstring.all == other.docstring.all) )
|
78
|
+
end
|
79
|
+
|
80
|
+
# The first return type associated with the pin.
|
81
|
+
# Use return_complex_types for an array of all return types.
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
def return_type
|
85
|
+
return nil if return_complex_types.empty?
|
86
|
+
return_complex_types.first.tag
|
87
|
+
end
|
88
|
+
|
89
|
+
# The namespace of the first return type.
|
90
|
+
# Use return_complex_types for an array of all return types.
|
91
|
+
#
|
92
|
+
# @return [String]
|
93
|
+
def return_namespace
|
94
|
+
return nil if return_complex_types.empty?
|
95
|
+
@return_namespace ||= return_complex_types.first.namespace
|
96
|
+
end
|
97
|
+
|
98
|
+
# The scope of the first return type.
|
99
|
+
# Use return_complex_types for an array of all return types.
|
100
|
+
#
|
101
|
+
# @return [String]
|
102
|
+
def return_scope
|
103
|
+
return nil if complex_types.empty?
|
104
|
+
@return_scope ||= return_complex_types.first.scope
|
105
|
+
end
|
106
|
+
|
107
|
+
# All of the pin's return types as an array of ComplexTypes.
|
108
|
+
#
|
109
|
+
# @return [Array<ComplexType>]
|
110
|
+
def return_complex_types
|
111
|
+
@return_complex_types ||= []
|
112
|
+
end
|
69
113
|
end
|
70
114
|
end
|
71
115
|
end
|
@@ -26,17 +26,29 @@ module Solargraph
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def return_type
|
29
|
+
# if @return_type.nil?
|
30
|
+
# if !docstring.nil?
|
31
|
+
# tag = docstring.tag(:type)
|
32
|
+
# @return_type = tag.types[0] unless tag.nil?
|
33
|
+
# else
|
34
|
+
# @return_type = @literal
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# @return_type
|
29
38
|
if @return_type.nil?
|
30
|
-
if
|
31
|
-
tag = docstring.tag(:type)
|
32
|
-
@return_type = tag.types[0] unless tag.nil?
|
33
|
-
else
|
39
|
+
if return_complex_types.empty?
|
34
40
|
@return_type = @literal
|
41
|
+
else
|
42
|
+
@return_type = return_complex_types.first.tag
|
35
43
|
end
|
36
44
|
end
|
37
45
|
@return_type
|
38
46
|
end
|
39
47
|
|
48
|
+
def return_complex_types
|
49
|
+
@return_complex_types ||= generate_complex_types
|
50
|
+
end
|
51
|
+
|
40
52
|
def nil_assignment?
|
41
53
|
return_type == 'NilClass'
|
42
54
|
end
|
@@ -44,6 +56,15 @@ module Solargraph
|
|
44
56
|
def variable?
|
45
57
|
true
|
46
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def generate_complex_types
|
63
|
+
return [] if docstring.nil?
|
64
|
+
tag = docstring.tag(:type)
|
65
|
+
return [] if tag.nil?
|
66
|
+
ComplexType.parse *tag.types
|
67
|
+
end
|
47
68
|
end
|
48
69
|
end
|
49
70
|
end
|
@@ -3,8 +3,7 @@ module Solargraph
|
|
3
3
|
class BlockParameter < Base
|
4
4
|
include Localized
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
# @return [Pin::Block]
|
8
7
|
attr_reader :block
|
9
8
|
|
10
9
|
def initialize location, namespace, name, docstring, block
|
@@ -13,33 +12,43 @@ module Solargraph
|
|
13
12
|
@presence = block.location.range
|
14
13
|
end
|
15
14
|
|
15
|
+
# @return [Integer]
|
16
16
|
def kind
|
17
17
|
Pin::BLOCK_PARAMETER
|
18
18
|
end
|
19
19
|
|
20
|
+
# @return [Integer]
|
20
21
|
def completion_item_kind
|
21
22
|
Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
|
22
23
|
end
|
23
24
|
|
25
|
+
# @return [Integer]
|
24
26
|
def symbol_kind
|
25
27
|
Solargraph::LanguageServer::SymbolKinds::VARIABLE
|
26
28
|
end
|
27
29
|
|
30
|
+
# The parameter's zero-based location in the block's signature.
|
31
|
+
#
|
32
|
+
# @return [Integer]
|
28
33
|
def index
|
29
34
|
block.parameters.index(self)
|
30
35
|
end
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
37
|
+
# @return [Array<Solargraph::ComplexType>]
|
38
|
+
def return_complex_types
|
39
|
+
if @return_complex_types.nil?
|
40
|
+
@return_complex_types = []
|
41
|
+
unless block.docstring.nil?
|
42
|
+
found = nil
|
43
|
+
params = block.docstring.tags(:param)
|
44
|
+
params.each do |p|
|
45
|
+
next unless p.name == name
|
46
|
+
found = p
|
47
|
+
end
|
48
|
+
@return_complex_types.concat ComplexType.parse(*found.types) unless found.nil? or found.types.nil?
|
39
49
|
end
|
40
|
-
@return_type = found.types[0] unless found.nil? or found.types.nil?
|
41
50
|
end
|
42
|
-
@
|
51
|
+
@return_complex_types
|
43
52
|
end
|
44
53
|
end
|
45
54
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module Pin
|
3
|
+
# DuckMethod pins are used to add completion items for type tags that
|
4
|
+
# use duck typing, e.g., `@param file [#read]`.
|
5
|
+
#
|
6
|
+
class DuckMethod < Pin::Method
|
7
|
+
# @param location [Solargraph::Source::Location]
|
8
|
+
# @param name [String]
|
9
|
+
#
|
10
|
+
def initialize location, name
|
11
|
+
super(location, 'Object', name, nil, :instance, :public, [])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -12,6 +12,10 @@ module Solargraph
|
|
12
12
|
@parameters = args
|
13
13
|
end
|
14
14
|
|
15
|
+
def parameter_names
|
16
|
+
@parameter_names ||= parameters.map{|p| p.split(/[ =:]/).first}
|
17
|
+
end
|
18
|
+
|
15
19
|
def kind
|
16
20
|
Solargraph::Pin::METHOD
|
17
21
|
end
|
@@ -29,16 +33,8 @@ module Solargraph
|
|
29
33
|
LanguageServer::SymbolKinds::METHOD
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
33
|
-
|
34
|
-
tag = docstring.tag(:return)
|
35
|
-
if tag.nil?
|
36
|
-
ol = docstring.tag(:overload)
|
37
|
-
tag = ol.tag(:return) unless ol.nil?
|
38
|
-
end
|
39
|
-
@return_type = tag.types[0] unless tag.nil? or tag.types.nil?
|
40
|
-
end
|
41
|
-
@return_type
|
36
|
+
def return_complex_types
|
37
|
+
@return_complex_types ||= generate_complex_types
|
42
38
|
end
|
43
39
|
|
44
40
|
def documentation
|
@@ -63,23 +59,17 @@ module Solargraph
|
|
63
59
|
@documentation
|
64
60
|
end
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
def
|
69
|
-
if
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
unless
|
74
|
-
param_tags.each do |t|
|
75
|
-
txt = t.name.to_s
|
76
|
-
txt += " [#{t.types.join(',')}]" unless t.types.nil? or t.types.empty?
|
77
|
-
txt += " #{t.text}" unless t.text.nil? or t.text.empty?
|
78
|
-
@params.push txt
|
79
|
-
end
|
80
|
-
end
|
62
|
+
private
|
63
|
+
|
64
|
+
def generate_complex_types
|
65
|
+
return [] if docstring.nil?
|
66
|
+
tag = docstring.tag(:return)
|
67
|
+
if tag.nil?
|
68
|
+
ol = docstring.tag(:overload)
|
69
|
+
tag = ol.tag(:return) unless ol.nil?
|
81
70
|
end
|
82
|
-
|
71
|
+
return [] if tag.nil?
|
72
|
+
ComplexType.parse *tag.types
|
83
73
|
end
|
84
74
|
end
|
85
75
|
end
|
@@ -1,18 +1,21 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module Pin
|
3
3
|
class MethodParameter < LocalVariable
|
4
|
-
def
|
5
|
-
if @
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
def return_complex_types
|
5
|
+
if @return_complex_types.nil?
|
6
|
+
@return_complex_types = []
|
7
|
+
unless block.docstring.nil?
|
8
|
+
found = nil
|
9
|
+
params = block.docstring.tags(:param)
|
10
|
+
params.each do |p|
|
11
|
+
next unless p.name == name
|
12
|
+
found = p
|
13
|
+
end
|
14
|
+
@return_complex_types.concat ComplexType.parse(*found.types) unless found.nil? or found.types.nil?
|
11
15
|
end
|
12
|
-
@return_type = found.types[0] unless found.nil? or found.types.nil?
|
13
16
|
end
|
14
17
|
super
|
15
|
-
@
|
18
|
+
@return_complex_types
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
@@ -51,8 +51,8 @@ module Solargraph
|
|
51
51
|
@path ||= (namespace.empty? ? '' : "#{namespace}::") + name
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
@
|
54
|
+
def return_complex_types
|
55
|
+
@return_complex_types ||= ComplexType.parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -5,16 +5,15 @@ module Solargraph
|
|
5
5
|
# method while analyzing signatures.
|
6
6
|
#
|
7
7
|
class ProxyMethod < Base
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def initialize return_type
|
12
|
-
@return_type = return_type
|
8
|
+
def initialize *return_types
|
9
|
+
@return_complex_types = ComplexType.parse(*return_types.reject(&:nil?))
|
13
10
|
end
|
14
11
|
|
15
12
|
# @return [String]
|
16
13
|
def namespace
|
17
|
-
@namespace ||= ApiMap::TypeMethods.extract_namespace(
|
14
|
+
# @namespace ||= ApiMap::TypeMethods.extract_namespace(return_type)
|
15
|
+
return nil if @return_complex_types.empty?
|
16
|
+
@namespace ||= @return_complex_types.first.namespace
|
18
17
|
end
|
19
18
|
|
20
19
|
# @return [Integer]
|
@@ -86,6 +86,10 @@ module Solargraph
|
|
86
86
|
@parameters ||= get_method_args
|
87
87
|
end
|
88
88
|
|
89
|
+
def parameter_names
|
90
|
+
@parameter_names ||= parameters.map{|p| p.split(/[ =:]/).first}
|
91
|
+
end
|
92
|
+
|
89
93
|
def visibility
|
90
94
|
@visibility ||= (code_object.respond_to?(:visibility) ? code_object.visibility : :public)
|
91
95
|
end
|
@@ -100,14 +104,14 @@ module Solargraph
|
|
100
104
|
def get_method_args
|
101
105
|
return [] unless code_object.kind_of?(YARD::CodeObjects::MethodObject)
|
102
106
|
args = []
|
103
|
-
code_object.parameters.each
|
107
|
+
code_object.parameters.each do |a|
|
104
108
|
p = a[0]
|
105
109
|
unless a[1].nil?
|
106
110
|
p += ' =' unless p.end_with?(':')
|
107
111
|
p += " #{a[1]}"
|
108
112
|
end
|
109
113
|
args.push p
|
110
|
-
|
114
|
+
end
|
111
115
|
args
|
112
116
|
end
|
113
117
|
end
|
data/lib/solargraph/source.rb
CHANGED
@@ -207,7 +207,7 @@ module Solargraph
|
|
207
207
|
end
|
208
208
|
|
209
209
|
# @param updater [Source::Updater]
|
210
|
-
def synchronize updater
|
210
|
+
def synchronize updater, reparse = true
|
211
211
|
raise 'Invalid synchronization' unless updater.filename == filename
|
212
212
|
original_code = @code
|
213
213
|
original_fixed = @fixed
|
@@ -215,6 +215,7 @@ module Solargraph
|
|
215
215
|
@fixed = updater.write(original_code, true)
|
216
216
|
@version = updater.version
|
217
217
|
return if @code == original_code
|
218
|
+
return unless reparse
|
218
219
|
begin
|
219
220
|
parse
|
220
221
|
@fixed = @code
|
@@ -248,6 +249,8 @@ module Solargraph
|
|
248
249
|
@all_pins.select{|pin| pin.location == location}.first
|
249
250
|
end
|
250
251
|
|
252
|
+
# @param line [Integer] A zero-based line number
|
253
|
+
# @param column [Integer] A zero-based column number
|
251
254
|
# @return [Solargraph::Source::Fragment]
|
252
255
|
def fragment_at line, column
|
253
256
|
Fragment.new(self, line, column)
|
@@ -321,8 +324,28 @@ module Solargraph
|
|
321
324
|
end
|
322
325
|
|
323
326
|
def process_parsed node, comments
|
324
|
-
|
325
|
-
|
327
|
+
new_map_data = Mapper.map(filename, code, node, comments)
|
328
|
+
synchronize_mapped *new_map_data
|
329
|
+
end
|
330
|
+
|
331
|
+
def synchronize_mapped new_pins, new_locals, new_requires, new_symbols, new_path_macros, new_domains
|
332
|
+
resync = (
|
333
|
+
@pins.nil? or
|
334
|
+
@locals.nil? or
|
335
|
+
@pins[1..-1] != new_pins[1..-1] or
|
336
|
+
@locals != new_locals
|
337
|
+
# @requires != new_requires or
|
338
|
+
# @path_macros != new_path_macros or
|
339
|
+
# @new_domains != new_domains
|
340
|
+
)
|
341
|
+
@pins = new_pins
|
342
|
+
@locals = new_locals
|
343
|
+
@requires = new_requires
|
344
|
+
@symbols = new_symbols
|
345
|
+
@path_macros = new_path_macros
|
346
|
+
@domains = new_domains
|
347
|
+
# Check for bare minimum change required to synchronize workspaces, etc.
|
348
|
+
@stime = Time.now if resync
|
326
349
|
end
|
327
350
|
|
328
351
|
class << self
|