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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]