in src/main/java/org/apache/sling/scripting/sightly/impl/plugin/ListPlugin.java [46:170]
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");
private String collectionNotEmpty = compilerContext.generateVariable("notEmpty");
private String beginVariable = compilerContext.generateVariable(BEGIN);
private String stepVariable = compilerContext.generateVariable(STEP);
private String endVariable = compilerContext.generateVariable(END);
private String validStartStepEnd = compilerContext.generateVariable("validStartStepEnd");
private boolean beginAtIndexZero = false;
private boolean stepOne = false;
@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 VariableBinding.Start(collectionNotEmpty, new BinaryOperation(BinaryOperator.GT, new Identifier
(collectionSizeVar), NumericConstant.ZERO)));
stream.write(new Conditional.Start(collectionNotEmpty, true));
Map<String, ExpressionNode> options = expression.getOptions();
if (options.containsKey(BEGIN)) {
stream.write(new VariableBinding.Start(beginVariable, expression.getOptions().get(BEGIN)));
} else {
beginAtIndexZero = true;
stream.write(new VariableBinding.Start(beginVariable, NumericConstant.ZERO));
}
if (options.containsKey(STEP)) {
stream.write(new VariableBinding.Start(stepVariable, expression.getOptions().get(STEP)));
} else {
stepOne = true;
stream.write(new VariableBinding.Start(stepVariable, NumericConstant.ONE));
}
if (options.containsKey(END)) {
stream.write(new VariableBinding.Start(endVariable, expression.getOptions().get(END)));
} else {
stream.write(new VariableBinding.Start(endVariable, new Identifier(collectionSizeVar)));
}
stream.write(new VariableBinding.Start(validStartStepEnd,
new BinaryOperation(BinaryOperator.AND,
new BinaryOperation(BinaryOperator.AND,
new BinaryOperation(BinaryOperator.LT, new Identifier(beginVariable), new Identifier(collectionSizeVar)),
new BinaryOperation(
BinaryOperator.AND,
new BinaryOperation(BinaryOperator.GEQ, new Identifier(beginVariable), NumericConstant.ZERO),
new BinaryOperation(BinaryOperator.GT, new Identifier(stepVariable), NumericConstant.ZERO)
)
),
new BinaryOperation(BinaryOperator.GT, new Identifier(endVariable), NumericConstant.ZERO)
)
)
);
stream.write(new Conditional.Start(validStartStepEnd, 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)));
String stepConditionVariable = compilerContext.generateVariable("stepCondition");
stream.write(new VariableBinding.Start(stepConditionVariable,
beginAtIndexZero && stepOne ? new NumericConstant(0) :
new BinaryOperation(
BinaryOperator.REM,
new BinaryOperation(
BinaryOperator.SUB,
new Identifier(indexVariable),
new Identifier(beginVariable)
),
new Identifier(stepVariable))
)
);
String loopTraversalVariable = compilerContext.generateVariable("traversal");
stream.write(new VariableBinding.Start(loopTraversalVariable,
new BinaryOperation(
BinaryOperator.AND,
new BinaryOperation(
BinaryOperator.AND,
new BinaryOperation(BinaryOperator.GEQ, new Identifier(indexVariable), new Identifier(beginVariable)),
new BinaryOperation(BinaryOperator.LEQ, new Identifier(indexVariable), new Identifier(endVariable))
),
new BinaryOperation(BinaryOperator.EQ, new Identifier(stepConditionVariable), NumericConstant.ZERO)
)
)
);
stream.write(new Conditional.Start(loopTraversalVariable, true));
}
@Override
public void afterChildren(PushStream stream) {
stream.write(Conditional.END);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
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);
stream.write(VariableBinding.END);
stream.write(VariableBinding.END);
stream.write(Conditional.END);
stream.write(VariableBinding.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;
}
};
}