class Puppet_X::Binford2k::Itemize::Parser

Attributes

results[R]

Public Class Methods

new(filename, options = {}) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 9
def initialize(filename, options = {})
  @@visitor ||= Puppet::Pops::Visitor.new(nil, "count", 0, 0)
  @filename   = filename
  @options    = options
  @results    = {
    :types     => {},
    :classes   => {},
    :functions => {},
  }
end

Public Instance Methods

compute(target) click to toggle source

Start walking the tree and count each tracked token

# File lib/puppet_x/binford2k/itemize/parser.rb, line 43
  def compute(target)
    @path = []
    count(target)
    target._pcore_all_contents(@path) { |element| count(element) }
# Puppet 4.x version
#    target.eAllContents.each {|m|  abc(m) }
    @results
  end
count(o) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 52
def count(o)
  @@visitor.visit_this_0(self, o)
end
count_CallMethodExpression(o) click to toggle source

postfix functions

# File lib/puppet_x/binford2k/itemize/parser.rb, line 82
def count_CallMethodExpression(o)
  record_function(o, o.functor_expr.right_expr.value)
end
count_CallNamedFunctionExpression(o) click to toggle source

prefix functions

# File lib/puppet_x/binford2k/itemize/parser.rb, line 87
def count_CallNamedFunctionExpression(o)
  record_function(o, o.functor_expr.value)
end
count_Object(o) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 56
def count_Object(o)
  # nop
end
count_ResourceExpression(o) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 60
def count_ResourceExpression(o)
  resource_name = o.type_name.value
  case resource_name
  when 'class'
    # for classes declared as resource-style, we have to traverse back up the
    # tree to see if this resource body was declared by a class resource.
    o.bodies.each do |klass|
      case klass.title
      when Puppet::Pops::Model::LiteralList
        klass.title.values.each do |item|
          record(:classes, item.value)
        end
      else
        record(:classes, klass.title.value)
      end
    end
  else
    record(:types, resource_name)
  end
end
dump!() click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 130
def dump!
  require 'json'
  puts JSON.pretty_generate(@results)
end
parse!() click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 28
def parse!
  begin
    parser = Puppet::Pops::Parser::EvaluatingParser.new
    source = Puppet::FileSystem.read(@filename)
    result = parser.parse_string(source, @filename)
    compute(result)
  rescue => e
    Puppet.err "Parse error for #{@filename}."
    Puppet.err e.message
    Puppet.debug e.backtrace.join "\n"
  end
  self
end
record(kind, thing) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 20
def record(kind, thing)
  fail("Unknown kind #{kind}") unless @results.keys.include? kind

  thing = thing.sub(/^::/, '')
  @results[kind][thing] ||= 0
  @results[kind][thing]  += 1
end
record_function(o, function_name) click to toggle source
# File lib/puppet_x/binford2k/itemize/parser.rb, line 91
def record_function(o, function_name)
  case function_name
  when 'include', 'contain', 'require'
    o.arguments.each do |klass|
      record(:classes, klass.value)
    end

  when 'create_resources'
    Puppet.warn_once(:dependency, 'create_resources', 'create_resources detected. Please update to use iteration instead.', :default, :default)
    record(:functions, function_name)
    record(:types, o.arguments.first.value)

  else
    record(:functions, function_name)
  end
end
value_of(obj) click to toggle source

lots of edge cases of edge cases here. Monkeypatching seems more reliable

# File lib/puppet_x/binford2k/itemize/parser.rb, line 109
def value_of(obj)
  case obj
  when Puppet::Pops::Model::ConcatenatedString
    obj.segments.map {|t| t.value rescue nil }.join('<??>')
  when Puppet::Pops::Model::VariableExpression,
       Puppet::Pops::Model::CallMethodExpression,
       Puppet::Pops::Model::LiteralDefault
    '<??>'
  when Puppet::Pops::Model::CallMethodExpression
    value_of(obj.functor_expr.right_expr)
  when Puppet::Pops::Model::AccessExpression
    obj.keys.map {|t| t.value rescue nil }.join
  when Puppet::Pops::Model::ArithmeticExpression
    value_of(obj.left_expr) + obj.operator + value_of(obj.right_expr)
  when Puppet::Pops::Model::CallNamedFunctionExpression
    "#{obj.functor_expr.value}(#{obj.arguments.map {|a| a.value rescue nil }.join(',')})"
  else
    obj.value
  end
end