Fix #1109 - allow empty if or else branches

This changesets allow empty if or else branches:

if true {
} else {
}

It works by emitting on the parser stack an AST node that doesn't
do anything (a no-op). This allows the less intrusive code
as no part of the if evaluation code has been touched.
This commit is contained in:
Brice Figureau 2008-10-04 16:11:03 +02:00 коммит произвёл James Turnbull
Родитель 5268487ac8
Коммит 0c297be5da
7 изменённых файлов: 728 добавлений и 599 удалений

Просмотреть файл

@ -91,6 +91,7 @@ require 'puppet/parser/ast/ifstatement'
require 'puppet/parser/ast/leaf' require 'puppet/parser/ast/leaf'
require 'puppet/parser/ast/minus' require 'puppet/parser/ast/minus'
require 'puppet/parser/ast/node' require 'puppet/parser/ast/node'
require 'puppet/parser/ast/nop'
require 'puppet/parser/ast/not' require 'puppet/parser/ast/not'
require 'puppet/parser/ast/resource' require 'puppet/parser/ast/resource'
require 'puppet/parser/ast/resource_defaults' require 'puppet/parser/ast/resource_defaults'

Просмотреть файл

@ -0,0 +1,11 @@
require 'puppet/parser/ast/branch'
class Puppet::Parser::AST
# This class is a no-op, it doesn't produce anything
# when evaluated, hence it's name :-)
class Nop < AST::Leaf
def evaluate(scope)
# nothing to do
end
end
end

Просмотреть файл

@ -417,6 +417,18 @@ ifstatement: IF expression LBRACE statements RBRACE else {
args[:else] = val[5] args[:else] = val[5]
end end
result = ast AST::IfStatement, args
}
| IF expression LBRACE RBRACE else {
args = {
:test => val[1],
:statements => ast(AST::Nop)
}
if val[4]
args[:else] = val[4]
end
result = ast AST::IfStatement, args result = ast AST::IfStatement, args
} }
@ -424,6 +436,9 @@ else: # nothing
| ELSE LBRACE statements RBRACE { | ELSE LBRACE statements RBRACE {
result = ast AST::Else, :statements => val[2] result = ast AST::Else, :statements => val[2]
} }
| ELSE LBRACE RBRACE {
result = ast AST::Else, :statements => ast(AST::Nop)
}
# Unlike yacc/bison, it seems racc # Unlike yacc/bison, it seems racc
# gives tons of shift/reduce warnings # gives tons of shift/reduce warnings

Разница между файлами не показана из-за своего большого размера Загрузить разницу

20
spec/unit/parser/ast/nop.rb Executable file
Просмотреть файл

@ -0,0 +1,20 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../../../spec_helper'
describe Puppet::Parser::AST::Nop do
before do
@scope = mock 'scope'
end
it "should do nothing on evaluation" do
Puppet::Parser::AST.expects(:safeevaluate).never
Puppet::Parser::AST::Nop.new({}).evaluate(@scope)
end
it "should not return anything" do
Puppet::Parser::AST::Nop.new({}).evaluate(@scope).should be_nil
end
end

Просмотреть файл

@ -116,4 +116,30 @@ describe Puppet::Parser do
end end
describe Puppet::Parser, "when parsing if statements" do
it "should not raise errors with empty if" do
lambda { @parser.parse("if true { }") }.should_not raise_error
end
it "should not raise errors with empty else" do
lambda { @parser.parse("if false { notice('if') } else { }") }.should_not raise_error
end
it "should not raise errors with empty if and else" do
lambda { @parser.parse("if false { } else { }") }.should_not raise_error
end
it "should create a nop node for empty branch" do
AST::Nop.expects(:new)
@parser.parse("if true { }")
end
it "should create a nop node for empty else branch" do
AST::Nop.expects(:new)
@parser.parse("if true { notice('test') } else { }")
end
end
end end

Просмотреть файл

@ -0,0 +1,9 @@
if false {
} else {
# nothing here
}
if true {
# still nothing
}