Package client.net.sf.saxon.ce.expr

Source Code of client.net.sf.saxon.ce.expr.ExpressionVisitor

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

import client.net.sf.saxon.ce.Configuration;
import client.net.sf.saxon.ce.expr.instruct.Executable;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.tree.util.SourceLocator;
import client.net.sf.saxon.ce.type.ItemType;

import java.util.Iterator;
import java.util.Stack;

/**
*  The ExpressionVisitor supports the various phases of processing of an expression tree which require
*  a recursive walk of the tree structure visiting each node in turn. In maintains a stack holding the
*  ancestor nodes of the node currently being visited.
*/

public class ExpressionVisitor {

    private Stack<Expression> stack;
    private Executable executable;
    private StaticContext staticContext;
    private Configuration configuration;

    /**
     * Create an ExpressionVisitor
     */

    public ExpressionVisitor() {
        stack = new Stack<Expression>();
    }
   
    private SourceLocator getLastLocator() {
      int stackSize = stack.size();
      Expression[] expr = new Expression[stackSize];
      stack.toArray(expr);
      SourceLocator result = null;
      for (int i = stackSize -1; i > -1; i--) {
        if (expr[i].sourceLocator != null) {
          return expr[i].sourceLocator;
        }
      }
      return result;
    }
   
    public String getLocation() {
      SourceLocator sl = getLastLocator();
      String message = "";
      if (sl != null) {
        message = sl.getLocation();
        int pos = message.indexOf(" in ");
        if (pos > -1) {
          message = message.substring(0, pos);
        }
      }
     
      return message;
    }

    /**
     * Get the Saxon configuration
     * @return the Saxon configuration
     */

    public Configuration getConfiguration() {
        return configuration;
    }

    /**
     * Set the Saxon configuration
     * @param configuration the Saxon configuration
     */


    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    /**
     * Get the Executable containing the expressions being visited
     * @return the Executable
     */

    public Executable getExecutable() {
        return executable;
    }

    /**
     * Set the Executable containing the expressions being visited
     * @param executable the Executable
     */

    public void setExecutable(Executable executable) {
        this.executable = executable;
    }

    /**
     * Get the static context for the expressions being visited. Note: this may not reflect all changes
     * in static context (e.g. namespace context, base URI) applying to nested expressions
     * @return the static context
     */

    public StaticContext getStaticContext() {
        return staticContext;
    }

    /**
     * Set the static context for the expressions being visited. Note: this may not reflect all changes
     * in static context (e.g. namespace context, base URI) applying to nested expressions
     * @param staticContext the static context
     */

    public void setStaticContext(StaticContext staticContext) {
        this.staticContext = staticContext;
    }

    /**
     * Factory method: make an expression visitor
     * @param env the static context
     * @return the new expression visitor
     */

    public static ExpressionVisitor make(StaticContext env, Executable exec) {
        ExpressionVisitor visitor = new ExpressionVisitor();
        visitor.setStaticContext(env);
        visitor.setExecutable(exec);
        visitor.setConfiguration(env.getConfiguration());
        return visitor;
    }

    /**
     * Issue a warning message
     * @param message the message
     */

    public void issueWarning(String message, SourceLocator locator) {
        staticContext.issueWarning(message, locator);
    }

    /**
     * Create a dynamic context suitable for early evaluation of constant subexpressions
     */

    public XPathContext makeDynamicContext() {
        return staticContext.makeEarlyEvaluationContext();
    }

    /**
     * Simplify an expression, via the ExpressionVisitor
     * @param exp the expression to be simplified
     * @return the simplified expression
     * @throws XPathException
     */

    public Expression simplify(Expression exp) throws XPathException {
        if (exp != null) {
            stack.push(exp);
            Expression exp2 = exp.simplify(this);
            if (exp2 != exp) {
                ExpressionTool.copyLocationInfo(exp, exp2);
            }
            stack.pop();
            return exp2;
        } else {
            return null;
        }
    }

    /**
     * Type check an expression, via the ExpressionVisitor
     * @param exp the expression to be typechecked
     * @param contextItemType the static type of the context item for this expression
     * @return the expression that results from type checking (this may be wrapped in expressions that
     * perform dynamic checking of the item type or cardinality, or that perform atomization or numeric
     * promotion)
     * @throws XPathException if static type checking fails, that is, if the expression cannot possibly
     * deliver a value of the required type
     */

    public Expression typeCheck(Expression exp, ItemType contextItemType) throws XPathException {
        if (exp != null) {
            stack.push(exp);
            Expression exp2 = exp.typeCheck(this, contextItemType);
            if (exp2 != exp) {
                ExpressionTool.copyLocationInfo(exp, exp2);
            }
            stack.pop();
            return exp2;
        } else {
            return null;
        }
    }

   /**
     * Optimize an expression, via the ExpressionVisitor
     * @param exp the expression to be typechecked
     * @param contextItemType the static type of the context item for this expression
     * @return the rewritten expression
     * @throws XPathException
     */

    public Expression optimize(Expression exp, ItemType contextItemType) throws XPathException {
        if (exp != null) {
            stack.push(exp);
            Expression exp2 = exp.optimize(this, contextItemType);
            if (exp2 != exp) {
                ExpressionTool.copyLocationInfo(exp, exp2);
            }
            stack.pop();
            return exp2;
        } else {
            return null;
        }
    }

    /**
     * Return true if the current expression at the top of the visitor's stack is evaluated repeatedly
     * when a given ancestor expression is evaluated once
     * @param ancestor the ancestor expression. May be null, in which case the search goes all the way
     * to the base of the stack.
     * @return true if the current expression is evaluated repeatedly
     */

    public boolean isLoopingSubexpression(Expression ancestor) {
        int top = stack.size()-1;
        while (true) {
            if (top <= 0) {
                return false;
            }
            Expression parent = stack.get(top - 1);
            if (parent.hasLoopingSubexpression((stack.get(top)))) {
                return true;
            }
            if (parent == ancestor) {
                return false;
            }
            top--;
        }
    }

   /**
     * Reset the static properties for the current expression and for all its containing expressions.
     * This should be done whenever the expression is changed in a way that might
     * affect the properties. It causes the properties to be recomputed next time they are needed.
     */

    public final void resetStaticProperties() {
       Iterator<Expression> up = stack.iterator();
       while (up.hasNext()) {
           Expression exp = up.next();
           exp.resetLocalStaticProperties();
       }
    }


}

// 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.expr.ExpressionVisitor

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.