Parent

Class/Module Index [+]

Quicksearch

Brakeman::SexpProcessor

SexpProcessor provides a uniform interface to process Sexps.

In order to create your own SexpProcessor subclass you'll need to call super in the initialize method, then set any of the Sexp flags you want to be different from the defaults.

SexpProcessor uses a Sexp's type to determine which process method to call in the subclass. For Sexp s(:lit, 1) SexpProcessor will call process_lit, if it is defined.

Constants

VERSION

Attributes

context[R]

Return a stack of contexts. Most recent node is first.

env[R]

A scoped environment to make you happy.

expected[RW]

Expected result class

Public Class Methods

new() click to toggle source

Creates a new SexpProcessor. Use super to invoke this initializer from SexpProcessor subclasses, then use the attributes above to customize the functionality of the SexpProcessor

# File lib/ruby_parser/bm_sexp_processor.rb, line 38
def initialize
  @expected            = Sexp

  # we do this on an instance basis so we can subclass it for
  # different processors.
  @processors = {}
  @context    = []

  public_methods.each do |name|
    if name.to_s.start_with? "process_" then
      @processors[name[8..-1].to_sym] = name.to_sym
    end
  end
end

Public Instance Methods

in_context(type) click to toggle source
# File lib/ruby_parser/bm_sexp_processor.rb, line 141
def in_context type
  self.context.unshift type

  yield

  self.context.shift
end
process(exp) click to toggle source

Default Sexp processor. Invokes process_<type> methods matching the Sexp type given. Performs additional checks as specified by the initializer.

# File lib/ruby_parser/bm_sexp_processor.rb, line 58
def process(exp)
  return nil if exp.nil?

  result = nil

  type = exp.first
  raise "Type should be a Symbol, not: #{exp.first.inspect} in #{exp.inspect}" unless Symbol === type

  in_context type do
    # now do a pass with the real processor (or generic)
    meth = @processors[type]
    if meth then
      if $DEBUG
        result = error_handler(type) do
          self.send(meth, exp)
        end
      else
        result = self.send(meth, exp)
      end

    else
      result = self.process_default(exp)
    end
  end
  
  raise SexpTypeError, "Result must be a #{@expected}, was #{result.class}:#{result.inspect}" unless @expected === result
  
  result
end
process_dummy(exp) click to toggle source

A fairly generic processor for a dummy node. Dummy nodes are used when your processor is doing a complicated rewrite that replaces the current sexp with multiple sexps.

Bogus Example:

def process_something(exp)
  return s(:dummy, process(exp), s(:extra, 42))
end
# File lib/ruby_parser/bm_sexp_processor.rb, line 108
def process_dummy(exp)
  result = @expected.new(:dummy) rescue @expected.new

  until exp.empty? do
    result << self.process(exp.shift)
  end

  result
end
scope(&block) click to toggle source

Add a scope level to the current env. Eg:

def process_defn exp
  name = exp.shift
  args = process(exp.shift)
  scope do
    body = process(exp.shift)
    # ...
  end
end

env[:x] = 42
scope do
  env[:x]       # => 42
  env[:y] = 24
end
env[:y]         # => nil
# File lib/ruby_parser/bm_sexp_processor.rb, line 137
def scope &block
  env.scope(&block)
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.