summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast/hostclass.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/parser/ast/hostclass.rb')
-rw-r--r--lib/puppet/parser/ast/hostclass.rb82
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
new file mode 100644
index 000000000..a5a228716
--- /dev/null
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -0,0 +1,82 @@
+class Puppet::Parser::AST
+ # The code associated with a class. This is different from components
+ # in that each class is a singleton -- only one will exist for a given
+ # node.
+ class HostClass < AST::Component
+ @name = :class
+ attr_accessor :parentclass
+
+ def evaluate(scope,hash,objtype,objname)
+ if scope.lookupclass(@name)
+ Puppet.debug "%s class already evaluated" % @name
+ return nil
+ end
+
+ if tmp = self.evalparent(scope, hash, objname)
+ # Override our scope binding with the parent scope
+ # binding. This is quite hackish, but I can't think
+ # of another way to make sure our scopes end up under
+ # our parent scopes.
+ scope = tmp
+ end
+
+ # just use the Component evaluate method, but change the type
+ # to our own type
+ retval = super(scope,hash,@name,objname)
+
+ # Set the mark after we evaluate, so we don't record it but
+ # then encounter an error
+ scope.setclass(@name)
+ return retval
+ end
+
+ # Evaluate our parent class. Parent classes are evaluated in the
+ # exact same scope as the children. This is maybe not a good idea
+ # but, eh.
+ def evalparent(scope, args, name)
+ if @parentclass
+ parentobj = nil
+
+ begin
+ parentobj = scope.lookuptype(@parentclass)
+ 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
+ raise error
+ end
+ unless parentobj
+ error = Puppet::ParseError.new(
+ "Could not find parent '%s' of '%s'" %
+ [@parentclass,@name])
+ error.line = self.line
+ error.file = self.file
+ raise error
+ end
+
+ # Verify that the parent and child are of the same type
+ unless parentobj.class == self.class
+ error = Puppet::ParseError.new(
+ "Class %s has incompatible parent type, %s vs %s" %
+ [@name, parentobj.class, self.class]
+ )
+ error.file = self.file
+ error.line = self.line
+ raise error
+ end
+ return parentobj.safeevaluate(scope,args,@parentclass,name)
+ end
+ end
+
+ def initialize(hash)
+ @parentclass = nil
+ super
+ end
+
+ end
+
+end