Resolve issue #602

This commit is contained in:
Eric MORAND 2024-01-05 13:50:51 +00:00
parent 52b1b65753
commit b79b79ffc9
3 changed files with 50 additions and 23 deletions

View File

@ -337,11 +337,11 @@ export const createParser = (
return null;
}
}
if (type === "block_reference" || type === "print" || type === "text") {
return null;
}
// here, nested means "being at the root level of a child template"
// we need to discard the wrapping node for the "body" node
nested = nested || (type !== "wrapper");
@ -653,7 +653,24 @@ export const createParser = (
return Object.keys(traits).length > 0
};
const isBinary = (token: Token): TwingOperator | null => {
const isBinary = (token: Token): {
associativity: TwingOperator["associativity"];
expressionFactory: TwingOperator["expressionFactory"];
name: TwingOperator["name"];
precedence: TwingOperator["precedence"];
} | {
expressionFactory: null;
name: "is" | "is not";
precedence: TwingOperator["precedence"];
} | null => {
if (token.value === "is" || token.value === "is not") {
return {
expressionFactory: null,
name: token.value,
precedence: 100
};
}
return (token.test("OPERATOR") && binaryOperatorsRegister.get(token.value)) || null;
};
@ -1020,30 +1037,29 @@ export const createParser = (
let expression = getPrimary(stream);
let token = stream.current;
let operator: TwingOperator | null = null;
let operator: ReturnType<typeof isBinary> = null;
if ((token.value === "is not") || (token.value === "is")) {
while (((operator = isBinary(token)) !== null && operator.precedence >= precedence)) {
stream.next();
if (token.value === "is not") {
expression = parseNotTestExpression(stream, expression);
if (operator.expressionFactory === null) {
expression = parseTestExpression(stream, expression);
if (operator.name === "is not") {
const {line, column} = stream.current;
expression = createNotNode(expression, line, column);
}
}
else {
expression = parseTestExpression(stream, expression);
}
}
else {
while (((operator = isBinary(token)) !== null) && operator.precedence >= precedence) {
stream.next();
const {expressionFactory} = operator;
const operand = parseExpression(stream, operator.associativity === "LEFT" ? operator.precedence + 1 : operator.precedence, true);
expression = expressionFactory([expression, operand], token.line, token.column);
token = stream.current;
}
token = stream.current;
}
if (precedence === 0) {
@ -1233,12 +1249,6 @@ export const createParser = (
return createWrapperNode(targets, line, column);
};
const parseNotTestExpression = (stream: TwingTokenStream, node: TwingBaseExpressionNode): TwingBaseExpressionNode => {
const {line, column} = stream.current;
return createNotNode(parseTestExpression(stream, node), line, column);
};
const parsePostfixExpression = (stream: TwingTokenStream, node: TwingBaseExpressionNode, prefixToken: Token): TwingBaseExpressionNode => {
while (true) {
let token = stream.current;

View File

@ -1,4 +1,5 @@
import "./basic";
import "./expression";
import "./expression_as_boolean";
import "./on-hash";
import "./on-hash";
import "./with-test-as-binary-expression-operand";

View File

@ -0,0 +1,16 @@
import {runTest} from "../../TestBase";
runTest({
description: '"if" tag with a test as binary expression operand',
templates: {
"index.twig": `
{% if a is defined and b %}true{% else %}false{% endif %}
`
},
expectation: `
true`,
context: Promise.resolve({
a: true,
b: true
})
});