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