Skip to content

Commit

Permalink
Extend EscapeVelocity with the #parse directive and the #[[...]]# quo…
Browse files Browse the repository at this point in the history
…ting construct. Also allow # not followed by an identifier, which is treated as a plain # character.

RELNOTES=n/a

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=180868803
  • Loading branch information
eamonnmcmanus authored and ronshapiro committed Jan 8, 2018
1 parent d6badd2 commit d5ca4ab
Show file tree
Hide file tree
Showing 12 changed files with 498 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
class ConstantExpressionNode extends ExpressionNode {
private final Object value;

ConstantExpressionNode(int lineNumber, Object value) {
super(lineNumber);
ConstantExpressionNode(String resourceName, int lineNumber, Object value) {
super(resourceName, lineNumber);
this.value = value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
* @author emcmanus@google.com (Éamonn McManus)
*/
abstract class DirectiveNode extends Node {
DirectiveNode(int lineNumber) {
super(lineNumber);
DirectiveNode(String resourceName, int lineNumber) {
super(resourceName, lineNumber);
}

/**
Expand All @@ -62,7 +62,7 @@ static class SetNode extends DirectiveNode {
private final Node expression;

SetNode(String var, Node expression) {
super(expression.lineNumber);
super(expression.resourceName, expression.lineNumber);
this.var = var;
this.expression = expression;
}
Expand All @@ -86,8 +86,13 @@ static class IfNode extends DirectiveNode {
private final Node truePart;
private final Node falsePart;

IfNode(int lineNumber, ExpressionNode condition, Node trueNode, Node falseNode) {
super(lineNumber);
IfNode(
String resourceName,
int lineNumber,
ExpressionNode condition,
Node trueNode,
Node falseNode) {
super(resourceName, lineNumber);
this.condition = condition;
this.truePart = trueNode;
this.falsePart = falseNode;
Expand All @@ -112,8 +117,8 @@ static class ForEachNode extends DirectiveNode {
private final ExpressionNode collection;
private final Node body;

ForEachNode(int lineNumber, String var, ExpressionNode in, Node body) {
super(lineNumber);
ForEachNode(String resourceName, int lineNumber, String var, ExpressionNode in, Node body) {
super(resourceName, lineNumber);
this.var = var;
this.collection = in;
this.body = body;
Expand All @@ -130,7 +135,7 @@ Object evaluate(EvaluationContext context) {
} else if (collectionValue instanceof Map<?, ?>) {
iterable = ((Map<?, ?>) collectionValue).values();
} else {
throw new EvaluationException("Not iterable: " + collectionValue);
throw evaluationException("Not iterable: " + collectionValue);
}
Runnable undo = context.setVar(var, null);
StringBuilder sb = new StringBuilder();
Expand Down Expand Up @@ -178,8 +183,12 @@ static class MacroCallNode extends DirectiveNode {
private final ImmutableList<Node> thunks;
private Macro macro;

MacroCallNode(int lineNumber, String name, ImmutableList<Node> argumentNodes) {
super(lineNumber);
MacroCallNode(
String resourceName,
int lineNumber,
String name,
ImmutableList<Node> argumentNodes) {
super(resourceName, lineNumber);
this.name = name;
this.thunks = argumentNodes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
* @author emcmanus@google.com (Éamonn McManus)
*/
abstract class ExpressionNode extends Node {
ExpressionNode(int lineNumber) {
super(lineNumber);
ExpressionNode(String resourceName, int lineNumber) {
super(resourceName, lineNumber);
}

/**
Expand Down Expand Up @@ -113,7 +113,7 @@ static class BinaryExpressionNode extends ExpressionNode {
final ExpressionNode rhs;

BinaryExpressionNode(ExpressionNode lhs, Operator op, ExpressionNode rhs) {
super(lhs.lineNumber);
super(lhs.resourceName, lhs.lineNumber);
this.lhs = lhs;
this.op = op;
this.rhs = rhs;
Expand Down Expand Up @@ -194,7 +194,7 @@ static class NotExpressionNode extends ExpressionNode {
private final ExpressionNode expr;

NotExpressionNode(ExpressionNode expr) {
super(expr.lineNumber);
super(expr.resourceName, expr.lineNumber);
this.expr = expr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
* @author emcmanus@google.com (Éamonn McManus)
*/
abstract class Node {
final String resourceName;
final int lineNumber;

Node(int lineNumber) {
Node(String resourceName, int lineNumber) {
this.resourceName = resourceName;
this.lineNumber = lineNumber;
}

Expand All @@ -55,36 +57,44 @@ abstract class Node {
*/
abstract Object evaluate(EvaluationContext context);

private String where() {
String where = "In expression on line " + lineNumber;
if (resourceName != null) {
where += " of " + resourceName;
}
return where;
}

EvaluationException evaluationException(String message) {
return new EvaluationException("In expression on line " + lineNumber + ": " + message);
return new EvaluationException(where() + ": " + message);
}

EvaluationException evaluationException(Throwable cause) {
return new EvaluationException("In expression on line " + lineNumber + ": " + cause, cause);
return new EvaluationException(where() + ": " + cause, cause);
}

/**
* Returns an empty node in the parse tree. This is used for example to represent the trivial
* "else" part of an {@code #if} that does not have an explicit {@code #else}.
*/
static Node emptyNode(int lineNumber) {
return new Cons(lineNumber, ImmutableList.<Node>of());
static Node emptyNode(String resourceName, int lineNumber) {
return new Cons(resourceName, lineNumber, ImmutableList.<Node>of());
}

/**
* Create a new parse tree node that is the concatenation of the given ones. Evaluating the
* new node produces the same string as evaluating each of the given nodes and concatenating the
* result.
*/
static Node cons(int lineNumber, ImmutableList<Node> nodes) {
return new Cons(lineNumber, nodes);
static Node cons(String resourceName, int lineNumber, ImmutableList<Node> nodes) {
return new Cons(resourceName, lineNumber, nodes);
}

private static final class Cons extends Node {
private final ImmutableList<Node> nodes;

Cons(int lineNumber, ImmutableList<Node> nodes) {
super(lineNumber);
Cons(String resourceName, int lineNumber, ImmutableList<Node> nodes) {
super(resourceName, lineNumber);
this.nodes = nodes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,19 @@
public class ParseException extends RuntimeException {
private static final long serialVersionUID = 1;

ParseException(String message, int lineNumber) {
super(message + ", on line " + lineNumber);
ParseException(String message, String resourceName, int lineNumber) {
super(message + ", " + where(resourceName, lineNumber));
}

ParseException(String message, int lineNumber, String context) {
super(message + ", on line " + lineNumber + ", at text starting: " + context);
ParseException(String message, String resourceName, int lineNumber, String context) {
super(message + ", " + where(resourceName, lineNumber) + ", at text starting: " + context);
}

private static String where(String resourceName, int lineNumber) {
if (resourceName == null) {
return "on line " + lineNumber;
} else {
return "on line " + lineNumber + " of " + resourceName;
}
}
}
Loading

0 comments on commit d5ca4ab

Please sign in to comment.