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 + -
显示快捷键?