Class: Audition::Rewriters::Memoization::SingletonIvars

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/audition/rewriters.rb

Overview

Collects ivar operations that touch the class object: inside def self.x, inside class << self methods, or directly in the class body (recorded with body: true, which disqualifies the group). Instance-method ivars are ignored.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSingletonIvars

Returns a new instance of SingletonIvars.



614
615
616
617
618
619
620
621
# File 'lib/audition/rewriters.rb', line 614

def initialize
  @groups = Hash.new { |h, k| h[k] = [] }
  @namespace = []
  @sclass_depth = 0
  @def_stack = []
  @defined_depth = 0
  super
end

Instance Attribute Details

#groupsObject (readonly)

Returns the value of attribute groups.



612
613
614
# File 'lib/audition/rewriters.rb', line 612

def groups
  @groups
end

Instance Method Details

#visit_class_node(node) ⇒ Object



623
624
625
626
627
# File 'lib/audition/rewriters.rb', line 623

def visit_class_node(node)
  scoped(node.constant_path.location.slice, :class) do
    super(node)
  end
end

#visit_def_node(node) ⇒ Object



648
649
650
651
652
653
654
655
656
657
658
# File 'lib/audition/rewriters.rb', line 648

def visit_def_node(node)
  kind =
    node.receiver.is_a?(Prism::SelfNode) ? :self : :plain
  @def_stack.push(
    {kind: kind, id: node.object_id,
     name: node.name, node: node}
  )
  super
ensure
  @def_stack.pop
end

#visit_defined_node(node) ⇒ Object

A defined?(@x) that is not the recognized guard idiom probes ivar presence; rewriting the read to Ractor storage would make the probe unconditionally true, so every op inside disqualifies its group (recorded as :other).



665
666
667
668
669
670
# File 'lib/audition/rewriters.rb', line 665

def visit_defined_node(node)
  @defined_depth += 1
  super
ensure
  @defined_depth -= 1
end

#visit_if_node(node) ⇒ Object

Matches the guard statement of the second memoization idiom: return @x if defined?(@x). On a match the inner reads are not visited (they belong to the guard, not to the data flow) and the whole statement is recorded so the planner can delete it.



677
678
679
680
681
682
683
684
# File 'lib/audition/rewriters.rb', line 677

def visit_if_node(node)
  name = guard_name(node)
  if name
    record(node, :guard, name)
  else
    super
  end
end

#visit_module_node(node) ⇒ Object



629
630
631
632
633
# File 'lib/audition/rewriters.rb', line 629

def visit_module_node(node)
  scoped(node.constant_path.location.slice, :module) do
    super(node)
  end
end

#visit_singleton_class_node(node) ⇒ Object



635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/audition/rewriters.rb', line 635

def visit_singleton_class_node(node)
  if node.expression.is_a?(Prism::SelfNode)
    @sclass_depth += 1
    begin
      super
    ensure
      @sclass_depth -= 1
    end
  else
    super
  end
end