class MethodBasedSexpProcessor

A simple subclass of SexpProcessor that tracks method and class stacks for you. Use method_name, klass_name, or signature to refer to where you're at in processing. If you have to subclass process_(class|module|defn|defs) you must call super.

Attributes

class_stack[R]
method_locations[R]
method_stack[R]
sclass[R]

Public Class Methods

new() click to toggle source
Calls superclass method SexpProcessor.new
# File lib/sexp_processor.rb, line 447
def initialize
  super
  @sclass              = []
  @class_stack         = []
  @method_stack        = []
  @method_locations    = {}
  self.require_empty   = false
end

Public Instance Methods

in_klass(name) { || ... } click to toggle source

Adds name to the class stack, for the duration of the block

# File lib/sexp_processor.rb, line 459
def in_klass name
  if Sexp === name then
    name = case name.first
           when :colon2 then
             name = name.flatten
             name.delete :const
             name.delete :colon2
             name.join("::")
           when :colon3 then
             name.last.to_s
           else
             raise "unknown type #{name.inspect}"
           end
  end

  @class_stack.unshift name

  with_new_method_stack do
    yield
  end
ensure
  @class_stack.shift
end
in_method(name, file, line, line_max=nil) { || ... } click to toggle source

Adds name to the method stack, for the duration of the block

# File lib/sexp_processor.rb, line 486
def in_method name, file, line, line_max=nil
  method_name = Regexp === name ? name.inspect : name.to_s
  @method_stack.unshift method_name
  line_max = "-#{line_max}" if line_max
  @method_locations[signature] = "#{file}:#{line}#{line_max}"
  yield
ensure
  @method_stack.shift
end
in_sklass() { || ... } click to toggle source

Tracks whether we're in a singleton class or not. Doesn't track actual receiver.

# File lib/sexp_processor.rb, line 500
def in_sklass
  @sclass.push true

  with_new_method_stack do
    yield
  end
ensure
  @sclass.pop
end
klass_name() click to toggle source

Returns the first class in the list, or @@no_class if there are none.

# File lib/sexp_processor.rb, line 514
def klass_name
  name = @class_stack.first

  if Sexp === name then
    raise "you shouldn't see me"
  elsif @class_stack.any?
    @class_stack.reverse.join("::").sub(/\([^\)]+\)$/, '')
  else
    @@no_class
  end
end
method_name() click to toggle source

Returns the first method in the list, or “#none” if there are none.

# File lib/sexp_processor.rb, line 530
def method_name
  m = @method_stack.first || @@no_method
  m = "##{m}" unless m =~ /::/
  m
end
process_class(exp) { || ... } click to toggle source

Process a class node until empty. Tracks all nesting. If you have to subclass and override this method, you can clall super with a block.

# File lib/sexp_processor.rb, line 541
def process_class(exp)
  exp.shift unless auto_shift_type # node type
  in_klass exp.shift do
    if block_given? then
      yield
    else
      process_until_empty exp
    end
  end
  s()
end
process_defn(exp) { || ... } click to toggle source

Process a method node until empty. Tracks your location. If you have to subclass and override this method, you can clall super with a block.

# File lib/sexp_processor.rb, line 558
def process_defn(exp)
  exp.shift unless auto_shift_type # node type
  name = @sclass.empty? ? exp.shift : "::#{exp.shift}"

  in_method name, exp.file, exp.line, exp.line_max do
    if block_given? then
      yield
    else
      process_until_empty exp
    end
  end
  s()
end
process_defs(exp) { || ... } click to toggle source

Process a singleton method node until empty. Tracks your location. If you have to subclass and override this method, you can clall super with a block.

# File lib/sexp_processor.rb, line 577
def process_defs(exp)
  exp.shift unless auto_shift_type # node type
  process exp.shift # recv
  in_method "::#{exp.shift}", exp.file, exp.line, exp.line_max do
    if block_given? then
      yield
    else
      process_until_empty exp
    end
  end
  s()
end
process_module(exp) { || ... } click to toggle source

Process a module node until empty. Tracks all nesting. If you have to subclass and override this method, you can clall super with a block.

# File lib/sexp_processor.rb, line 595
def process_module(exp)
  exp.shift unless auto_shift_type # node type
  in_klass exp.shift do
    if block_given? then
      yield
    else
      process_until_empty exp
    end
  end
  s()
end
process_sclass(exp) { || ... } click to toggle source

Process a singleton class node until empty. Tracks all nesting. If you have to subclass and override this method, you can clall super with a block.

# File lib/sexp_processor.rb, line 612
def process_sclass(exp)
  exp.shift unless auto_shift_type # node type
  in_sklass do
    if block_given? then
      yield
    else
      process_until_empty exp
    end
  end
  s()
end
process_until_empty(exp) click to toggle source

Process each element of exp in turn.

# File lib/sexp_processor.rb, line 627
def process_until_empty exp
  until exp.empty?
    sexp = exp.shift
    process sexp if Sexp === sexp
  end
end
signature() click to toggle source

Returns the method signature for the current method.

# File lib/sexp_processor.rb, line 637
def signature
  "#{klass_name}#{method_name}"
end
with_new_method_stack() { || ... } click to toggle source

Reset the method stack for the duration of the block. Used for class scoping.

# File lib/sexp_processor.rb, line 645
def with_new_method_stack
  old_method_stack, @method_stack = @method_stack, []

  yield
ensure
  @method_stack = old_method_stack
end