Class: Puppet_X::Binford2k::Itemize::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet_x/binford2k/itemize/parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, options = {}) ⇒ Parser

Returns a new instance of Parser.



9
10
11
12
13
14
15
16
17
18
# 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

Instance Attribute Details

#resultsObject (readonly)

Returns the value of attribute results.



7
8
9
# File 'lib/puppet_x/binford2k/itemize/parser.rb', line 7

def results
  @results
end

Instance Method Details

#compute(target) ⇒ Object

Start walking the tree and count each tracked token



43
44
45
46
47
48
49
50
# 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) ⇒ Object



52
53
54
# File 'lib/puppet_x/binford2k/itemize/parser.rb', line 52

def count(o)
  @@visitor.visit_this_0(self, o)
end

#count_CallMethodExpression(o) ⇒ Object

postfix functions



82
83
84
# 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) ⇒ Object

prefix functions



87
88
89
# 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) ⇒ Object



56
57
58
# File 'lib/puppet_x/binford2k/itemize/parser.rb', line 56

def count_Object(o)
  # nop
end

#count_ResourceExpression(o) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 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!Object



130
131
132
133
# File 'lib/puppet_x/binford2k/itemize/parser.rb', line 130

def dump!
  require 'json'
  puts JSON.pretty_generate(@results)
end

#parse!Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# 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) ⇒ Object



20
21
22
23
24
25
26
# 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) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# 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) ⇒ Object

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



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# 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