diff options
Diffstat (limited to 'lib/puppet/parser/ast/compdef.rb')
| -rw-r--r-- | lib/puppet/parser/ast/compdef.rb | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/lib/puppet/parser/ast/compdef.rb b/lib/puppet/parser/ast/compdef.rb new file mode 100644 index 000000000..ffd0dc0e0 --- /dev/null +++ b/lib/puppet/parser/ast/compdef.rb @@ -0,0 +1,108 @@ +class Puppet::Parser::AST + # Define a new component. This basically just stores the + # associated parse tree by name in our current scope. Note that + # there is currently a mismatch in how we look up components -- it + # usually uses scopes, but sometimes uses '@@settypes'. + # FIXME This class should verify that each of its direct children + # has an abstractable name -- i.e., if a file does not include a + # variable in its name, then the user is essentially guaranteed to + # encounter an error if the component is instantiated more than + # once. + class CompDef < AST::Branch + attr_accessor :name, :args, :code + + def each + [@name,@args,@code].each { |child| yield child } + end + + # Store the parse tree. + def evaluate(scope) + name = @name.safeevaluate(scope) + args = @args.safeevaluate(scope) + + begin + scope.settype(name, + AST::Component.new( + :name => name, + :args => args, + :code => @code + ) + ) + rescue Puppet::ParseError => except + except.line = self.line + except.file = self.file + raise except + rescue => detail + error = Puppet::ParseError.new(detail) + error.line = self.line + error.file = self.file + error.stack = caller + raise error + end + end + + def initialize(hash) + @parentclass = nil + super + + Puppet.debug "Defining type %s" % @name.value + + # we need to both mark that a given argument is valid, + # and we need to also store any provided default arguments + # FIXME This creates a global list of types and their + # acceptable arguments. This should really be scoped + # instead. + @@settypes[@name.value] = self + end + + def tree(indent = 0) + return [ + @name.tree(indent + 1), + ((@@indline * 4 * indent) + self.typewrap("define")), + @args.tree(indent + 1), + @code.tree(indent + 1), + ].join("\n") + end + + def to_s + return "define %s(%s) {\n%s }" % [@name, @args, @code] + end + + # Check whether a given argument is valid. Searches up through + # any parent classes that might exist. + def validarg?(param) + found = false + if @args.is_a?(AST::ASTArray) + found = @args.detect { |arg| + if arg.is_a?(AST::ASTArray) + arg[0].value == param + else + arg.value == param + end + } + else + found = @args.value == param + #Puppet.warning "got arg %s" % @args.inspect + #hash[@args.value] += 1 + end + + if found + return true + # a nil parentclass is an empty astarray + # stupid but true + elsif @parentclass + parent = @@settypes[@parentclass.value] + if parent and parent != [] + return parent.validarg?(param) + else + raise Puppet::Error, "Could not find parent class %s" % + @parentclass.value + end + else + return false + end + + end + end + +end |
