diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/parser/ast.rb | 2 | ||||
-rw-r--r-- | lib/puppet/parser/ast/compdef.rb | 46 | ||||
-rw-r--r-- | lib/puppet/parser/ast/component.rb | 39 | ||||
-rw-r--r-- | lib/puppet/parser/ast/objectdef.rb | 78 |
4 files changed, 75 insertions, 90 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index 5eb4ebaa2..d690ff1a8 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -15,7 +15,7 @@ module Puppet [:typecheck, true, "Whether to validate types during parsing."], [:paramcheck, true, "Whether to validate parameters during parsing."] ) - attr_accessor :line, :file, :parent + attr_accessor :line, :file, :parent, :scope # Just used for 'tree', which is only used in debugging. @@pink = "[0;31m" diff --git a/lib/puppet/parser/ast/compdef.rb b/lib/puppet/parser/ast/compdef.rb index ef099eff8..07eda339e 100644 --- a/lib/puppet/parser/ast/compdef.rb +++ b/lib/puppet/parser/ast/compdef.rb @@ -49,13 +49,6 @@ class Puppet::Parser::AST 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) @@ -70,42 +63,7 @@ class Puppet::Parser::AST 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 + +# $Id$ diff --git a/lib/puppet/parser/ast/component.rb b/lib/puppet/parser/ast/component.rb index f5105c44b..858ef86f6 100644 --- a/lib/puppet/parser/ast/component.rb +++ b/lib/puppet/parser/ast/component.rb @@ -13,8 +13,8 @@ class Puppet::Parser::AST attr_accessor :name, :args, :code, :scope, :autoname, :keyword def evaluate(scope,hash,objtype,objname) - scope = scope.newscope + @scope = scope # The type is the component or class name scope.type = objtype @@ -100,6 +100,41 @@ class Puppet::Parser::AST # under ours. This allows them to find our definitions. return scope end - end + # Check whether a given argument is valid. Searches up through + # any parent classes that might exist. + def validarg?(param) + found = false + unless @args.is_a? Array + @args = [@args] + end + + found = @args.detect { |arg| + if arg.is_a? Array + arg[0] == param + else + arg == param + end + } + + if found + # It's a valid arg for us + return true + elsif @parentclass + # Else, check any existing parent + parent = @scope.lookuptype(@parentclass) + if parent and parent != [] + return parent.validarg?(param) + else + raise Puppet::Error, "Could not find parent class %s" % + @parentclass + end + else + # Or just return false + return false + end + end + end end + +# $Id$ diff --git a/lib/puppet/parser/ast/objectdef.rb b/lib/puppet/parser/ast/objectdef.rb index cf1525540..e75b07ccb 100644 --- a/lib/puppet/parser/ast/objectdef.rb +++ b/lib/puppet/parser/ast/objectdef.rb @@ -41,6 +41,7 @@ class Puppet::Parser::AST # Does not actually return an object; instead sets an object # in the current scope. def evaluate(scope) + @scope = scope hash = {} # Get our type and name. @@ -52,7 +53,8 @@ class Puppet::Parser::AST 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 @@ -67,20 +69,6 @@ class Puppet::Parser::AST 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 - end - end - - autonamed = false # Autogenerate the name if one was not passed. if defined? @name @@ -110,7 +98,7 @@ class Puppet::Parser::AST 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) + unless object begin #Puppet.debug( # ("Setting object '%s' " + @@ -184,15 +172,7 @@ class Puppet::Parser::AST @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 @@ -209,6 +189,9 @@ class Puppet::Parser::AST self.paramdefinedcheck(objtype, param) end } + + # Mark that we've made it all the way through. + @checked = true end def parambuiltincheck(type, param) @@ -234,7 +217,8 @@ class Puppet::Parser::AST 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 @@ -245,7 +229,9 @@ class Puppet::Parser::AST 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] @@ -306,22 +292,29 @@ class Puppet::Parser::AST # 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 - - #unless builtin - # Puppet.debug "%s is a defined type" % objtype - #end - - self.paramcheck(builtin, objtype) + 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 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 - @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 @@ -332,5 +325,4 @@ class Puppet::Parser::AST ] end end - end |