You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2002/05/03 16:17:32 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler Mode.java

santiagopg    02/05/03 07:17:32

  Modified:    java/src/org/apache/xalan/xsltc/compiler Mode.java
  Log:
  Fixed for Bugzilla 2886 (node15).
  
  Revision  Changes    Path
  1.20      +162 -82   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java
  
  Index: Mode.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Mode.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- Mode.java	1 Feb 2002 20:07:08 -0000	1.19
  +++ Mode.java	3 May 2002 14:17:32 -0000	1.20
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Mode.java,v 1.19 2002/02/01 20:07:08 tmiller Exp $
  + * @(#)$Id: Mode.java,v 1.20 2002/05/03 14:17:32 santiagopg Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -82,21 +82,54 @@
    */
   final class Mode implements Constants {
   
  -    private final QName      _name;       // The QName of this mode
  -    private final Stylesheet _stylesheet; // The owning stylesheet
  -    private final String     _methodName; // The method name for this mode
  -    private Vector           _templates;  // All templates in this mode
  -
  -    // Pattern/test sequence for pattern with node()-type kernel
  -    private Vector    _nodeGroup = null;
  -    private TestSeq   _nodeTestSeq = null;
  -
  -    // Pattern/test sequence for pattern with id() or key()-type kernel
  -    private Vector    _idxGroup = null;
  -    private TestSeq   _idxTestSeq = null;
  +    /**
  +     * The name of this mode as defined in the stylesheet.
  +     */
  +    private final QName _name;
  +
  +    /**
  +     * A reference to the stylesheet object that owns this mode.
  +     */
  +    private final Stylesheet _stylesheet; 
  +
  +    /**
  +     * The name of the method in which this mode is compiled.
  +     */
  +    private final String _methodName;
  +
  +    /**
  +     * A vector of all the templates in this mode.
  +     */
  +    private Vector _templates; 
  +
  +    /**
  +     * Group for patterns with node()-type kernel.
  +     */
  +    private Vector _nodeGroup = null;
  +
  +    /**
  +     * Test sequence for patterns with node()-type kernel.
  +     */
  +    private TestSeq _nodeTestSeq = null;
  +
  +    /**
  +     * Group for patterns with id() or key()-type kernel.
  +     */
  +    private Vector _idxGroup = null;
   
  -    // Pattern/test sequence for patterns with any other kernel type
  +    /**
  +     * Test sequence for patterns with id() or key()-type kernel.
  +     */
  +    private TestSeq  _idxTestSeq = null;
  +
  +    /**
  +     * Group for patterns with any other kernel type.
  +     */
       private Vector[]  _patternGroups;
  +
  +    /**
  +     * Test sequence for patterns with any other kernel type.
  +     */
       private TestSeq[] _testSeq;
   
       private Hashtable _neededTemplates = new Hashtable();
  @@ -114,7 +147,8 @@
   
   
       /**
  -     * Creates a new Mode
  +     * Creates a new Mode.
  +     *
        * @param name A textual representation of the mode's QName
        * @param stylesheet The Stylesheet in which the mode occured
        * @param suffix A suffix to append to the method name for this mode
  @@ -200,15 +234,20 @@
   	    // Get the next template
   	    final Template template = (Template)templates.nextElement();
   
  -	    // Add this template to a table of named templates if it has a name.
  -	    // If there are multiple templates with the same name, all but one
  -	    // (the one with highest priority) will be disabled.
  -	    if (template.isNamed() && !template.disabled())
  +	    /* 
  +	     * Add this template to a table of named templates if it has a name.
  +	     * If there are multiple templates with the same name, all but one
  +	     * (the one with highest priority) will be disabled.
  +	     */
  +	    if (template.isNamed() && !template.disabled()) {
   		_namedTemplates.put(template, this);
  +	    }
   
   	    // Add this template to a test sequence if it has a pattern
   	    final Pattern pattern = template.getPattern();
  -	    if (pattern != null) flattenAlternative(pattern, template, keys);
  +	    if (pattern != null) {
  +		flattenAlternative(pattern, template, keys);
  +	    }
   	}
   	prepareTestSequences();
       }
  @@ -261,10 +300,7 @@
   	Vector patterns;
   
   	// Use the vector for id()/key()/node() patterns if no kernel type
  -	if (kernelType == -1)
  -	    patterns = _nodeGroup;
  -	else
  -	    patterns = _patternGroups[kernelType];
  +	patterns = (kernelType == -1) ? _nodeGroup : _patternGroups[kernelType];
   
   	// Create a new vector if needed and insert the very first pattern
   	if (patterns == null) {
  @@ -389,7 +425,8 @@
   
       private void compileTemplates(ClassGenerator classGen,
   				  MethodGenerator methodGen,
  -				  InstructionHandle next) {
  +				  InstructionHandle next) 
  +    {
           Enumeration templates = _namedTemplates.keys();
           while (templates.hasMoreElements()) {
               final Template template = (Template)templates.nextElement();
  @@ -563,22 +600,16 @@
       }
   
       /**
  -     * Auxillary method to determine if a qname describes an attribute/element
  +     * Auxiliary method to determine if a qname describes an attribute/element
        */
       private static boolean isAttributeName(String qname) {
   	final int col = qname.lastIndexOf(':') + 1;
  -	if (qname.charAt(col) == '@')
  -	    return(true);
  -	else
  -	    return(false);
  +	return (qname.charAt(col) == '@');
       }
   
       private static boolean isNamespaceName(String qname) {
   	final int col = qname.lastIndexOf(':');
  -	if ((col > -1) && (qname.charAt(qname.length()-1) == '*'))
  -	    return(true);
  -	else
  -	    return(false);
  +	return (col > -1 && qname.charAt(qname.length()-1) == '*');
       }
   
       /**
  @@ -588,9 +619,9 @@
       public void compileApplyTemplates(ClassGenerator classGen) {
   	final XSLTC xsltc = classGen.getParser().getXSLTC();
   	final ConstantPoolGen cpg = classGen.getConstantPool();
  -	final Vector names      = xsltc.getNamesIndex();
  +	final Vector names = xsltc.getNamesIndex();
   
  -	// (*) Create the applyTemplates() method
  +	// Create the applyTemplates() method
   	final org.apache.bcel.generic.Type[] argTypes =
   	    new org.apache.bcel.generic.Type[3];
   	argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
  @@ -611,20 +642,20 @@
   				classGen.getConstantPool());
   	methodGen.addException("org.apache.xalan.xsltc.TransletException");
   
  -	// (*) Create the local variablea
  +	// Create a local variable to hold the current node
   	final LocalVariableGen current;
   	current = methodGen.addLocalVariable2("current",
   					      org.apache.bcel.generic.Type.INT,
   					      mainIL.getEnd());
   	_currentIndex = current.getIndex();
   
  -	// (*) Create the "body" instruction list that will eventually hold the
  -	//     code for the entire method (other ILs will be appended).
  +	// Create the "body" instruction list that will eventually hold the
  +	// code for the entire method (other ILs will be appended).
   	final InstructionList body = new InstructionList();
   	body.append(NOP);
   
  -	// (*) Create an instruction list that contains the default next-node
  -	//     iteration
  +	// Create an instruction list that contains the default next-node
  +	// iteration
   	final InstructionList ilLoop = new InstructionList();
   	ilLoop.append(methodGen.loadIterator());
   	ilLoop.append(methodGen.nextNode());
  @@ -635,41 +666,44 @@
   	// by a single IFNE(body.getStart()) instruction - need workaround:
           final BranchHandle ifeq = ilLoop.append(new IFEQ(null));
   	final BranchHandle loop = ilLoop.append(new GOTO_W(null));
  -	ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here!
  +	ifeq.setTarget(ilLoop.append(RETURN)); 	// applyTemplates() ends here!
   	final InstructionHandle ihLoop = ilLoop.getStart();
   
  -	// (*) Compile default handling of elements (traverse children)
  +	// Compile default handling of elements (traverse children)
   	InstructionList ilRecurse =
   	    compileDefaultRecursion(classGen, methodGen, ihLoop);
   	InstructionHandle ihRecurse = ilRecurse.getStart();
   
  -	// (*) Compile default handling of text/attribute nodes (output text)
  +	// Compile default handling of text/attribute nodes (output text)
   	InstructionList ilText =
   	    compileDefaultText(classGen, methodGen, ihLoop);
   	InstructionHandle ihText = ilText.getStart();
   
   	// Distinguish attribute/element/namespace tests for further processing
   	final int[] types = new int[DOM.NTYPES + names.size()];
  -	for (int i = 0; i < types.length; i++) types[i] = i;
  +	for (int i = 0; i < types.length; i++) {
  +	    types[i] = i;
  +	}
   
  +	// Initialize isAttribute[] and isNamespace[] arrays
   	final boolean[] isAttribute = new boolean[types.length];
   	final boolean[] isNamespace = new boolean[types.length];
   	for (int i = 0; i < names.size(); i++) {
   	    final String name = (String)names.elementAt(i);
  -	    isAttribute[i+DOM.NTYPES] = isAttributeName(name);
  -	    isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
  +	    isAttribute[i + DOM.NTYPES] = isAttributeName(name);
  +	    isNamespace[i + DOM.NTYPES] = isNamespaceName(name);
   	}
   
  -	// (*) Compile all templates - regardless of pattern type
  +	// Compile all templates - regardless of pattern type
   	compileTemplates(classGen, methodGen, ihLoop);
   
  -	// (*) Handle template with explicit "*" pattern
  +	// Handle template with explicit "*" pattern
   	final TestSeq elemTest = _testSeq[DOM.ELEMENT];
   	InstructionHandle ihElem = ihRecurse;
   	if (elemTest != null)
   	    ihElem = elemTest.compile(classGen, methodGen, ihRecurse);
   
  -	// (*) Handle template with explicit "@*" pattern
  +	// Handle template with explicit "@*" pattern
   	final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
   	InstructionHandle ihAttr = ihText;
   	if (attrTest != null)
  @@ -685,39 +719,58 @@
   	    loop.setTarget(body.getStart());
   	}
   
  -	// (*) If there is a match on node() we need to replace ihElem
  -	//     and ihText (default behaviour for elements & text).
  +	// If there is a match on node() we need to replace ihElem
  +	// and ihText if the priority of node() is higher
   	if (_nodeTestSeq != null) {
  -	    double nodePrio = -0.5; //_nodeTestSeq.getPriority();
  +
  +	    // Compare priorities of node() and "*"
  +	    double nodePrio = -0.5; 	//_nodeTestSeq.getPriority();
   	    int    nodePos  = _nodeTestSeq.getPosition();
   	    double elemPrio = (0 - Double.MAX_VALUE);
   	    int    elemPos  = Integer.MIN_VALUE;
  +
   	    if (elemTest != null) {
   		elemPrio = elemTest.getPriority();
   		elemPos  = elemTest.getPosition();
   	    }
  -	    if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
  -		((elemPrio == nodePrio) && (elemPos < nodePos))) {
  +	    if (elemPrio == Double.NaN || elemPrio < nodePrio || 
  +		(elemPrio == nodePrio && elemPos < nodePos)) 
  +	    {
   		ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  -		ihText = ihElem;
  +	    }
  +
  +	    // Compare priorities of node() and text()
  +	    final TestSeq textTest = _testSeq[DOM.TEXT];
  +	    double textPrio = (0 - Double.MAX_VALUE);
  +	    int    textPos  = Integer.MIN_VALUE;
  +
  +	    if (textTest != null) {
  +		textPrio = textTest.getPriority();
  +		textPos  = textTest.getPosition();
  +	    }
  +	    if (textPrio == Double.NaN || textPrio < nodePrio ||
  +	        (textPrio == nodePrio && textPos < nodePos)) 
  +	    {
  +		ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  +		_testSeq[DOM.TEXT] = _nodeTestSeq;
   	    }
   	}
   
  -	// (*) Handle templates with "ns:*" pattern
  +	// Handle templates with "ns:*" pattern
   	InstructionHandle elemNamespaceHandle = ihElem;
   	InstructionList nsElem = compileNamespaces(classGen, methodGen,
   						   isNamespace, isAttribute,
   						   false, ihElem);
   	if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
   
  -	// (*) Handle templates with "ns:@*" pattern
  +	// Handle templates with "ns:@*" pattern
   	InstructionHandle attrNamespaceHandle = ihAttr;
   	InstructionList nsAttr = compileNamespaces(classGen, methodGen,
   						   isNamespace, isAttribute,
   						   true, ihAttr);
   	if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
   
  -	// (*) Handle templates with "ns:elem" or "ns:@attr" pattern
  +	// Handle templates with "ns:elem" or "ns:@attr" pattern
   	final InstructionHandle[] targets = new InstructionHandle[types.length];
   	for (int i = DOM.NTYPES; i < targets.length; i++) {
   	    final TestSeq testSeq = _testSeq[i];
  @@ -902,7 +955,7 @@
   	// Process all patterns from those templates
   	processPatterns(_keys);
   
  -	// (*) Create the applyTemplates() method
  +	// Create the applyTemplates() method
   	final org.apache.bcel.generic.Type[] argTypes =
   	    new org.apache.bcel.generic.Type[3];
   	argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
  @@ -936,20 +989,20 @@
   	    return;
   	}
   
  -	// (*) Create the local variablea
  +	// Create the local variablea
   	final LocalVariableGen current;
   	current = methodGen.addLocalVariable2("current",
   					      org.apache.bcel.generic.Type.INT,
   					      mainIL.getEnd());
   	_currentIndex = current.getIndex();
   
  -	// (*) Create the "body" instruction list that will eventually hold the
  -	//     code for the entire method (other ILs will be appended).
  +	// Create the "body" instruction list that will eventually hold the
  +	// code for the entire method (other ILs will be appended).
   	final InstructionList body = new InstructionList();
   	body.append(NOP);
   
  -	// (*) Create an instruction list that contains the default next-node
  -	//     iteration
  +	// Create an instruction list that contains the default next-node
  +	// iteration
   	final InstructionList ilLoop = new InstructionList();
   	ilLoop.append(methodGen.loadIterator());
   	ilLoop.append(methodGen.nextNode());
  @@ -965,7 +1018,9 @@
   
   	// Distinguish attribute/element/namespace tests for further processing
   	final int[] types = new int[DOM.NTYPES + names.size()];
  -	for (int i = 0; i < types.length; i++) types[i] = i;
  +	for (int i = 0; i < types.length; i++) {
  +	    types[i] = i;
  +	}
   
   	final boolean[] isAttribute = new boolean[types.length];
   	final boolean[] isNamespace = new boolean[types.length];
  @@ -975,20 +1030,22 @@
   	    isNamespace[i+DOM.NTYPES] = isNamespaceName(name);
   	}
   
  -	// (*) Compile all templates - regardless of pattern type
  +	// Compile all templates - regardless of pattern type
   	compileTemplateCalls(classGen, methodGen, ihLoop, min, max);
   
  -	// (*) Handle template with explicit "*" pattern
  +	// Handle template with explicit "*" pattern
   	final TestSeq elemTest = _testSeq[DOM.ELEMENT];
   	InstructionHandle ihElem = ihLoop;
  -	if (elemTest != null)
  +	if (elemTest != null) {
   	    ihElem = elemTest.compile(classGen, methodGen, ihLoop);
  +	}
   
  -	// (*) Handle template with explicit "@*" pattern
  +	// Handle template with explicit "@*" pattern
   	final TestSeq attrTest = _testSeq[DOM.ATTRIBUTE];
   	InstructionHandle ihAttr = ihLoop;
  -	if (attrTest != null)
  +	if (attrTest != null) {
   	    ihAttr = attrTest.compile(classGen, methodGen, ihAttr);
  +	}
   
   	// Do tests for id() and key() patterns first
   	InstructionList ilKey = null;
  @@ -1000,40 +1057,61 @@
   	    loop.setTarget(body.getStart());
   	}
   
  -	// (*) If there is a match on node() we need to replace ihElem
  -	//     and ihText (default behaviour for elements & text).
  +	// If there is a match on node() we need to replace ihElem
  +	// and ihText if the priority of node() is higher
   	InstructionHandle ihText = ihLoop;
   	if (_nodeTestSeq != null) {
  -	    double nodePrio = -0.5; //_nodeTestSeq.getPriority();
  +
  +	    // Compare priorities of node() and "*"
  +	    double nodePrio = -0.5; 	//_nodeTestSeq.getPriority();
   	    int    nodePos  = _nodeTestSeq.getPosition();
   	    double elemPrio = (0 - Double.MAX_VALUE);
   	    int    elemPos  = Integer.MIN_VALUE;
  +
   	    if (elemTest != null) {
   		elemPrio = elemTest.getPriority();
   		elemPos  = elemTest.getPosition();
   	    }
  -	    if ((elemPrio == Double.NaN) || (elemPrio < nodePrio) ||
  -		((elemPrio == nodePrio) && (elemPos < nodePos))) {
  +
  +	    if (elemPrio == Double.NaN || elemPrio < nodePrio || 
  +		(elemPrio == nodePrio && elemPos < nodePos)) 
  +	    {
   		ihElem = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  -		ihText = ihElem;
  +	    }
  +
  +	    // Compare priorities of node() and text()
  +	    final TestSeq textTest = _testSeq[DOM.TEXT];
  +	    double textPrio = (0 - Double.MAX_VALUE);
  +	    int    textPos  = Integer.MIN_VALUE;
  +
  +	    if (textTest != null) {
  +		textPrio = textTest.getPriority();
  +		textPos  = textTest.getPosition();
  +	    }
  +
  +	    if (textPrio == Double.NaN || textPrio < nodePrio ||
  +	        (textPrio == nodePrio && textPos < nodePos)) 
  +	    {
  +		ihText = _nodeTestSeq.compile(classGen, methodGen, ihLoop);
  +		_testSeq[DOM.TEXT] = _nodeTestSeq;
   	    }
   	}
   
  -	// (*) Handle templates with "ns:*" pattern
  +	// Handle templates with "ns:*" pattern
   	InstructionHandle elemNamespaceHandle = ihElem;
   	InstructionList nsElem = compileNamespaces(classGen, methodGen,
   						   isNamespace, isAttribute,
   						   false, ihElem);
   	if (nsElem != null) elemNamespaceHandle = nsElem.getStart();
   
  -	// (*) Handle templates with "ns:@*" pattern
  +	// Handle templates with "ns:@*" pattern
   	InstructionList nsAttr = compileNamespaces(classGen, methodGen,
   						   isNamespace, isAttribute,
   						   true, ihAttr);
   	InstructionHandle attrNamespaceHandle = ihAttr;
   	if (nsAttr != null) attrNamespaceHandle = nsAttr.getStart();
   
  -	// (*) Handle templates with "ns:elem" or "ns:@attr" pattern
  +	// Handle templates with "ns:elem" or "ns:@attr" pattern
   	final InstructionHandle[] targets = new InstructionHandle[types.length];
   	for (int i = DOM.NTYPES; i < targets.length; i++) {
   	    final TestSeq testSeq = _testSeq[i];
  @@ -1080,12 +1158,14 @@
   	// Match on processing instruction - default: loop
   	InstructionHandle ihPI = ihLoop;
   	if (_nodeTestSeq != null) ihPI = ihElem;
  -	if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null)
  +	if (_testSeq[DOM.PROCESSING_INSTRUCTION] != null) {
   	    targets[DOM.PROCESSING_INSTRUCTION] =
   		_testSeq[DOM.PROCESSING_INSTRUCTION].
   		compile(classGen, methodGen, ihPI);
  -	else
  +	}
  +	else {
   	    targets[DOM.PROCESSING_INSTRUCTION] = ihPI;
  +	}
   	
   	// Match on comments - default: process next node
   	InstructionHandle ihComment = ihLoop;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org