http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2468

If you can stomach it, here is my latest summary of this bug. Any help would
be appreciated. In it I've set out to examine the set of iterators in xsltc
that implement setStartNode(int):

AbsoluteIterator, CurrentNodeListIterator, FilteredStepIterator,
FilterIterator MatchingIterator, NthIterator, ReverseIterator,
SingletonIterator SortingIterator, StepIterator, UnionIterator

AbsoluteIterator implements this method as follows:

public NodeIterator setStartNode(int node) {
    if (_isRestartable) {
        resetPosition();
        NodeIterator iter = _source.setStartNode(_startNode = DOM.ROOTNODE);
        return iter;
    }
    return reset();
}

There are some things I find curius about this code. Presently unfamiliar
with AbsoluteIterator, I can't clearly determine if the things I find curius
about this code are in-fact bugs.

Firstly, most of the above mentioned iterators return from their
implementation of setStartNode(int) using either "return this;" or "return
resetPosition();". Whats different here is that (depending upon the
codepath) the _source iterator could be returned to the caller. I consider
this behaviour suspicious.

Additionally suspicious about this iterator is that when _isRestartable ==
false the iterator will call reset() - with no ultimate effect since the
next() method is implemented as:

public int next() {
    // Should never be called
    return returnNode(NodeIterator.END);
}

How can AbsoluteIterator usefully be used with next() implemented this way?

Perhaps it doesn't matter. Let's look at some example xsl (my patched
version of mk031.xsl):

<xsl:for-each select="/programme/composer/fullname">
    <xsl:call-template name="make-list">
        <xsl:with-param name="names" select="/programme/composer/fullname"/>
    </xsl:call-template>
</xsl:for-each>

This results in the parameter initialization of the xpath to be (shown here
from the decompiled translet):

this.addParameter(
  "names",
  new AbsoluteIterator(
    new StepIterator(
      (new StepIterator(
        domadapter.getTypedAxisIterator(3, 7),
        domadapter.getTypedAxisIterator(3, 8)
      )),
      domadapter.getTypedAxisIterator(3, 9)
    )
  ).setStartNode(i),
  false
);
make_list(domadapter, nodeiterator, transletoutputhandler, i);

Notice that this code calls AbsoluteIterator::setStartNode(int) and
initialized to state i. This i is also passed into the template (important
in the next step). Since setStartNode(int) follows the "if (_isRestartable)"
codepath, the "return iter;" will return the outer StepIterator instance
which will be pushed onto the parameter stack.

When the parameter is retrieved from the stack
StepIterator::setStartNode(int) will be called, using the same variable i:

Object object = this.addParameter("names", "", true);
nodeiterator =
BasisLibrary.referenceToNodeSet(object).reset().setStartNode(i);

thus reinitializing the iterator into a different state.

So, where's the bug? Is it:

1. in AbsoluteIterator::setStartNode(int): perhaps it shouldn't return the
_source iterator but should instead allow itself to be pushed onto the
stack? If so, AbsoluteIterator::next() certainly is also broken (if the
comment is any indication).

2. somewhere in the code generation of the local iterator: inparticular, the
call to StepIterator::setStartNode(int) resets the iterator to an incorrect
state - in the case of an xpath constructed on the stack perhaps this call
should not be made? Would the resolution then be inside
Expression::startResetIterator(...)?

3. because the template call is enclosed in a for-each and the current node
(i which is passed as an argument) changes each loop the problem is that the
iterator's reinitialization (inside make$list) is using the wrong i. Should
it be DOM.ROOTNODE?

4. somewhere else?

Anyone have any thoughts on the matter?

dazed but not yet (completely) confused,

john

Reply via email to