diff options
| author | Paul Berry <paul@puppetlabs.com> | 2010-08-13 15:43:34 -0700 |
|---|---|---|
| committer | Paul Berry <paul@puppetlabs.com> | 2010-08-13 15:54:26 -0700 |
| commit | 4da88fb4cd57871f16649d50572240ac3f7420f0 (patch) | |
| tree | 1b0df4e444bc27f925aac293cf721fa7acee06f7 /lib/puppet/parser/ast | |
| parent | caca187dffbd6e628d7eda599c7f2939dd05fafc (diff) | |
| download | puppet-4da88fb4cd57871f16649d50572240ac3f7420f0.tar.gz puppet-4da88fb4cd57871f16649d50572240ac3f7420f0.tar.xz puppet-4da88fb4cd57871f16649d50572240ac3f7420f0.zip | |
[#4496]+[#4521]+[#4522] Add structures to the AST to represent type definitions (classes, definitions, and nodes).
Previously, type definitions were not represented directly in the AST.
Instead, the parser would instantiate types and insert them into
known_resource_types as soon as they were parsed. This made it
difficult to distinguish which types had come from the file that was
just parsed and which types had been loaded previously, which led to
bug 4496.
A side-effect of this change is that the user is no longer allowed to
define types inside of conditional constructs (such as if/else). This
was allowed before but had unexpected semantics (bugs 4521 and 4522).
It is still possible, however, to place an "include" statement inside
a conditional construct, and have that "include" statement trigger the
autoloading of a file that instantiates types.
Diffstat (limited to 'lib/puppet/parser/ast')
| -rw-r--r-- | lib/puppet/parser/ast/astarray.rb | 19 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/definition.rb | 12 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/hostclass.rb | 26 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/node.rb | 17 | ||||
| -rw-r--r-- | lib/puppet/parser/ast/top_level_construct.rb | 4 |
5 files changed, 77 insertions, 1 deletions
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb index 529998e3c..432300c7a 100644 --- a/lib/puppet/parser/ast/astarray.rb +++ b/lib/puppet/parser/ast/astarray.rb @@ -9,6 +9,11 @@ class Puppet::Parser::AST class ASTArray < Branch include Enumerable + # True if this ASTArray represents a list of statements in a + # context that defines a namespace. Classes and definitions may + # only appear in such a context. + attr_accessor :is_a_namespace + # Return a child by index. Probably never used. def [](index) @children[index] @@ -32,7 +37,19 @@ class Puppet::Parser::AST } rets = items.flatten.collect { |child| - child.safeevaluate(scope) + if child.respond_to? :instantiate + if is_a_namespace + # no problem, just don't evaluate it. + else + msg = "Classes, definitions, and nodes may only appear at toplevel or inside other classes" + error = Puppet::Error.new(msg) + error.line = child.line + error.file = child.file + raise error + end + else + child.safeevaluate(scope) + end } rets.reject { |o| o.nil? } end diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb new file mode 100644 index 000000000..09f52b519 --- /dev/null +++ b/lib/puppet/parser/ast/definition.rb @@ -0,0 +1,12 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Definition < Puppet::Parser::AST::TopLevelConstruct + def initialize(name, context = {}) + @name = name + @context = context + end + + def instantiate(modname) + return [Puppet::Resource::Type.new(:definition, @name, @context.merge(:module_name => modname))] + end +end diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb new file mode 100644 index 000000000..d539e4deb --- /dev/null +++ b/lib/puppet/parser/ast/hostclass.rb @@ -0,0 +1,26 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Hostclass < Puppet::Parser::AST::TopLevelConstruct + attr_accessor :name, :context + + def initialize(name, context = {}) + @context = context + @name = name + end + + def instantiate(modname) + all_types = [Puppet::Resource::Type.new(:hostclass, @name, @context.merge(:module_name => modname))] + if code + code.each do |nested_ast_node| + if nested_ast_node.respond_to? :instantiate + all_types += nested_ast_node.instantiate(modname) + end + end + end + return all_types + end + + def code() + @context[:code] + end +end diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb new file mode 100644 index 000000000..c19a24ce0 --- /dev/null +++ b/lib/puppet/parser/ast/node.rb @@ -0,0 +1,17 @@ +require 'puppet/parser/ast/top_level_construct' + +class Puppet::Parser::AST::Node < Puppet::Parser::AST::TopLevelConstruct + attr_accessor :names + + def initialize(names, context = {}) + raise ArgumentError, "names should be an array" unless names.is_a? Array + @names = names + @context = context + end + + def instantiate(modname) + @names.collect do |name| + Puppet::Resource::Type.new(:node, name, @context.merge(:module_name => modname)) + end + end +end diff --git a/lib/puppet/parser/ast/top_level_construct.rb b/lib/puppet/parser/ast/top_level_construct.rb new file mode 100644 index 000000000..901a939c2 --- /dev/null +++ b/lib/puppet/parser/ast/top_level_construct.rb @@ -0,0 +1,4 @@ +# The base class for AST nodes representing top level things: +# hostclasses, definitions, and nodes. +class Puppet::Parser::AST::TopLevelConstruct < Puppet::Parser::AST +end |
