You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mo...@apache.org on 2001/06/11 14:03:51 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler AttributeSet.java Choose.java Constants.java If.java LiteralElement.java Stylesheet.java UseAttributeSets.java When.java XSLTC.java XslAttribute.java

morten      01/06/11 05:03:50

  Modified:    java/src/org/apache/xalan/xsltc/compiler AttributeSet.java
                        Choose.java Constants.java If.java
                        LiteralElement.java Stylesheet.java
                        UseAttributeSets.java When.java XSLTC.java
                        XslAttribute.java
  Log:
  This putback contains three fixes:
   o) fix for complex <xsl:attribute-set> inheritance structures
   o) fix for xsl:element-available() function used in <xsl:when> or
      <xsl:if> to test support for various extension elements
   o) fix for preserving namespace prefixes for <xsl:attribute> output.
  Submitted by:	morten@xml.apache.org
  Reviewed by:	morten@xml.apache.org
  
  Revision  Changes    Path
  1.4       +109 -25   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java
  
  Index: AttributeSet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/AttributeSet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AttributeSet.java	2001/06/06 10:44:38	1.3
  +++ AttributeSet.java	2001/06/11 12:03:28	1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: AttributeSet.java,v 1.3 2001/06/06 10:44:38 morten Exp $
  + * @(#)$Id: AttributeSet.java,v 1.4 2001/06/11 12:03:28 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -76,57 +77,140 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class AttributeSet extends TopLevelElement {
  +
  +    // Error messages
  +    private static final String NO_NAME_ERROR =
  +	"Attribute set missing 'name' attribute.";
  +    private static final String BASTARD_ERROR =
  +	"Attribute sets can only have <xsl:attribute> child elements.";
  +
  +    // This prefix is used for the method name of attribute set methods
       private static final String AttributeSetPrefix = "%as";
       
  +    // Element contents
       private QName            _name;
       private UseAttributeSets _useSets;
  -    private String           _methodName;
  +    private String           _method;
  +    private boolean          _ignore = false;
       
  +    /**
  +     * Returns the QName of this attribute set
  +     */
  +    public QName getName() {
  +	return _name;
  +    }
  +
  +    /**
  +     * Returns the method name of this attribute set. This method name is
  +     * generated by the compiler (XSLTC)
  +     */
  +    public String getMethodName() {
  +	return _method;
  +    }
  +
  +    /**
  +     * Call this method to prevent a method for being compiled for this set.
  +     * This is used in case several <xsl:attribute-set...> elements constitute
  +     * a single set (with one name). The last element will merge itself with
  +     * any previous set(s) with the same name and disable the other set(s).
  +     */
  +    public void ignore() {
  +	_ignore = true;
  +    }
  +
  +    /**
  +     * Parse the contents of this attribute set. Recognised attributes are
  +     * "name" (required) and "use-attribute-sets" (optional).
  +     */
       public void parseContents(Parser parser) {
  +	
  +	// Get this attribute set's name
   	_name = parser.getQName(getAttribute("name"));
  +	if ((_name == null) || (_name.equals(Constants.EMPTYSTRING))) {
  +	    final ErrorMsg msg = new ErrorMsg(NO_NAME_ERROR, getLineNumber());
  +	    parser.reportError(Constants.ERROR, msg);
  +	}
  +
  +	// Get any included attribute sets (similar to inheritance...)
   	final String useSets = getAttribute("use-attribute-sets");
   	if (useSets.length() > 0) {
   	    _useSets = new UseAttributeSets(useSets, parser);
   	}
  -	//!!! add check whether children are XslAttributes
  -	parseChildren(parser);
  -    }
  -    
  -    public QName getName() {
  -	return _name;
  -    }
   
  -    public String getMethodName() {
  -	return _methodName;
  +	// Parse the contents of this node. All child elements must be
  +	// <xsl:attribute> elements. Other elements cause an error.
  +	final Vector contents = getContents();
  +	final int count = contents.size();
  +	for (int i=0; i<count; i++) {
  +	    SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
  +	    if (child instanceof XslAttribute) {
  +		parser.getSymbolTable().setCurrentNode(child);
  +		child.parseContents(parser);
  +	    }
  +	    else {
  +		final ErrorMsg msg =
  +		    new ErrorMsg(BASTARD_ERROR, getLineNumber());
  +		parser.reportError(Constants.ERROR, msg);
  +	    }
  +	}
  +
  +	// Point the symbol table back at us...
  +	parser.getSymbolTable().setCurrentNode(this);
       }
   
  +    /**
  +     * Type check the contents of this element
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
   
  -	final AttributeSet extant = stable.addAttributeSet(this);
  -	if (extant != null) {
  -	    merge(extant);
  +	if (_ignore) return (Type.Void);
  +
  +	final AttributeSet other = stable.addAttributeSet(this);
  +	if (other != null) {
  +	    _method = other.getMethodName();
  +	    merge(other);
  +	    other.ignore();
   	}
  -	
  -	_methodName = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
  -	
  -	if (_useSets != null) {
  -	    _useSets.typeCheck(stable);
  +	else {
  +	    _method = AttributeSetPrefix + getXSLTC().nextAttributeSetSerial();
   	}
  +
  +	if (_useSets != null) _useSets.typeCheck(stable);
   	typeCheckContents(stable);
   	return Type.Void;
       }
   
  -    private void merge(AttributeSet ext) {
  -	final Enumeration attributes = ext.elements();
  +    /**
  +     * Merge this attribute set with some other one
  +     */
  +    private void merge(AttributeSet other) {
  +	// Both attribute sets may inherit from other sets...
  +	if (_useSets == null)
  +	    _useSets = other._useSets;
  +	else
  +	    _useSets.addAttributeSets(other.getAttribute("use-attribute-sets"));
  +
  +	// Merge the contents of the two attribute sets...
  +	final Enumeration attributes = other.elements();
   	while (attributes.hasMoreElements())
   	    addElement((XslAttribute)attributes.nextElement());
       }
   
  +    /**
  +     * Compile a method that outputs the attributes in this set
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  -	methodGen = new AttributeSetMethodGenerator(_methodName, classGen);
  -	if (_useSets != null) {
  -	    _useSets.translate(classGen, methodGen);
  -	}
  +
  +	if (_ignore) return;
  +
  +	// Create a new method generator for an attribute set method
  +	methodGen = new AttributeSetMethodGenerator(_method, classGen);
  +
  +	// Translate other used attribute sets first, as local attributes
  +	// take precedence (last attributes overrides first)
  +	if (_useSets != null) _useSets.translate(classGen, methodGen);
  +
  +	// Translate all local attributes
   	final Enumeration attributes = elements();
   	while (attributes.hasMoreElements()) {
   	    final XslAttribute attribute =
  
  
  
  1.2       +96 -49    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Choose.java
  
  Index: Choose.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Choose.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Choose.java	2001/04/17 18:51:22	1.1
  +++ Choose.java	2001/06/11 12:03:29	1.2
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Choose.java,v 1.1 2001/04/17 18:51:22 sboag Exp $
  + * @(#)$Id: Choose.java,v 1.2 2001/06/11 12:03:29 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -72,6 +72,17 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class Choose extends Instruction {
  +
  +    private final static String MISSING_WHEN_ERROR =
  +	"At least one When element required in Choose";
  +    private final static String ILLEGAL_ELEMENT_ERROR =
  +	"Only When|Otherwise elements allowed in Choose";
  +    private final static String MULTIPLE_OTHERWISE_ERROR =
  +	"Only one Otherwise element allowed in Choose";
  +
  +    /**
  +     * Display the element contents (a lot of when's and an otherwise)
  +     */
       public void display(int indent) {
   	indent(indent);
   	Util.println("Choose");
  @@ -79,66 +90,102 @@
   	displayContents(indent + IndentIncrement);
       }
   	
  +    /**
  +     * Translate this Choose element. Generate a test-chain for the various
  +     * <xsl:when> elements and default to the <xsl:otherwise> if present.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   	final Vector whenElements = new Vector();
   	Otherwise otherwise = null;
   	Enumeration elements = elements();
  +
  +	// These two are for reporting errors only
  +	ErrorMsg error = null;
  +	final int line = getLineNumber();
  +
  +	// Traverse all child nodes - must be either When or Otherwise
   	while (elements.hasMoreElements()) {
   	    Object element = elements.nextElement();
  -	    if (element instanceof When)
  +	    // Add a When child element
  +	    if (element instanceof When) {
   		whenElements.addElement(element);
  -	    else if (element instanceof Otherwise)
  -		if (otherwise == null)
  +	    }
  +	    // Add an Otherwise child element
  +	    else if (element instanceof Otherwise) {
  +		if (otherwise == null) {
   		    otherwise = (Otherwise)element;
  -		else
  -		    System.err.println("Only one Otherwise element allowed in Choose");
  -	    else
  -		System.err.println("Only When|Otherwise elements allowed in Choose");
  -	}
  -	if (whenElements.size() > 0) {
  -	    InstructionList il = methodGen.getInstructionList();
  -	    // next element will hold a handle to the beginning of next
  -	    // When/Otherwise if test on current When fails
  -	    BranchHandle nextElement = null;
  -	    Vector exitHandles = new Vector();
  -	    InstructionHandle exit = null;
  -	    Enumeration whens = whenElements.elements();
  -	    while (whens.hasMoreElements()) {
  -		final When when = (When)whens.nextElement();
  -		final Expression test = when.getTest();
  -		if (nextElement != null)
  -		    nextElement.setTarget(il.append(NOP));
  -		test.translateDesynthesized(classGen, methodGen);
  -		if ((test instanceof FunctionCall) &&
  -		    !(test instanceof ElementAvailableCall) &&
  -		    !(test instanceof ContainsCall))
  -		    test._falseList.add(il.append(new IFEQ(null)));
  -		// remember end of condition
  -		InstructionHandle truec = il.getEnd();
  -		when.translateContents(classGen, methodGen);
  -		// goto exit after executing the body of when
  -		exitHandles.addElement(il.append(new GOTO(null)));
  -		if (whens.hasMoreElements() || otherwise != null) {
  -		    nextElement = il.append(new GOTO(null));
  -		    test.backPatchFalseList(nextElement);
   		}
  -		else
  -		    test.backPatchFalseList(exit = il.append(NOP));
  -		test.backPatchTrueList(truec.getNext());
  +		else {
  +		    error = new ErrorMsg(MULTIPLE_OTHERWISE_ERROR, line);
  +		    getParser().reportError(Constants.ERROR, error);
  +		}
   	    }
  -	    if (otherwise != null) {
  -		nextElement.setTarget(il.append(NOP));
  -		otherwise.translateContents(classGen, methodGen);
  -		exit = il.append(NOP);
  +	    // It is an error if we find some other element here
  +	    else {
  +		error = new ErrorMsg(ILLEGAL_ELEMENT_ERROR, line);
  +		getParser().reportError(Constants.ERROR, error);
   	    }
  -	    // now that end is known set targets of exit gotos
  -	    Enumeration exitGotos = exitHandles.elements();
  -	    while (exitGotos.hasMoreElements()) {
  -		BranchHandle gotoExit = (BranchHandle)exitGotos.nextElement();
  -		gotoExit.setTarget(exit);
  +	}
  +
  +	// Make sure that there is at least one <xsl:when> element
  +	if (whenElements.size() == 0) {
  +	    error = new ErrorMsg(MISSING_WHEN_ERROR, getLineNumber());
  +	    getParser().reportError(Constants.ERROR, error);
  +	    return;
  +	}
  +
  +	InstructionList il = methodGen.getInstructionList();
  +
  +	// next element will hold a handle to the beginning of next
  +	// When/Otherwise if test on current When fails
  +	BranchHandle nextElement = null;
  +	Vector exitHandles = new Vector();
  +	InstructionHandle exit = null;
  +
  +	Enumeration whens = whenElements.elements();
  +	while (whens.hasMoreElements()) {
  +	    final When when = (When)whens.nextElement();
  +	    final Expression test = when.getTest();
  +
  +	    InstructionHandle truec = il.getEnd();
  +
  +	    if (nextElement != null)
  +		nextElement.setTarget(il.append(NOP));
  +	    test.translateDesynthesized(classGen, methodGen);
  +	    if ((test instanceof FunctionCall) &&
  +		!(test instanceof ElementAvailableCall) &&
  +		!(test instanceof ContainsCall))
  +		test._falseList.add(il.append(new IFEQ(null)));
  +	    // remember end of condition
  +	    truec = il.getEnd();
  +
  +	    // The When object should be ignored completely in case it tests
  +	    // for the support of a non-available element
  +	    if (!when.ignore()) when.translateContents(classGen, methodGen);
  +
  +	    // goto exit after executing the body of when
  +	    exitHandles.addElement(il.append(new GOTO(null)));
  +	    if (whens.hasMoreElements() || otherwise != null) {
  +		nextElement = il.append(new GOTO(null));
  +		test.backPatchFalseList(nextElement);
   	    }
  +	    else
  +		test.backPatchFalseList(exit = il.append(NOP));
  +	    test.backPatchTrueList(truec.getNext());
  +	}
  +	
  +	// Translate any <xsl:otherwise> element
  +	if (otherwise != null) {
  +	    nextElement.setTarget(il.append(NOP));
  +	    otherwise.translateContents(classGen, methodGen);
  +	    exit = il.append(NOP);
  +	}
  +
  +	// now that end is known set targets of exit gotos
  +	Enumeration exitGotos = exitHandles.elements();
  +	while (exitGotos.hasMoreElements()) {
  +	    BranchHandle gotoExit = (BranchHandle)exitGotos.nextElement();
  +	    gotoExit.setTarget(exit);
   	}
  -	else
  -	    System.err.println("At least one When element required in Choose");
       }
   }
  
  
  
  1.6       +5 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Constants.java	2001/06/08 12:57:52	1.5
  +++ Constants.java	2001/06/11 12:03:30	1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Constants.java,v 1.5 2001/06/08 12:57:52 morten Exp $
  + * @(#)$Id: Constants.java,v 1.6 2001/06/11 12:03:30 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -333,6 +333,9 @@
       public static final String RESET     	    
   	= "reset";
   
  +    public static final String ATTR_SET_SIG
  +	= "(" + TRANSLET_OUTPUT_SIG + ")V";
  +
       public static final String GET_NODE_NAME_SIG   
   	= "(" + NODE_SIG + ")" + STRING_SIG;
       public static final String CHARACTERSW_SIG     
  @@ -453,7 +456,7 @@
       public static final String XSLT_URI 
   	= "http://www.w3.org/1999/XSL/Transform";
       public static final String TRANSLET_URI 
  -	= "http://www.apache.org/xalan/xsltc";
  +	= "http://xml.apache.org/xalan/xsltc";
       public static final String FALLBACK_CLASS
   	= "org.apache.xalan.xsltc.compiler.Fallback";
   }
  
  
  
  1.4       +39 -6     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java
  
  Index: If.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/If.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- If.java	2001/06/06 10:45:01	1.3
  +++ If.java	2001/06/11 12:03:32	1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: If.java,v 1.3 2001/06/06 10:45:01 morten Exp $
  + * @(#)$Id: If.java,v 1.4 2001/06/11 12:03:32 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -72,8 +73,13 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class If extends Instruction {
  +
       private Expression _test;
  +    private boolean    _ignore = false;
   
  +    /**
  +     * Display the contents of this element
  +     */
       public void display(int indent) {
   	indent(indent);
   	Util.println("If");
  @@ -82,32 +88,59 @@
   	Util.println(_test.toString());
   	displayContents(indent + IndentIncrement);
       }
  -		
  +
  +    /**
  +     * Parse the "test" expression and contents of this element.
  +     */
       public void parseContents(Parser parser) {
  +	// Parse the "test" expression
   	_test = parser.parseExpression(this, "test", null);
  -	parseChildren(parser);
   
  -        // make sure required attribute(s) have been set
  +        // Make sure required attribute(s) have been set
           if (_test.isDummy()) {
   	    reportError(this, parser, ErrorMsg.NREQATTR_ERR, "test");
   	    return;
           }
  +
  +	// We will ignore the contents of this <xsl:if> if we know that the
  +	// test will always return 'false'.
  +	if (_test instanceof ElementAvailableCall) {
  +	    ElementAvailableCall call = (ElementAvailableCall)_test;
  +	    _ignore = !call.getResult();
  +	    return;
  +	}
  +
  +	parseChildren(parser);
       }
   
  +    /**
  +     * Type-check the "test" expression and contents of this element.
  +     * The contents will be ignored if we know the test will always fail.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  +	// Type-check the "test" expression
   	if (_test.typeCheck(stable) instanceof BooleanType == false) {
   	    _test = new CastExpr(_test, Type.Boolean);
   	}
  -	typeCheckContents(stable);
  +	// Type check the element contents
  +	if (!_ignore) {
  +	    typeCheckContents(stable);
  +	}
   	return Type.Void;
       }
   
  +    /**
  +     * Translate the "test" expression and contents of this element.
  +     * The contents will be ignored if we know the test will always fail.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   	final InstructionList il = methodGen.getInstructionList();
   	_test.translateDesynthesized(classGen, methodGen);
   	// remember end of condition
   	final InstructionHandle truec = il.getEnd();
  -	translateContents(classGen, methodGen);
  +	if (!_ignore) {
  +	    translateContents(classGen, methodGen);
  +	}
   	_test.backPatchFalseList(il.append(NOP));
   	_test.backPatchTrueList(truec.getNext());
       }
  
  
  
  1.7       +14 -8     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java
  
  Index: LiteralElement.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/LiteralElement.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- LiteralElement.java	2001/06/08 15:28:13	1.6
  +++ LiteralElement.java	2001/06/11 12:03:33	1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: LiteralElement.java,v 1.6 2001/06/08 15:28:13 morten Exp $
  + * @(#)$Id: LiteralElement.java,v 1.7 2001/06/11 12:03:33 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -188,9 +188,9 @@
       }
   
       /**
  -     *
  +     * Add an attribute to this element
        */
  -    private void addAttribute(SyntaxTreeNode attribute) {
  +    public void addAttribute(SyntaxTreeNode attribute) {
   	if (_attributeElements == null) {
   	    _attributeElements = new Vector(2);
   	}
  @@ -198,9 +198,9 @@
       }
   
       /**
  -     *
  +     * Set the first attribute of this element
        */
  -    public void addLocalAttribute(SyntaxTreeNode attribute) {
  +    public void setFirstAttribute(SyntaxTreeNode attribute) {
   	if (_attributeElements == null) {
   	    _attributeElements = new Vector(2);
   	}
  @@ -208,6 +208,10 @@
       }
   
   
  +    /**
  +     * Type-check the contents of this element. The element itself does not
  +     * need any type checking as it leaves nothign on the JVM's stack.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
   	// Type-check all attributes
   	if (_attributeElements != null) {
  @@ -271,11 +275,13 @@
   	    final QName qname = parser.getQName(_attributes.getQName(i));
   	    final String val = _attributes.getValue(i);
   
  -	    // Handle xsl:use-attribute-sets
  +	    // Handle xsl:use-attribute-sets. Attribute sets are placed first
  +	    // in the vector or attributes to make sure that later local
  +	    // attributes can override an attributes in the set.
   	    if (qname == parser.getUseAttributeSets()) {
  -		addAttribute(new UseAttributeSets(val, parser));
  +		setFirstAttribute(new UseAttributeSets(val, parser));
   	    }
  -	    // Ignore other attributes in XSL namespace
  +	    // Ignore all other attributes in XSL namespace
   	    else if (qname.getNamespace().equals(XSLT_URI)) {
   
   	    }
  
  
  
  1.8       +5 -4      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Stylesheet.java	2001/06/07 15:16:00	1.7
  +++ Stylesheet.java	2001/06/11 12:03:34	1.8
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Stylesheet.java,v 1.7 2001/06/07 15:16:00 morten Exp $
  + * @(#)$Id: Stylesheet.java,v 1.8 2001/06/11 12:03:34 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -418,10 +418,9 @@
   	    Object element = elements.nextElement();
   	    // xsl:template
   	    if (element instanceof Template) {
  -		_templates.addElement(element);
  -		
   		// Separate templates by modes
   		final Template template = (Template)element;
  +		_templates.addElement(template);
   		getMode(template.getModeName()).addTemplate(template);
   	    }
   	    // xsl:attribute-set
  @@ -444,7 +443,9 @@
   
   	compileConstructor(classGen, lastOutputElement);
   
  -	getXSLTC().dumpClass(classGen.getJavaClass());
  +	if (!getParser().errorsFound()) {
  +	    getXSLTC().dumpClass(classGen.getJavaClass());
  +	}
       }
   	
       private void compileConstructor(ClassGenerator classGen, Output output) {
  
  
  
  1.3       +60 -21    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java
  
  Index: UseAttributeSets.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/UseAttributeSets.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- UseAttributeSets.java	2001/05/02 10:25:12	1.2
  +++ UseAttributeSets.java	2001/06/11 12:03:35	1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: UseAttributeSets.java,v 1.2 2001/05/02 10:25:12 morten Exp $
  + * @(#)$Id: UseAttributeSets.java,v 1.3 2001/06/11 12:03:35 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,12 +58,14 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
   package org.apache.xalan.xsltc.compiler;
   
  -import java.util.Vector;
  +import java.util.HashSet;
  +import java.util.Iterator;
   import java.util.Enumeration;
   import java.util.StringTokenizer;
   
  @@ -72,38 +74,75 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class UseAttributeSets extends Instruction {
  -    private final Vector _qNames = new Vector(2); // QNames
  -    
  -    public UseAttributeSets(String useSets, Parser parser) {
  +
  +    // Only error that can occur:
  +    private final static String ATTR_SET_NOT_FOUND =
  +	"Attempting to use non-existing attribute set: ";
  +
  +    // Contains the names of all references attribute sets
  +    private final HashSet _sets = new HashSet(3);
  +
  +    /**
  +     * Constructur - define initial attribute sets to use
  +     */
  +    public UseAttributeSets(String setNames, Parser parser) {
   	setParser(parser);
  -	final StringTokenizer tokens = new StringTokenizer(useSets);
  -	while (tokens.hasMoreTokens()) {
  -	    _qNames.addElement(parser.getQName(tokens.nextToken()));
  +	addAttributeSets(setNames);
  +    }
  +
  +    /**
  +     * This method is made public to enable an AttributeSet object to merge
  +     * itself with another AttributeSet (including any other AttributeSets
  +     * the two may inherit from).
  +     */
  +    public void addAttributeSets(String setNames) {
  +	if ((setNames != null) && (!setNames.equals(Constants.EMPTYSTRING))) {
  +	    final StringTokenizer tokens = new StringTokenizer(setNames);
  +	    while (tokens.hasMoreTokens()) {
  +		final QName qname = getParser().getQName(tokens.nextToken());
  +		_sets.add(qname);
  +	    }
   	}
       }
  -    
  +
  +    /**
  +     * Do nada.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  -	//!!! check if sets defined
   	return Type.Void;
       }
  -    
  +
  +    /**
  +     * Generate a call to the method compiled for this attribute set
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  +
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
   	final SymbolTable symbolTable = getParser().getSymbolTable();
  -	final Enumeration calls = _qNames.elements();
  -	while (calls.hasMoreElements()) {
  -	    final QName name = (QName)calls.nextElement();
  -	    final AttributeSet atts = symbolTable.lookupAttributeSet(name);
  -	    if (atts != null) {
  -		final String methodName = atts.getMethodName();
  +
  +	// Get the QNames of the attribut sets we want to use
  +	final Iterator sets = _sets.iterator();
  +	// Go through each attribute set and generate a method call
  +	while (sets.hasNext()) {
  +	    // Get the attribute set name
  +	    final QName name = (QName)sets.next();
  +	    // Get the AttributeSet reference from the symbol table
  +	    final AttributeSet attrs = symbolTable.lookupAttributeSet(name);
  +	    // Compile the call to the set's method if the set exists
  +	    if (attrs != null) {
  +		final String methodName = attrs.getMethodName();
   		il.append(classGen.loadTranslet());
   		il.append(methodGen.loadHandler());
  -		final int method =
  -		    cpg.addMethodref(classGen.getClassName(),
  -				     methodName,
  -				     "(" + TRANSLET_OUTPUT_SIG + ")V");
  +		final int method = cpg.addMethodref(classGen.getClassName(),
  +						    methodName, ATTR_SET_SIG);
   		il.append(new INVOKESPECIAL(method));
  +	    }
  +	    // Generate an error if the attribute set does not exist
  +	    else {
  +		final ErrorMsg msg =  new ErrorMsg(ATTR_SET_NOT_FOUND+name,
  +						   getLineNumber());
  +		getParser().reportError(Constants.ERROR, msg);
   	    }
   	}
       }
  
  
  
  1.5       +35 -15    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java
  
  Index: When.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/When.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- When.java	2001/06/07 15:16:06	1.4
  +++ When.java	2001/06/11 12:03:35	1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: When.java,v 1.4 2001/06/07 15:16:06 morten Exp $
  + * @(#)$Id: When.java,v 1.5 2001/06/11 12:03:35 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -58,6 +58,7 @@
    *
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
  + * @author Morten Jorgensen
    *
    */
   
  @@ -66,8 +67,13 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   final class When extends Instruction {
  -    private Expression _test;
  +
  +    private static final String NO_CHOOSE_ERROR =
  +	"Instruction 'when' must be used within a 'choose'.";
   	
  +    private Expression _test;
  +    private boolean _ignore = false;
  +
       public void display(int indent) {
   	indent(indent);
   	Util.println("When");
  @@ -81,37 +87,51 @@
   	return _test;
       }
   
  +    public boolean ignore() {
  +	return(_ignore);
  +    }
  +
       public void parseContents(Parser parser) {
  -	boolean ignore = false;
   	_test = parser.parseExpression(this, "test", null);
   	if (_test instanceof ElementAvailableCall) {
   	    ElementAvailableCall call = (ElementAvailableCall)_test;
  -	    ignore = !call.getResult();
  +	    _ignore = !call.getResult();
  +	    return;
   	}
   
  -	if (!ignore) {
  -	    parseChildren(parser);
  -	}
  +	parseChildren(parser);
   
  -	// make sure required attribute(s) have been set
  +	// Make sure required attribute(s) have been set
   	if (_test.isDummy()) {
   	    reportError(this, parser, ErrorMsg.NREQATTR_ERR, "test");
  -	    return;
   	}
       }
  -	
  +
  +    /**
  +     * Type-check this when element. The test should always be type checked,
  +     * while we do not bother with the contents if we know the test fails.
  +     * This is important in cases where the "test" expression tests for
  +     * the support of a non-available element, and the <xsl:when> body contains
  +     * this non-available element.
  +     */
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  +	// Type-check the test expression
   	if (_test.typeCheck(stable) instanceof BooleanType == false) {
   	    _test = new CastExpr(_test, Type.Boolean);
   	}
  -	typeCheckContents(stable);
  +	// Type-check the contents (if necessary)
  +	if (!_ignore) {
  +	    typeCheckContents(stable);
  +	}
   	return Type.Void;
       }
  -	
  +
  +    /**
  +     * This method should never be called. An Otherwise object will explicitly
  +     * translate the "test" expression and and contents of this element.
  +     */
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  -	final ErrorMsg msg =
  -	    new ErrorMsg("Instruction 'when' must be used within a 'choose'.", 
  -			 getLineNumber());
  +	final ErrorMsg msg = new ErrorMsg(NO_CHOOSE_ERROR, getLineNumber());
   	getParser().reportError(Constants.ERROR, msg);
       }
   }
  
  
  
  1.7       +27 -20    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java
  
  Index: XSLTC.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XSLTC.java	2001/06/07 15:16:07	1.6
  +++ XSLTC.java	2001/06/11 12:03:36	1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: XSLTC.java,v 1.6 2001/06/07 15:16:07 morten Exp $
  + * @(#)$Id: XSLTC.java,v 1.7 2001/06/11 12:03:36 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -197,33 +197,40 @@
   	    
   	    // Get the root node of the abstract syntax tree
   	    final SyntaxTreeNode element = _parser.parse(url);
  -	    // Process any error and/or warning messages
  +
  +	    // Process any error and/or warning messages found so far...
   	    _parser.printWarnings();
  -	    if (_parser.errorsFound()) {
  +	    if ((_parser.errorsFound()) || (element == null)) {
   		_parser.printErrors();
   		return false;
   	    }
   
  -	    if ((!_parser.errorsFound()) && (element != null)) {
  -		_stylesheet = _parser.makeStylesheet(element);
  -		_stylesheet.setURL(url);
  -		// This is the top level stylesheet - it has no parent
  -		_stylesheet.setParentStylesheet(null);
  -		_parser.setCurrentStylesheet(_stylesheet);
  -		_parser.createAST(_stylesheet);
  -		if (_stylesheet != null && _parser.errorsFound() == false) {
  -		    _stylesheet.setMultiDocument(_multiDocument);
  -		    _stylesheet.translate();
  -		}
  -		else {
  -		    _parser.printErrors();
  -		}		
  -	    }
  -	    else {
  +	    // Create the abstract syntax tree and parse each node in it
  +	    _stylesheet = _parser.makeStylesheet(element);
  +	    _stylesheet.setURL(url);
  +	    _stylesheet.setParentStylesheet(null);
  +	    _parser.setCurrentStylesheet(_stylesheet);
  +	    _parser.createAST(_stylesheet);
  +
  +	    // Process any error and/or warning messages found so far...
  +	    _parser.printWarnings();
  +	    if ((_parser.errorsFound()) || (_stylesheet == null)) {
   		_parser.printErrors();
  +		return false;
   	    }
  +
  +	    // Compile the translet
  +	    _stylesheet.setMultiDocument(_multiDocument);
  +	    _stylesheet.translate();
  +
  +	    // Process any error and/or warning messages found so far...
   	    _parser.printWarnings();
  -	    return !_parser.errorsFound();
  +	    if ((_parser.errorsFound()) || (_stylesheet == null)) {
  +		_parser.printErrors();
  +		return false;
  +	    }
  +
  +	    return true;
   	}
   	catch (CompilerException e) {
   	    e.printStackTrace();
  
  
  
  1.6       +3 -3      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java
  
  Index: XslAttribute.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XslAttribute.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XslAttribute.java	2001/06/08 15:28:14	1.5
  +++ XslAttribute.java	2001/06/11 12:03:38	1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: XslAttribute.java,v 1.5 2001/06/08 15:28:14 morten Exp $
  + * @(#)$Id: XslAttribute.java,v 1.6 2001/06/11 12:03:38 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -126,7 +126,7 @@
   	// Get namespace from namespace attribute?
   	if ((namespace != null) && (namespace != Constants.EMPTYSTRING)) {
   	    // Prefix could be in symbol table
  -	    //_prefix = stable.lookupPrefix(namespace);
  +	    _prefix = lookupPrefix(namespace);
   	    _namespace = new AttributeValueTemplate(namespace, parser);
   	}
   	// Get namespace from prefix in name attribute?
  @@ -169,7 +169,7 @@
   	}
   
   	if (parent instanceof LiteralElement) {
  -	    ((LiteralElement)parent).addLocalAttribute(this);
  +	    ((LiteralElement)parent).addAttribute(this);
   	}
   
   	_name = AttributeValue.create(this, name, parser);
  
  
  

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