Package client.net.sf.saxon.ce.style

Source Code of client.net.sf.saxon.ce.style.XSLVariableDeclaration

package client.net.sf.saxon.ce.style;

import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.expr.instruct.GeneralVariable;
import client.net.sf.saxon.ce.expr.instruct.GlobalVariable;
import client.net.sf.saxon.ce.expr.instruct.SlotManager;
import client.net.sf.saxon.ce.pattern.AnyNodeTest;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.TypeHierarchy;
import client.net.sf.saxon.ce.value.SequenceType;
import client.net.sf.saxon.ce.value.Value;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
* Generic class for xsl:variable and xsl:param elements. <br>
*/

public abstract class XSLVariableDeclaration
        extends XSLGeneralVariable
        implements VariableDeclaration, StylesheetProcedure {

    // The slot number for the variable is allocated at this level (a) for global variables, and
    // (b) for local parameters. For local variables, slot numbers are allocated only after an entire
    // template or function has been compiled.

    private int slotNumber = -9876// initial value designed solely to show up when debugging

    // List of VariableReference objects that reference this XSLVariableDeclaration
    protected List references = new ArrayList(10);

    /**
     * Ask whether this node is a declaration, that is, a permitted child of xsl:stylesheet
     * (including xsl:include and xsl:import).
     * @return true for this element
     */

    @Override
    public boolean isDeclaration() {
        return true;
    }   

    /**
     * Get the SlotManager associated with this stylesheet construct. The SlotManager contains the
     * information needed to manage the local stack frames used by run-time instances of the code.
     * @return the associated SlotManager object
     */

    public SlotManager getSlotManager() {
        return slotManager;
    }

    /**
     * Get the slot number allocated to this variable (its position in the stackframe)
     * @return the allocated slot number
     */

    public int getSlotNumber() {
        return slotNumber;
    }

    /**
     * Allocate a slot number to this variable
     * @param slot the position of the variable on the local stack frame
     */

    public void setSlotNumber(int slot) {
        slotNumber = slot;
    }

    /**
     * Get the static type of the variable.
     * @return the static type declared for the variable
    */

    public abstract SequenceType getRequiredType();

    /**
    * Method called by VariableReference to register the variable reference for
    * subsequent fixup
    */

    public void registerReference(VariableReference ref) {
        references.add(ref);
    }

    /**
    * Determine whether this node is an instruction.
    * @return true - it is an instruction (well, it can be, anyway)
    */

    public boolean isInstruction() {
        return true;
    }

    /**
    * Notify all references to this variable of the data type
    */

    public void fixupReferences() throws XPathException {
        final SequenceType type = getRequiredType();
        final TypeHierarchy th = getConfiguration().getTypeHierarchy();
        final Iterator iter = references.iterator();
        while (iter.hasNext()) {
            Value constantValue = null;
            int properties = 0;
            if (this instanceof XSLVariable) {
                if (select instanceof Literal) {
                    // we can't rely on the constant value because it hasn't yet been type-checked,
                    // which could change it (eg by numeric promotion). Rather than attempt all the type-checking
                    // now, we do a quick check. See test bug64
                    int relation = th.relationship(select.getItemType(th), type.getPrimaryType());
                    if (relation == TypeHierarchy.SAME_TYPE || relation == TypeHierarchy.SUBSUMED_BY) {
                        constantValue = ((Literal)select).getValue();
                    }
                }
                if (select != null) {
                    properties = select.getSpecialProperties();
                }
            }
            ((VariableReference)iter.next()).setStaticType(type, constantValue, properties);
        }
        super.fixupReferences();
    }

    /**
    * Check that the variable is not already declared, and allocate a slot number
     * @param decl
     */

    public void validate(Declaration decl) throws XPathException {
        super.validate(decl);
        if (global) {
            if (!redundant) {
                slotNumber = getExecutable().getGlobalVariableMap().allocateSlotNumber(getVariableQName());
            }
        }
    }

    /**
     * Notify all variable references of the Binding instruction
     * @param binding the Binding that represents this variable declaration in the executable code tree
    */

    protected void fixupBinding(Binding binding) {
        Iterator iter = references.iterator();
        while (iter.hasNext()) {
            ((VariableReference)iter.next()).fixup(binding);
        }
    }

    /**
     * Set the number of references to this variable. This code is invoked only for a global variable,
     * and only if there is at least one reference.
     * @param var the variable
     */

    protected void setReferenceCount(GeneralVariable var) {
        var.setReferenceCount(10)// TODO: temporary
    }

    protected void index(Declaration decl, PrincipalStylesheetModule top) throws XPathException {
        top.indexVariableDeclaration(decl);
    }

    /**
     * Optimize the stylesheet construct
     * @param declaration
     */

    public void optimize(Declaration declaration) throws XPathException {
        if (global && !redundant && select!=null) {
            Expression exp2 = select;
            ExpressionVisitor visitor = makeExpressionVisitor();
            Optimizer opt = getConfiguration().getOptimizer();
            try {
                if (opt.getOptimizationLevel() != Optimizer.NO_OPTIMIZATION) {
                    exp2 = exp2.optimize(visitor, AnyNodeTest.getInstance());
                }

            } catch (XPathException err) {
                err.maybeSetLocation(this);
                compileError(err);
            }

            // Try to extract new global variables from the body of the variable declaration
            // (but don't extract the whole body!)
//            if (opt.getOptimizationLevel() != Optimizer.NO_OPTIMIZATION) {
//                exp2 = opt.promoteExpressionsToGlobal(exp2, visitor, true);
//            }
            // dropped because it doesn't seem to do much good - just splits up an expression
            // into lots of small global variables.

            allocateSlots(exp2);
            if (slotManager != null && slotManager.getNumberOfVariables() > 0) {
                ((GlobalVariable)compiledVariable).setContainsLocals(slotManager);
            }

            if (exp2 != select) {
                select = exp2;
                compiledVariable.setSelectExpression(select);
            }
        }
    }

    /**
     * Get the compiled variable
     * @return the compiled variable if it has been compiled, or null otherwise
     */

    public GeneralVariable getCompiledVariable() {
        return compiledVariable;
    }
}

// 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.
TOP

Related Classes of client.net.sf.saxon.ce.style.XSLVariableDeclaration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.