package lux.xquery; import lux.xpath.AbstractExpression; import lux.xpath.ExpressionVisitor; public class FLWOR extends AbstractExpression { private final FLWORClause[] clauses; public FLWOR (AbstractExpression returnExpression, FLWORClause... clauses) { super (Type.FLWOR); this.clauses = clauses; subs = new AbstractExpression[] { returnExpression }; } // (return (let (for sequence (where) (order by)))) @Override public AbstractExpression accept(ExpressionVisitor visitor) { for (int i = 0; i < clauses.length; i++) { // accept in forward order since queries get reversed on the stack. // This leaves the deepest query at the top of the stack (last in), // so it can be popped out first as we unwind in visit() clauses[i].accept (visitor); } subs[0] = getReturnExpression().accept(visitor); return visitor.visit(this); } @Override public void toString(StringBuilder buf) { boolean inWhereClause = false; for (FLWORClause clause : clauses) { if (clause instanceof WhereClause) { // combine Saxon's adjacent where clauses into a single one if (inWhereClause) { buf.append ("and "); clause.getSequence().toString(buf); } else { inWhereClause = true; clause.toString(buf); } } else { clause.toString(buf); } buf.append("\n "); } buf.append ("return "); getReturnExpression().toString(buf); buf.append ("\n"); } public AbstractExpression getReturnExpression () { return subs[0]; } public FLWORClause[] getClauses () { return clauses; } @Override public AbstractExpression replaceRoot(AbstractExpression replacement) { super.replaceRoot(replacement); for (FLWORClause clause : clauses) { clause.getSequence().replaceRoot(replacement); } return this; } @Override public AbstractExpression getRoot () { return getReturnExpression().getRoot(); } // TODO: are we confused here? Spec lists different precedence (2) // for assignment operator, but something failed when we did that? @Override public int getPrecedence () { return 3; } /** * @return the last context step of the return expression. */ @Override public AbstractExpression getLastContextStep () { return getReturnExpression().getLastContextStep(); } } /* 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/. */