All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.expr.instruct.Fork Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2018-2023 Saxonica Limited
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.expr.instruct;

import net.sf.saxon.expr.Expression;
import net.sf.saxon.expr.Operand;
import net.sf.saxon.expr.OperandRole;
import net.sf.saxon.expr.elab.Elaborator;
import net.sf.saxon.expr.elab.PushElaborator;
import net.sf.saxon.expr.elab.PushEvaluator;
import net.sf.saxon.expr.parser.ExpressionTool;
import net.sf.saxon.expr.parser.RebindingMap;
import net.sf.saxon.om.StandardNames;
import net.sf.saxon.trace.ExpressionPresenter;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.AnyItemType;
import net.sf.saxon.type.ErrorType;
import net.sf.saxon.type.ItemType;
import net.sf.saxon.type.Type;

import java.util.Arrays;


/**
 * This class implements an xsl:fork expression.
 */

public class Fork extends Instruction {

    Operand[] operanda;

    /**
     * Create a Fork instruction
     * @param prongs the children of the xsl:fork instructions.
     */

    public Fork(Operand[] prongs) {
        operanda = new Operand[prongs.length];
        for (int i=0; i operands() {
        return Arrays.asList(operanda);
    }

    /**
     * Get the namecode of the instruction for use in diagnostics
     *
     * @return a code identifying the instruction: typically but not always
     *         the fingerprint of a name in the XSLT namespace
     */

    @Override
    public int getInstructionNameCode() {
        return StandardNames.XSL_FORK;
    }

    /**
     * Get the number of prongs in the fork
     * @return the number of xsl:sequence children
     */

    public int getSize() {
        return operanda.length;
    }

    /**
     * Get the n'th child expression of the xsl:fork (zero-based)
     * @param i the index of the required subexpression
     * @return the i'th subexpression if it exists
     * @throws IllegalArgumentException if i is out of range
     */

    public Expression getProng(int i) {
        return operanda[i].getChildExpression();
    }

    /**
     * Determine the item type of the value returned by the function
     */

    /*@NotNull*/
    @Override
    public ItemType getItemType() {
        if (getSize() == 0) {
            return ErrorType.getInstance();
        }
        ItemType t1 = null;
        for (Operand o : operands()) {
            ItemType t2 = o.getChildExpression().getItemType();
            t1 = t1 == null ? t2 : Type.getCommonSuperType(t1, t2);
            if (t1 instanceof AnyItemType) {
                return t1;  // no point going any further
            }
        }
        return t1;
    }

    /**
     * Get the (partial) name of a class that supports streaming of this kind of expression
     *
     * @return the partial name of a class that can be instantiated to provide streaming support in Saxon-EE,
     * or null if there is no such class
     */
    @Override
    public String getStreamerName() {
        return "Fork";
    }

    /**
     * Copy an expression. This makes a deep copy.
     *
     * @return the copy of the original expression
     * @param rebindings the rebinding map
     */

    /*@NotNull*/
    @Override
    public Expression copy(RebindingMap rebindings) {
        Expression[] e2 = new Expression[getSize()];
        int i=0;
        for (Operand o : operands()) {
            e2[i++] = o.getChildExpression().copy(rebindings);
        }
        Fork f2 = new Fork(e2);
        ExpressionTool.copyLocationInfo(this, f2);
        return f2;
    }

    /**
     * Diagnostic print of expression structure. The abstract expression tree
     * is written to the supplied output destination.
     *
     * @param out the expression presenter used to display the structure
     */

    @Override
    public void export(ExpressionPresenter out) throws XPathException {
        out.startElement("fork", this);
        for (Operand o : operands()) {
            o.getChildExpression().export(out);
        }
        out.endElement();
    }

    @Override
    public Elaborator getElaborator() {
        return new ForkElaborator();
    }

    private static class ForkElaborator extends PushElaborator {

        @Override
        public PushEvaluator elaborateForPush() {
            Fork expr = (Fork)getExpression();
            PushEvaluator[] prongs = new PushEvaluator[expr.getSize()];
            for (int i=0; i {
                // non-streamed evaluation
                for (PushEvaluator prong : prongs) {
                    dispatchTailCall(prong.processLeavingTail(output, context));
                }
                return null;
            };
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy