Class: RubyCop::Policy

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_cop/policy.rb

Overview

Visitor class for Ruby::Node subclasses. Determines whether the node is safe according to our rules.

Constant Summary collapse

CALL_BLACKLIST =
%w[
  abort
  alias_method
  at_exit
  autoload
  binding
  callcc
  caller
  class_eval
  const_get
  const_set
  eval
  exec
  exit
  fail
  fork
  gets
  global_variables
  instance_eval
  load
  loop
  method
  module_eval
  open
  readline
  readlines
  redo
  remove_const
  require
  send
  set_trace_func
  sleep
  spawn
  srand
  syscall
  system
  trap
  undef
  __callee__
  __method__
].to_set.freeze
KEYWORD_WHITELIST =
%w[
  false
  nil
  self
  true
].to_set.freeze

Instance Method Summary collapse

Constructor Details

#initializePolicy

Returns a new instance of Policy.



7
8
9
10
# File 'lib/ruby_cop/policy.rb', line 7

def initialize
  @const_list = GrayList.new
  initialize_const_blacklist
end

Instance Method Details

#blacklist_const(const) ⇒ Object



16
17
18
# File 'lib/ruby_cop/policy.rb', line 16

def blacklist_const(const)
  @const_list.blacklist(const)
end

#const_allowed?(const) ⇒ Boolean

Returns:

  • (Boolean)


20
21
22
# File 'lib/ruby_cop/policy.rb', line 20

def const_allowed?(const)
  @const_list.allow?(const)
end

#inspectObject



12
13
14
# File 'lib/ruby_cop/policy.rb', line 12

def inspect
  '#<%s:0x%x>' % [self.class.name, object_id]
end

#visit(node) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ruby_cop/policy.rb', line 28

def visit(node)
  klass = node.class.ancestors.detect do |ancestor|
    respond_to?("visit_#{ancestor.name.split('::').last}")
  end
  if klass
    send("visit_#{klass.name.split('::').last}", node)
  else
    warn "unhandled node type: #{node.inspect}:#{node.class.name}"
    true
  end
end

#visit_Alias(node) ⇒ Object



40
41
42
# File 'lib/ruby_cop/policy.rb', line 40

def visit_Alias(node)
  false # never allowed
end

#visit_Args(node) ⇒ Object



44
45
46
# File 'lib/ruby_cop/policy.rb', line 44

def visit_Args(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Array(node) ⇒ Object



48
49
50
# File 'lib/ruby_cop/policy.rb', line 48

def visit_Array(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Assoc(node) ⇒ Object



52
53
54
# File 'lib/ruby_cop/policy.rb', line 52

def visit_Assoc(node)
  visit(node.key) && visit(node.value)
end

#visit_Binary(node) ⇒ Object



56
57
58
# File 'lib/ruby_cop/policy.rb', line 56

def visit_Binary(node)
  visit(node.lvalue) && visit(node.rvalue)
end

#visit_Block(node) ⇒ Object



60
61
62
# File 'lib/ruby_cop/policy.rb', line 60

def visit_Block(node)
  (node.params.nil? || visit(node.params)) && node.elements.all? { |e| visit(e) }
end

#visit_Call(node) ⇒ Object



106
107
108
# File 'lib/ruby_cop/policy.rb', line 106

def visit_Call(node)
  !CALL_BLACKLIST.include?(node.identifier.token.to_s) && [node.target, node.arguments, node.block].compact.all? { |e| visit(e) }
end

#visit_Case(node) ⇒ Object



110
111
112
# File 'lib/ruby_cop/policy.rb', line 110

def visit_Case(node)
  visit(node.expression) && visit(node.block)
end

#visit_ChainedBlock(node) ⇒ Object



114
115
116
# File 'lib/ruby_cop/policy.rb', line 114

def visit_ChainedBlock(node)
  node.elements.all? { |e| visit(e) } && node.blocks.all? { |e| visit(e) } && (node.params.nil? || visit(node.params))
end

#visit_Char(node) ⇒ Object



130
131
132
# File 'lib/ruby_cop/policy.rb', line 130

def visit_Char(node)
  true
end

#visit_Class(node) ⇒ Object



118
119
120
# File 'lib/ruby_cop/policy.rb', line 118

def visit_Class(node)
  visit(node.const) && (node.superclass.nil? || visit(node.superclass)) && visit(node.body)
end

#visit_ClassVariable(node) ⇒ Object



122
123
124
# File 'lib/ruby_cop/policy.rb', line 122

def visit_ClassVariable(node)
  false # never allowed
end

#visit_ClassVariableAssignment(node) ⇒ Object



126
127
128
# File 'lib/ruby_cop/policy.rb', line 126

def visit_ClassVariableAssignment(node)
  false # never allowed
end

#visit_Constant(node) ⇒ Object



134
135
136
# File 'lib/ruby_cop/policy.rb', line 134

def visit_Constant(node)
  const_allowed?(node.token)
end

#visit_ConstantAssignment(node) ⇒ Object



138
139
140
# File 'lib/ruby_cop/policy.rb', line 138

def visit_ConstantAssignment(node)
  visit(node.lvalue) && visit(node.rvalue)
end

#visit_Defined(node) ⇒ Object



142
143
144
# File 'lib/ruby_cop/policy.rb', line 142

def visit_Defined(node)
  false # never allowed (though it's probably safe)
end

#visit_Else(node) ⇒ Object



146
147
148
# File 'lib/ruby_cop/policy.rb', line 146

def visit_Else(node)
  node.elements.all? { |e| visit(e) }
end

#visit_ExecutableString(node) ⇒ Object



150
151
152
# File 'lib/ruby_cop/policy.rb', line 150

def visit_ExecutableString(node)
  false # never allowed
end

#visit_Float(node) ⇒ Object



154
155
156
# File 'lib/ruby_cop/policy.rb', line 154

def visit_Float(node)
  true
end

#visit_For(node) ⇒ Object



158
159
160
# File 'lib/ruby_cop/policy.rb', line 158

def visit_For(node)
  visit(node.variable) && visit(node.range) && visit(node.statements)
end

#visit_GlobalVariable(node) ⇒ Object



162
163
164
# File 'lib/ruby_cop/policy.rb', line 162

def visit_GlobalVariable(node)
  false # never allowed
end

#visit_GlobalVariableAssignment(node) ⇒ Object



166
167
168
# File 'lib/ruby_cop/policy.rb', line 166

def visit_GlobalVariableAssignment(node)
  false # never allowed
end

#visit_Hash(node) ⇒ Object



170
171
172
# File 'lib/ruby_cop/policy.rb', line 170

def visit_Hash(node)
  node.assocs.nil? || node.assocs.all? { |e| visit(e) }
end

#visit_Identifier(node) ⇒ Object



174
175
176
# File 'lib/ruby_cop/policy.rb', line 174

def visit_Identifier(node)
  !CALL_BLACKLIST.include?(node.token)
end

#visit_If(node) ⇒ Object Also known as: visit_Unless



178
179
180
# File 'lib/ruby_cop/policy.rb', line 178

def visit_If(node)
  visit(node.expression) && node.elements.all? { |e| visit(e) } && node.blocks.all? { |e| visit(e) }
end

#visit_IfMod(node) ⇒ Object Also known as: visit_UnlessMod



183
184
185
# File 'lib/ruby_cop/policy.rb', line 183

def visit_IfMod(node)
  visit(node.expression) && node.elements.all? { |e| visit(e) }
end

#visit_IfOp(node) ⇒ Object



188
189
190
# File 'lib/ruby_cop/policy.rb', line 188

def visit_IfOp(node)
  visit(node.condition) && visit(node.then_part) && visit(node.else_part)
end

#visit_InstanceVariable(node) ⇒ Object



192
193
194
# File 'lib/ruby_cop/policy.rb', line 192

def visit_InstanceVariable(node)
  true
end

#visit_InstanceVariableAssignment(node) ⇒ Object



196
197
198
# File 'lib/ruby_cop/policy.rb', line 196

def visit_InstanceVariableAssignment(node)
  visit(node.rvalue)
end

#visit_Integer(node) ⇒ Object



200
201
202
# File 'lib/ruby_cop/policy.rb', line 200

def visit_Integer(node)
  true
end

#visit_Keyword(node) ⇒ Object



211
212
213
# File 'lib/ruby_cop/policy.rb', line 211

def visit_Keyword(node)
  KEYWORD_WHITELIST.include?(node.token)
end

#visit_Label(node) ⇒ Object



215
216
217
# File 'lib/ruby_cop/policy.rb', line 215

def visit_Label(node)
  true
end

#visit_LocalVariableAssignment(node) ⇒ Object



219
220
221
# File 'lib/ruby_cop/policy.rb', line 219

def visit_LocalVariableAssignment(node)
  visit(node.rvalue)
end

#visit_Method(node) ⇒ Object



223
224
225
# File 'lib/ruby_cop/policy.rb', line 223

def visit_Method(node)
  [node.target, node.params, node.body].compact.all? { |e| visit(e) }
end

#visit_Module(node) ⇒ Object



227
228
229
# File 'lib/ruby_cop/policy.rb', line 227

def visit_Module(node)
  visit(node.const) && visit(node.body)
end

#visit_MultiAssignment(node) ⇒ Object



231
232
233
# File 'lib/ruby_cop/policy.rb', line 231

def visit_MultiAssignment(node)
  visit(node.lvalue) && visit(node.rvalue)
end

#visit_MultiAssignmentList(node) ⇒ Object



235
236
237
# File 'lib/ruby_cop/policy.rb', line 235

def visit_MultiAssignmentList(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Params(node) ⇒ Object



239
240
241
# File 'lib/ruby_cop/policy.rb', line 239

def visit_Params(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Program(node) ⇒ Object



243
244
245
# File 'lib/ruby_cop/policy.rb', line 243

def visit_Program(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Range(node) ⇒ Object



247
248
249
# File 'lib/ruby_cop/policy.rb', line 247

def visit_Range(node)
  visit(node.min) && visit(node.max)
end

#visit_RescueMod(node) ⇒ Object



251
252
253
# File 'lib/ruby_cop/policy.rb', line 251

def visit_RescueMod(node)
  node.elements.all? { |e| visit(e) } && visit(node.expression)
end

#visit_RescueParams(node) ⇒ Object



255
256
257
# File 'lib/ruby_cop/policy.rb', line 255

def visit_RescueParams(node)
  node.elements.all? { |e| visit(e) }
end

#visit_SingletonClass(node) ⇒ Object



259
260
261
# File 'lib/ruby_cop/policy.rb', line 259

def visit_SingletonClass(node)
  visit(node.superclass) && visit(node.body)
end

#visit_SplatArg(node) ⇒ Object



263
264
265
# File 'lib/ruby_cop/policy.rb', line 263

def visit_SplatArg(node)
  visit(node.arg)
end

#visit_Statements(node) ⇒ Object



267
268
269
# File 'lib/ruby_cop/policy.rb', line 267

def visit_Statements(node)
  node.elements.all? { |e| visit(e) }
end

#visit_String(node) ⇒ Object



271
272
273
274
# File 'lib/ruby_cop/policy.rb', line 271

def visit_String(node)
  # embedded strings can have statements in them, so check those
  node.elements.reject { |e| e.is_a?(::String) }.all? { |e| visit(e) }
end

#visit_StringConcat(node) ⇒ Object



276
277
278
# File 'lib/ruby_cop/policy.rb', line 276

def visit_StringConcat(node)
  node.elements.all? { |e| visit(e) }
end

#visit_Symbol(node) ⇒ Object



280
281
282
# File 'lib/ruby_cop/policy.rb', line 280

def visit_Symbol(node)
  true
end

#visit_Unary(node) ⇒ Object



284
285
286
# File 'lib/ruby_cop/policy.rb', line 284

def visit_Unary(node)
  visit(node.operand)
end

#visit_Until(node) ⇒ Object Also known as: visit_UntilMod



288
289
290
# File 'lib/ruby_cop/policy.rb', line 288

def visit_Until(node)
  false # never allowed
end

#visit_When(node) ⇒ Object



293
294
295
# File 'lib/ruby_cop/policy.rb', line 293

def visit_When(node)
  visit(node.expression) && node.elements.all? { |e| visit(e) }
end

#visit_While(node) ⇒ Object Also known as: visit_WhileMod



297
298
299
# File 'lib/ruby_cop/policy.rb', line 297

def visit_While(node)
  false # never allowed
end

#whitelist_const(const) ⇒ Object



24
25
26
# File 'lib/ruby_cop/policy.rb', line 24

def whitelist_const(const)
  @const_list.whitelist(const)
end