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
  dup
  eval
  exec
  exit
  fail
  fork
  gets
  global_variables
  instance_eval
  load
  loop
  method
  module_eval
  open
  readline
  readlines
  redo
  remove_const
  require
  retry
  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



108
109
110
# File 'lib/ruby_cop/policy.rb', line 108

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



112
113
114
# File 'lib/ruby_cop/policy.rb', line 112

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

#visit_ChainedBlock(node) ⇒ Object



116
117
118
# File 'lib/ruby_cop/policy.rb', line 116

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



132
133
134
# File 'lib/ruby_cop/policy.rb', line 132

def visit_Char(node)
  true
end

#visit_Class(node) ⇒ Object



120
121
122
# File 'lib/ruby_cop/policy.rb', line 120

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

#visit_ClassVariable(node) ⇒ Object



124
125
126
# File 'lib/ruby_cop/policy.rb', line 124

def visit_ClassVariable(node)
  false # never allowed
end

#visit_ClassVariableAssignment(node) ⇒ Object



128
129
130
# File 'lib/ruby_cop/policy.rb', line 128

def visit_ClassVariableAssignment(node)
  false # never allowed
end

#visit_Constant(node) ⇒ Object



136
137
138
# File 'lib/ruby_cop/policy.rb', line 136

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

#visit_ConstantAssignment(node) ⇒ Object



140
141
142
# File 'lib/ruby_cop/policy.rb', line 140

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

#visit_Defined(node) ⇒ Object



144
145
146
# File 'lib/ruby_cop/policy.rb', line 144

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

#visit_Else(node) ⇒ Object



148
149
150
# File 'lib/ruby_cop/policy.rb', line 148

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

#visit_ExecutableString(node) ⇒ Object



152
153
154
# File 'lib/ruby_cop/policy.rb', line 152

def visit_ExecutableString(node)
  false # never allowed
end

#visit_Float(node) ⇒ Object



156
157
158
# File 'lib/ruby_cop/policy.rb', line 156

def visit_Float(node)
  true
end

#visit_For(node) ⇒ Object



160
161
162
# File 'lib/ruby_cop/policy.rb', line 160

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

#visit_GlobalVariable(node) ⇒ Object



164
165
166
# File 'lib/ruby_cop/policy.rb', line 164

def visit_GlobalVariable(node)
  false # never allowed
end

#visit_GlobalVariableAssignment(node) ⇒ Object



168
169
170
# File 'lib/ruby_cop/policy.rb', line 168

def visit_GlobalVariableAssignment(node)
  false # never allowed
end

#visit_Hash(node) ⇒ Object



172
173
174
# File 'lib/ruby_cop/policy.rb', line 172

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

#visit_Identifier(node) ⇒ Object



176
177
178
# File 'lib/ruby_cop/policy.rb', line 176

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

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



180
181
182
# File 'lib/ruby_cop/policy.rb', line 180

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



185
186
187
# File 'lib/ruby_cop/policy.rb', line 185

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

#visit_IfOp(node) ⇒ Object



190
191
192
# File 'lib/ruby_cop/policy.rb', line 190

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

#visit_InstanceVariable(node) ⇒ Object



194
195
196
# File 'lib/ruby_cop/policy.rb', line 194

def visit_InstanceVariable(node)
  true
end

#visit_InstanceVariableAssignment(node) ⇒ Object



198
199
200
# File 'lib/ruby_cop/policy.rb', line 198

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

#visit_Integer(node) ⇒ Object



202
203
204
# File 'lib/ruby_cop/policy.rb', line 202

def visit_Integer(node)
  true
end

#visit_Keyword(node) ⇒ Object



213
214
215
# File 'lib/ruby_cop/policy.rb', line 213

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

#visit_Label(node) ⇒ Object



217
218
219
# File 'lib/ruby_cop/policy.rb', line 217

def visit_Label(node)
  true
end

#visit_LocalVariableAssignment(node) ⇒ Object



221
222
223
# File 'lib/ruby_cop/policy.rb', line 221

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

#visit_Method(node) ⇒ Object



225
226
227
# File 'lib/ruby_cop/policy.rb', line 225

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

#visit_Module(node) ⇒ Object



229
230
231
# File 'lib/ruby_cop/policy.rb', line 229

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

#visit_MultiAssignment(node) ⇒ Object



233
234
235
# File 'lib/ruby_cop/policy.rb', line 233

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

#visit_MultiAssignmentList(node) ⇒ Object



237
238
239
# File 'lib/ruby_cop/policy.rb', line 237

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

#visit_Params(node) ⇒ Object



241
242
243
# File 'lib/ruby_cop/policy.rb', line 241

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

#visit_Program(node) ⇒ Object



245
246
247
# File 'lib/ruby_cop/policy.rb', line 245

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

#visit_Range(node) ⇒ Object



249
250
251
# File 'lib/ruby_cop/policy.rb', line 249

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

#visit_RescueMod(node) ⇒ Object



253
254
255
# File 'lib/ruby_cop/policy.rb', line 253

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

#visit_RescueParams(node) ⇒ Object



257
258
259
# File 'lib/ruby_cop/policy.rb', line 257

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

#visit_SingletonClass(node) ⇒ Object



261
262
263
# File 'lib/ruby_cop/policy.rb', line 261

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

#visit_SplatArg(node) ⇒ Object



265
266
267
# File 'lib/ruby_cop/policy.rb', line 265

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

#visit_Statements(node) ⇒ Object



269
270
271
# File 'lib/ruby_cop/policy.rb', line 269

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

#visit_String(node) ⇒ Object



273
274
275
276
# File 'lib/ruby_cop/policy.rb', line 273

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



278
279
280
# File 'lib/ruby_cop/policy.rb', line 278

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

#visit_Symbol(node) ⇒ Object



282
283
284
# File 'lib/ruby_cop/policy.rb', line 282

def visit_Symbol(node)
  true
end

#visit_Unary(node) ⇒ Object



286
287
288
# File 'lib/ruby_cop/policy.rb', line 286

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

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



290
291
292
# File 'lib/ruby_cop/policy.rb', line 290

def visit_Until(node)
  false # never allowed
end

#visit_When(node) ⇒ Object



295
296
297
# File 'lib/ruby_cop/policy.rb', line 295

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

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



299
300
301
# File 'lib/ruby_cop/policy.rb', line 299

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