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