@Override public LocalBinding getBinding() { return (LocalBinding)super.getBinding(); }
/** * Get the value of this variable in a given context. * * @param c the XPathContext which contains the relevant variable bindings * @return the value of the variable, if it is defined * @throws XPathException if the variable is undefined */ public SequenceIterator iterate(XPathContext c) throws XPathException { try { ValueRepresentation actual = evaluateVariable(c); return Value.getIterator(actual); } catch (XPathException err) { err.maybeSetLocation(this); throw err; } catch (AssertionError err) { String msg = err.getMessage() + " Variable " + getDisplayName() + " at " + getLineNumber() + " of " + getSystemId(); throw new AssertionError(msg); } }
/** * Rebind all variable references to a binding * @param exp the expression whose contained variable references are to be rebound * @param oldBinding the old binding for the variable references * @param newBinding the new binding to which the variables should be rebound */ public static void rebindVariableReferences( Expression exp, Binding oldBinding, Binding newBinding) { if (exp instanceof VariableReference) { if (((VariableReference)exp).getBinding() == oldBinding) { ((VariableReference)exp).fixup(newBinding); } } else { Iterator iter = exp.iterateSubExpressions(); while (iter.hasNext()) { Expression e = (Expression)iter.next(); rebindVariableReferences(e, oldBinding, newBinding); } } }
public Item evaluateItem(XPathContext c) throws XPathException { try { Sequence<?> actual = evaluateVariable(c); assert actual != null; return actual.head(); } catch (XPathException err) { err.maybeSetLocation(getLocation()); throw err; } }
/** * Provide additional information about the type of the variable, typically derived by analyzing * the initializer of the variable binding * * @param type the item type of the variable * @param cardinality the cardinality of the variable * @param constantValue the actual value of the variable, if this is known statically, otherwise null * @param properties additional static properties of the variable's initializer */ public void refineVariableType(ItemType type, int cardinality, GroundedValue<?> constantValue, int properties) { TypeHierarchy th = getConfiguration().getTypeHierarchy(); ItemType oldItemType = getItemType(); ItemType newItemType = oldItemType; if (th.isSubType(type, oldItemType)) { newItemType = type; } if (oldItemType instanceof NodeTest && type instanceof AtomicType) { // happens when all references are flattened newItemType = type; } int newcard = cardinality & getCardinality(); if (newcard == 0) { // this will probably lead to a type error later newcard = getCardinality(); } SequenceType seqType = SequenceType.makeSequenceType(newItemType, newcard); setStaticType(seqType, constantValue, properties); }
public void refineVariableType(ItemType type, int cardinality, Value constantValue, int properties, ExpressionVisitor visitor) { Executable exec = visitor.getExecutable(); if (exec == null) { // happens during use-when evaluation return; } TypeHierarchy th = exec.getConfiguration().getTypeHierarchy(); ItemType oldItemType = getItemType(th); ItemType newItemType = oldItemType; if (th.isSubType(type, oldItemType)) { newItemType = type; } int newcard = cardinality & getCardinality(); if (newcard==0) { // this will probably lead to a type error later newcard = getCardinality(); } SequenceType seqType = SequenceType.makeSequenceType(newItemType, newcard); setStaticType(seqType, constantValue, properties); }
/** * Refine the type information associated with this variable declaration. This is useful when the * type of the variable has not been explicitly declared (which is common); the variable then takes * a static type based on the type of the expression to which it is bound. The effect of this call * is to update the static expression type for all references to this variable. * @param type the inferred item type of the expression to which the variable is bound * @param cardinality the inferred cardinality of the expression to which the variable is bound * @param constantValue the constant value to which the variable is bound (null if there is no constant value) * @param properties other static properties of the expression to which the variable is bound * @param visitor an expression visitor to provide context information * @param currentExpression the expression that binds the variable */ public void refineTypeInformation(ItemType type, int cardinality, Value constantValue, int properties, ExpressionVisitor visitor, Assignation currentExpression) { List references = new ArrayList(); ExpressionTool.gatherVariableReferences(currentExpression.getAction(), this, references); for (Iterator iter=references.iterator(); iter.hasNext();) { BindingReference ref = (BindingReference)iter.next(); if (ref instanceof VariableReference) { ((VariableReference)ref).refineVariableType(type, cardinality, constantValue, properties, visitor); visitor.resetStaticProperties(); ExpressionTool.resetPropertiesWithinSubtree(currentExpression); } } }
@Override public Sequence<?> evaluate(Expression expr, XPathContext context) throws XPathException { try { return ((VariableReference) expr).evaluateVariable(context); } catch (ClassCastException e) { // should not happen assert false; // but if it does... return LAZY_SEQUENCE.evaluate(expr, context); } }
/** * Refine the type information associated with this variable declaration. This is useful when the * type of the variable has not been explicitly declared (which is common); the variable then takes * a static type based on the type of the expression to which it is bound. The effect of this call * is to update the static expression type for all references to this variable. * @param type the inferred item type of the expression to which the variable is bound * @param cardinality the inferred cardinality of the expression to which the variable is bound * @param constantValue the constant value to which the variable is bound (null if there is no constant value) * @param properties other static properties of the expression to which the variable is bound * @param currentExpression the expression that binds the variable */ public void refineTypeInformation(final ItemType type, final int cardinality, final GroundedValue<?> constantValue, final int properties, final Assignation currentExpression) throws XPathException { ExpressionTool.processExpressionTree(currentExpression.getAction(), null, (exp, result) -> { if (exp instanceof VariableReference && ((VariableReference)exp).getBinding() == currentExpression) { ((VariableReference) exp).refineVariableType(type, cardinality, constantValue, properties); } return false; }); }
/** * Get the value of this variable in a given context. * * @param c the XPathContext which contains the relevant variable bindings * @return the value of the variable, if it is defined * @throws XPathException if the variable is undefined */ /*@NotNull*/ public SequenceIterator<?> iterate(XPathContext c) throws XPathException { try { Sequence<?> actual = evaluateVariable(c); assert actual != null; return actual.iterate(); } catch (XPathException err) { err.maybeSetLocation(getLocation()); throw err; } catch (NullPointerException err) { err.printStackTrace(); String msg = "Internal error: no value for variable $" + getDisplayName() + " at line " + getLocation().getLineNumber() + (getLocation().getSystemId() == null ? "" : " of " + getLocation().getSystemId()); StandardErrorListener.printStackTrace(c, c.getConfiguration().getLogger(), 2); throw new AssertionError(msg); } catch (AssertionError err) { err.printStackTrace(); String msg = err.getMessage() + ". Variable reference $" + getDisplayName() + " at line " + getLocation().getLineNumber() + (getLocation().getSystemId() == null ? "" : " of " + getLocation().getSystemId()); StandardErrorListener.printStackTrace(c, c.getConfiguration().getLogger(), 2); throw new AssertionError(msg); } }
/** * Produce a short string identifying the expression for use in error messages * * @return a short string, sufficient to identify the expression */ @Override public String toShortString() { return "$" + getDisplayName(); }
var.fixup(compiledVar); var.setStaticType(compiledVar.getRequiredType(), sourceBinding.getConstantValue(), 0); } else { sourceBinding.registerReference(var);
public AbstractExpression exprFor (VariableReference var) { if (var.getBinding() != null) { StructuredQName varName= var.getBinding().getVariableQName(); return new Variable (qnameFor (varName)); } else { // total HACK, but Saxon provides no other public method to retrieve the constant value try { Object o = var.optimize(null, null); if (o instanceof Literal) { return exprFor ((Literal) o); } } catch (XPathException e) { throw new LuxException ("Unsupported variable reference: " + var); } throw new LuxException ("Unsupported variable reference: " + var); } }
/** * Create a Variable Reference * * @param binding the variable binding to which this variable refers */ public VariableReference(Binding binding) { //System.err.println("Creating varRef1"); variableName = binding.getVariableQName(); fixup(binding); }
/** * Fix up this variable reference to a Binding object, which enables the value of the variable * to be located at run-time. */ public void fixup(Binding binding) { this.binding = binding; resetLocalStaticProperties(); }
/** * An implementation of Expression must provide at least one of the methods evaluateItem(), iterate(), or process(). * This method indicates which of these methods is provided. This implementation provides both all three methods * natively. */ public int getImplementationMethod() { return (Cardinality.allowsMany(getCardinality()) ? 0 : EVALUATE_METHOD) | ITERATE_METHOD | PROCESS_METHOD; }
/** * Set static type. This is a callback from the variable declaration object. As well * as supplying the static type, it may also supply a compile-time value for the variable. * As well as the type information, other static properties of the value are supplied: * for example, whether the value is an ordered node-set. * @param type the static type of the variable * @param value the value of the variable if this is a compile-time constant * @param properties static properties of the expression to which the variable is bound */ public void setStaticType(SequenceType type, Value value, int properties) { // System.err.println(this + " Set static type = " + type); staticType = type; constantValue = value; // Although the variable may be a context document node-set at the point it is defined, // the context at the point of use may be different, so this property cannot be transferred. staticProperties = (properties & ~StaticProperty.CONTEXT_DOCUMENT_NODESET) | type.getCardinality() | getDependencies(); }
/** * Determine whether all references to this variable are using the value either * (a) by atomizing it, or (b) by taking its string value. (This excludes usages * such as testing the existence of a node or taking the effective boolean value). * * @return true if all references are known to atomize (or stringify) the value, * false otherwise. The value false may indicate "not known". */ private boolean allReferencesAreFlattened() { if (references != null) { for (VariableReference ref : references) { if (!ref.isFlattened()) { return false; } } return true; } return false; }
public void refineVariableType(ItemType type, int cardinality, Value constantValue, int properties, ExpressionVisitor visitor) { Executable exec = visitor.getExecutable(); if (exec == null) { // happens during use-when evaluation return; } TypeHierarchy th = exec.getConfiguration().getTypeHierarchy(); ItemType oldItemType = getItemType(th); ItemType newItemType = oldItemType; if (th.isSubType(type, oldItemType)) { newItemType = type; } int newcard = cardinality & getCardinality(); if (newcard==0) { // this will probably lead to a type error later newcard = getCardinality(); } SequenceType seqType = SequenceType.makeSequenceType(newItemType, newcard); setStaticType(seqType, constantValue, properties); }
/** * Provide additional information about the type of the variable, typically derived by analyzing * the initializer of the variable binding * * @param type the item type of the variable * @param cardinality the cardinality of the variable * @param constantValue the actual value of the variable, if this is known statically, otherwise null * @param properties additional static properties of the variable's initializer */ public void refineVariableType(ItemType type, int cardinality, GroundedValue<?> constantValue, int properties) { TypeHierarchy th = getConfiguration().getTypeHierarchy(); ItemType oldItemType = getItemType(); ItemType newItemType = oldItemType; if (th.isSubType(type, oldItemType)) { newItemType = type; } if (oldItemType instanceof NodeTest && type instanceof AtomicType) { // happens when all references are flattened newItemType = type; } int newcard = cardinality & getCardinality(); if (newcard == 0) { // this will probably lead to a type error later newcard = getCardinality(); } SequenceType seqType = SequenceType.makeSequenceType(newItemType, newcard); setStaticType(seqType, constantValue, properties); }