summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast.rb
blob: 75df319f65f495c6a3ee477931b81744a7fe145f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# the parent class for all of our syntactical objects

require 'puppet'

module Puppet
    module Parser
        # The base class for all of the objects that make up the parse trees.
        # Handles things like file name, line #, and also does the initialization
        # for all of the parameters of all of the child objects.
        class AST
            # Do this so I don't have to type the full path in all of the subclasses
            AST = Puppet::Parser::AST

            Puppet.setdefaults("ast",
                :typecheck => [true, "Whether to validate types during parsing."],
                :paramcheck => [true, "Whether to validate parameters during parsing."]
            )
            attr_accessor :line, :file, :parent, :scope

            # Just used for 'tree', which is only used in debugging.
            @@pink = ""
            @@green = ""
            @@yellow = ""
            @@slate = ""
            @@reset = ""

            # Just used for 'tree', which is only used in debugging.
            @@indent = " " * 4
            @@indline = @@pink + ("-" * 4) + @@reset
            @@midline = @@slate + ("-" * 4) + @@reset

            @@settypes = {}

            # Just used for 'tree', which is only used in debugging.
            def AST.indention
                return @@indent * @@indention
            end

            # Just used for 'tree', which is only used in debugging.
            def AST.midline
                return @@midline
            end

            # Evaluate the current object.  Basically just iterates across all
            # of the contained children and evaluates them in turn, returning a
            # list of all of the collected values, rejecting nil values
            def evaluate(args)
                #Puppet.debug("Evaluating ast %s" % @name)
                value = self.collect { |obj|
                    obj.safeevaluate(args)
                }.reject { |obj|
                    obj.nil?
                }
            end

            # The version of the evaluate method that should be called, because it
            # correctly handles errors.  It is critical to use this method because
            # it can enable you to catch the error where it happens, rather than
            # much higher up the stack.
            def safeevaluate(*args)
                begin
                    self.evaluate(*args)
                rescue Puppet::DevError => except
                    except.line ||= @line
                    except.file ||= @file
                    raise
                rescue Puppet::ParseError => except
                    except.line ||= @line
                    except.file ||= @file
                    raise
                rescue => detail
                    #if Puppet[:debug]
                    #    puts detail.backtrace
                    #end
                    error = Puppet::DevError.new(
                        "Child of type %s failed with error %s: %s" %
                            [self.class, detail.class, detail.to_s]
                    )
                    error.line ||= @line
                    error.file ||= @file
                    error.backtrace = detail.backtrace
                    raise error
                end
            end

            # Again, just used for printing out the parse tree.
            def typewrap(string)
                #return self.class.to_s.sub(/.+::/,'') +
                    #"(" + @@green + string.to_s + @@reset + ")"
                return @@green + string.to_s + @@reset +
                    "(" + self.class.to_s.sub(/.+::/,'') + ")"
            end

            # Initialize the object.  Requires a hash as the argument, and
            # takes each of the parameters of the hash and calls the settor
            # method for them.  This is probably pretty inefficient and should
            # likely be changed at some point.
            def initialize(args)
                @file = nil
                @line = nil
                args.each { |param,value|
                    method = param.to_s + "="
                    unless self.respond_to?(method)
                        error = Puppet::ParseError.new(
                            "Invalid parameter %s to object class %s" %
                                [param,self.class.to_s]
                        )
                        error.line = self.line
                        error.file = self.file
                        raise error
                    end

                    begin
                        #Puppet.debug("sending %s to %s" % [method, self.class])
                        self.send(method,value)
                    rescue => detail
                        error = Puppet::DevError.new(
                            "Could not set parameter %s on class %s: %s" %
                                [method,self.class.to_s,detail]
                        )
                        error.line ||= self.line
                        error.file ||= self.file
                        raise error
                    end
                }
            end
            #---------------------------------------------------------------
        end
    end
end

require 'puppet/parser/ast/astarray'
require 'puppet/parser/ast/branch'
require 'puppet/parser/ast/caseopt'
require 'puppet/parser/ast/casestatement'
require 'puppet/parser/ast/classdef'
require 'puppet/parser/ast/compdef'
require 'puppet/parser/ast/component'
require 'puppet/parser/ast/hostclass'
require 'puppet/parser/ast/leaf'
require 'puppet/parser/ast/node'
require 'puppet/parser/ast/nodedef'
require 'puppet/parser/ast/objectdef'
require 'puppet/parser/ast/objectparam'
require 'puppet/parser/ast/objectref'
require 'puppet/parser/ast/selector'
require 'puppet/parser/ast/typedefaults'
require 'puppet/parser/ast/vardef'
require 'puppet/parser/ast/tag'
require 'puppet/parser/ast/function'

# $Id$