xalan-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minc...@apache.org
Subject svn commit: r476471 - in /xalan/java/trunk/src/org/apache/xalan/xsltc/compiler: Key.java KeyCall.java Stylesheet.java SymbolTable.java TopLevelElement.java UnresolvedRef.java VariableBase.java VariableRefBase.java
Date Sat, 18 Nov 2006 08:36:28 GMT
Author: minchau
Date: Sat Nov 18 00:36:27 2006
New Revision: 476471

URL: http://svn.apache.org/viewvc?view=rev&rev=476471
Log:
Committing Santiago's pathc for XALANJ-2108 to not 
have an error on certain XSLT parameters that have an
error, but are not used.

Modified:
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Key.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/KeyCall.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/TopLevelElement.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableBase.java
    xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Key.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Key.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Key.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Key.java Sat Nov 18 00:36:27 2006
@@ -21,6 +21,8 @@
 
 package org.apache.xalan.xsltc.compiler;
 
+import java.util.Vector;
+
 import org.apache.bcel.generic.BranchHandle;
 import org.apache.bcel.generic.ConstantPoolGen;
 import org.apache.bcel.generic.GOTO;
@@ -71,7 +73,7 @@
      * The type of the _use expression.
      */
     private Type _useType;
-
+        
     /**
      * Parse the <xsl:key> element and attributes
      * @param parser A reference to the stylesheet parser
@@ -84,7 +86,11 @@
             ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, name, this);
             parser.reportError(Constants.ERROR, err);           
         }
+        
+        // Parse key name and add to symbol table
         _name = parser.getQNameIgnoreDefaultNs(name);
+        getSymbolTable().addKey(_name, this);
+        
 	_match = parser.parsePattern(this, "match", null);
 	_use = parser.parseExpression(this, "use", null);
 

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/KeyCall.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/KeyCall.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/KeyCall.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/KeyCall.java Sat Nov 18 00:36:27
2006
@@ -99,7 +99,34 @@
 	}
     }
 
-    /**
+     /**
+     * If this call to key() is in a top-level element like  another variable
+     * or param, add a dependency between that top-level element and the 
+     * referenced key. For example,
+     *
+     *   <xsl:key name="x" .../>
+     *   <xsl:variable name="y" select="key('x', 1)"/>
+     *
+     * and assuming this class represents "key('x', 1)", add a reference 
+     * between variable y and key x. Note that if 'x' is unknown statically
+     * in key('x', 1), there's nothing we can do at this point.
+     */
+    public void addParentDependency() {
+        // If name unknown statically, there's nothing we can do
+        if (_resolvedQName == null) return;
+        
+	SyntaxTreeNode node = this;
+	while (node != null && node instanceof TopLevelElement == false) {
+	    node = node.getParent();
+	}
+        
+        TopLevelElement parent = (TopLevelElement) node;        
+        if (parent != null) {
+            parent.addDependency(getSymbolTable().getKey(_resolvedQName));
+        }        
+    }
+    
+   /**
      * Type check the parameters for the id() or key() function.
      * The index name (for key() call only) must be a string or convertable
      * to a string, and the lookup-value must be a string or a node-set.
@@ -142,6 +169,9 @@
             _valueType = _value.typeCheck(stable);
 	}
 
+    // If in a top-level element, create dependency to the referenced key
+    addParentDependency();
+    
 	return returnType;
     }
 

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Stylesheet.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Stylesheet.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/Stylesheet.java Sat Nov 18 00:36:27
2006
@@ -1118,12 +1118,17 @@
 
     /**
      * Compile a topLevel() method into the output class. This method is 
-     * called from transform() to handle all non-template top-level elemtents.
+     * called from transform() to handle all non-template top-level elements.
      * Returns the signature of the topLevel() method.
+     *
+     * Global variables/params and keys are first sorted to resolve 
+     * dependencies between them. The XSLT 1.0 spec does not allow a key 
+     * to depend on a variable. However, for compatibility with Xalan
+     * interpretive, that type of dependency is allowed. Note also that
+     * the buildKeys() method is still generated as it is used by the 
+     * LoadDocument class, but it no longer called from transform().
      */
-    private String compileTopLevel(ClassGenerator classGen,
-				   Enumeration elements) {
-
+    private String compileTopLevel(ClassGenerator classGen) {
 	final ConstantPoolGen cpg = classGen.getConstantPool();
 
 	final org.apache.bcel.generic.Type[] argTypes = {
@@ -1160,16 +1165,33 @@
 	il.append(new PUSH(cpg, DTM.ROOT_NODE));
 	current.setStart(il.append(new ISTORE(current.getIndex())));
 
-	// Resolve any forward referenes and translate global variables/params
-	_globals = resolveReferences(_globals);
-	final int count = _globals.size();
-	for (int i = 0; i < count; i++) {
-	    final VariableBase var = (VariableBase)_globals.elementAt(i);
-	    var.translate(classGen,toplevel);
-	}
+    // Create a new list containing variables/params + keys
+    Vector varDepElements = new Vector(_globals);        
+    Enumeration elements = elements();
+    while (elements.hasMoreElements()) {
+        final Object element = elements.nextElement();
+        if (element instanceof Key) {
+            varDepElements.add(element);
+        }
+    }
+            
+    // Determine a partial order for the variables/params and keys
+    varDepElements = resolveDependencies(varDepElements);
+    
+    // Translate vars/params and keys in the right order
+    final int count = varDepElements.size();
+    for (int i = 0; i < count; i++) {
+        final TopLevelElement tle = (TopLevelElement) varDepElements.elementAt(i);      
     
+        tle.translate(classGen, toplevel);            
+        if (tle instanceof Key) {
+            final Key key = (Key) tle;
+            _keys.put(key.getName(), key);
+        }
+    }
 
-	// Compile code for other top-level elements
-	Vector whitespaceRules = new Vector();
+    // Compile code for other top-level elements
+    Vector whitespaceRules = new Vector();
+    elements = elements();
 	while (elements.hasMoreElements()) {
 	    final Object element = elements.nextElement();
 	    // xsl:decimal-format
@@ -1200,47 +1222,36 @@
 	
 	return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V");
     }
-
+    
     /**
-     * This method returns a vector with variables in the order in 
-     * which they are to be compiled. The order is determined by the 
-     * dependencies between them and the order in which they were defined 
-     * in the stylesheet. The first step is to close the input vector under
-     * the dependence relation (this is usually needed when variables are
-     * defined inside other variables in a RTF).
+     * This method returns a vector with variables/params and keys in the 
+     * order in which they are to be compiled for initialization. The order
+     * is determined by analyzing the dependencies between them. The XSLT 1.0 
+     * spec does not allow a key to depend on a variable. However, for 
+     * compatibility with Xalan interpretive, that type of dependency is 
+     * allowed and, therefore, consider to determine the partial order.
      */
-    private Vector resolveReferences(Vector input) {
-
-	// Make sure that the vector 'input' is closed
+    private Vector resolveDependencies(Vector input) {
+	/* DEBUG CODE - INGORE 
 	for (int i = 0; i < input.size(); i++) {
-	    final VariableBase var = (VariableBase) input.elementAt(i);
-	    final Vector dep  = var.getDependencies();
-	    final int depSize = (dep != null) ? dep.size() : 0;
-
-	    for (int j = 0; j < depSize; j++) {
-		final VariableBase depVar = (VariableBase) dep.elementAt(j);
-		if (!input.contains(depVar)) {
-		    input.addElement(depVar);
-		}
-	    }
+	    final TopLevelElement e = (TopLevelElement) input.elementAt(i);
+	    System.out.println("e = " + e + " depends on:");
+            Vector dep = e.getDependencies();
+            for (int j = 0; j < (dep != null ? dep.size() : 0); j++) {
+                System.out.println("\t" + dep.elementAt(j));
+            }
 	}
-
-	/* DEBUG CODE - INGORE
-	for (int i = 0; i < input.size(); i++) {
-	    final VariableBase var = (VariableBase) input.elementAt(i);
-	    System.out.println("var = " + var);
-	}
-	System.out.println("=================================");
-	*/
+	System.out.println("=================================");	
+        */
 
 	Vector result = new Vector();
 	while (input.size() > 0) {
 	    boolean changed = false;
 	    for (int i = 0; i < input.size(); ) {
-		final VariableBase var = (VariableBase)input.elementAt(i);
-		final Vector dep = var.getDependencies();
+		final TopLevelElement vde = (TopLevelElement) input.elementAt(i);
+		final Vector dep = vde.getDependencies();
 		if (dep == null || result.containsAll(dep)) {
-		    result.addElement(var);
+		    result.addElement(vde);
 		    input.remove(i);
 		    changed = true;
 		}
@@ -1258,23 +1269,24 @@
 	    }
 	}
 
-	/* DEBUG CODE - INGORE
+	/* DEBUG CODE - INGORE 
 	System.out.println("=================================");
 	for (int i = 0; i < result.size(); i++) {
-	    final VariableBase var = (VariableBase) result.elementAt(i);
-	    System.out.println("var = " + var);
+	    final TopLevelElement e = (TopLevelElement) result.elementAt(i);
+	    System.out.println("e = " + e);
 	}
-	*/
+        */
 
 	return result;
     }
 
     /**
-     * Compile a buildKeys() method into the output class. This method is 
-     * called from transform() to handle build all indexes needed by key().
+     * Compile a buildKeys() method into the output class. Note that keys 
+     * for the input document are created in topLevel(), not in this method. 
+     * However, we still need this method to create keys for documents loaded
+     * via the XPath document() function. 
      */
     private String compileBuildKeys(ClassGenerator classGen) {
-
 	final ConstantPoolGen cpg = classGen.getConstantPool();
 
 	final org.apache.bcel.generic.Type[] argTypes = {
@@ -1300,7 +1312,6 @@
 	buildKeys.addException("org.apache.xalan.xsltc.TransletException");
 	
 	final Enumeration elements = elements();
-	// Compile code for other top-level elements
 	while (elements.hasMoreElements()) {
 	    // xsl:key
 	    final Object element = elements.nextElement();
@@ -1406,25 +1417,21 @@
 					   "("+OUTPUT_HANDLER_SIG+")V");
 	il.append(new INVOKEVIRTUAL(index));
 
-        // Compile buildKeys -- TODO: omit if not needed                
-        
+        /*
+         * Compile buildKeys() method. Note that this method is not 
+         * invoked here as keys for the input document are now created
+         * in topLevel(). However, this method is still needed by the
+         * LoadDocument class.
+         */        
         final String keySig = compileBuildKeys(classGen);
-        final int    keyIdx = cpg.addMethodref(getClassName(),
+        final int keyIdx = cpg.addMethodref(getClassName(),
                                                "buildKeys", keySig);
-        il.append(classGen.loadTranslet());     // The 'this' pointer
-        il.append(classGen.loadTranslet());
-        il.append(new GETFIELD(domField));      // The DOM reference
-        il.append(transf.loadIterator());       // Not really used, but...
-        il.append(transf.loadHandler());        // The output handler
-        il.append(new PUSH(cpg, DTM.ROOT_NODE)); // Start with the root node
-        il.append(new INVOKEVIRTUAL(keyIdx));
-
-
-    // Look for top-level elements that need handling
+                
+        // Look for top-level elements that need handling
 	final Enumeration toplevel = elements();
-	if ((_globals.size() > 0) || (toplevel.hasMoreElements())) {
+	if (_globals.size() > 0 || toplevel.hasMoreElements()) {
 	    // Compile method for handling top-level elements
-	    final String topLevelSig = compileTopLevel(classGen, toplevel);
+	    final String topLevelSig = compileTopLevel(classGen);
 	    // Get a reference to that method
 	    final int topLevelIdx = cpg.addMethodref(getClassName(),
 						     "topLevel",
@@ -1436,10 +1443,7 @@
 	    il.append(transf.loadIterator());
 	    il.append(transf.loadHandler());    // The output handler
 	    il.append(new INVOKEVIRTUAL(topLevelIdx));
-	}
-	
-
-
+	}	
 
 	// start document
 	il.append(transf.loadHandler());

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/SymbolTable.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/SymbolTable.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/SymbolTable.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/SymbolTable.java Sat Nov 18 00:36:27
2006
@@ -45,6 +45,7 @@
     private Hashtable _aliases = null;
     private Hashtable _excludedURI = null;
     private Hashtable _decimalFormats = null;
+    private Hashtable _keys = null;
 
     public DecimalFormatting getDecimalFormatting(QName name) {
 	if (_decimalFormats == null) return null;
@@ -56,6 +57,16 @@
 	_decimalFormats.put(name, symbols);
     }
 
+    public Key getKey(QName name) {
+	if (_keys == null) return null;
+	return (Key) _keys.get(name);
+    }
+
+    public void addKey(QName name, Key key) {
+	if (_keys == null) _keys = new Hashtable();
+	_keys.put(name, key);
+    }
+    
     public Stylesheet addStylesheet(QName name, Stylesheet node) {
 	return (Stylesheet)_stylesheets.put(name, node);
     }

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/TopLevelElement.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/TopLevelElement.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/TopLevelElement.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/TopLevelElement.java Sat Nov 18 00:36:27
2006
@@ -21,6 +21,8 @@
 
 package org.apache.xalan.xsltc.compiler;
 
+import java.util.Vector;
+
 import org.apache.bcel.generic.InstructionList;
 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
@@ -31,6 +33,12 @@
 
 class TopLevelElement extends SyntaxTreeNode {
 
+    /*
+     * List of dependencies with other variables, parameters or
+     * keys defined at the top level.
+     */
+    protected Vector _dependencies = null;
+
     /**
      * Type check all the children of this node.
      */
@@ -65,4 +73,26 @@
 	Util.println("TopLevelElement");
 	displayContents(indent + IndentIncrement);
     }
+    
+    /**
+     * Add a dependency with other top-level elements like
+     * variables, parameters or keys.
+     */
+    public void addDependency(TopLevelElement other) {
+	if (_dependencies == null) {
+	    _dependencies = new Vector();
+	}
+	if (!_dependencies.contains(other)) {
+	    _dependencies.addElement(other);
+	}
+    }
+
+    /**
+     * Get the list of dependencies with other top-level elements
+     * like variables, parameteres or keys.
+     */
+    public Vector getDependencies() {
+	return _dependencies;
+    }
+
 }

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/UnresolvedRef.java Sat Nov 18 00:36:27
2006
@@ -32,15 +32,12 @@
  */
 final class UnresolvedRef extends VariableRefBase {
 
-    private QName           _variableName = null;
+    private QName _variableName = null;
     private VariableRefBase _ref = null;
-    private VariableBase    _var = null;
-    private Stylesheet      _sheet = null;
 
     public UnresolvedRef(QName name) {
 	super();
 	_variableName = name;
-	_sheet = getStylesheet();
     }
 
     public QName getName() {
@@ -58,23 +55,25 @@
 	// At this point the AST is already built and we should be able to
 	// find any declared global variable or parameter
 	VariableBase ref = parser.lookupVariable(_variableName);
-	if (ref == null) ref = (VariableBase)stable.lookupName(_variableName);
+	if (ref == null) {
+            ref = (VariableBase)stable.lookupName(_variableName);
+        }
 	if (ref == null) {
 	    reportError();
 	    return null;
 	}
 	
-	// Insert the referenced variable as something the parent variable
-	// is dependent of (this class should only be used under variables)
-	if ((_var = findParentVariable()) != null) _var.addDependency(ref);
-
-	// Instanciate a true variable/parameter ref
-	if (ref instanceof Variable)
-	    return(new VariableRef((Variable)ref));
-	else if (ref instanceof Param)
-	    return(new ParameterRef((Param)ref));
-	else
-	    return null;
+        // If in a top-level element, create dependency to the referenced var
+        _variable = ref;
+        addParentDependency();
+        
+	if (ref instanceof Variable) {
+	    return new VariableRef((Variable) ref);
+        }
+	else if (ref instanceof Param) {
+	    return new ParameterRef((Param)ref);
+        }        
+        return null;
     }
 
     public Type typeCheck(SymbolTable stable) throws TypeCheckError {

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableBase.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableBase.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableBase.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableBase.java Sat Nov 18 00:36:27
2006
@@ -66,9 +66,6 @@
     // Used to make sure parameter field is not added twice
     protected boolean    _ignore = false;
 
-    // Used to order top-level variables so that there are no forward references
-    protected int        _weight = 0;
-
     /**
      * Disable this variable/parameter
      */
@@ -90,25 +87,6 @@
      */
     public void removeReference(VariableRefBase vref) {
 	_refs.remove(vref);
-    }
-
-    /**
-     *
-     */
-    public void addDependency(VariableBase other) {
-	if (_dependencies == null) {
-	    _dependencies = new Vector();
-	}
-	if (!_dependencies.contains(other)) {
-	    _dependencies.addElement(other);
-	}
-    }
-
-    /**
-     *
-     */
-    public Vector getDependencies() {
-	return _dependencies;
     }
 
     /**

Modified: xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java
URL: http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java?view=diff&rev=476471&r1=476470&r2=476471
==============================================================================
--- xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java (original)
+++ xalan/java/trunk/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java Sat Nov 18 00:36:27
2006
@@ -33,7 +33,7 @@
     /**
      * A reference to the associated variable.
      */
-    protected final VariableBase _variable; 
+    protected VariableBase _variable; 
 
     /**
      * A reference to the enclosing expression/instruction for which a
@@ -58,14 +58,37 @@
     }
 
     /**
-     * Returns a reference to any parent variable
+     * If this variable reference is in a top-level element like 
+     * another variable, param or key, add a dependency between
+     * that top-level element and the referenced variable. For
+     * example,
+     *
+     *   <xsl:variable name="x" .../>
+     *   <xsl:variable name="y" select="$x + 1"/>
+     *
+     * and assuming this class represents "$x", add a reference 
+     * between variable y and variable x.
      */
-    public VariableBase findParentVariable() {
+    public void addParentDependency() {
 	SyntaxTreeNode node = this;
-	while (node != null && !(node instanceof VariableBase)) {
+	while (node != null && node instanceof TopLevelElement == false) {
 	    node = node.getParent();
 	}
-	return (VariableBase) node;
+        
+        TopLevelElement parent = (TopLevelElement) node;        
+        if (parent != null) {
+            VariableBase var = _variable;
+            if (_variable._ignore) {
+                if (_variable instanceof Variable) {
+                    var = parent.getSymbolTable()
+                                .lookupVariable(_variable._name);
+                } else if (_variable instanceof Param) {
+                    var = parent.getSymbolTable().lookupParam(_variable._name);
+                }
+            }
+            
+            parent.addDependency(var);
+        }        
     }
 
     /**
@@ -115,21 +138,6 @@
 	    }
 	}
 
-	// Insert a dependency link from one variable to another
-        VariableBase parent = findParentVariable();
-        if (parent != null) {
-            VariableBase var = _variable;
-            if (_variable._ignore) {
-                if (_variable instanceof Variable) {
-                    var = parent.getSymbolTable()
-                                .lookupVariable(_variable._name);
-                } else if (_variable instanceof Param) {
-                    var = parent.getSymbolTable().lookupParam(_variable._name);
-                }
-            }
-            parent.addDependency(var);
-        }
-
         // Attempt to get the cached variable type
         _type = _variable.getType();
 
@@ -140,6 +148,9 @@
             _type = _variable.getType();
         }
 
+        // If in a top-level element, create dependency to the referenced var
+        addParentDependency();
+        
         // Return the type of the referenced variable
         return _type;
     }



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


Mime
View raw message