Module: Niceness

Included in:
ZombieKillerRewriter
Defined in:
lib/zombie_killer/niceness.rb

Overview

Niceness of a node means that it cannot be nil.

Note that the module depends on the includer to provide #scope (for #nice_variable)

Constant Summary collapse

NICE_LITERAL_NODE_TYPES =

Literals are nice, except the nil literal.

[
  :self,
  :false, :true,
  :int, :float,
  :str, :sym, :regexp,
  :array, :hash, :pair, :irange, # may contain nils but they are not nil
  :dstr,                      # "String #{interpolation}" mixes :str, :begin
  :dsym                       # :"#{foo}"
].to_set
NICE_GLOBAL_METHODS =

Methods that preserve niceness if all their arguments are nice These are global, called with a nil receiver

{
  # message, number of arguments
  :_ => 1,
}.freeze
NICE_OPERATORS =
{
  # message, number of arguments (other than receiver)
  :+ => 1,
}.freeze

Instance Method Summary collapse

Instance Method Details

#nice(node) ⇒ Object



19
20
21
22
# File 'lib/zombie_killer/niceness.rb', line 19

def nice(node)
  nice_literal(node) || nice_variable(node) || nice_send(node) ||
    nice_begin(node)
end

#nice_begin(node) ⇒ Object



57
58
59
# File 'lib/zombie_killer/niceness.rb', line 57

def nice_begin(node)
  node.type == :begin && nice(node.children.last)
end

#nice_literal(node) ⇒ Object



24
25
26
# File 'lib/zombie_killer/niceness.rb', line 24

def nice_literal(node)
  NICE_LITERAL_NODE_TYPES.include? node.type
end

#nice_send(node) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/zombie_killer/niceness.rb', line 44

def nice_send(node)
  return false unless node.type == :send
  receiver, message, *args = *node

  if receiver.nil?
    arity = NICE_GLOBAL_METHODS.fetch(message, -1)
  else
    return false unless nice(receiver)
    arity = NICE_OPERATORS.fetch(message, -1)
  end
  return args.size == arity && args.all?{ |a| nice(a) }
end

#nice_variable(node) ⇒ Object



28
29
30
# File 'lib/zombie_killer/niceness.rb', line 28

def nice_variable(node)
  node.type == :lvar && scope[node.children.first].nice
end