solargraph 0.32.5 → 0.33.0
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -11
- data/lib/solargraph.rb +1 -2
- data/lib/solargraph/api_map.rb +93 -63
- data/lib/solargraph/api_map/cache.rb +16 -1
- data/lib/solargraph/api_map/source_to_yard.rb +16 -7
- data/lib/solargraph/api_map/store.rb +55 -12
- data/lib/solargraph/complex_type.rb +58 -14
- data/lib/solargraph/complex_type/type_methods.rb +2 -2
- data/lib/solargraph/complex_type/unique_type.rb +33 -4
- data/lib/solargraph/core_fills.rb +40 -12
- data/lib/solargraph/diagnostics.rb +4 -3
- data/lib/solargraph/diagnostics/base.rb +6 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +17 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
- data/lib/solargraph/diagnostics/type_check.rb +51 -0
- data/lib/solargraph/diagnostics/update_errors.rb +1 -0
- data/lib/solargraph/language_server/host.rb +55 -25
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -2
- data/lib/solargraph/language_server/host/dispatch.rb +4 -8
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +4 -2
- data/lib/solargraph/language_server/message/initialize.rb +9 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/code_action.rb +15 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +25 -5
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +4 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +8 -4
- data/lib/solargraph/language_server/transport/adapter.rb +12 -15
- data/lib/solargraph/library.rb +23 -6
- data/lib/solargraph/location.rb +4 -0
- data/lib/solargraph/pin.rb +7 -3
- data/lib/solargraph/pin/attribute.rb +14 -13
- data/lib/solargraph/pin/base.rb +56 -43
- data/lib/solargraph/pin/base_method.rb +41 -18
- data/lib/solargraph/pin/base_variable.rb +17 -15
- data/lib/solargraph/pin/block.rb +22 -4
- data/lib/solargraph/pin/closure.rb +28 -0
- data/lib/solargraph/pin/common.rb +59 -0
- data/lib/solargraph/pin/constant.rb +4 -4
- data/lib/solargraph/pin/conversions.rb +8 -8
- data/lib/solargraph/pin/duck_method.rb +3 -3
- data/lib/solargraph/pin/instance_variable.rb +30 -0
- data/lib/solargraph/pin/keyword.rb +1 -1
- data/lib/solargraph/pin/local_variable.rb +3 -3
- data/lib/solargraph/pin/localized.rb +9 -5
- data/lib/solargraph/pin/method.rb +26 -40
- data/lib/solargraph/pin/method_alias.rb +9 -6
- data/lib/solargraph/pin/namespace.rb +33 -10
- data/lib/solargraph/pin/parameter.rb +150 -0
- data/lib/solargraph/pin/proxy_type.rb +8 -8
- data/lib/solargraph/pin/reference.rb +1 -12
- data/lib/solargraph/pin/reference/override.rb +18 -0
- data/lib/solargraph/pin/reference/require.rb +2 -1
- data/lib/solargraph/pin/singleton.rb +9 -0
- data/lib/solargraph/pin/symbol.rb +9 -4
- data/lib/solargraph/pin/yard_pin/constant.rb +12 -3
- data/lib/solargraph/pin/yard_pin/method.rb +18 -6
- data/lib/solargraph/pin/yard_pin/namespace.rb +13 -1
- data/lib/solargraph/position.rb +1 -1
- data/lib/solargraph/range.rb +4 -0
- data/lib/solargraph/shell.rb +83 -4
- data/lib/solargraph/source.rb +32 -12
- data/lib/solargraph/source/chain.rb +48 -28
- data/lib/solargraph/source/chain/call.rb +37 -38
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/head.rb +2 -8
- data/lib/solargraph/source/chain/instance_variable.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +2 -0
- data/lib/solargraph/source/cursor.rb +59 -24
- data/lib/solargraph/source/node_chainer.rb +0 -2
- data/lib/solargraph/source/node_methods.rb +12 -6
- data/lib/solargraph/source/source_chainer.rb +38 -44
- data/lib/solargraph/source_map.rb +11 -18
- data/lib/solargraph/source_map/clip.rb +13 -15
- data/lib/solargraph/source_map/mapper.rb +37 -26
- data/lib/solargraph/source_map/node_processor.rb +13 -8
- data/lib/solargraph/source_map/node_processor/alias_node.rb +8 -8
- data/lib/solargraph/source_map/node_processor/args_node.rb +10 -16
- data/lib/solargraph/source_map/node_processor/base.rb +47 -4
- data/lib/solargraph/source_map/node_processor/block_node.rb +9 -4
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +7 -2
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +8 -3
- data/lib/solargraph/source_map/node_processor/def_node.rb +45 -38
- data/lib/solargraph/source_map/node_processor/defs_node.rb +16 -6
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +8 -1
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +20 -6
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +10 -4
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +18 -12
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +1 -1
- data/lib/solargraph/source_map/node_processor/resbody_node.rb +30 -0
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +7 -1
- data/lib/solargraph/source_map/node_processor/send_node.rb +102 -52
- data/lib/solargraph/source_map/node_processor/sym_node.rb +4 -1
- data/lib/solargraph/source_map/region.rb +9 -8
- data/lib/solargraph/type_checker.rb +282 -0
- data/lib/solargraph/type_checker/param_def.rb +47 -0
- data/lib/solargraph/type_checker/problem.rb +25 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +1 -1
- data/lib/solargraph/workspace.rb +2 -2
- data/lib/solargraph/workspace/config.rb +0 -8
- data/lib/solargraph/yard_map.rb +25 -69
- data/lib/solargraph/yard_map/core_docs.rb +8 -3
- data/lib/solargraph/yard_map/core_gen.rb +1 -3
- data/lib/solargraph/yard_map/mapper.rb +85 -0
- data/lib/yard-solargraph.rb +2 -0
- metadata +14 -14
- data/lib/solargraph/diagnostics/type_not_defined.rb +0 -108
- data/lib/solargraph/live_map.rb +0 -126
- data/lib/solargraph/live_map/cache.rb +0 -38
- data/lib/solargraph/pin/block_parameter.rb +0 -103
- data/lib/solargraph/pin/method_parameter.rb +0 -40
- data/lib/solargraph/pin/plugin/method.rb +0 -25
- data/lib/solargraph/plugin.rb +0 -8
- data/lib/solargraph/plugin/base.rb +0 -41
- data/lib/solargraph/plugin/canceler.rb +0 -11
- data/lib/solargraph/plugin/process.rb +0 -172
- data/lib/solargraph/plugin/runtime.rb +0 -134
- data/lib/yard-coregen.rb +0 -16
@@ -3,7 +3,10 @@ module Solargraph
|
|
3
3
|
module NodeProcessor
|
4
4
|
class SymNode < Base
|
5
5
|
def process
|
6
|
-
pins.push Solargraph::Pin::Symbol.new(
|
6
|
+
pins.push Solargraph::Pin::Symbol.new(
|
7
|
+
get_node_location(node),
|
8
|
+
":#{node.children[0]}"
|
9
|
+
)
|
7
10
|
end
|
8
11
|
end
|
9
12
|
end
|
@@ -4,8 +4,8 @@ module Solargraph
|
|
4
4
|
# locations in a source.
|
5
5
|
#
|
6
6
|
class Region
|
7
|
-
# @return [
|
8
|
-
attr_reader :
|
7
|
+
# @return [Pin::Closure]
|
8
|
+
attr_reader :closure
|
9
9
|
|
10
10
|
# @return [Symbol]
|
11
11
|
attr_reader :scope
|
@@ -20,10 +20,11 @@ module Solargraph
|
|
20
20
|
# @param namespace [String]
|
21
21
|
# @param scope [Symbol]
|
22
22
|
# @param visibility [Symbol]
|
23
|
-
def initialize source: Solargraph::Source.load_string(''),
|
24
|
-
scope:
|
23
|
+
def initialize source: Solargraph::Source.load_string(''), closure: nil,
|
24
|
+
scope: nil, visibility: :public
|
25
25
|
@source = source
|
26
|
-
@
|
26
|
+
# @closure = closure
|
27
|
+
@closure = closure || Pin::Namespace.new(name: '', location: source.location)
|
27
28
|
@scope = scope
|
28
29
|
@visibility = visibility
|
29
30
|
end
|
@@ -35,14 +36,14 @@ module Solargraph
|
|
35
36
|
|
36
37
|
# Generate a new Region with the provided attribute changes.
|
37
38
|
#
|
38
|
-
# @param
|
39
|
+
# @param closure [Pin::Closure, nil]
|
39
40
|
# @param scope [Symbol, nil]
|
40
41
|
# @param visibility [Symbol, nil]
|
41
42
|
# @return [Region]
|
42
|
-
def update
|
43
|
+
def update closure: nil, scope: nil, visibility: nil
|
43
44
|
Region.new(
|
44
45
|
source: source,
|
45
|
-
|
46
|
+
closure: closure || self.closure,
|
46
47
|
scope: scope || self.scope,
|
47
48
|
visibility: visibility || self.visibility
|
48
49
|
)
|
@@ -0,0 +1,282 @@
|
|
1
|
+
module Solargraph
|
2
|
+
# A static analysis tool for validating data types.
|
3
|
+
#
|
4
|
+
class TypeChecker
|
5
|
+
autoload :Problem, 'solargraph/type_checker/problem'
|
6
|
+
autoload :ParamDef, 'solargraph/type_checker/param_def'
|
7
|
+
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :filename
|
10
|
+
|
11
|
+
# @param filename [String]
|
12
|
+
# @param api_map [ApiMap]
|
13
|
+
def initialize filename, api_map: nil
|
14
|
+
@filename = filename
|
15
|
+
# @todo Smarter directory resolution
|
16
|
+
@api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return type problems indicate that a method does not specify a type in a
|
20
|
+
# `@return` tag or the specified type could not be resolved to a known
|
21
|
+
# type.
|
22
|
+
#
|
23
|
+
# @return [Array<Problem>]
|
24
|
+
def return_type_problems
|
25
|
+
result = []
|
26
|
+
smap = api_map.source_map(filename)
|
27
|
+
pins = smap.pins.select { |pin| pin.is_a?(Solargraph::Pin::BaseMethod) }
|
28
|
+
pins.each { |pin| result.concat check_return_type(pin) }
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
# Param type problems indicate that a method does not specify a type in a
|
33
|
+
# `@param` tag for one or more of its parameters, a `@param` tag is defined
|
34
|
+
# that does not correlate with the method signature, or the specified type
|
35
|
+
# could not be resolved to a known type.
|
36
|
+
#
|
37
|
+
# @return [Array<Problem>]
|
38
|
+
def param_type_problems
|
39
|
+
result = []
|
40
|
+
smap = api_map.source_map(filename)
|
41
|
+
smap.locals.select { |pin| pin.is_a?(Solargraph::Pin::Parameter) }.each do |par|
|
42
|
+
next unless par.closure.is_a?(Solargraph::Pin::Method)
|
43
|
+
result.concat check_param_tags(par.closure)
|
44
|
+
type = par.typify(api_map)
|
45
|
+
pdefs = ParamDef.from(par.closure)
|
46
|
+
if type.undefined?
|
47
|
+
if par.return_type.undefined? && !pdefs.any? { |pd| pd.name == par.name && [:restarg, :kwrestarg].include?(pd.type) }
|
48
|
+
result.push Problem.new(
|
49
|
+
par.location, "#{par.closure.name} has undefined @param type for #{par.name}")
|
50
|
+
elsif !pdefs.any? { |pd| [:restarg, :kwrestarg].include?(pd.type) }
|
51
|
+
result.push Problem.new(par.location, "#{par.closure.name} has unresolved @param type for #{par.name}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
# Strict type problems indicate that a `@return` type or a `@param` type
|
59
|
+
# does not match the type inferred from code analysis; or that an argument
|
60
|
+
# sent to a method does not match the type specified in the corresponding
|
61
|
+
# `@param` tag.
|
62
|
+
#
|
63
|
+
# @return [Array<Problem>]
|
64
|
+
def strict_type_problems
|
65
|
+
result = []
|
66
|
+
smap = api_map.source_map(filename)
|
67
|
+
smap.pins.select { |pin| pin.is_a?(Pin::BaseMethod) }.each do |pin|
|
68
|
+
result.concat confirm_return_type(pin)
|
69
|
+
end
|
70
|
+
return result if smap.source.node.nil?
|
71
|
+
result.concat check_send_args smap.source.node
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
# @return [ApiMap]
|
78
|
+
attr_reader :api_map
|
79
|
+
|
80
|
+
# @param pin [Pin::BaseMethod]
|
81
|
+
# @return [Array<Problem>]
|
82
|
+
def check_param_tags pin
|
83
|
+
return [] if ParamDef.from(pin).map(&:type).include?(:kwrestarg)
|
84
|
+
result = []
|
85
|
+
pin.docstring.tags(:param).each do |par|
|
86
|
+
next if pin.parameter_names.include?(par.name)
|
87
|
+
result.push Problem.new(pin.location, "#{pin.name} has unknown @param #{par.name}")
|
88
|
+
end
|
89
|
+
result
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param pin [Pin::BaseMethod]
|
93
|
+
# @return [Array<Problem>]
|
94
|
+
def check_return_type pin
|
95
|
+
tagged = pin.typify(api_map)
|
96
|
+
if tagged.undefined?
|
97
|
+
if pin.return_type.undefined?
|
98
|
+
probed = pin.probe(api_map)
|
99
|
+
return [Problem.new(pin.location, "#{pin.name} has undefined @return type", probed.to_s)]
|
100
|
+
else
|
101
|
+
return [Problem.new(pin.location, "#{pin.name} has unresolved @return type #{pin.return_type}")]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
[]
|
105
|
+
end
|
106
|
+
|
107
|
+
# @param pin [Solargraph::Pin::Base]
|
108
|
+
# @return [Array<Problem>]
|
109
|
+
def confirm_return_type pin
|
110
|
+
tagged = pin.typify(api_map)
|
111
|
+
return [] if tagged.void? || tagged.undefined? || pin.is_a?(Pin::Attribute)
|
112
|
+
probed = pin.probe(api_map)
|
113
|
+
return [] if probed.undefined?
|
114
|
+
if tagged.to_s != probed.to_s
|
115
|
+
if probed.name == 'Array' && probed.subtypes.empty?
|
116
|
+
return [] if tagged.name == 'Array'
|
117
|
+
end
|
118
|
+
if probed.name == 'Hash' && probed.value_types.empty?
|
119
|
+
return [] if tagged.name == 'Hash'
|
120
|
+
end
|
121
|
+
all = true
|
122
|
+
probed.each do |pt|
|
123
|
+
tagged.each do |tt|
|
124
|
+
if pt.name == tt.name && !api_map.super_and_sub?(tt.namespace, pt.namespace) && !tagged.map(&:namespace).include?(pt.namespace)
|
125
|
+
all = false
|
126
|
+
break
|
127
|
+
elsif pt.name == tt.name && ['Array', 'Class', 'Module'].include?(pt.name)
|
128
|
+
if !(tt.subtypes.any? { |ttx| pt.subtypes.any? { |ptx| api_map.super_and_sub?(ttx.to_s, ptx.to_s) } })
|
129
|
+
all = false
|
130
|
+
break
|
131
|
+
end
|
132
|
+
elsif pt.name == tt.name && pt.name == 'Hash'
|
133
|
+
if !(tt.key_types.empty? && !pt.key_types.empty?) && !(tt.key_types.any? { |ttx| pt.key_types.any? { |ptx| api_map.super_and_sub?(ttx.to_s, ptx.to_s) } })
|
134
|
+
if !(tt.value_types.empty? && !pt.value_types.empty?) && !(tt.value_types.any? { |ttx| pt.value_types.any? { |ptx| api_map.super_and_sub?(ttx.to_s, ptx.to_s) } })
|
135
|
+
all = false
|
136
|
+
break
|
137
|
+
end
|
138
|
+
end
|
139
|
+
elsif pt.name != tt.name && !api_map.super_and_sub?(tt.to_s, pt.to_s) && !tagged.map(&:to_s).include?(pt.to_s)
|
140
|
+
all = false
|
141
|
+
break
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
return [] if all
|
146
|
+
return [Problem.new(pin.location, "@return type `#{tagged.to_s}` does not match inferred type `#{probed.to_s}`", probed.to_s)]
|
147
|
+
end
|
148
|
+
[]
|
149
|
+
end
|
150
|
+
|
151
|
+
def check_send_args node, skip_send = false
|
152
|
+
result = []
|
153
|
+
if node.type == :send
|
154
|
+
smap = api_map.source_map(filename)
|
155
|
+
locals = smap.locals_at(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)))
|
156
|
+
block = smap.locate_block_pin(node.loc.line, node.loc.column)
|
157
|
+
chain = Solargraph::Source::NodeChainer.chain(node, filename)
|
158
|
+
pins = chain.define(api_map, block, locals).select { |pin| pin.is_a?(Pin::BaseMethod ) }
|
159
|
+
if pins.empty?
|
160
|
+
if !more_signature?(node)
|
161
|
+
base = chain.base.define(api_map, block, locals).first
|
162
|
+
if base.nil? || report_location?(base.location)
|
163
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Unresolved method signature #{chain.links.map(&:word).join('.')}")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
else
|
167
|
+
pin = pins.first
|
168
|
+
ptypes = ParamDef.from(pin)
|
169
|
+
params = param_tags_from(pin)
|
170
|
+
cursor = 0
|
171
|
+
curtype = nil
|
172
|
+
node.children[2..-1].each_with_index do |arg, index|
|
173
|
+
curtype = ptypes[cursor] if curtype.nil? || curtype == :arg
|
174
|
+
if curtype.nil?
|
175
|
+
if pin.parameters[index].nil?
|
176
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Not enough arguments sent to #{pin.path}")
|
177
|
+
break
|
178
|
+
end
|
179
|
+
else
|
180
|
+
# @todo Break here? Not sure about that
|
181
|
+
break if curtype.type == :restarg || curtype.type == :kwrestarg
|
182
|
+
if arg.is_a?(Parser::AST::Node) && arg.type == :hash
|
183
|
+
arg.children.each do |pair|
|
184
|
+
sym = pair.children[0].children[0].to_s
|
185
|
+
partype = params[pin.parameter_names[index]]
|
186
|
+
if partype.nil?
|
187
|
+
if report_location?(pin.location)
|
188
|
+
unless ptypes.map(&:type).include?(:kwrestarg)
|
189
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "No @param type for #{pin.parameter_names[index]} in #{pin.path}")
|
190
|
+
end
|
191
|
+
end
|
192
|
+
else
|
193
|
+
chain = Solargraph::Source::NodeChainer.chain(pair.children[1], filename)
|
194
|
+
argtype = chain.infer(api_map, block, locals)
|
195
|
+
if argtype.tag != partype.tag
|
196
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong parameter type for #{pin.path}: #{pin.parameter_names[index]} expected #{partype.tag}, received #{argtype.tag}")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
elsif arg.is_a?(Parser::AST::Node) && arg.type == :splat
|
201
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Can't handle splat in #{pin.parameter_names[index]} #{pin.path}")
|
202
|
+
break if curtype != :arg && ptypes.map(&:type).include?(:restarg)
|
203
|
+
else
|
204
|
+
partype = params[pin.parameter_names[index]]
|
205
|
+
if partype.nil?
|
206
|
+
if report_location?(pin.location)
|
207
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "No @param type for #{pin.parameter_names[index]} in #{pin.path}")
|
208
|
+
end
|
209
|
+
else
|
210
|
+
arg = chain.links.last.arguments[index]
|
211
|
+
if arg.nil?
|
212
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong number of arguments to #{pin.path}")
|
213
|
+
else
|
214
|
+
argtype = arg.infer(api_map, block, locals)
|
215
|
+
if argtype.tag != partype.tag
|
216
|
+
result.push Problem.new(Solargraph::Location.new(filename, Solargraph::Range.from_node(node)), "Wrong parameter type for #{pin.path}: #{pin.parameter_names[index]} expected #{partype.tag}, received #{argtype.tag}")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
cursor += 1 if curtype == :arg
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
node.children.each do |child|
|
227
|
+
next unless child.is_a?(Parser::AST::Node)
|
228
|
+
next if child.type == :send && skip_send
|
229
|
+
result.concat check_send_args(child)
|
230
|
+
end
|
231
|
+
result
|
232
|
+
end
|
233
|
+
|
234
|
+
def param_tags_from pin
|
235
|
+
# @todo Look for see references
|
236
|
+
# and dig through all the pins
|
237
|
+
return {} if pin.nil?
|
238
|
+
tags = pin.docstring.tags(:param)
|
239
|
+
result = {}
|
240
|
+
tags.each do |tag|
|
241
|
+
result[tag.name] = ComplexType::UNDEFINED
|
242
|
+
result[tag.name] = ComplexType.try_parse(*tag.types).qualify(api_map, pin.context.namespace)
|
243
|
+
end
|
244
|
+
result
|
245
|
+
end
|
246
|
+
|
247
|
+
# @param location [Location, nil]
|
248
|
+
def report_location? location
|
249
|
+
return false if location.nil?
|
250
|
+
filename == location.filename || api_map.bundled?(location.filename)
|
251
|
+
end
|
252
|
+
|
253
|
+
def more_signature? node
|
254
|
+
node.children.any? do |child|
|
255
|
+
child.is_a?(Parser::AST::Node) && (
|
256
|
+
child.type == :send || (child.type == :block && more_signature?(child))
|
257
|
+
)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
class << self
|
262
|
+
# @param filename [String]
|
263
|
+
# @return [self]
|
264
|
+
def load filename
|
265
|
+
source = Solargraph::Source.load(filename)
|
266
|
+
api_map = Solargraph::ApiMap.new
|
267
|
+
api_map.map(source)
|
268
|
+
new(filename, api_map: api_map)
|
269
|
+
end
|
270
|
+
|
271
|
+
# @param code [String]
|
272
|
+
# @param filename [String, nil]
|
273
|
+
# @return [self]
|
274
|
+
def load_string code, filename = nil
|
275
|
+
source = Solargraph::Source.load_string(code, filename)
|
276
|
+
api_map = Solargraph::ApiMap.new
|
277
|
+
api_map.map(source)
|
278
|
+
new(filename, api_map: api_map)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class TypeChecker
|
3
|
+
# Data about a method parameter definition. This is the information from
|
4
|
+
# the args list in the def call, not the `@param` tags.
|
5
|
+
#
|
6
|
+
class ParamDef
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
# @return [Symbol]
|
11
|
+
attr_reader :type
|
12
|
+
|
13
|
+
def initialize name, type
|
14
|
+
@name = name
|
15
|
+
@type = type
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# Get an array of ParamDefs from a method pin.
|
20
|
+
#
|
21
|
+
# @param pin [Solargraph::Pin::BaseMethod]
|
22
|
+
# @return [Array<ParamDef>]
|
23
|
+
def from pin
|
24
|
+
result = []
|
25
|
+
pin.parameters.each_with_index do |full, index|
|
26
|
+
result.push ParamDef.new(pin.parameter_names[index], arg_type(full))
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @param string [String]
|
34
|
+
# @return [Symbol]
|
35
|
+
def arg_type string
|
36
|
+
return :kwrestarg if string.start_with?('**')
|
37
|
+
return :restarg if string.start_with?('*')
|
38
|
+
return :optarg if string.include?('=')
|
39
|
+
return :kwoptarg if string.end_with?(':')
|
40
|
+
return :kwarg if string =~ /^[a-z0-9_]*?:/
|
41
|
+
:arg
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class TypeChecker
|
3
|
+
# A problem reported by TypeChecker.
|
4
|
+
#
|
5
|
+
class Problem
|
6
|
+
# @return [Solargraph::Location]
|
7
|
+
attr_reader :location
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :message
|
11
|
+
|
12
|
+
# @return [String, nil]
|
13
|
+
attr_reader :suggestion
|
14
|
+
|
15
|
+
# @param location [Solargraph::Location]
|
16
|
+
# @param message [String]
|
17
|
+
# @param suggestion [String, nil]
|
18
|
+
def initialize location, message, suggestion = nil
|
19
|
+
@location = location
|
20
|
+
@message = message
|
21
|
+
@suggestion = suggestion
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/solargraph/version.rb
CHANGED
data/lib/solargraph/workspace.rb
CHANGED
@@ -126,7 +126,7 @@ module Solargraph
|
|
126
126
|
|
127
127
|
private
|
128
128
|
|
129
|
-
# @return [Hash
|
129
|
+
# @return [Hash{String => Solargraph::Source}]
|
130
130
|
def source_hash
|
131
131
|
@source_hash ||= {}
|
132
132
|
end
|
@@ -152,7 +152,7 @@ module Solargraph
|
|
152
152
|
result = []
|
153
153
|
gemspecs.each do |file|
|
154
154
|
base = File.dirname(file)
|
155
|
-
#
|
155
|
+
# HACK: Evaluating gemspec files violates the goal of not running
|
156
156
|
# workspace code, but this is how Gem::Specification.load does it
|
157
157
|
# anyway.
|
158
158
|
begin
|
@@ -34,7 +34,6 @@ module Solargraph
|
|
34
34
|
@raw_data['require'] ||= []
|
35
35
|
@raw_data['domains'] ||= []
|
36
36
|
@raw_data['reporters'] ||= %w[rubocop require_not_found]
|
37
|
-
@raw_data['plugins'] ||= []
|
38
37
|
@raw_data['require_paths'] ||= []
|
39
38
|
@raw_data['max_files'] ||= MAX_FILES
|
40
39
|
included
|
@@ -88,13 +87,6 @@ module Solargraph
|
|
88
87
|
raw_data['require_paths'] || []
|
89
88
|
end
|
90
89
|
|
91
|
-
# An array of Solargraph plugins to install.
|
92
|
-
#
|
93
|
-
# @return [Array<String>]
|
94
|
-
def plugins
|
95
|
-
raw_data['plugins']
|
96
|
-
end
|
97
|
-
|
98
90
|
# An array of reporters to use for diagnostics.
|
99
91
|
#
|
100
92
|
# @return [Array<String>]
|