This class, ExpressionTool, contains a number of useful static methods
for manipulating expressions. Most importantly, it provides the factory
method make() for constructing a new expression
CALL_EVALUATE_ITEM
public static final int CALL_EVALUATE_ITEM
EVALUATE_AND_MATERIALIZE_VARIABLE
public static final int EVALUATE_AND_MATERIALIZE_VARIABLE
EVALUATE_VARIABLE
public static final int EVALUATE_VARIABLE
ITERATE_AND_MATERIALIZE
public static final int ITERATE_AND_MATERIALIZE
LAZY_TAIL_EXPRESSION
public static final int LAZY_TAIL_EXPRESSION
MAKE_CLOSURE
public static final int MAKE_CLOSURE
MAKE_INDEXED_VARIABLE
public static final int MAKE_INDEXED_VARIABLE
MAKE_MEMO_CLOSURE
public static final int MAKE_MEMO_CLOSURE
MAKE_SINGLETON_CLOSURE
public static final int MAKE_SINGLETON_CLOSURE
NO_EVALUATION_NEEDED
public static final int NO_EVALUATION_NEEDED
PROCESS
public static final int PROCESS
RETURN_EMPTY_SEQUENCE
public static final int RETURN_EMPTY_SEQUENCE
SHARED_APPEND_EXPRESSION
public static final int SHARED_APPEND_EXPRESSION
UNDECIDED
public static final int UNDECIDED
allocateSlots
public static int allocateSlots(Expression exp,
int nextFree,
SlotManager frame)
Allocate slot numbers to range variables
exp
- the expression whose range variables need to have slot numbers assignednextFree
- the next slot number that is available for allocationframe
- a SlotManager object that is used to track the mapping of slot numbers
to variable names for debugging purposes. May be null.
- the next unallocated slot number.
callsFunction
public static boolean callsFunction(Expression exp,
StructuredQName qName)
Determine whether an expression contains a call on the function with a given fingerprint
exp
- The expression being testedqName
- The name of the function
- true if the expression contains a call on the function
copyLocationInfo
public static void copyLocationInfo(Expression from,
Expression to)
Copy location information (the line number and reference to the container) from one expression
to another
from
- the expression containing the location informationto
- the expression to which the information is to be copied
dependsOnVariable
public static boolean dependsOnVariable(Expression e,
Binding[] bindingList)
Determine whether an expression depends on any one of a set of variables
e
- the expression being testedbindingList
- the set of variables being tested
- true if the expression depends on one of the given variables
eagerEvaluate
public static ValueRepresentation eagerEvaluate(Expression exp,
XPathContext context)
throws XPathException
Evaluate an expression now; lazy evaluation is not permitted in this case
exp
- the expression to be evaluatedcontext
- the run-time evaluation context
- the result of evaluating the expression
XPathException
- if any dynamic error occurs evaluating the
expression
eagerEvaluationMode
public static int eagerEvaluationMode(Expression exp)
Determine the method of evaluation to be used when lazy evaluation of an expression is
preferred. This method is called at compile time, after all optimizations have been done,
to determine the preferred strategy for lazy evaluation, depending on the type of expression.
exp
- the expression to be evaluated
- an integer constant identifying the evaluation mode
ebvError
public static void ebvError(String reason)
throws XPathException
Report an error in computing the effective boolean value of an expression
reason
- the nature of the error
effectiveBooleanValue
public static boolean effectiveBooleanValue(SequenceIterator iterator)
throws XPathException
Determine the effective boolean value of a sequence, given an iterator over the sequence
iterator
- An iterator over the sequence whose effective boolean value is required
- the effective boolean value
evaluate
public static ValueRepresentation evaluate(Expression exp,
int evaluationMode,
XPathContext context,
int ref)
throws XPathException
Do lazy evaluation of an expression. This will return a value, which may optionally
be a SequenceIntent, which is a wrapper around an iterator over the value of the expression.
exp
- the expression to be evaluatedevaluationMode
- the evaluation mode for this expressioncontext
- the run-time evaluation context for the expression. If
the expression is not evaluated immediately, then parts of the
context on which the expression depends need to be saved as part of
the Closureref
- an indication of how the value will be used. The value 1 indicates that the value
is only expected to be used once, so that there is no need to keep it in memory. A small value >1
indicates multiple references, so the value will be saved when first evaluated. The special value
FILTERED indicates a reference within a loop of the form $x[predicate], indicating that the value
should be saved in a way that permits indexing.
- a value: either the actual value obtained by evaluating the
expression, or a Closure containing all the information needed to
evaluate it later
expressionSize
public static int expressionSize(Expression exp)
Get the size of an expression tree (the number of subexpressions it contains)
exp
- the expression whose size is required
- the size of the expression tree, as the number of nodes
gatherAllSubExpressions
public static void gatherAllSubExpressions(Expression exp,
HashSet set)
Gather the set of all the subexpressions of an expression (the transitive closure)
exp
- the parent expressionset
- the set to be populated; on return it will contain all the subexpressions.
Beware that testing for membership of a set of expressions relies on the equals() comparison,
which does not test identity.
gatherCalledFunctionNames
public static void gatherCalledFunctionNames(Expression e,
List list)
Gather a list of the names of the user-defined functions which a given expression calls directly
e
- the expression being testedlist
- a list of the functions that are called. The items in this list are strings in the format
"{uri}local/arity"
gatherCalledFunctions
public static void gatherCalledFunctions(Expression e,
List list)
Gather a list of all the user-defined functions which a given expression calls directly
e
- the expression being testedlist
- a list of the functions that are called. The items in this list must
be objects of class UserFunction
gatherReferencedVariables
public static void gatherReferencedVariables(Expression e,
List list)
Gather a list of all the variable bindings on which a given expression depends
e
- the expression being testedlist
- a list to which the bindings are to be added. The items in this list must
implement Binding
gatherVariableReferences
public static void gatherVariableReferences(Expression exp,
Binding binding,
List list)
Get a list of all references to a particular variable within a subtree
exp
- the expression at the root of the subtreebinding
- the variable binding whose references are soughtlist
- a list to be populated with the references to this variable
getReferenceCount
public static int getReferenceCount(Expression exp,
Binding binding,
boolean inLoop)
Determine how often a variable is referenced. This is the number of times
it is referenced at run-time: so a reference in a loop counts as "many". This code
currently handles local variables (Let expressions) and function parameters. It is
not currently used for XSLT template parameters. It's not the end of the world if
the answer is wrong (unless it's wrongly given as zero), but if wrongly returned as
1 then the variable will be repeatedly evaluated.
exp
- the expression within which variable references are to be countedbinding
- identifies the variable of interestinLoop
- true if the expression is within a loop, in which case a reference counts as many.
This should be set to false on the initial call, it may be set to true on an internal recursive
call
- the number of references. The interesting values are 0, 1, "many" (represented
by any value >1), and the special value FILTERED, which indicates that there are
multiple references and one or more of them is of the form $x[....] indicating that an
index might be useful.
indent
public static String indent(int level)
Construct indent string, for diagnostic output
level
- the indentation level (the number of spaces to return)
- a string of "level*2" spaces
isSubtreeExpression
public static boolean isSubtreeExpression(Expression exp)
Determine whether an expression can be evaluated without reference to the part of the context
document outside the subtree rooted at the context node.
exp
- the expression in question
- true if the expression has no dependencies on the context node, or if the only dependencies
on the context node are downward selections using the self, child, descendant, attribute, and namespace
axes.
isVariableReplaceableByDot
public static boolean isVariableReplaceableByDot(Expression exp,
Binding[] binding)
Determine whether it is possible to rearrange an expression so that all references to a given
variable are replaced by a reference to ".". This is true of there are no references to the variable
within a filter predicate or on the rhs of a "/" operator.
exp
- the expression in questionbinding
- an array of bindings defining range variables; the method tests that there are no
references to any of these variables within a predicate or on the rhs of "/"
- true if the variable reference can be replaced
lazyEvaluate
public static ValueRepresentation lazyEvaluate(Expression exp,
XPathContext context,
int ref)
throws XPathException
Do lazy evaluation of an expression. This will return a value, which may optionally
be a SequenceIntent, which is a wrapper around an iterator over the value of the expression.
exp
- the expression to be evaluatedcontext
- the run-time evaluation context for the expression. If
the expression is not evaluated immediately, then parts of the
context on which the expression depends need to be saved as part of
the Closureref
- an indication of how the value will be used. The value 1 indicates that the value
is only expected to be used once, so that there is no need to keep it in memory. A small value >1
indicates multiple references, so the value will be saved when first evaluated. The special value
FILTERED indicates a reference within a loop of the form $x[predicate], indicating that the value
should be saved in a way that permits indexing.
- a value: either the actual value obtained by evaluating the
expression, or a Closure containing all the information needed to
evaluate it later
lazyEvaluationMode
public static int lazyEvaluationMode(Expression exp)
Determine the method of evaluation to be used when lazy evaluation of an expression is
preferred. This method is called at compile time, after all optimizations have been done,
to determine the preferred strategy for lazy evaluation, depending on the type of expression.
exp
- the expression to be evaluated
- an integer constant identifying the evaluation mode
make
public static Expression make(String expression,
StaticContext env,
int start,
int terminator,
int lineNumber,
boolean compileWithTracing)
throws XPathException
Parse an expression. This performs the basic analysis of the expression against the
grammar, it binds variable references and function calls to variable definitions and
function definitions, and it performs context-independent expression rewriting for
optimization purposes.
expression
- The expression (as a character string)env
- An object giving information about the compile-time
context of the expressionstart
- position of the first significant character in the expressionterminator
- The token that marks the end of this expression; typically
Tokenizer.EOF, but may for example be a right curly bracelineNumber
- the line number of the start of the expressioncompileWithTracing
- true if diagnostic tracing during expression parsing is required
- an object of type Expression
markTailFunctionCalls
public static int markTailFunctionCalls(Expression exp,
StructuredQName qName,
int arity)
Scan an expression to find and mark any recursive tail function calls
exp
- the expression to be analyzedqName
- the name of the containing functionarity
- the arity of the containing function
- 0 if no tail call was found; 1 if a tail call to a different function was found;
2 if a tail call to the specified function was found. In this case the
UserFunctionCall object representing the tail function call will also have been marked as
a tail call.
rebindVariableReferences
public static void rebindVariableReferences(Expression exp,
Binding oldBinding,
Binding newBinding)
Rebind all variable references to a binding
exp
- the expression whose contained variable references are to be reboundoldBinding
- the old binding for the variable referencesnewBinding
- the new binding to which the variables should be rebound
resetPropertiesWithinSubtree
public static void resetPropertiesWithinSubtree(Expression exp)
Reset cached static properties within a subtree, meaning that they have to be
recalulated next time they are required
exp
- the root of the subtree within which static properties should be reset
resolveCallsToCurrentFunction
public static Expression resolveCallsToCurrentFunction(Expression exp,
Configuration config)
throws XPathException
Resolve calls to the XSLT current() function within an expression
exp
- the expression within which calls to current() should be resolvedconfig
- the Saxon configuration
- the expression after resolving calls to current()
unsorted
public static Expression unsorted(Optimizer opt,
Expression exp,
boolean eliminateDuplicates)
throws XPathException
Remove unwanted sorting from an expression, at compile time
opt
- the expression optimizerexp
- the expression to be optimizedeliminateDuplicates
- true if there is a need to eliminate duplicates even though
there is no need to deliver results in order.
- the expression after rewriting
unsortedIfHomogeneous
public static Expression unsortedIfHomogeneous(Optimizer opt,
Expression exp,
boolean eliminateDuplicates)
throws XPathException
Remove unwanted sorting from an expression, at compile time, if and only if it is known
that the result of the expression will be homogeneous (all nodes, or all atomic values).
This is done when we need the effective boolean value of a sequence: the EBV of a
homogenous sequence does not depend on its order, but this is not true when atomic
values and nodes are mixed: (N, AV) is true, but (AV, N) is an error.
opt
- the expression optimizerexp
- the expression to be optimizedeliminateDuplicates
- true if there is a need to eliminate duplicate nodes even though there
is no requirement to deliver results in order
- the expression after rewriting