Module: Rubocop::Cop::VariableInspector
Overview
This module provides a way to track local variables and scopes of Ruby.
This is intended to be used as mix-in, and the user class may override
some of hook methods.
Defined Under Namespace
Classes: NodeScanner, Scope, VariableEntry, VariableTable
Constant Summary
collapse
- VARIABLE_ASSIGNMENT_TYPES =
[:lvasgn, :match_with_lvasgn].freeze
- ARGUMENT_DECLARATION_TYPES =
[
:arg, :optarg, :restarg, :blockarg,
:kwarg, :kwoptarg, :kwrestarg,
:shadowarg
].freeze
- VARIABLE_DECLARATION_TYPES =
(VARIABLE_ASSIGNMENT_TYPES + ARGUMENT_DECLARATION_TYPES).freeze
- VARIABLE_USE_TYPES =
[:lvar].freeze
- SCOPE_TYPES =
[:module, :class, :sclass, :def, :defs, :block].freeze
Instance Method Summary
collapse
Instance Method Details
#after_declaring_variable(variable_entry) ⇒ Object
295
296
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 295
def after_declaring_variable(variable_entry)
end
|
#after_entering_scope(scope) ⇒ Object
283
284
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 283
def after_entering_scope(scope)
end
|
#after_leaving_scope(scope) ⇒ Object
289
290
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 289
def after_leaving_scope(scope)
end
|
#before_declaring_variable(variable_entry) ⇒ Object
292
293
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 292
def before_declaring_variable(variable_entry)
end
|
#before_entering_scope(scope) ⇒ Object
280
281
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 280
def before_entering_scope(scope)
end
|
#before_leaving_scope(scope) ⇒ Object
286
287
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 286
def before_leaving_scope(scope)
end
|
#inspect_variables(root_node) ⇒ Object
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 157
def inspect_variables(root_node)
return unless root_node
unless root_node.type == :begin
root_node = Parser::AST::Node.new(:begin, [root_node])
end
inspect_variables_in_scope(root_node)
end
|
#inspect_variables_in_scope(scope_node) ⇒ Object
This is called for each scope recursively.
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 169
def inspect_variables_in_scope(scope_node)
variable_table.push_scope(scope_node)
NodeScanner.scan_nodes_in_scope(scope_node) do |node, index|
if scope_node.type == :block && index == 0 && node.type == :send
throw :skip_children
elsif [:sclass, :defs].include?(scope_node.type) && index == 0
throw :skip_children
end
process_node(node)
end
variable_table.pop_scope
end
|
#process_named_captures(match_with_lvasgn_node) ⇒ Object
266
267
268
269
270
271
272
273
274
275
276
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 266
def process_named_captures(match_with_lvasgn_node)
regexp_string = match_with_lvasgn_node.children[0]
.children[0]
.children[0]
regexp = Regexp.new(regexp_string)
variable_names = regexp.named_captures.keys
variable_names.each do |name|
process_variable_assignment(match_with_lvasgn_node, name)
end
end
|
#process_node(node) ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 188
def process_node(node)
case node.type
when *ARGUMENT_DECLARATION_TYPES
variable_table.add_variable_entry(node)
when :lvasgn
variable_name = node.children.first
process_variable_assignment(node, variable_name)
when :match_with_lvasgn
process_named_captures(node)
when *VARIABLE_USE_TYPES
variable_name = node.children.first
variable_entry = variable_table.find_variable_entry(variable_name)
unless variable_entry
fail "Using undeclared local variable \"#{variable_name}\" " +
"at #{node.loc.expression}, #{node.inspect}"
end
variable_entry.used = true
when :block
NodeScanner.scan_nodes_in_scope(node.children.first) do |n|
process_node(n)
end
inspect_variables_in_scope(node)
when :sclass, :defs
process_node(node.children.first)
inspect_variables_in_scope(node)
when *SCOPE_TYPES
inspect_variables_in_scope(node)
end
end
|
#process_variable_assignment(node, name) ⇒ Object
257
258
259
260
261
262
263
264
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 257
def process_variable_assignment(node, name)
entry = variable_table.find_variable_entry(name)
if entry
entry.used = true
else
variable_table.add_variable_entry(node, name)
end
end
|
#variable_table ⇒ Object
152
153
154
|
# File 'lib/rubocop/cop/variable_inspector.rb', line 152
def variable_table
@variable_table ||= VariableTable.new(self)
end
|