You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mo...@apache.org on 2001/10/08 09:47:59 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler ParentLocationPath.java RelativeLocationPath.java Step.java xpath.cup

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:	morten@xml.apache.org
  Reviewed by:	morten@xml.apache.org
  
  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: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org