redundentexpreliminator.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,474 行 · 第 1/4 页
JAVA
1,474 行
/** * Visit a LocationPath. * @param owner The owner of the expression, to which the expression can * be reset if rewriting takes place. * @param path The LocationPath object. * @return true if the sub expressions should be traversed. */ public boolean visitLocationPath(ExpressionOwner owner, LocPathIterator path) { // Don't optimize "." or single step variable paths. // Both of these cases could use some further optimization by themselves. if(path instanceof SelfIteratorNoPredicate) { return true; } else if(path instanceof WalkingIterator) { WalkingIterator wi = (WalkingIterator)path; AxesWalker aw = wi.getFirstWalker(); if((aw instanceof FilterExprWalker) && (null == aw.getNextWalker())) { FilterExprWalker few = (FilterExprWalker)aw; Expression exp = few.getInnerExpression(); if(exp instanceof Variable) return true; } } if (isAbsolute(path) && (null != m_absPaths)) { if(DEBUG) validateNewAddition(m_absPaths, owner, path); m_absPaths.addElement(owner); } else if (m_isSameContext && (null != m_paths)) { if(DEBUG) validateNewAddition(m_paths, owner, path); m_paths.addElement(owner); } return true; } /** * Visit a predicate within a location path. Note that there isn't a * proper unique component for predicates, and that the expression will * be called also for whatever type Expression is. * * @param owner The owner of the expression, to which the expression can * be reset if rewriting takes place. * @param pred The predicate object. * @return true if the sub expressions should be traversed. */ public boolean visitPredicate(ExpressionOwner owner, Expression pred) { boolean savedIsSame = m_isSameContext; m_isSameContext = false; // Any further down, just collect the absolute paths. pred.callVisitors(owner, this); m_isSameContext = savedIsSame; // We've already gone down the subtree, so don't go have the caller // go any further. return false; } /** * Visit an XSLT top-level instruction. * * @param elem The xsl instruction element object. * @return true if the sub expressions should be traversed. */ boolean visitTopLevelInstruction(ElemTemplateElement elem) { int type = elem.getXSLToken(); switch(type) { case Constants.ELEMNAME_TEMPLATE : return visitInstruction(elem); default: return true; } } /** * Visit an XSLT instruction. Any element that isn't called by one * of the other visit methods, will be called by this method. * * @param elem The xsl instruction element object. * @return true if the sub expressions should be traversed. */ boolean visitInstruction(ElemTemplateElement elem) { int type = elem.getXSLToken(); switch (type) { case Constants.ELEMNAME_CALLTEMPLATE : case Constants.ELEMNAME_TEMPLATE : case Constants.ELEMNAME_FOREACH : { // Just get the select value. if(type == Constants.ELEMNAME_FOREACH) { ElemForEach efe = (ElemForEach) elem; Expression select = efe.getSelect(); select.callVisitors(efe, this); } Vector savedPaths = m_paths; m_paths = new Vector(); // Visit children. Call the superclass callChildVisitors, because // we don't want to visit the xsl:for-each select attribute, or, for // that matter, the xsl:template's match attribute. elem.callChildVisitors(this, false); eleminateRedundentLocals(elem); m_paths = savedPaths; // select.callVisitors(efe, this); return false; } case Constants.ELEMNAME_NUMBER : case Constants.ELEMNAME_SORT : // Just collect absolute paths until and unless we can fully // analyze these cases. boolean savedIsSame = m_isSameContext; m_isSameContext = false; elem.callChildVisitors(this); m_isSameContext = savedIsSame; return false; default : return true; } } // ==== DIAGNOSTIC AND DEBUG FUNCTIONS ==== /** * Print out to std err the number of paths reduced. */ protected void diagnoseNumPaths(Vector paths, int numPathsEliminated, int numUniquePathsEliminated) { if (numPathsEliminated > 0) { if(paths == m_paths) { System.err.println("Eliminated " + numPathsEliminated + " total paths!"); System.err.println( "Consolodated " + numUniquePathsEliminated + " redundent paths!"); } else { System.err.println("Eliminated " + numPathsEliminated + " total global paths!"); System.err.println( "Consolodated " + numUniquePathsEliminated + " redundent global paths!"); } } } /** * Assert that the expression is a LocPathIterator, and, if * not, try to give some diagnostic info. */ private final void assertIsLocPathIterator(Expression expr1, ExpressionOwner eo) throws RuntimeException { if(!(expr1 instanceof LocPathIterator)) { String errMsg; if(expr1 instanceof Variable) { errMsg = "Programmer's assertion: expr1 not an iterator: "+ ((Variable)expr1).getQName(); } else { errMsg = "Programmer's assertion: expr1 not an iterator: "+ expr1.getClass().getName(); } throw new RuntimeException(errMsg + ", "+ eo.getClass().getName()+" "+ expr1.exprGetParent()); } } /** * Validate some assumptions about the new LocPathIterator and it's * owner and the state of the list. */ private static void validateNewAddition(Vector paths, ExpressionOwner owner, LocPathIterator path) throws RuntimeException { assertion(owner.getExpression() == path, "owner.getExpression() != path!!!"); int n = paths.size(); // There should never be any duplicates in the list! for(int i = 0; i < n; i++) { ExpressionOwner ew = (ExpressionOwner)paths.elementAt(i); assertion(ew != owner, "duplicate owner on the list!!!"); assertion(ew.getExpression() != path, "duplicate expression on the list!!!"); } } /** * Simple assertion. */ protected static void assertion(boolean b, String msg) { if(!b) { throw new RuntimeException(XSLMessages.createMessage(XSLTErrorResources.ER_ASSERT_REDUNDENT_EXPR_ELIMINATOR, new Object[]{msg})); // "Programmer's assertion in RundundentExprEliminator: "+msg); } } /** * Since we want to sort multistep expressions by length, use * a linked list with elements of type MultistepExprHolder. */ class MultistepExprHolder implements Cloneable { ExpressionOwner m_exprOwner; // Will change to null once we have processed this item. final int m_stepCount; MultistepExprHolder m_next; /** * Clone this object. */ public Object clone() throws CloneNotSupportedException { return super.clone(); } /** * Create a MultistepExprHolder. * * @param exprOwner the owner of the expression we are holding. * It must hold a LocationPathIterator. * @param stepCount The number of steps in the location path. */ MultistepExprHolder(ExpressionOwner exprOwner, int stepCount, MultistepExprHolder next) { m_exprOwner = exprOwner; assertion(null != m_exprOwner, "exprOwner can not be null!"); m_stepCount = stepCount; m_next = next; } /** * Add a new MultistepExprHolder in sorted order in the list. * * @param exprOwner the owner of the expression we are holding. * It must hold a LocationPathIterator. * @param stepCount The number of steps in the location path. * @return The new head of the linked list. */ MultistepExprHolder addInSortedOrder(ExpressionOwner exprOwner, int stepCount) { MultistepExprHolder first = this; MultistepExprHolder next = this; MultistepExprHolder prev = null; while(null != next) { if(stepCount >= next.m_stepCount) { MultistepExprHolder newholder = new MultistepExprHolder(exprOwner, stepCount, next); if(null == prev) first = newholder; else prev.m_next = newholder; return first; } prev = next; next = next.m_next; } prev.m_next = new MultistepExprHolder(exprOwner, stepCount, null); return first; } /** * Remove the given element from the list. 'this' should * be the head of the list. If the item to be removed is not * found, an assertion will be made. * * @param itemToRemove The item to remove from the list. * @return The head of the list, which may have changed if itemToRemove * is the same as this element. Null if the item to remove is the * only item in the list. */ MultistepExprHolder unlink(MultistepExprHolder itemToRemove) { MultistepExprHolder first = this; MultistepExprHolder next = this; MultistepExprHolder prev = null; while(null != next) { if(next == itemToRemove) { if(null == prev) first = next.m_next; else prev.m_next = next.m_next; next.m_next = null; return first; } prev = next; next = next.m_next; } assertion(false, "unlink failed!!!"); return null; } /** * Get the number of linked list items. */ int getLength() { int count = 0; MultistepExprHolder next = this; while(null != next) { count++; next = next.m_next; } return count; } /** * Print diagnostics out for the multistep list. */ protected void diagnose() { System.err.print("Found multistep iterators: " + this.getLength() + " "); MultistepExprHolder next = this; while (null != next) { System.err.print("" + next.m_stepCount); next = next.m_next; if (null != next) System.err.print(", "); } System.err.println(); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?