morten      01/10/08 00:47:59

  Modified:    java/src/org/apache/xalan/xsltc/compiler
                        ParentLocationPath.java RelativeLocationPath.java
                        Step.java xpath.cup
  Log:
  Fix for ordering of certain node sets.
  PR:           bugzilla 3766
  Obtained from:        n/a
  Submitted by: [EMAIL PROTECTED]
  Reviewed by:  [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.9       +73 -9     
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java
  
  Index: ParentLocationPath.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParentLocationPath.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ParentLocationPath.java   2001/10/05 09:47:55     1.8
  +++ ParentLocationPath.java   2001/10/08 07:47:59     1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: ParentLocationPath.java,v 1.8 2001/10/05 09:47:55 morten Exp $
  + * @(#)$Id: ParentLocationPath.java,v 1.9 2001/10/08 07:47:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -73,18 +73,27 @@
       private final RelativeLocationPath _path;
       private Type stype;
       private boolean _orderNodes = false;
  +    private boolean _axisMismatch = false;
   
       public ParentLocationPath(RelativeLocationPath path, Expression step) {
        _path = path;
        _step = step;
        _path.setParent(this);
        _step.setParent(this);
  +
  +     if (_step instanceof Step) {
  +         _axisMismatch = checkAxisMismatch();
  +     }
       }
                
       public void setAxis(int axis) {
        _path.setAxis(axis);
       }
   
  +    public int getAxis() {
  +     return _path.getAxis();
  +    }
  +
       public RelativeLocationPath getPath() {
        return(_path);
       }
  @@ -107,19 +116,74 @@
        stype = _step.typeCheck(stable);
        _path.typeCheck(stable);
   
  -     if (descendantAxis() && _path.descendantAxis())
  -         _orderNodes = true;
  +     if (_axisMismatch) enableNodeOrdering();
   
        return _type = Type.NodeSet;    
       }
   
  -    public boolean descendantAxis() {
  -     if (_step instanceof Step) {
  -         return ((Step)_step).descendantAxis();
  -     }
  -     else if (_step instanceof ParentLocationPath) {
  -         return ((ParentLocationPath)_step).descendantAxis();
  +    public void enableNodeOrdering() {
  +     SyntaxTreeNode parent = getParent();
  +     if (parent instanceof ParentLocationPath)
  +         ((ParentLocationPath)parent).enableNodeOrdering();
  +     else {
  +         _orderNodes = true;
        }
  +    }
  +
  +    /**
  +     * This method is used to determine if this parent location path is a
  +     * combination of two step's with axes that will create duplicate or
  +     * unordered nodes.
  +     */
  +    public boolean checkAxisMismatch() {
  +
  +     int left = _path.getAxis();
  +     int right = ((Step)_step).getAxis();
  +
  +     if (((left == Axis.ANCESTOR) || (left == Axis.ANCESTORORSELF)) &&
  +         ((right == Axis.CHILD) ||
  +          (right == Axis.DESCENDANT) ||
  +          (right == Axis.DESCENDANTORSELF) ||
  +          (right == Axis.PARENT) ||
  +          (right == Axis.PRECEDING) ||
  +          (right == Axis.PRECEDINGSIBLING)))
  +         return true;
  +
  +     if ((left == Axis.CHILD) &&
  +         (right == Axis.ANCESTOR) ||
  +         (right == Axis.ANCESTORORSELF) ||
  +         (right == Axis.PARENT) ||
  +         (right == Axis.PRECEDING))
  +         return true;
  +
  +     if ((left == Axis.DESCENDANT) || (left == Axis.DESCENDANTORSELF))
  +         return true;
  +
  +     if (((left == Axis.FOLLOWING) || (left == Axis.FOLLOWINGSIBLING)) &&
  +         ((right == Axis.FOLLOWING) ||
  +          (right == Axis.PARENT) ||
  +          (right == Axis.PRECEDING) ||
  +          (right == Axis.PRECEDINGSIBLING)))
  +         return true;
  +
  +     if (((left == Axis.PRECEDING) || (left == Axis.PRECEDINGSIBLING)) &&
  +         ((right == Axis.DESCENDANT) ||
  +          (right == Axis.DESCENDANTORSELF) ||
  +          (right == Axis.FOLLOWING) ||
  +          (right == Axis.FOLLOWINGSIBLING) ||
  +          (right == Axis.PARENT) ||
  +          (right == Axis.PRECEDING) ||
  +          (right == Axis.PRECEDINGSIBLING)))
  +         return true;
  +
  +     return false;
  +    }
  +
  +    public final boolean descendantAxis() {
  +     if (_path.descendantAxis())
  +         return true;
  +     if (_step instanceof RelativeLocationPath)
  +         return ((RelativeLocationPath)_step).descendantAxis();
        return(false);
       }
   
  
  
  
  1.2       +2 -1      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/RelativeLocationPath.java
  
  Index: RelativeLocationPath.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/RelativeLocationPath.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RelativeLocationPath.java 2001/04/17 18:51:46     1.1
  +++ RelativeLocationPath.java 2001/10/08 07:47:59     1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: RelativeLocationPath.java,v 1.1 2001/04/17 18:51:46 sboag Exp $
  + * @(#)$Id: RelativeLocationPath.java,v 1.2 2001/10/08 07:47:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -64,6 +64,7 @@
   package org.apache.xalan.xsltc.compiler;
   
   abstract class RelativeLocationPath extends Expression {
  +    public abstract int getAxis();
       public abstract void setAxis(int axis);
       public abstract boolean descendantAxis();
   }
  
  
  
  1.19      +54 -19    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java
  
  Index: Step.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Step.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- Step.java 2001/10/05 09:47:55     1.18
  +++ Step.java 2001/10/08 07:47:59     1.19
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Step.java,v 1.18 2001/10/05 09:47:55 morten Exp $
  + * @(#)$Id: Step.java,v 1.19 2001/10/08 07:47:59 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -206,17 +206,18 @@
        _hadPredicates = hasPredicates();
   
        if (isAbbreviatedDot()) {
  -         _type = Type.Node;
  +         if (hasParent())
  +             _type = Type.NodeSet;
  +         else
  +             _type = Type.Node;
        }
        else if (isAbbreviatedDDot()) {
            _type = Type.NodeSet;
        }
        else {
            // Special case for '@attr' with no parent or predicates
  -         if (_axis == Axis.ATTRIBUTE
  -             && _nodeType != NodeTest.ATTRIBUTE
  -             && !hasParent()
  -             && !hasPredicates()) {
  +         if ((_axis == Axis.ATTRIBUTE) && (_nodeType!=NodeTest.ATTRIBUTE) &&
  +             (!hasParent()) && (!hasPredicates())) {
                _type = Type.Node;
            }
            else {
  @@ -234,6 +235,34 @@
       }
   
       /**
  +     * This method is used to determine whether the node-set produced by
  +     * this step must be reversed before returned to the parent element.
  +     * <xsl:apply-templates> should always return nodes in document order,
  +     * while others, such as <xsl:value-of> and <xsl:for-each> should return
  +     * nodes in the order of the axis in use.
  +     */
  +    private boolean reverseNodeSet() {
  +     // Check if axis returned nodes in reverse document order
  +     if ((_axis == Axis.ANCESTOR)  || (_axis == Axis.ANCESTORORSELF) ||
  +         (_axis == Axis.PRECEDING) || (_axis == Axis.PRECEDINGSIBLING)) {
  +
  +         // Do not reverse nodes if we have a parent step that will reverse
  +         // the nodes for us.
  +         if (hasParent()) return false;
  +         if (hasPredicates()) return false;
  +         if (_hadPredicates) return false;
  +         
  +         // Check if this step occured under an <xsl:apply-templates> element
  +         SyntaxTreeNode parent = this;
  +         do {
  +             parent = parent.getParent();
  +             if (parent instanceof ApplyTemplates) return true;
  +         } while (parent != null);
  +     }
  +     return false;
  +    }
  +
  +    /**
        * Translate a step by pushing the appropriate iterator onto the stack.
        * The abbreviated steps '.' and '@attr' do not create new iterators
        * if they are not part of a LocationPath and have no filters.
  @@ -274,8 +303,18 @@
            }
   
            // Special case for '.'
  -         if (_type == Type.Node) {
  -             il.append(methodGen.loadContextNode());
  +         if (isAbbreviatedDot()) {
  +             if (_type == Type.Node) {
  +                 il.append(methodGen.loadContextNode());
  +             }
  +             else {
  +                 il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR)));
  +                 il.append(DUP);
  +                 il.append(methodGen.loadContextNode());
  +                 final int init = cpg.addMethodref(SINGLETON_ITERATOR, 
"<init>",
  +                                                   "(" + NODE_SIG +")V");
  +                 il.append(new INVOKESPECIAL(init));
  +             }
                return;
            }
   
  @@ -340,7 +379,7 @@
   
                // Now, for reverse iterators we may need to re-arrange the
                // node ordering (ancestor-type iterators).
  -             if (!(getParent() instanceof ForEach) && (!hasParent()))
  +             if (reverseNodeSet())
                    orderIterator(classGen, methodGen);
                break;
            }
  @@ -476,16 +515,12 @@
                              MethodGenerator methodGen) {
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
  -     if ((_axis == Axis.ANCESTOR)  || (_axis == Axis.ANCESTORORSELF) ||
  -         (_axis == Axis.PRECEDING) || (_axis == Axis.PRECEDINGSIBLING)) {
  -         final int init = cpg.addMethodref(REVERSE_ITERATOR, "<init>",
  -                                           "("+NODE_ITERATOR_SIG+")V");
  -
  -         il.append(new NEW(cpg.addClass(REVERSE_ITERATOR)));
  -         il.append(DUP_X1);
  -         il.append(SWAP);
  -         il.append(new INVOKESPECIAL(init));
  -     }
  +     final int init = cpg.addMethodref(REVERSE_ITERATOR, "<init>",
  +                                       "("+NODE_ITERATOR_SIG+")V");
  +     il.append(new NEW(cpg.addClass(REVERSE_ITERATOR)));
  +     il.append(DUP_X1);
  +     il.append(SWAP);
  +     il.append(new INVOKESPECIAL(init));
       }
   
   
  
  
  
  1.18      +4 -3      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup
  
  Index: xpath.cup
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- xpath.cup 2001/10/05 09:47:55     1.17
  +++ xpath.cup 2001/10/08 07:47:59     1.18
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: xpath.cup,v 1.17 2001/10/05 09:47:55 morten Exp $
  + * @(#)$Id: xpath.cup,v 1.18 2001/10/08 07:47:59 morten Exp $
    *
    * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
    * 
  @@ -452,9 +452,10 @@
   AbbreviatedRelativeLocationPath ::= RelativeLocationPath:rlp DSLASH Step:step
           {: 
           Step nodeStep;
  -        final Step temp = (Step) step;
  +        final Step temp = (Step)step;
  +           final int  axis = temp.getAxis();
              // THIS CODE IS NOT GOOD - PREDICATES ARE MISPLACED!!!!!
  -        if (temp.getAxis() == Axis.CHILD) {
  +        if ((axis == Axis.CHILD) || (axis == Axis.ATTRIBUTE)) {
               // Expand 'rlp//child::E' into 'rlp/descendant::E'
               nodeStep = new Step(Axis.DESCENDANT, 
                                   temp.getNodeType(), 
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to