lib/puppet/parser/ast/objectdef.rb in puppet-0.13.2 vs lib/puppet/parser/ast/objectdef.rb in puppet-0.13.6

- old
+ new

@@ -13,48 +13,36 @@ # probably not used at all def [](index) return @params[index] end - # Auto-generate a name - def autoname(type, object) - case object - when Puppet::Type: - raise Puppet::Error, - "Built-in types must be provided with a name" - when Node: - return type - else - Puppet.debug "Autogenerating name for object of type %s" % - type - return [type, "-", self.object_id].join("") - end - end - # Iterate across all of our children. def each [@type,@name,@params].flatten.each { |param| #Puppet.debug("yielding param %s" % param) yield param } end # Does not actually return an object; instead sets an object # in the current scope. - def evaluate(scope) + def evaluate(hash) + scope = hash[:scope] + @scope = scope hash = {} # Get our type and name. - objtype = @type.safeevaluate(scope) + objtype = @type.safeevaluate(:scope => scope) # If the type was a variable, we wouldn't have typechecked yet. # Do it now, if so. unless @checked self.typecheck(objtype) end - # See if our object type was defined + # See if our object type was defined. If not, we know it's + # builtin because we already typechecked. begin object = scope.lookuptype(objtype) rescue Puppet::ParseError => except except.line = self.line except.file = self.file @@ -65,92 +53,76 @@ error.file = self.file error.backtrace = detail.backtrace raise error end - unless object - # If not, verify that it's a builtin type - object = Puppet::Type.type(objtype) - - # Type.type returns nil on object types that aren't found - unless object - error = Puppet::ParseError.new("Invalid type %s" % objtype) - error.line = self.line - error.file = self.file - raise error + objnames = [nil] + # Autogenerate the name if one was not passed. + if self.name + objnames = @name.safeevaluate(:scope => scope) + # it's easier to always use an array, even for only one name + unless objnames.is_a?(Array) + objnames = [objnames] end end - - autonamed = false - # Autogenerate the name if one was not passed. - if defined? @name - objnames = @name.safeevaluate(scope) - else - objnames = self.autoname(objtype, object) - autonamed = true - end - - # it's easier to always use an array, even for only one name - unless objnames.is_a?(Array) - objnames = [objnames] - end - # Retrieve the defaults for our type hash = getdefaults(objtype, scope) # then set all of the specified params @params.each { |param| - ary = param.safeevaluate(scope) + ary = param.safeevaluate(:scope => scope) hash[ary[0]] = ary[1] } # this is where our implicit iteration takes place; # if someone passed an array as the name, then we act # just like the called us many times objnames.collect { |objname| # If the object is a class, that means it's a builtin type, so # we just store it in the scope - if object.is_a?(Class) - begin - #Puppet.debug( - # ("Setting object '%s' " + - # "in scope %s " + - # "with arguments %s") % - # [objname, scope.object_id, hash.inspect] - #) - obj = scope.setobject( - objtype, - objname, - hash, - @file, - @line - ) - 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.backtrace = detail.backtrace - raise error - end - else - # but things like components create a new type; if we find - # one of those, evaluate that with our arguments - #Puppet.debug("Calling object '%s' with arguments %s" % - # [object.name, hash.inspect]) - obj = object.safeevaluate(scope,hash,objtype,objname) - - # Retain any name generation stuff - obj.autoname = autonamed - - # and pass the result on - obj + begin + #Puppet.debug( + # ("Setting object '%s' " + + # "in scope %s " + + # "with arguments %s") % + # [objname, scope.object_id, hash.inspect] + #) + obj = scope.setobject( + :type => objtype, + :name => objname, + :arguments => hash, + :file => @file, + :line => @line + ) + 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.backtrace = detail.backtrace + raise error end +# else +# # but things like components create a new type; if we find +# # one of those, evaluate that with our arguments +# #Puppet.debug("Calling object '%s' with arguments %s" % +# # [object.name, hash.inspect]) +# #obj = object.safeevaluate(scope,hash,objtype,objname) +# obj = object.safeevaluate( +# :scope => scope, +# :arguments => hash, +# :type => objtype, +# :name => objname +# ) +# +# # and pass the result on +# obj +# end }.reject { |obj| obj.nil? } end # Retrieve the defaults for our type def getdefaults(objtype, scope) @@ -182,19 +154,11 @@ # Create our ObjectDef. Handles type checking for us. def initialize(hash) @checked = false super - if @type.is_a?(Variable) - Puppet.debug "Delaying typecheck" - return - else - self.typecheck(@type.value) - - objtype = @type.value - end - + self.typecheck(@type.value) end # Verify that all passed parameters are valid def paramcheck(builtin, objtype) # This defaults to true @@ -207,10 +171,13 @@ self.parambuiltincheck(builtin, param) else self.paramdefinedcheck(objtype, param) end } + + # Mark that we've made it all the way through. + @checked = true end def parambuiltincheck(type, param) unless param.is_a?(AST::ObjectParam) raise Puppet::DevError, @@ -232,22 +199,25 @@ raise error end end def paramdefinedcheck(objtype, param) - # FIXME we might need to do more here eventually... + # FIXME We might need to do more here eventually. Metaparams + # behave strangely on containers. if Puppet::Type.metaparam?(param.param.value.intern) return end begin pname = param.param.value rescue => detail raise Puppet::DevError, detail.to_s end - unless @@settypes[objtype].validarg?(pname) + # FIXME This should look through the scope tree, not in a global + # hash + unless objtype.validarg?(pname) error = Puppet::ParseError.new( "Invalid parameter '%s' for type '%s'" % [pname,objtype] ) error.line = self.line @@ -304,33 +274,39 @@ builtin = Puppet::Type.type(objtype) rescue TypeError # nothing; we've already set builtin to false end - unless builtin or @@settypes.include?(objtype) - error = Puppet::ParseError.new( - "Unknown type '%s'" % objtype - ) - error.line = self.line - error.file = self.file - raise error - end + typeobj = nil + if builtin + self.paramcheck(builtin, objtype) + else + # If there's no set scope, then we're in initialize, not + # evaluate, so we can't test defined types. + return true unless defined? @scope and @scope - #unless builtin - # Puppet.debug "%s is a defined type" % objtype - #end + # Unless we can look up the type, throw an error + unless objtype = @scope.lookuptype(objtype) + error = Puppet::ParseError.new( + "Unknown type '%s'" % objtype + ) + error.line = self.line + error.file = self.file + raise error + end - self.paramcheck(builtin, objtype) - - @checked = true + # Now that we have the type, verify all of the parameters. + # Note that we're now passing an AST Class object or whatever + # as the type, not a simple string. + self.paramcheck(builtin, objtype) + end end def to_s return "%s => { %s }" % [@name, @params.collect { |param| param.to_s }.join("\n") ] end end - end