Example #1
0
  public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();

    // Save current node and current iterator on the stack
    il.append(methodGen.loadCurrentNode());
    il.append(methodGen.loadIterator());

    // Collect sort objects associated with this instruction
    final Vector sortObjects = new Vector();
    Enumeration children = elements();
    while (children.hasMoreElements()) {
      final Object child = children.nextElement();
      if (child instanceof Sort) {
        sortObjects.addElement(child);
      }
    }

    if ((_type != null) && (_type instanceof ResultTreeType)) {
      // Store existing DOM on stack - must be restored when loop is done
      il.append(methodGen.loadDOM());

      // <xsl:sort> cannot be applied to a result tree - issue warning
      if (sortObjects.size() > 0) {
        ErrorMsg msg = new ErrorMsg(ErrorMsg.RESULT_TREE_SORT_ERR, this);
        getParser().reportError(WARNING, msg);
      }

      // Put the result tree on the stack (DOM)
      _select.translate(classGen, methodGen);
      // Get an iterator for the whole DOM - excluding the root node
      _type.translateTo(classGen, methodGen, Type.NodeSet);
      // Store the result tree as the default DOM
      il.append(SWAP);
      il.append(methodGen.storeDOM());
    } else {
      // Compile node iterator
      if (sortObjects.size() > 0) {
        Sort.translateSortIterator(classGen, methodGen, _select, sortObjects);
      } else {
        _select.translate(classGen, methodGen);
      }

      if (_type instanceof ReferenceType == false) {
        il.append(methodGen.loadContextNode());
        il.append(methodGen.setStartNode());
      }
    }

    // Overwrite current iterator
    il.append(methodGen.storeIterator());

    // Give local variables (if any) default values before starting loop
    initializeVariables(classGen, methodGen);

    final BranchHandle nextNode = il.append(new GOTO(null));
    final InstructionHandle loop = il.append(NOP);

    translateContents(classGen, methodGen);

    nextNode.setTarget(il.append(methodGen.loadIterator()));
    il.append(methodGen.nextNode());
    il.append(DUP);
    il.append(methodGen.storeCurrentNode());
    il.append(new IFGT(loop));

    // Restore current DOM (if result tree was used instead for this loop)
    if ((_type != null) && (_type instanceof ResultTreeType)) {
      il.append(methodGen.storeDOM());
    }

    // Restore current node and current iterator from the stack
    il.append(methodGen.storeIterator());
    il.append(methodGen.storeCurrentNode());
  }