diff --git a/lib/puppet/pops/issues.rb b/lib/puppet/pops/issues.rb index e7b3c467e89..24bd5666be9 100644 --- a/lib/puppet/pops/issues.rb +++ b/lib/puppet/pops/issues.rb @@ -495,6 +495,10 @@ def self.hard_issue(issue_code, *args, &block) "Use of reserved word: #{word}, must be quoted if intended to be a String value" end + RESERVED_TYPE_NAME = hard_issue :RESERVED_TYPE_NAME, :name do + "The name: '#{name}' is already defined by Puppet and can not be used as the name of #{label.a_an(semantic)}." + end + UNMATCHED_SELECTOR = hard_issue :UNMATCHED_SELECTOR, :param_value do "No matching entry for selector parameter with value '#{param_value}'" end diff --git a/lib/puppet/pops/validation/checker4_0.rb b/lib/puppet/pops/validation/checker4_0.rb index 53f696a6bb9..4baff2ebcf4 100644 --- a/lib/puppet/pops/validation/checker4_0.rb +++ b/lib/puppet/pops/validation/checker4_0.rb @@ -245,12 +245,39 @@ def check_NamedAccessExpression(o) end end + RESERVED_TYPE_NAMES = { + 'type' => true, + 'any' => true, + 'unit' => true, + 'scalar' => true, + 'boolean' => true, + 'numeric' => true, + 'integer' => true, + 'float' => true, + 'collection' => true, + 'array' => true, + 'hash' => true, + 'tuple' => true, + 'struct' => true, + 'variant' => true, + 'optional' => true, + 'enum' => true, + 'regexp' => true, + 'pattern' => true, + 'runtime' => true, + } + # for 'class', 'define', and function def check_NamedDefinition(o) top(o.eContainer, o) if o.name !~ Puppet::Pops::Patterns::CLASSREF acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name}) end + + if RESERVED_TYPE_NAMES[o.name()] + acceptor.accept(Issues::RESERVED_TYPE_NAME, o, {:name => o.name}) + end + if violator = ends_with_idem(o.body) acceptor.accept(Issues::IDEM_NOT_ALLOWED_LAST, violator, {:container => o}) end diff --git a/spec/unit/pops/validator/validator_spec.rb b/spec/unit/pops/validator/validator_spec.rb index ab4f3ebc744..2dcb9ed3f8b 100644 --- a/spec/unit/pops/validator/validator_spec.rb +++ b/spec/unit/pops/validator/validator_spec.rb @@ -120,6 +120,41 @@ def validate(model) end end + context 'for reserved type names' do + [# type/Type, is a reserved name but results in syntax error because it is a keyword in lower case form + 'any', + 'unit', + 'scalar', + 'boolean', + 'numeric', + 'integer', + 'float', + 'collection', + 'array', + 'hash', + 'tuple', + 'struct', + 'variant', + 'optional', + 'enum', + 'regexp', + 'pattern', + 'runtime', + ].each do |name| + + it "produces an error for 'class #{name}'" do + source = "class #{name} {}" + expect(validate(parse(source))).to have_issue(Puppet::Pops::Issues::RESERVED_TYPE_NAME) + end + + it "produces an error for 'define #{name}'" do + source = "define #{name} {}" + expect(validate(parse(source))).to have_issue(Puppet::Pops::Issues::RESERVED_TYPE_NAME) + end + end + + end + def parse(source) Puppet::Pops::Parser::Parser.new().parse_string(source) end