summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast/compdef.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/parser/ast/compdef.rb')
-rw-r--r--lib/puppet/parser/ast/compdef.rb108
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