/** * Create a clone copy of this VariableReference * @return the cloned copy */ public Expression copy() { if (binding == null) { throw new UnsupportedOperationException("Cannot copy a variable reference whose binding is unknown"); } LocalVariableReference ref = new LocalVariableReference(); ref.binding = binding; ref.staticType = staticType; ref.slotNumber = slotNumber; ref.constantValue = constantValue; ref.displayName = displayName; ExpressionTool.copyLocationInfo(this, ref); return ref; }
/** * Bind a variable used in an XPath Expression to the XSLVariable element in which it is declared. * This method is provided for use by the XPath parser, and it should not be called by the user of * the API, or overridden, unless variables are to be declared using a mechanism other than the * declareVariable method of this class. * * @param qName the name of the variable * @return the resulting variable reference */ public Expression bindVariable(StructuredQName qName) throws XPathException { XPathVariable var = variables.get(qName); if (var == null) { if (autoDeclare) { return new LocalVariableReference(declareVariable(qName)); } else { throw new XPathException("Undeclared variable in XPath expression: $" + qName.getClarkName(), "XPST0008"); } } else { return new LocalVariableReference(var); } }
/** * Bind a variable used in an XPath Expression to the XSLVariable element in which it is declared. * This method is provided for use by the XPath parser, and it should not be called by the user of * the API, or overridden, unless variables are to be declared using a mechanism other than the * declareVariable method of this class. * * @param qName the name of the variable * @return the resulting variable reference */ public Expression bindVariable(StructuredQName qName) throws XPathException { XPathVariable var = variables.get(qName); if (var == null) { if (autoDeclare) { return new LocalVariableReference(declareVariable(qName)); } else { throw new XPathException("Undeclared variable in XPath expression: $" + qName.getClarkName(), "XPST0008"); } } else { return new LocalVariableReference(var); } }
/** * Replace any calls on current() by a variable reference bound to the supplied binding */ @Override public void bindCurrent(LocalBinding binding) { if (ExpressionTool.callsFunction(equivalentExpr, Current.FN_CURRENT, false)) { if (equivalentExpr.isCallOn(Current.class)) { equivalentExpr = new LocalVariableReference(binding); } else { replaceCurrent(equivalentExpr, binding); } } }
/** * Replace any calls on current() by a variable reference bound to the supplied binding */ @Override public void bindCurrent(LocalBinding binding) { if (ExpressionTool.callsFunction(equivalentExpr, Current.FN_CURRENT, false)) { if (equivalentExpr.isCallOn(Current.class)) { equivalentExpr = new LocalVariableReference(binding); } else { replaceCurrent(equivalentExpr, binding); } } }
/** * Bind a variable to an object that can be used to refer to it * * @param qName the name of the variable * @return a VariableDeclaration object that can be used to identify it in the Bindery, * @throws net.sf.saxon.trans.XPathException * if the variable has not been declared */ @Override public Expression bindVariable(StructuredQName qName) throws XPathException { SourceBinding siblingVar = bindLocalVariable(qName); if (siblingVar == null) { return super.bindVariable(qName); } else { VariableReference var = new LocalVariableReference(qName); siblingVar.registerReference(var); return var; } }
/** * Bind a variable to an object that can be used to refer to it * * @param qName the name of the variable * @return a VariableDeclaration object that can be used to identify it in the Bindery, * @throws net.sf.saxon.trans.XPathException * if the variable has not been declared */ @Override public Expression bindVariable(StructuredQName qName) throws XPathException { SourceBinding siblingVar = bindLocalVariable(qName); if (siblingVar == null) { return super.bindVariable(qName); } else { VariableReference var = new LocalVariableReference(qName); siblingVar.registerReference(var); return var; } }
/** * Bind a variable to an object that can be used to refer to it * @param qName the name of the variable * @return a VariableDeclaration object that can be used to identify it in the Bindery * @throws XPathException if the variable has not been declared */ public VariableReference bindVariable(StructuredQName qName) throws XPathException { XSLVariableDeclaration xslVariableDeclaration = element.bindVariable(qName); VariableReference var = (xslVariableDeclaration.isGlobal() ? new VariableReference() : new LocalVariableReference()); xslVariableDeclaration.registerReference(var); return var; }
/** * Replace this VariableReference where appropriate by a more efficient implementation. This * can only be done after all slot numbers are allocated. The efficiency is gained by binding the * VariableReference directly to a local or global slot, rather than going via the Binding object * @param parent the parent expression of this variable reference */ public void refineVariableReference(Expression parent) { if (binding instanceof Assignation || binding instanceof LocalParam || binding instanceof UserFunctionParameter) { // A LocalVariableReference can be evaluated directly, without going via the Binding object. int slot = binding.getLocalSlotNumber(); if (slot < 0) { // if slots haven't been allocated yet, we've come here too early. // See test group036 with -T option for an example. return; } LocalVariableReference ref = new LocalVariableReference(); ref.setSlotNumber(slot); ref.binding = binding; ref.staticType = staticType; ref.displayName = displayName; ExpressionTool.copyLocationInfo(this, ref); boolean found = parent.replaceSubExpression(this, ref); if (!found) { throw new IllegalStateException("Child expression not found in parent"); } } }
/** * Replace this VariableReference where appropriate by a more efficient implementation. This * can only be done after all slot numbers are allocated. The efficiency is gained by binding the * VariableReference directly to a local or global slot, rather than going via the Binding object * @param parent the parent expression of this variable reference */ public void refineVariableReference(Expression parent) { if (binding instanceof Assignation || binding instanceof LocalParam || binding instanceof UserFunctionParameter) { // A LocalVariableReference can be evaluated directly, without going via the Binding object. int slot = binding.getLocalSlotNumber(); if (slot < 0) { // if slots haven't been allocated yet, we've come here too early. // See test group036 with -T option for an example. return; } LocalVariableReference ref = new LocalVariableReference(); ref.setSlotNumber(slot); ref.binding = binding; ref.staticType = staticType; ref.displayName = displayName; ExpressionTool.copyLocationInfo(this, ref); boolean found = parent.replaceSubExpression(this, ref); if (!found) { throw new IllegalStateException("Child expression not found in parent"); } } }
LocalVariableReference ref = new LocalVariableReference(getVariableName()); ref.copyFrom(this); ref.slotNumber = slotNumber;
/** * Replace any call to current() within a contained expression by a reference to a variable * @param exp the expression in which the replacement is to take place (which must not itself be * a call to current()) * @param binding the binding for the variable reference */ protected static void replaceCurrent(Expression exp, LocalBinding binding) { for (Operand o : exp.operands()) { Expression child = o.getChildExpression(); if (child.isCallOn(Current.class)) { LocalVariableReference ref = new LocalVariableReference(binding); o.setChildExpression(ref); } else { replaceCurrent(child, binding); } } }
/** * Replace any call to current() within a contained expression by a reference to a variable * @param exp the expression in which the replacement is to take place (which must not itself be * a call to current()) * @param binding the binding for the variable reference */ protected static void replaceCurrent(Expression exp, LocalBinding binding) { for (Operand o : exp.operands()) { Expression child = o.getChildExpression(); if (child.isCallOn(Current.class)) { LocalVariableReference ref = new LocalVariableReference(binding); o.setChildExpression(ref); } else { replaceCurrent(child, binding); } } }
/** * Replace any calls on current() by a variable reference bound to the supplied binding */ @Override public void bindCurrent(LocalBinding binding) { Expression predicate = getPredicate(); if (predicate.isCallOn(Current.class)) { predicateOp.setChildExpression(new LocalVariableReference(binding)); } else if (ExpressionTool.callsFunction(predicate, Current.FN_CURRENT, false)) { replaceCurrent(predicate, binding); } getBasePattern().bindCurrent(binding); }
/** * Replace any calls on current() by a variable reference bound to the supplied binding */ @Override public void bindCurrent(LocalBinding binding) { Expression predicate = getPredicate(); if (predicate.isCallOn(Current.class)) { predicateOp.setChildExpression(new LocalVariableReference(binding)); } else if (ExpressionTool.callsFunction(predicate, Current.FN_CURRENT, false)) { replaceCurrent(predicate, binding); } getBasePattern().bindCurrent(binding); }
private Expression parseTypeswitchReturnClause(StructuredQName varQName, LetExpression outerLet) throws XPathException { Expression action; // t.treatCurrentAsOperator(); // expect(Token.RETURN); // nextToken(); LetExpression innerLet = makeLetExpression(); innerLet.setRequiredType(SequenceType.ANY_SEQUENCE); innerLet.setVariableQName(varQName); innerLet.setSequence(new LocalVariableReference(outerLet)); declareRangeVariable(innerLet); action = parseExprSingle(); undeclareRangeVariable(); innerLet.setAction(action); return innerLet; // if (Literal.isEmptySequence(action)) { // // The purpose of simplifying this now is that () is allowed in a branch even in XQuery Update when // // other branches of the typeswitch are updating. // return action; // } else { // return innerLet; // } }
private Expression parseTypeswitchReturnClause(StructuredQName varQName, LetExpression outerLet) throws XPathException { Expression action; // t.treatCurrentAsOperator(); // expect(Token.RETURN); // nextToken(); LetExpression innerLet = makeLetExpression(); innerLet.setRequiredType(SequenceType.ANY_SEQUENCE); innerLet.setVariableQName(varQName); innerLet.setSequence(new LocalVariableReference(outerLet)); declareRangeVariable(innerLet); action = parseExprSingle(); undeclareRangeVariable(); innerLet.setAction(action); return innerLet; // if (Literal.isEmptySequence(action)) { // // The purpose of simplifying this now is that () is allowed in a branch even in XQuery Update when // // other branches of the typeswitch are updating. // return action; // } else { // return innerLet; // } }
/** * Replace calls to current() by a variable reference. * * @param expr the expression potentially containing the calls to be replaced * @param binding the variable binding to be referenced * @return true if any replacement was carried out within the subtree of this expression */ public static boolean replaceCallsToCurrent(Expression expr, LocalBinding binding) { boolean found = false; for (Operand o : expr.operands()) { Expression child = o.getChildExpression(); if (child.isCallOn(Current.class)) { LocalVariableReference var = new LocalVariableReference(binding); ExpressionTool.copyLocationInfo(child, var); o.setChildExpression(var); binding.addReference(var, true); found = true; } else { found = replaceCallsToCurrent(child, binding); } } if (found) { expr.resetLocalStaticProperties(); } return found; }
private Expression parseTypeswitchReturnClause(StructuredQName varQName, LetExpression outerLet) throws XPathException { Expression action; t.treatCurrentAsOperator(); expect(Token.RETURN); nextToken(); LetExpression innerLet = makeLetExpression(); innerLet.setRequiredType(SequenceType.ANY_SEQUENCE); innerLet.setVariableQName(varQName); innerLet.setSequence(new LocalVariableReference(outerLet)); declareRangeVariable(innerLet); action = parseExprSingle(); undeclareRangeVariable(); innerLet.setAction(action); action = innerLet; return action; }
private Expression parseTypeswitchReturnClause(StructuredQName varQName, LetExpression outerLet) throws XPathException { Expression action; t.treatCurrentAsOperator(); expect(Token.RETURN); nextToken(); LetExpression innerLet = makeLetExpression(); innerLet.setRequiredType(SequenceType.ANY_SEQUENCE); innerLet.setVariableQName(varQName); innerLet.setSequence(new LocalVariableReference(outerLet)); declareRangeVariable(innerLet); action = parseExprSingle(); undeclareRangeVariable(); innerLet.setAction(action); return innerLet; // if (Literal.isEmptySequence(action)) { // // The purpose of simplifying this now is that () is allowed in a branch even in XQuery Update when // // other branches of the typeswitch are updating. // return action; // } else { // return innerLet; // } }