use of org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation in project sling by apache.
the class RepeatPlugin method invoke.
@Override
public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
return new DefaultPluginInvoke() {
private String listVariable = compilerContext.generateVariable("collectionVar");
private String collectionSizeVar = compilerContext.generateVariable("size");
@Override
public void beforeElement(PushStream stream, String tagName) {
stream.write(new VariableBinding.Start(listVariable, expression.getRoot()));
stream.write(new VariableBinding.Start(collectionSizeVar, new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable))));
stream.write(new Conditional.Start(collectionSizeVar, true));
String itemVariable = decodeItemVariable();
String loopStatusVar = Syntax.itemLoopStatusVariable(itemVariable);
String indexVariable = compilerContext.generateVariable("index");
stream.write(new Loop.Start(listVariable, itemVariable, indexVariable));
stream.write(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar)));
}
@Override
public void afterTagClose(PushStream stream, boolean isSelfClosing) {
stream.write(NEW_LINE);
}
@Override
public void afterElement(PushStream stream) {
stream.write(VariableBinding.END);
stream.write(Loop.END);
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
}
private String decodeItemVariable() {
String[] args = callInfo.getArguments();
if (args.length > 0) {
return args[0];
}
return Syntax.DEFAULT_LIST_ITEM_VAR_NAME;
}
private MapLiteral buildStatusObj(String indexVar, String sizeVar) {
HashMap<String, ExpressionNode> obj = new HashMap<>();
Identifier indexId = new Identifier(indexVar);
BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO);
BinaryOperation lastExpr = new BinaryOperation(BinaryOperator.EQ, indexId, new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE));
obj.put(INDEX, indexId);
obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE));
obj.put(FIRST, firstExpr);
obj.put(MIDDLE, new UnaryOperation(UnaryOperator.NOT, new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr)));
obj.put(LAST, lastExpr);
obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO));
obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE));
return new MapLiteral(obj);
}
private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
return new BinaryOperation(BinaryOperator.EQ, new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO), expected);
}
};
}
use of org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation in project sling by apache.
the class ExpressionReducer method evaluate.
@Override
public EvalResult evaluate(BinaryOperation binaryOperation) {
EvalResult left = eval(binaryOperation.getLeftOperand());
EvalResult right = eval(binaryOperation.getRightOperand());
if (!(left.isConstant() && right.isConstant())) {
return EvalResult.nonConstant(new BinaryOperation(binaryOperation.getOperator(), left.getNode(), right.getNode()));
}
return EvalResult.constant(binaryOperation.getOperator().eval(left.getValue(), right.getValue()));
}
use of org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation in project sling by apache.
the class MarkupHandler method emitMultipleFragment.
private void emitMultipleFragment(String name, Interpolation interpolation, char quoteChar, PluginInvoke invoke) {
// Simplified algorithm for attribute output, which works when the interpolation is not of size 1. In this
// case we are certain that the attribute value cannot be the boolean value true, so we can skip this test
// altogether
Expression expression = expressionWrapper.transform(interpolation, getAttributeMarkupContext(name), ExpressionContext.ATTRIBUTE);
String attrContent = symbolGenerator.next("attrContent");
String shouldDisplayAttr = symbolGenerator.next("shouldDisplayAttr");
stream.write(new VariableBinding.Start(attrContent, expression.getRoot()));
stream.write(new VariableBinding.Start(shouldDisplayAttr, new BinaryOperation(BinaryOperator.OR, new Identifier(attrContent), new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrContent)))));
stream.write(new Conditional.Start(shouldDisplayAttr, true));
emitAttributeStart(name);
invoke.beforeAttributeValue(stream, name, expression.getRoot());
emitAttributeValueStart(quoteChar);
stream.write(new OutputVariable(attrContent));
emitAttributeEnd(quoteChar);
invoke.afterAttributeValue(stream, name);
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
}
use of org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation in project sling by apache.
the class ListPlugin method invoke.
@Override
public PluginInvoke invoke(final Expression expression, final PluginCallInfo callInfo, final CompilerContext compilerContext) {
return new DefaultPluginInvoke() {
private String listVariable = compilerContext.generateVariable("collectionVar");
private String collectionSizeVar = compilerContext.generateVariable("size");
@Override
public void beforeElement(PushStream stream, String tagName) {
stream.write(new VariableBinding.Start(listVariable, expression.getRoot()));
stream.write(new VariableBinding.Start(collectionSizeVar, new UnaryOperation(UnaryOperator.LENGTH, new Identifier(listVariable))));
stream.write(new Conditional.Start(collectionSizeVar, true));
}
@Override
public void beforeChildren(PushStream stream) {
String itemVariable = decodeItemVariable();
String loopStatusVar = Syntax.itemLoopStatusVariable(itemVariable);
String indexVariable = compilerContext.generateVariable("index");
stream.write(new Loop.Start(listVariable, itemVariable, indexVariable));
stream.write(new VariableBinding.Start(loopStatusVar, buildStatusObj(indexVariable, collectionSizeVar)));
}
@Override
public void afterChildren(PushStream stream) {
stream.write(VariableBinding.END);
stream.write(Loop.END);
}
@Override
public void afterElement(PushStream stream) {
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
}
private String decodeItemVariable() {
String[] args = callInfo.getArguments();
if (args.length > 0) {
return args[0];
}
return Syntax.DEFAULT_LIST_ITEM_VAR_NAME;
}
private MapLiteral buildStatusObj(String indexVar, String sizeVar) {
HashMap<String, ExpressionNode> obj = new HashMap<>();
Identifier indexId = new Identifier(indexVar);
BinaryOperation firstExpr = new BinaryOperation(BinaryOperator.EQ, indexId, NumericConstant.ZERO);
BinaryOperation lastExpr = new BinaryOperation(BinaryOperator.EQ, indexId, new BinaryOperation(BinaryOperator.SUB, new Identifier(sizeVar), NumericConstant.ONE));
obj.put(INDEX, indexId);
obj.put(COUNT, new BinaryOperation(BinaryOperator.ADD, indexId, NumericConstant.ONE));
obj.put(FIRST, firstExpr);
obj.put(MIDDLE, new UnaryOperation(UnaryOperator.NOT, new BinaryOperation(BinaryOperator.OR, firstExpr, lastExpr)));
obj.put(LAST, lastExpr);
obj.put(ODD, parityCheck(indexId, NumericConstant.ZERO));
obj.put(EVEN, parityCheck(indexId, NumericConstant.ONE));
return new MapLiteral(obj);
}
private ExpressionNode parityCheck(ExpressionNode numericExpression, NumericConstant expected) {
return new BinaryOperation(BinaryOperator.EQ, new BinaryOperation(BinaryOperator.REM, numericExpression, NumericConstant.TWO), expected);
}
};
}
use of org.apache.sling.scripting.sightly.compiler.expression.nodes.BinaryOperation in project sling by apache.
the class MarkupHandler method emitSingleFragment.
private void emitSingleFragment(String name, Interpolation interpolation, char quoteChar, PluginInvoke invoke) {
//raw expression
Expression valueExpression = expressionWrapper.transform(interpolation, null, ExpressionContext.ATTRIBUTE);
//holds the raw attribute value
String attrValue = symbolGenerator.next("attrValue");
//holds the escaped attribute value
String attrContent = symbolGenerator.next("attrContent");
// holds the comparison (attrValue == true)
String isTrueVar = symbolGenerator.next("isTrueAttr");
String shouldDisplayAttr = symbolGenerator.next("shouldDisplayAttr");
MarkupContext markupContext = getAttributeMarkupContext(name);
boolean alreadyEscaped = false;
if (valueExpression.getRoot() instanceof RuntimeCall) {
RuntimeCall rc = (RuntimeCall) valueExpression.getRoot();
if (RuntimeFunction.XSS.equals(rc.getFunctionName())) {
alreadyEscaped = true;
}
}
ExpressionNode node = valueExpression.getRoot();
//attrContent = <expr>
stream.write(new VariableBinding.Start(attrValue, node));
if (!alreadyEscaped) {
Expression contentExpression = valueExpression.withNode(new Identifier(attrValue));
stream.write(new VariableBinding.Start(attrContent, adjustContext(compilerContext, contentExpression, markupContext, ExpressionContext.ATTRIBUTE).getRoot()));
stream.write(new VariableBinding.Start(shouldDisplayAttr, new BinaryOperation(BinaryOperator.OR, new Identifier(attrContent), new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue)))));
} else {
stream.write(new VariableBinding.Start(shouldDisplayAttr, new BinaryOperation(BinaryOperator.OR, new Identifier(attrValue), new BinaryOperation(BinaryOperator.EQ, new StringConstant("false"), new Identifier(attrValue)))));
}
// if (attrContent)
stream.write(new Conditional.Start(shouldDisplayAttr, true));
//write("attrName");
emitAttributeStart(name);
invoke.beforeAttributeValue(stream, name, node);
stream.write(new //isTrueAttr = (attrValue == true)
VariableBinding.Start(//isTrueAttr = (attrValue == true)
isTrueVar, new BinaryOperation(BinaryOperator.EQ, new Identifier(attrValue), BooleanConstant.TRUE)));
//if (!isTrueAttr)
stream.write(new Conditional.Start(isTrueVar, false));
// write("='");
emitAttributeValueStart(quoteChar);
if (!alreadyEscaped) {
//write(attrContent)
stream.write(new OutputVariable(attrContent));
} else {
// write(attrValue)
stream.write(new OutputVariable(attrValue));
}
//write("'");
emitAttributeEnd(quoteChar);
//end if isTrueAttr
stream.write(Conditional.END);
//end scope for isTrueAttr
stream.write(VariableBinding.END);
invoke.afterAttributeValue(stream, name);
//end if attrContent
stream.write(Conditional.END);
//end scope for attrContent
stream.write(VariableBinding.END);
if (!alreadyEscaped) {
stream.write(VariableBinding.END);
}
//end scope for attrValue
stream.write(VariableBinding.END);
}
Aggregations