public PluginInvoke invoke()

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;
            }
        };
    }