Class: Preval::Visitors::AttrAccessor

Inherits:
Preval::Visitor show all
Defined in:
lib/preval/visitors/attr_accessor.rb

Instance Method Summary collapse

Methods inherited from Preval::Visitor

enable!

Instance Method Details

#on_def(node) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/preval/visitors/attr_accessor.rb', line 6

def on_def(node)
  # auto create attr_readers
  if node.type_match?(:@ident, :params, :bodystmt) &&
     # def foo; @foo; end
     node[1].body.none? &&
     # there are no params to this method
     node[2, 0].type_match?(:stmts_new, :var_ref) &&
     # there is only one statement in the body and its a var reference
     node[2, 0, 1, 0].is?(:@ivar) &&
     # the var reference is referencing an instance variable
     node[0].body == node[2, 0, 1, 0].body[1..-1]
     # the name of the variable matches the name of the method

    ast = Parser.parse("attr_reader :#{node[0].body}")
    node.update(:stmts_add, ast.body[0].body)
  end

  # auto create attr_writers
  if node.type_match?(:@ident, :paren, :bodystmt) &&
     # def foo=(value); @foo = value; end
     node[0].body.end_with?('=') &&
     # this is a setter method
     node[1, 0, 0].length == 1 &&
     # there is exactly one required param
     node[1, 0].body[1..-1].none? &&
     # there are no other params
     (
       node[2, 0].type_match?(:stmts_new, :assign) || (
         node[2, 0, 0].type_match?(:stmts_new, :void_stmt) &&
         node[2, 0].type_match?(:stmts_add, :assign)
       )
     ) &&
     # there is only one statement in the body and it's an assignment
     node[2, 0, 1].type_match?(:var_field, :var_ref) &&
     # assigning a variable
     node[2, 0, 1, 0, 0].is?(:@ivar) &&
     # assigning to an instance variable
     node[0].body[0..-2] == node[2, 0, 1, 0, 0].body[1..-1] &&
     # variable name matches the method name
     node[1, 0, 0][0].body == node[2, 0, 1, 1, 0].body
     # assignment variable matches the argument name

    ast = Parser.parse("attr_writer :#{node[0].body[0..-2]}")
    node.update(:stmts_add, ast.body[0].body)
  end
end