diff --git a/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsParser.g4 b/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsParser.g4 index 8066deee4..e631d797f 100644 --- a/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsParser.g4 +++ b/handlebars/src/main/antlr4/com/github/jknack/handlebars/internal/HbsParser.g4 @@ -74,7 +74,7 @@ block : startToken = START_BLOCK DECORATOR? sexpr blockParams? END thenBody=body - elseBlock* + elseBlock END_BLOCK nameEnd=QID END ; @@ -97,8 +97,8 @@ sexpr elseBlock : - elseStmt - | elseStmtChain + elseStmtChain* + elseStmt? ; elseStmt diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/internal/TemplateBuilder.java b/handlebars/src/main/java/com/github/jknack/handlebars/internal/TemplateBuilder.java index b0d67bf99..c8e7c90a4 100644 --- a/handlebars/src/main/java/com/github/jknack/handlebars/internal/TemplateBuilder.java +++ b/handlebars/src/main/java/com/github/jknack/handlebars/internal/TemplateBuilder.java @@ -240,53 +240,53 @@ public Template visitBlock(final BlockContext ctx) { } // else Block elseroot = block; - for (ElseBlockContext elseBlock : ctx.elseBlock()) { - ElseStmtContext elseStmt = elseBlock.elseStmt(); - if (elseStmt != null) { - // basic else - Template unless = visitBody(elseStmt.unlessBody); - if (unless != null) { - String inverseLabel = elseStmt.inverseToken.getText(); - if (inverseLabel.startsWith(startDelim)) { - inverseLabel = inverseLabel.substring(startDelim.length()); - } - if (inverseLabel.endsWith("~")) { - inverseLabel = inverseLabel.substring(0, inverseLabel.length() - 1); - } - elseroot.inverse(inverseLabel, unless); - } - } else { - // else chain - ElseStmtChainContext elseStmtChain = elseBlock.elseStmtChain(); - SexprContext elseexpr = elseStmtChain.sexpr(); - Token elsenameStart = elseexpr.QID().getSymbol(); - String elsename = elsenameStart.getText(); - String type = elseStmtChain.inverseToken.getText(); - if (type.equals("else")) { - type = "else "; - } - Block elseblock = - new Block( - handlebars, - elsename, - false, - type, - params(elseexpr.param()), - hash(elseexpr.hash()), - blockParams(elseStmtChain.blockParams())); - elseblock.filename(source.filename()); - elseblock.position(elsenameStart.getLine(), elsenameStart.getCharPositionInLine()); - elseblock.startDelimiter(startDelim); - elseblock.endDelimiter(elseStmtChain.END().getText()); - Template elsebody = visitBody(elseStmtChain.unlessBody); - elseblock.body(elsebody); - - String inverseLabel = elseStmtChain.inverseToken.getText(); + ElseBlockContext elseBlock = ctx.elseBlock(); + ElseStmtContext elseStmt = elseBlock.elseStmt(); + List elseStmtChain = elseBlock.elseStmtChain(); + for (ElseStmtChainContext elseStmtChainContext : elseStmtChain) { + // else if chain + SexprContext elseexpr = elseStmtChainContext.sexpr(); + Token elsenameStart = elseexpr.QID().getSymbol(); + String elsename = elsenameStart.getText(); + String type = elseStmtChainContext.inverseToken.getText(); + if (type.equals("else")) { + type = "else "; + } + Block elseblock = + new Block( + handlebars, + elsename, + false, + type, + params(elseexpr.param()), + hash(elseexpr.hash()), + blockParams(elseStmtChainContext.blockParams())); + elseblock.filename(source.filename()); + elseblock.position(elsenameStart.getLine(), elsenameStart.getCharPositionInLine()); + elseblock.startDelimiter(startDelim); + elseblock.endDelimiter(elseStmtChainContext.END().getText()); + Template elsebody = visitBody(elseStmtChainContext.unlessBody); + elseblock.body(elsebody); + + String inverseLabel = elseStmtChainContext.inverseToken.getText(); + if (inverseLabel.startsWith(startDelim)) { + inverseLabel = inverseLabel.substring(startDelim.length()); + } + elseroot.inverse(inverseLabel, elseblock); + elseroot = elseblock; + } + if (elseStmt != null) { + // basic else + Template unless = visitBody(elseStmt.unlessBody); + if (unless != null) { + String inverseLabel = elseStmt.inverseToken.getText(); if (inverseLabel.startsWith(startDelim)) { inverseLabel = inverseLabel.substring(startDelim.length()); } - elseroot.inverse(inverseLabel, elseblock); - elseroot = elseblock; + if (inverseLabel.endsWith("~")) { + inverseLabel = inverseLabel.substring(0, inverseLabel.length() - 1); + } + elseroot.inverse(inverseLabel, unless); } } hasTag(true); diff --git a/handlebars/src/test/java/com/github/jknack/handlebars/ParsingErrorTest.java b/handlebars/src/test/java/com/github/jknack/handlebars/ParsingErrorTest.java index 8d9c156ae..ac4a449ae 100644 --- a/handlebars/src/test/java/com/github/jknack/handlebars/ParsingErrorTest.java +++ b/handlebars/src/test/java/com/github/jknack/handlebars/ParsingErrorTest.java @@ -59,7 +59,9 @@ public class ParsingErrorTest extends AbstractTest { "idx3", "{{list.[]}}", "idx4", - "{{list.[}}"); + "{{list.[}}", + "multipleElse", + "{{#if true}} b1 {{else}} b2 {{else}} b3 {{/if}}"); @Test public void correctPath() throws IOException { @@ -166,6 +168,11 @@ public void idx4() throws IOException { assertThrows(HandlebarsException.class, () -> parse("idx4")); } + @Test + public void multipleElse() throws IOException { + assertThrows(HandlebarsException.class, () -> parse("multipleElse")); + } + private void parse(final String candidate) throws IOException { try { String input = (String) source.get(candidate);