summaryrefslogtreecommitdiffstats
path: root/lib/puppet/parser/ast
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-05-09 05:50:34 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-05-09 05:50:34 +0000
commit513b87a86e9b77bb9f1b011aa55222ce9cfb3a8d (patch)
treeeee376e11f0d3ec84972548af2ab804c7c062bfe /lib/puppet/parser/ast
parentfe16f83a1b56f5d8644ee08585cc3086d4acc2a0 (diff)
downloadpuppet-513b87a86e9b77bb9f1b011aa55222ce9cfb3a8d.tar.gz
puppet-513b87a86e9b77bb9f1b011aa55222ce9cfb3a8d.tar.xz
puppet-513b87a86e9b77bb9f1b011aa55222ce9cfb3a8d.zip
Preliminary commit of the first phase of the parser redesign. The biggest difference is that overrides should now work for definitions (although i do not yet have a test case -- i will add one on the next commit). The way this is implemented is by having scopes translate themselves at eval time, but in two phases -- the first phase does the overrides, and the second phase does the evaluation of definitions and classes.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1180 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet/parser/ast')
-rw-r--r--lib/puppet/parser/ast/component.rb15
-rw-r--r--lib/puppet/parser/ast/hostclass.rb47
2 files changed, 45 insertions, 17 deletions
diff --git a/lib/puppet/parser/ast/component.rb b/lib/puppet/parser/ast/component.rb
index 00677e1ea..50e8df5a8 100644
--- a/lib/puppet/parser/ast/component.rb
+++ b/lib/puppet/parser/ast/component.rb
@@ -14,12 +14,12 @@ class Puppet::Parser::AST
#def evaluate(scope,hash,objtype,objname)
def evaluate(hash)
- scope = hash[:scope]
+ origscope = hash[:scope]
objtype = hash[:type]
objname = hash[:name]
arguments = hash[:arguments] || {}
- scope = scope.newscope(
+ scope = origscope.newscope(
:type => @type,
:name => objname,
:keyword => self.keyword
@@ -95,9 +95,14 @@ class Puppet::Parser::AST
# Now just evaluate the code with our new bindings.
self.code.safeevaluate(:scope => scope)
- # We return the scope, so that our children can make their scopes
- # under ours. This allows them to find our definitions.
- return scope
+ # If we're being evaluated as a parent class, we want to return the
+ # scope, so it can be overridden and such, but if not, we want to
+ # return a TransBucket of our objects.
+ if hash.include?(:asparent)
+ return scope
+ else
+ return scope.to_trans
+ end
end
# Check whether a given argument is valid. Searches up through
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index 8290f4ef0..a69d185e0 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -11,7 +11,7 @@ class Puppet::Parser::AST
scope = hash[:scope]
objtype = hash[:type]
objname = hash[:name]
- hash = hash[:arguments]
+ args = hash[:arguments]
# Verify that we haven't already been evaluated
# FIXME The second subclass won't evaluate the parent class
# code at all, and any overrides will throw an error.
@@ -26,30 +26,51 @@ class Puppet::Parser::AST
# Default to creating a new context
newcontext = true
+ transscope = nil
if parentscope = self.evalparent(
- :scope => scope, :arguments => hash, :name => objname
+ :scope => scope, :arguments => args, :name => 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.
+ if parentscope.is_a? Puppet::TransBucket
+ raise Puppet::DevError, "Got a bucket instead of a scope"
+ end
+
scope = parentscope
+ transscope = parentscope
# But don't create a new context if our parent created one
newcontext = false
end
- # just use the Component evaluate method, but change the type
- # to our own type
- #retval = super(scope,hash,@name,objname)
- retval = super(
+ # Just use the Component evaluate method, but change the type
+ # to our own type.
+ result = super(
:scope => scope,
- :arguments => hash,
+ :arguments => args,
:type => @type,
- :name => objname,
- :newcontext => newcontext
+ :name => objname, # might be nil
+ :newcontext => newcontext,
+ :asparent => hash[:asparent] # might be nil
)
- return retval
+
+ # This is important but painfully difficult. If we're the top-level
+ # class, that is, we have no parent classes, then the transscope
+ # is our own scope, but if there are parent classes, then the topmost
+ # parent's scope is the transscope, since it contains its code and
+ # all of the subclass's code.
+ transscope ||= result
+
+ if hash[:asparent]
+ # If we're a parent class, then return the scope object itself.
+ return result
+ else
+ # But if we're the final subclass, translate the whole scope tree
+ # into TransObjects and TransBuckets.
+ return transscope.to_trans
+ end
end
# Evaluate our parent class. Parent classes are evaluated in the
@@ -97,11 +118,13 @@ class Puppet::Parser::AST
raise error
end
# We don't need to pass the type, because the parent will just
- # use its own type
+ # use its own type. Specify that it's being evaluated as a parent,
+ # so that it returns the scope, not a transbucket.
return parentobj.safeevaluate(
:scope => scope,
:arguments => args,
- :name => name
+ :name => name,
+ :asparent => true
)
else
return false