19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: WalkerFactory.java 469314 2006-10-30 23:31:59Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath.axes;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.Axis;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMFilter;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTMIterator;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.Expression;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.Compiler;
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.FunctionTable;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.OpCodes;
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.compiler.OpMap;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XNumber;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.ContextMatchStepPattern;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.FunctionPattern;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.NodeTest;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.patterns.StepPattern;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This class is both a factory for XPath location path expressions,
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * which are built from the opcode map output, and an analysis engine
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for the location path expressions in order to provide optimization hints.
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class WalkerFactory
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This method is for building an array of possible levels
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * where the target element(s) could be found for a match.
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param lpi The owning location path iterator.
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return non-null AxesWalker derivative.
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static AxesWalker loadOneWalker(
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          WalkingIterator lpi, Compiler compiler, int stepOpCodePos)
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    AxesWalker firstWalker = null;
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType = compiler.getOp(stepOpCodePos);
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (stepType != OpCodes.ENDOP)
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // m_axesWalkers = new AxesWalker[1];
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // As we unwind from the recursion, create the iterators.
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      firstWalker = createDefaultWalker(compiler, stepType, lpi, 0);
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      firstWalker.init(compiler, stepOpCodePos, stepType);
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return firstWalker;
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This method is for building an array of possible levels
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * where the target element(s) could be found for a match.
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param lpi The owning location path iterator object.
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepIndex The top-level step index withing the iterator.
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return non-null AxesWalker derivative.
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @xsl.usage advanced
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static AxesWalker loadWalkers(
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          WalkingIterator lpi, Compiler compiler, int stepOpCodePos, int stepIndex)
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    AxesWalker firstWalker = null;
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    AxesWalker walker, prevWalker = null;
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int analysis = analyze(compiler, stepOpCodePos, stepIndex);
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      walker = createDefaultWalker(compiler, stepOpCodePos, lpi, analysis);
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      walker.init(compiler, stepOpCodePos, stepType);
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      walker.exprSetParent(lpi);
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // walker.setAnalysis(analysis);
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == firstWalker)
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        firstWalker = walker;
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        prevWalker.setNextWalker(walker);
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        walker.setPrevWalker(prevWalker);
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevWalker = walker;
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (stepOpCodePos < 0)
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return firstWalker;
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isSet(int analysis, int bits)
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & bits));
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static void diagnoseIterator(String name, int analysis, Compiler compiler)
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println(compiler.toString()+", "+name+", "
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             + Integer.toBinaryString(analysis) + ", "
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             + getAnalysisString(analysis));
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a new LocPathIterator iterator.  The exact type of iterator
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * returned is based on an analysis of the XPath operations.
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param opPos The position of the operation code for this itterator.
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return non-null reference to a LocPathIterator or derivative.
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static DTMIterator newDTMIterator(
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int opPos,
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          boolean isTopLevel)
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int firstStepPos = OpMap.getFirstChildPos(opPos);
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int analysis = analyze(compiler, firstStepPos, 0);
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean isOneStep = isOneStep(analysis);
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTMIterator iter;
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (isOneStep && walksSelfOnly(analysis) &&
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        isWild(analysis) && !hasPredicate(analysis))
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DEBUG_ITERATOR_CREATION)
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        diagnoseIterator("SelfIteratorNoPredicate", analysis, compiler);
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Then use a simple iteration of the attributes, with node test
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // and predicate testing.
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      iter = new SelfIteratorNoPredicate(compiler, opPos, analysis);
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Is the iteration exactly one child step?
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (walksChildrenOnly(analysis) && isOneStep)
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Does the pattern specify *any* child with no predicate? (i.e. select="child::node()".
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (isWild(analysis) && !hasPredicate(analysis))
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (DEBUG_ITERATOR_CREATION)
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("ChildIterator", analysis, compiler);
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Use simple child iteration without any test.
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new ChildIterator(compiler, opPos, analysis);
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (DEBUG_ITERATOR_CREATION)
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("ChildTestIterator", analysis, compiler);
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Else use simple node test iteration with predicate test.
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new ChildTestIterator(compiler, opPos, analysis);
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Is the iteration a one-step attribute pattern (i.e. select="@foo")?
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (isOneStep && walksAttributes(analysis))
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DEBUG_ITERATOR_CREATION)
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        diagnoseIterator("AttributeIterator", analysis, compiler);
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Then use a simple iteration of the attributes, with node test
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // and predicate testing.
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      iter = new AttributeIterator(compiler, opPos, analysis);
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(isOneStep && !walksFilteredList(analysis))
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if( !walksNamespaces(analysis)
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      && (walksInDocOrder(analysis) || isSet(analysis, BIT_PARENT)))
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (false || DEBUG_ITERATOR_CREATION)
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("OneStepIteratorForward", analysis, compiler);
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Then use a simple iteration of the attributes, with node test
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // and predicate testing.
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new OneStepIteratorForward(compiler, opPos, analysis);
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (false || DEBUG_ITERATOR_CREATION)
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("OneStepIterator", analysis, compiler);
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Then use a simple iteration of the attributes, with node test
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // and predicate testing.
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new OneStepIterator(compiler, opPos, analysis);
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Analysis of "//center":
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // bits: 1001000000001010000000000000011
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // count: 3
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // root
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // child:node()
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // BIT_DESCENDANT_OR_SELF
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // It's highly possible that we should have a seperate bit set for
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // "//foo" patterns.
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // For at least the time being, we can't optimize patterns like
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // "//table[3]", because this has to be analyzed as
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // "/descendant-or-self::node()/table[3]" in order for the indexes
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // to work right.
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if (isOptimizableForDescendantIterator(compiler, firstStepPos, 0)
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // && getStepCount(analysis) <= 3
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // && walksDescendants(analysis)
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // && walksSubtreeOnlyFromRootOrContext(analysis)
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             )
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DEBUG_ITERATOR_CREATION)
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        diagnoseIterator("DescendantIterator", analysis, compiler);
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      iter = new DescendantIterator(compiler, opPos, analysis);
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(isNaturalDocOrder(compiler, firstStepPos, 0, analysis))
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (false || DEBUG_ITERATOR_CREATION)
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("WalkingIterator", analysis, compiler);
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new WalkingIterator(compiler, opPos, analysis, true);
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//        if (DEBUG_ITERATOR_CREATION)
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//          diagnoseIterator("MatchPatternIterator", analysis, compiler);
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//        return new MatchPatternIterator(compiler, opPos, analysis);
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (DEBUG_ITERATOR_CREATION)
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          diagnoseIterator("WalkingIteratorSorted", analysis, compiler);
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        iter = new WalkingIteratorSorted(compiler, opPos, analysis, true);
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(iter instanceof LocPathIterator)
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ((LocPathIterator)iter).setIsTopLevel(isTopLevel);
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return iter;
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Special purpose function to see if we can optimize the pattern for
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a DescendantIterator.
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return 32 bits as an integer that give information about the location
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * path as a whole.
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static int getAxisFromStep(
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int stepOpCodePos)
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType = compiler.getOp(stepOpCodePos);
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (stepType)
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING :
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.FOLLOWING;
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING_SIBLINGS :
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.FOLLOWINGSIBLING;
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING :
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.PRECEDING;
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING_SIBLINGS :
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.PRECEDINGSIBLING;
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PARENT :
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.PARENT;
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_NAMESPACE :
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.NAMESPACE;
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS :
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.ANCESTOR;
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS_OR_SELF :
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.ANCESTORORSELF;
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ATTRIBUTES :
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.ATTRIBUTE;
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ROOT :
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.ROOT;
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_CHILDREN :
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.CHILD;
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS_OR_SELF :
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.DESCENDANTORSELF;
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS :
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.DESCENDANT;
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_SELF :
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.SELF;
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_EXTFUNCTION :
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_FUNCTION :
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_GROUP :
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_VARIABLE :
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return Axis.FILTEREDLIST;
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               //+ stepType);
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   }
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Get a corresponding BIT_XXX from an axis.
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param axis One of Axis.ANCESTOR, etc.
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return One of BIT_ANCESTOR, etc.
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static public int getAnalysisBitFromAxes(int axis)
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (axis) // Generate new traverser
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ANCESTOR :
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_ANCESTOR;
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ANCESTORORSELF :
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_ANCESTOR_OR_SELF;
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ATTRIBUTE :
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_ATTRIBUTE;
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.CHILD :
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_CHILD;
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.DESCENDANT :
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_DESCENDANT;
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.DESCENDANTORSELF :
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_DESCENDANT_OR_SELF;
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.FOLLOWING :
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_FOLLOWING;
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.FOLLOWINGSIBLING :
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_FOLLOWING_SIBLING;
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.NAMESPACE :
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.NAMESPACEDECLS :
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_NAMESPACE;
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.PARENT :
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_PARENT;
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.PRECEDING :
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_PRECEDING;
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.PRECEDINGSIBLING :
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_PRECEDING_SIBLING;
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.SELF :
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_SELF;
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ALLFROMNODE :
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_DESCENDANT_OR_SELF;
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // case Axis.PRECEDINGANDANCESTOR :
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.DESCENDANTSFROMROOT :
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ALL :
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.DESCENDANTSORSELFFROMROOT :
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_ANY_DESCENDANT_FROM_ROOT;
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.ROOT :
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_ROOT;
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case Axis.FILTEREDLIST :
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_FILTER;
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        default :
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return BIT_FILTER;
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static boolean functionProximateOrContainsProximate(Compiler compiler,
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                      int opPos)
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int endFunc = opPos + compiler.getOp(opPos + 1) - 1;
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    opPos = OpMap.getFirstChildPos(opPos);
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int funcID = compiler.getOp(opPos);
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //  System.out.println("funcID: "+funcID);
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //  System.out.println("opPos: "+opPos);
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //  System.out.println("endFunc: "+endFunc);
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch(funcID)
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case FunctionTable.FUNC_LAST:
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case FunctionTable.FUNC_POSITION:
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default:
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        opPos++;
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int i = 0;
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++)
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int innerExprOpPos = p+2;
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int argOp = compiler.getOp(innerExprOpPos);
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          boolean prox = isProximateInnerExpr(compiler, innerExprOpPos);
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(prox)
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return true;
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static boolean isProximateInnerExpr(Compiler compiler, int opPos)
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int op = compiler.getOp(opPos);
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int innerExprOpPos = opPos+2;
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch(op)
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_ARGUMENT:
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(isProximateInnerExpr(compiler, innerExprOpPos))
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_VARIABLE:
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_NUMBERLIT:
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_LITERAL:
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_LOCATIONPATH:
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break; // OK
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_FUNCTION:
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean isProx = functionProximateOrContainsProximate(compiler, opPos);
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(isProx)
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GT:
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GTE:
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_LT:
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_LTE:
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_EQUALS:
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int leftPos = OpMap.getFirstChildPos(op);
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int rightPos = compiler.getNextOpPos(leftPos);
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        isProx = isProximateInnerExpr(compiler, leftPos);
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(isProx)
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        isProx = isProximateInnerExpr(compiler, rightPos);
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(isProx)
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default:
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true; // be conservative...
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Tell if the predicates need to have proximity knowledge.
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean mightBeProximate(Compiler compiler, int opPos, int stepType)
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws javax.xml.transform.TransformerException
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean mightBeProximate = false;
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int argLen;
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (stepType)
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_VARIABLE :
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_EXTFUNCTION :
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_FUNCTION :
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_GROUP :
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      argLen = compiler.getArgLength(opPos);
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      argLen = compiler.getArgLengthOfStep(opPos);
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int predPos = compiler.getFirstPredicateOpPos(opPos);
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int count = 0;
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.OP_PREDICATE == compiler.getOp(predPos))
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      count++;
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int innerExprOpPos = predPos+2;
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int predOp = compiler.getOp(innerExprOpPos);
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch(predOp)
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_VARIABLE:
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        	return true; // Would need more smarts to tell if this could be a number or not!
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_LOCATIONPATH:
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // OK.
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_NUMBER:
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_NUMBERLIT:
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true; // that's all she wrote!
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_FUNCTION:
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          boolean isProx
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            = functionProximateOrContainsProximate(compiler, innerExprOpPos);
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(isProx)
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return true;
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_GT:
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_GTE:
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_LT:
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_LTE:
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        case OpCodes.OP_EQUALS:
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int leftPos = OpMap.getFirstChildPos(innerExprOpPos);
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int rightPos = compiler.getNextOpPos(leftPos);
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          isProx = isProximateInnerExpr(compiler, leftPos);
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(isProx)
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return true;
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          isProx = isProximateInnerExpr(compiler, rightPos);
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(isProx)
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return true;
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        default:
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true; // be conservative...
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predPos = compiler.getNextOpPos(predPos);
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return mightBeProximate;
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Special purpose function to see if we can optimize the pattern for
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a DescendantIterator.
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepIndex The top-level step index withing the iterator.
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return 32 bits as an integer that give information about the location
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * path as a whole.
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isOptimizableForDescendantIterator(
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int stepOpCodePos, int stepIndex)
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType;
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepCount = 0;
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean foundDorDS = false;
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean foundSelf = false;
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean foundDS = false;
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nodeTestType = OpCodes.NODETYPE_NODE;
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // The DescendantIterator can only do one node test.  If there's more
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // than one, use another iterator.
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(nodeTestType != OpCodes.NODETYPE_NODE && nodeTestType != OpCodes.NODETYPE_ROOT)
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepCount++;
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(stepCount > 3)
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean mightBeProximate = mightBeProximate(compiler, stepOpCodePos, stepType);
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(mightBeProximate)
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (stepType)
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING :
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING_SIBLINGS :
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING :
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING_SIBLINGS :
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PARENT :
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_VARIABLE :
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_EXTFUNCTION :
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_FUNCTION :
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GROUP :
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_NAMESPACE :
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS :
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS_OR_SELF :
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ATTRIBUTES :
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ATTRIBUTE :
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ANY_ANCESTOR :
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ROOT :
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(1 != stepCount)
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_CHILDREN :
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(!foundDS && !(foundDorDS && foundSelf))
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS_OR_SELF :
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        foundDS = true;
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS :
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(3 == stepCount)
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        foundDorDS = true;
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_SELF :
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(1 != stepCount)
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        foundSelf = true;
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default :
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  // + stepType);
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      nodeTestType = compiler.getStepTestType(stepOpCodePos);
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nextStepOpCodePos < 0)
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(OpCodes.ENDOP != compiler.getOp(nextStepOpCodePos))
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(compiler.countPredicates(stepOpCodePos) > 0)
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepOpCodePos = nextStepOpCodePos;
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Analyze the location path and return 32 bits that give information about
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the location path as a whole.  See the BIT_XXX constants for meaning about
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * each of the bits.
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepIndex The top-level step index withing the iterator.
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return 32 bits as an integer that give information about the location
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * path as a whole.
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static int analyze(
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int stepOpCodePos, int stepIndex)
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType;
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepCount = 0;
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int analysisResult = 0x00000000;  // 32 bits of analysis
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepCount++;
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // String namespace = compiler.getStepNS(stepOpCodePos);
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // boolean isNSWild = (null != namespace)
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //                   ? namespace.equals(NodeTest.WILD) : false;
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // String localname = compiler.getStepLocalName(stepOpCodePos);
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // boolean isWild = (null != localname) ? localname.equals(NodeTest.WILD) : false;
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean predAnalysis = analyzePredicate(compiler, stepOpCodePos,
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                              stepType);
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (predAnalysis)
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_PREDICATE;
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (stepType)
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_VARIABLE :
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_EXTFUNCTION :
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_FUNCTION :
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GROUP :
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_FILTER;
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ROOT :
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_ROOT;
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS :
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_ANCESTOR;
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS_OR_SELF :
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_ANCESTOR_OR_SELF;
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ATTRIBUTES :
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_ATTRIBUTE;
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_NAMESPACE :
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_NAMESPACE;
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_CHILDREN :
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_CHILD;
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS :
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_DESCENDANT;
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS_OR_SELF :
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Use a special bit to to make sure we get the right analysis of "//foo".
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (2 == stepCount && BIT_ROOT == analysisResult)
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          analysisResult |= BIT_ANY_DESCENDANT_FROM_ROOT;
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_DESCENDANT_OR_SELF;
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING :
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_FOLLOWING;
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING_SIBLINGS :
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_FOLLOWING_SIBLING;
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING :
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_PRECEDING;
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING_SIBLINGS :
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_PRECEDING_SIBLING;
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PARENT :
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_PARENT;
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_SELF :
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_SELF;
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ATTRIBUTE :
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= (BIT_MATCH_PATTERN | BIT_ATTRIBUTE);
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ANY_ANCESTOR :
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= (BIT_MATCH_PATTERN | BIT_ANCESTOR);
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= (BIT_MATCH_PATTERN | BIT_PARENT);
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default :
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                   //+ stepType);
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (OpCodes.NODETYPE_NODE == compiler.getOp(stepOpCodePos + 3))  // child::node()
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        analysisResult |= BIT_NODETEST_ANY;
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (stepOpCodePos < 0)
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    analysisResult |= (stepCount & BITS_COUNT);
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return analysisResult;
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Tell if the given axis goes downword.  Bogus name, if you can think of
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * a better one, please do tell.  This really has to do with inverting
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * attribute axis.
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param axis One of Axis.XXX.
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the axis is not a child axis and does not go up from
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the axis root.
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isDownwardAxisOfMany(int axis)
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ((Axis.DESCENDANTORSELF == axis) ||
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          (Axis.DESCENDANT == axis)
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          || (Axis.FOLLOWING == axis)
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//          || (Axis.FOLLOWINGSIBLING == axis)
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          || (Axis.PRECEDING == axis)
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//          || (Axis.PRECEDINGSIBLING == axis)
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          );
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Read a <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a>
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as a generalized match pattern.  What this means is that the LocationPath
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is read backwards, as a test on a given node, to see if it matches the
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * criteria of the selection, and ends up at the context node.  Essentially,
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * this is a backwards query from a given node, to find the context node.
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * <p>So, the selection "foo/daz[2]" is, in non-abreviated expanded syntax,
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * "self::node()/following-sibling::foo/child::daz[position()=2]".
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Taking this as a match pattern for a probable node, it works out to
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * "self::daz/parent::foo[child::daz[position()=2 and isPrevStepNode()]
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * precedingSibling::node()[isContextNodeOfLocationPath()]", adding magic
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * isPrevStepNode and isContextNodeOfLocationPath operations.  Predicates in
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the location path have to be executed by the following step,
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * because they have to know the context of their execution.
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mpi The MatchPatternIterator to which the steps will be attached.
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler The compiler that holds the syntax tree/op map to
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * construct from.
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The current op code position within the opmap.
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepIndex The top-level step index withing the iterator.
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return A StepPattern object, which may contain relative StepPatterns.
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static StepPattern loadSteps(
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          MatchPatternIterator mpi, Compiler compiler, int stepOpCodePos,
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                       int stepIndex)
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DEBUG_PATTERN_CREATION)
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("================");
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("loadSteps for: "+compiler.getPatternString());
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType;
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StepPattern step = null;
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StepPattern firstStep = null, prevStep = null;
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int analysis = analyze(compiler, stepOpCodePos, stepIndex);
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis,
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                      firstStep, prevStep);
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == firstStep)
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        firstStep = step;
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //prevStep.setNextWalker(step);
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        step.setRelativePathPattern(prevStep);
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevStep = step;
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (stepOpCodePos < 0)
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int axis = Axis.SELF;
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int paxis = Axis.SELF;
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StepPattern tail = step;
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (StepPattern pat = step; null != pat;
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         pat = pat.getRelativePathPattern())
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nextAxis = pat.getAxis();
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //int nextPaxis = pat.getPredicateAxis();
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      pat.setAxis(axis);
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // The predicate axis can't be moved!!!  Test Axes103
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // pat.setPredicateAxis(paxis);
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // If we have an attribute or namespace axis that went up, then
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // it won't find the attribute in the inverse, since the select-to-match
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // axes are not invertable (an element is a parent of an attribute, but
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // and attribute is not a child of an element).
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // If we don't do the magic below, then "@*/ancestor-or-self::*" gets
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // inverted for match to "self::*/descendant-or-self::@*/parent::node()",
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // which obviously won't work.
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // So we will rewrite this as:
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // "self::*/descendant-or-self::*/attribute::*/parent::node()"
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Child has to be rewritten a little differently:
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // select: "@*/parent::*"
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // inverted match: "self::*/child::@*/parent::node()"
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // rewrite: "self::*/attribute::*/parent::node()"
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Axes that go down in the select, do not have to have special treatment
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // in the rewrite. The following inverted match will still not select
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // anything.
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // select: "@*/child::*"
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // inverted match: "self::*/parent::@*/parent::node()"
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Lovely business, this.
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // -sb
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int whatToShow = pat.getWhatToShow();
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if(whatToShow == DTMFilter.SHOW_ATTRIBUTE ||
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         whatToShow == DTMFilter.SHOW_NAMESPACE)
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ?
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       Axis.ATTRIBUTE : Axis.NAMESPACE;
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(isDownwardAxisOfMany(axis))
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          StepPattern attrPat = new StepPattern(whatToShow,
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    pat.getNamespace(),
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                    pat.getLocalName(),
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                //newAxis, pat.getPredicateAxis);
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                newAxis, 0); // don't care about the predicate axis
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XNumber score = pat.getStaticScore();
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setNamespace(null);
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setLocalName(NodeTest.WILD);
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          attrPat.setPredicates(pat.getPredicates());
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setPredicates(null);
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setWhatToShow(DTMFilter.SHOW_ELEMENT);
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          StepPattern rel = pat.getRelativePathPattern();
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setRelativePathPattern(attrPat);
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          attrPat.setRelativePathPattern(rel);
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          attrPat.setStaticScore(score);
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // This is needed to inverse a following pattern, because of the
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // wacky Xalan rules for following from an attribute.  See axes108.
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // By these rules, following from an attribute is not strictly
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // inverseable.
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if(Axis.PRECEDING == pat.getAxis())
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pat.setAxis(Axis.PRECEDINGANDANCESTOR);
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else if(Axis.DESCENDANT == pat.getAxis())
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pat.setAxis(Axis.DESCENDANTORSELF);
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat = attrPat;
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if(Axis.CHILD == pat.getAxis())
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // In this case just change the axis.
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // pat.setWhatToShow(whatToShow);
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          pat.setAxis(Axis.ATTRIBUTE);
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = nextAxis;
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //paxis = nextPaxis;
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      tail = pat;
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(axis < Axis.ALL)
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis);
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // We need to keep the new nodetest from affecting the score...
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XNumber score = tail.getStaticScore();
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      tail.setRelativePathPattern(selfPattern);
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      tail.setStaticScore(score);
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      selfPattern.setStaticScore(score);
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (DEBUG_PATTERN_CREATION)
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("Done loading steps: "+step.toString());
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("");
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return step;  // start from last pattern?? //firstStep;
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create a StepPattern that is contained within a LocationPath.
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler The compiler that holds the syntax tree/op map to
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * construct from.
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The current op code position within the opmap.
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param mpi The MatchPatternIterator to which the steps will be attached.
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param analysis 32 bits of analysis, from which the type of AxesWalker
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 may be influenced.
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param tail The step that is the first step analyzed, but the last
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  step in the relative match linked list, i.e. the tail.
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                  May be null.
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param head The step that is the current head of the relative
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 match step linked list.
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 May be null.
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the head of the list.
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static StepPattern createDefaultStepPattern(
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int opPos, MatchPatternIterator mpi,
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int analysis, StepPattern tail, StepPattern head)
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType = compiler.getOp(opPos);
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean simpleInit = false;
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean prevIsOneStepDown = true;
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int whatToShow = compiler.getWhatToShow(opPos);
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StepPattern ai = null;
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int axis, predicateAxis;
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (stepType)
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_VARIABLE :
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_EXTFUNCTION :
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_FUNCTION :
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_GROUP :
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      Expression expr;
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (stepType)
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_VARIABLE :
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_EXTFUNCTION :
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_FUNCTION :
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GROUP :
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        expr = compiler.compile(opPos);
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default :
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        expr = compiler.compile(opPos + 2);
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.FILTEREDLIST;
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.FILTEREDLIST;
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new FunctionPattern(expr, axis, predicateAxis);
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      simpleInit = true;
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ROOT :
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      whatToShow = DTMFilter.SHOW_DOCUMENT
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                   | DTMFilter.SHOW_DOCUMENT_FRAGMENT;
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.ROOT;
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.ROOT;
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new StepPattern(DTMFilter.SHOW_DOCUMENT |
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                DTMFilter.SHOW_DOCUMENT_FRAGMENT,
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                axis, predicateAxis);
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ATTRIBUTES :
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      whatToShow = DTMFilter.SHOW_ATTRIBUTE;
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.PARENT;
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.ATTRIBUTE;
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // ai = new StepPattern(whatToShow, Axis.SELF, Axis.SELF);
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_NAMESPACE :
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      whatToShow = DTMFilter.SHOW_NAMESPACE;
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.PARENT;
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.NAMESPACE;
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // ai = new StepPattern(whatToShow, axis, predicateAxis);
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS :
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.DESCENDANT;
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.ANCESTOR;
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_CHILDREN :
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.PARENT;
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.CHILD;
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS_OR_SELF :
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.DESCENDANTORSELF;
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.ANCESTORORSELF;
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_SELF :
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.SELF;
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.SELF;
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PARENT :
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.CHILD;
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.PARENT;
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING_SIBLINGS :
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.FOLLOWINGSIBLING;
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.PRECEDINGSIBLING;
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING :
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.FOLLOWING;
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.PRECEDING;
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING_SIBLINGS :
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.PRECEDINGSIBLING;
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.FOLLOWINGSIBLING;
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING :
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.PRECEDING;
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.FOLLOWING;
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS_OR_SELF :
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.ANCESTORORSELF;
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.DESCENDANTORSELF;
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS :
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      axis = Axis.ANCESTOR;
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      predicateAxis = Axis.DESCENDANT;
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 //+ stepType);
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null == ai)
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      whatToShow = compiler.getWhatToShow(opPos); // %REVIEW%
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new StepPattern(whatToShow, compiler.getStepNS(opPos),
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                compiler.getStepLocalName(opPos),
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                axis, predicateAxis);
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (false || DEBUG_PATTERN_CREATION)
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print("new step: "+ ai);
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print(", axis: " + Axis.getNames(ai.getAxis()));
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print(", predAxis: " + Axis.getNames(ai.getAxis()));
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print(", what: ");
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print("    ");
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai.debugWhatToShow(ai.getWhatToShow());
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int argLen = compiler.getFirstPredicateOpPos(opPos);
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    ai.setPredicates(compiler.getCompiledPredicates(argLen));
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ai;
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Analyze a step and give information about it's predicates.  Right now this
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * just returns true or false if the step has a predicate.
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param opPos The opcode position for the step.
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepType The type of step, one of OP_GROUP, etc.
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if step has a predicate.
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static boolean analyzePredicate(Compiler compiler, int opPos, int stepType)
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws javax.xml.transform.TransformerException
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int argLen;
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (stepType)
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_VARIABLE :
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_EXTFUNCTION :
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_FUNCTION :
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_GROUP :
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      argLen = compiler.getArgLength(opPos);
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      argLen = compiler.getArgLengthOfStep(opPos);
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int pos = compiler.getFirstPredicateOpPos(opPos);
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int nPredicates = compiler.countPredicates(pos);
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (nPredicates > 0) ? true : false;
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Create the proper Walker from the axes type.
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param opPos The opcode position for the step.
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param lpi The owning location path iterator.
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param analysis 32 bits of analysis, from which the type of AxesWalker
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 may be influenced.
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return non-null reference to AxesWalker derivative.
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws RuntimeException if the input is bad.
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static AxesWalker createDefaultWalker(Compiler compiler, int opPos,
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          WalkingIterator lpi, int analysis)
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    AxesWalker ai = null;
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType = compiler.getOp(opPos);
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /*
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("0: "+compiler.getOp(opPos));
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("1: "+compiler.getOp(opPos+1));
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("2: "+compiler.getOp(opPos+2));
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("3: "+compiler.getOp(opPos+3));
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("4: "+compiler.getOp(opPos+4));
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    System.out.println("5: "+compiler.getOp(opPos+5));
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    */
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean simpleInit = false;
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int totalNumberWalkers = (analysis & BITS_COUNT);
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean prevIsOneStepDown = true;
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (stepType)
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_VARIABLE :
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_EXTFUNCTION :
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_FUNCTION :
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.OP_GROUP :
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DEBUG_WALKER_CREATION)
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        System.out.println("new walker:  FilterExprWalker: " + analysis
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                           + ", " + compiler.toString());
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new FilterExprWalker(lpi);
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      simpleInit = true;
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ROOT :
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.ROOT);
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS :
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new ReverseAxesWalker(lpi, Axis.ANCESTOR);
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ANCESTORS_OR_SELF :
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new ReverseAxesWalker(lpi, Axis.ANCESTORORSELF);
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_ATTRIBUTES :
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.ATTRIBUTE);
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_NAMESPACE :
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.NAMESPACE);
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_CHILDREN :
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.CHILD);
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS :
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.DESCENDANT);
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_DESCENDANTS_OR_SELF :
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.DESCENDANTORSELF);
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING :
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.FOLLOWING);
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_FOLLOWING_SIBLINGS :
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.FOLLOWINGSIBLING);
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING :
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new ReverseAxesWalker(lpi, Axis.PRECEDING);
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PRECEDING_SIBLINGS :
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new ReverseAxesWalker(lpi, Axis.PRECEDINGSIBLING);
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_PARENT :
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      prevIsOneStepDown = false;
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new ReverseAxesWalker(lpi, Axis.PARENT);
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case OpCodes.FROM_SELF :
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai = new AxesWalker(lpi, Axis.SELF);
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                 //+ stepType);
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (simpleInit)
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ai.initNodeTest(DTMFilter.SHOW_ALL);
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int whatToShow = compiler.getWhatToShow(opPos);
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      /*
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.print("construct: ");
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NodeTest.debugWhatToShow(whatToShow);
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      System.out.println("or stuff: "+(whatToShow & (DTMFilter.SHOW_ATTRIBUTE
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             | DTMFilter.SHOW_ELEMENT
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                             | DTMFilter.SHOW_PROCESSING_INSTRUCTION)));
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      */
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((0 == (whatToShow
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                 & (DTMFilter.SHOW_ATTRIBUTE | DTMFilter.SHOW_NAMESPACE | DTMFilter.SHOW_ELEMENT
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    | DTMFilter.SHOW_PROCESSING_INSTRUCTION))) || (whatToShow == DTMFilter.SHOW_ALL))
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ai.initNodeTest(whatToShow);
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ai.initNodeTest(whatToShow, compiler.getStepNS(opPos),
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        compiler.getStepLocalName(opPos));
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ai;
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static String getAnalysisString(int analysis)
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StringBuffer buf = new StringBuffer();
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    buf.append("count: "+getStepCount(analysis)+" ");
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_NODETEST_ANY) != 0)
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("NTANY|");
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_PREDICATE) != 0)
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("PRED|");
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_ANCESTOR) != 0)
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("ANC|");
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_ANCESTOR_OR_SELF) != 0)
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("ANCOS|");
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_ATTRIBUTE) != 0)
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("ATTR|");
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_CHILD) != 0)
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("CH|");
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_DESCENDANT) != 0)
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("DESC|");
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_DESCENDANT_OR_SELF) != 0)
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("DESCOS|");
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_FOLLOWING) != 0)
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("FOL|");
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_FOLLOWING_SIBLING) != 0)
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("FOLS|");
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_NAMESPACE) != 0)
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("NS|");
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_PARENT) != 0)
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("P|");
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_PRECEDING) != 0)
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("PREC|");
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_PRECEDING_SIBLING) != 0)
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("PRECS|");
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_SELF) != 0)
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append(".|");
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_FILTER) != 0)
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("FLT|");
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if((analysis & BIT_ROOT) != 0)
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf.append("R|");
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return buf.toString();
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Set to true for diagnostics about walker creation */
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static final boolean DEBUG_PATTERN_CREATION = false;
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Set to true for diagnostics about walker creation */
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static final boolean DEBUG_WALKER_CREATION = false;
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Set to true for diagnostics about iterator creation */
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static final boolean DEBUG_ITERATOR_CREATION = false;
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean hasPredicate(int analysis)
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & BIT_PREDICATE));
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isWild(int analysis)
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & BIT_NODETEST_ANY));
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksAncestors(int analysis)
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksAttributes(int analysis)
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & BIT_ATTRIBUTE));
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksNamespaces(int analysis)
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & BIT_NAMESPACE));
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksChildren(int analysis)
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (0 != (analysis & BIT_CHILD));
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksDescendants(int analysis)
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF);
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSubtree(int analysis)
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | BIT_CHILD);
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSubtreeOnlyMaybeAbsolute(int analysis)
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksSubtree(analysis)
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksExtraNodes(analysis)
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSubtreeOnly(int analysis)
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksSubtreeOnlyMaybeAbsolute(analysis)
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksFilteredList(int analysis)
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_FILTER);
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSubtreeOnlyFromRootOrContext(int analysis)
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksSubtree(analysis)
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksExtraNodes(analysis)
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isSet(analysis, BIT_FILTER)
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksInDocOrder(int analysis)
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (walksSubtreeOnlyMaybeAbsolute(analysis)
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           || walksExtraNodesOnly(analysis)
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           || walksFollowingOnlyMaybeAbsolute(analysis))
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isSet(analysis, BIT_FILTER)
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksFollowingOnlyMaybeAbsolute(int analysis)
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_SELF | BIT_FOLLOWING_SIBLING | BIT_FOLLOWING)
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSubtree(analysis)
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksUp(int analysis)
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_PARENT | BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF);
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSideways(int analysis)
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING |
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                           BIT_PRECEDING | BIT_PRECEDING_SIBLING);
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksExtraNodes(int analysis)
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_NAMESPACE | BIT_ATTRIBUTE);
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksExtraNodesOnly(int analysis)
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksExtraNodes(analysis)
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isSet(analysis, BIT_SELF)
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSubtree(analysis)
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isAbsolute(int analysis)
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_ROOT | BIT_FILTER);
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksChildrenOnly(int analysis)
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksChildren(analysis)
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isSet(analysis, BIT_SELF)
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksExtraNodes(analysis)
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksDescendants(analysis)
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksChildrenAndExtraAndSelfOnly(int analysis)
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksChildren(analysis)
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksDescendants(analysis)
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksDescendantsAndExtraAndSelfOnly(int analysis)
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return !walksChildren(analysis)
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && walksDescendants(analysis)
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT))
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksSelfOnly(int analysis)
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_SELF)
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSubtree(analysis)
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksUpOnly(int analysis)
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return !walksSubtree(analysis)
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && walksUp(analysis)
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksDownOnly(int analysis)
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksSubtree(analysis)
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean walksDownExtraOnly(int analysis)
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return walksSubtree(analysis) &&  walksExtraNodes(analysis)
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksUp(analysis)
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !walksSideways(analysis)
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && !isAbsolute(analysis)
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ;
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean canSkipSubtrees(int analysis)
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return isSet(analysis, BIT_CHILD) | walksSideways(analysis);
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean canCrissCross(int analysis)
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // This could be done faster.  Coded for clarity.
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(walksSelfOnly(analysis))
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksDownOnly(analysis) && !canSkipSubtrees(analysis))
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksChildrenAndExtraAndSelfOnly(analysis))
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksDescendantsAndExtraAndSelfOnly(analysis))
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksUpOnly(analysis))
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksExtraNodesOnly(analysis))
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else if(walksSubtree(analysis)
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           && (walksSideways(analysis)
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            || walksUp(analysis)
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            || canSkipSubtrees(analysis)))
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Tell if the pattern can be 'walked' with the iteration steps in natural
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * document order, without duplicates.
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param analysis The general analysis of the pattern.
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the walk can be done in natural order.
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  static public boolean isNaturalDocOrder(int analysis)
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(canCrissCross(analysis) || isSet(analysis, BIT_NAMESPACE) ||
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       walksFilteredList(analysis))
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(walksInDocOrder(analysis))
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return true;
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return false;
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Tell if the pattern can be 'walked' with the iteration steps in natural
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * document order, without duplicates.
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param compiler non-null reference to compiler object that has processed
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *                 the XPath operations into an opcode map.
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepOpCodePos The opcode position for the step.
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stepIndex The top-level step index withing the iterator.
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param analysis The general analysis of the pattern.
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return true if the walk can be done in natural order.
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private static boolean isNaturalDocOrder(
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Compiler compiler, int stepOpCodePos, int stepIndex, int analysis)
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(canCrissCross(analysis))
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Namespaces can present some problems, so just punt if we're looking for
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // these.
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(isSet(analysis, BIT_NAMESPACE))
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // The following, preceding, following-sibling, and preceding sibling can
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // be found in doc order if we get to this point, but if they occur
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // together, they produce
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // duplicates, so it's better for us to eliminate this case so we don't
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // have to check for duplicates during runtime if we're using a
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // WalkingIterator.
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) &&
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson       isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING))
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return  false;
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // OK, now we have to check for select="@*/axis::*" patterns, which
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // can also cause duplicates to happen.  But select="axis*/@::*" patterns
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // are OK, as are select="@foo/axis::*" patterns.
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Unfortunately, we can't do this just via the analysis bits.
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepType;
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int stepCount = 0;
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    boolean foundWildAttribute = false;
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Steps that can traverse anything other than down a
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // subtree or that can produce duplicates when used in
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // combonation are counted with this variable.
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int potentialDuplicateMakingStepCount = 0;
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos)))
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepCount++;
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (stepType)
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ATTRIBUTES :
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ATTRIBUTE :
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(foundWildAttribute) // Maybe not needed, but be safe.
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // This doesn't seem to work as a test for wild card.  Hmph.
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // int nodeTestType = compiler.getStepTestType(stepOpCodePos);
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        String localName = compiler.getStepLocalName(stepOpCodePos);
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // System.err.println("localName: "+localName);
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(localName.equals("*"))
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          foundWildAttribute = true;
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING :
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_FOLLOWING_SIBLINGS :
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING :
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PRECEDING_SIBLINGS :
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_PARENT :
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_VARIABLE :
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_EXTFUNCTION :
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_FUNCTION :
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.OP_GROUP :
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_NAMESPACE :
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS :
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ANCESTORS_OR_SELF :
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_ANY_ANCESTOR :
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS_OR_SELF :
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_DESCENDANTS :
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(potentialDuplicateMakingStepCount > 0)
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return false;
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        potentialDuplicateMakingStepCount++;
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_ROOT :
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_CHILDREN :
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case OpCodes.FROM_SELF :
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if(foundWildAttribute)
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return false;
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default :
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: "
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                  // + stepType);
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos);
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (nextStepOpCodePos < 0)
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      stepOpCodePos = nextStepOpCodePos;
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return true;
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static boolean isOneStep(int analysis)
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (analysis & BITS_COUNT) == 0x00000001;
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static int getStepCount(int analysis)
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (analysis & BITS_COUNT);
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * First 8 bits are the number of top-level location steps.  Hopefully
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  there will never be more that 255 location steps!!!
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BITS_COUNT = 0x000000FF;
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** 4 bits are reserved for future use. */
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BITS_RESERVED = 0x00000F00;
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if the expression contains a top-level predicate. */
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_PREDICATE = (0x00001000);
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain an ancestor step. */
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_ANCESTOR = (0x00001000 << 1);
17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain an ancestor-or-self step. */
17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_ANCESTOR_OR_SELF = (0x00001000 << 2);
17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain an attribute step. */
17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_ATTRIBUTE = (0x00001000 << 3);
17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a child step. */
17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_CHILD = (0x00001000 << 4);
17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a descendant step. */
17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_DESCENDANT = (0x00001000 << 5);
17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a descendant-or-self step. */
17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_DESCENDANT_OR_SELF = (0x00001000 << 6);
17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a following step. */
17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_FOLLOWING = (0x00001000 << 7);
17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a following-sibiling step. */
17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_FOLLOWING_SIBLING = (0x00001000 << 8);
17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a namespace step. */
17689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_NAMESPACE = (0x00001000 << 9);
17699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a parent step. */
17719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_PARENT = (0x00001000 << 10);
17729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a preceding step. */
17749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_PRECEDING = (0x00001000 << 11);
17759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a preceding-sibling step. */
17779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_PRECEDING_SIBLING = (0x00001000 << 12);
17789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a self step. */
17809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_SELF = (0x00001000 << 13);
17819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
17839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Bit is on if any of the walkers contain a filter (i.e. id(), extension
17849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  function, etc.) step.
17859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
17869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_FILTER = (0x00001000 << 14);
17879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if any of the walkers contain a root step. */
17899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_ROOT = (0x00001000 << 15);
17909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
17929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If any of these bits are on, the expression may likely traverse outside
17939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  the given subtree.
17949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
17959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BITMASK_TRAVERSES_OUTSIDE_SUBTREE = (BIT_NAMESPACE  // ??
17969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_PRECEDING_SIBLING
17979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_PRECEDING
17989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_FOLLOWING_SIBLING
17999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_FOLLOWING
18009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_PARENT  // except parent of attrs.
18019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_ANCESTOR_OR_SELF
18029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_ANCESTOR
18039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_FILTER
18049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                                | BIT_ROOT);
18059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
18079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Bit is on if any of the walkers can go backwards in document
18089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  order from the context node.
18099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
18109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_BACKWARDS_SELF = (0x00001000 << 16);
18119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Found "//foo" pattern */
18139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_ANY_DESCENDANT_FROM_ROOT = (0x00001000 << 17);
18149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
18169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Bit is on if any of the walkers contain an node() test.  This is
18179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *  really only useful if the count is 1.
18189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
18199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_NODETEST_ANY = (0x00001000 << 18);
18209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // can't go higher than 18!
18229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /** Bit is on if the expression is a match pattern. */
18249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public static final int BIT_MATCH_PATTERN = (0x00001000 << 19);
18259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1826