You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by sa...@apache.org on 2003/10/07 17:44:22 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler CastCall.java Parser.java xpath.cup
santiagopg 2003/10/07 08:44:22
Modified: java/src/org/apache/xalan/xsltc/compiler Parser.java
xpath.cup
Added: java/src/org/apache/xalan/xsltc/compiler CastCall.java
Log:
Adding a new extension function for XSLTC. Using this extension function, it is
possible to recover type information lost by the use of xsl:param (see Bugzilla
19038). Here is an example:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:java="http://xml.apache.org/xalan/java"
xmlns:xsltc="http://xml.apache.org/xalan/xsltc">
<xsl:param name="object"/>
<xsl:template match="/">
<xsl:value-of select="java:length(xsltc:cast('java.lang.String', $object))"/>
</xsl:template>
</xsl:stylesheet>
Without using xsltc:cast(), XSLTC will report an error as the type of param
'object' cannot be determined statically. The type of xsltc:cast() is:
object[T] cast('T', reference | object[R])
where 'T' indicates that the type of the first argument must be a literal
string. A ClassCastException may be thrown at runtime if R is not convertible
to T.
I believe we still need a fully-dynamic solution that does not rely on this
extension function. However, the two solutions can coexists, especially since
using xsltc:cast() will always be more efficient than any alternative based
on Java reflection.
Revision Changes Path
1.60 +3 -1 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java
Index: Parser.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Parser.java,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -r1.59 -r1.60
--- Parser.java 14 Aug 2003 16:27:43 -0000 1.59
+++ Parser.java 7 Oct 2003 15:44:22 -0000 1.60
@@ -782,6 +782,7 @@
MethodType S_SS = new MethodType(Type.String, Type.String, Type.String);
MethodType S_DS = new MethodType(Type.String, Type.Real, Type.String);
MethodType S_SR = new MethodType(Type.String, Type.String, Type.Real);
+ MethodType O_SO = new MethodType(Type.Reference, Type.String, Type.Reference);
MethodType D_SS =
new MethodType(Type.NodeSet, Type.String, Type.String);
@@ -862,6 +863,7 @@
// Extensions
_symbolTable.addPrimop("nodeset", D_O);
_symbolTable.addPrimop("objectType", S_O);
+ _symbolTable.addPrimop("cast", O_SO);
// Operators +, -, *, /, % defined on real types.
_symbolTable.addPrimop("+", R_RR);
1.48 +8 -1 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup
Index: xpath.cup
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/xpath.cup,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- xpath.cup 1 Apr 2003 21:09:00 -0000 1.47
+++ xpath.cup 7 Oct 2003 15:44:22 -0000 1.48
@@ -122,6 +122,10 @@
return _parser.getQNameIgnoreDefaultNs(name);
}
+ public QName getQName(String namespace, String prefix, String localname) {
+ return _parser.getQName(namespace, prefix, localname);
+ }
+
public void setMultiDocument(boolean flag) {
_xsltc.setMultiDocument(flag);
}
@@ -1021,6 +1025,9 @@
}
else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
RESULT = new NamespaceUriCall(fname, argl);
+ }
+ else if (fname == parser.getQName(Constants.TRANSLET_URI, "xsltc", "cast")) {
+ RESULT = new CastCall(fname, argl);
}
// Special case for extension function nodeset()
else if (fname.getLocalPart().equals("nodeset") || fname.getLocalPart().equals("node-set")) {
1.1 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastCall.java
Index: CastCall.java
===================================================================
/*
* @(#)$Id: CastCall.java,v 1.1 2003/10/07 15:44:22 santiagopg Exp $
*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Sun
* Microsystems., http://www.sun.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* @author Santiago Pericas-Geertsen
*
*/
package org.apache.xalan.xsltc.compiler;
import java.util.Vector;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.CHECKCAST;
import org.apache.bcel.generic.InstructionList;
import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
import org.apache.xalan.xsltc.compiler.util.Type;
import org.apache.xalan.xsltc.compiler.util.ObjectType;
import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
final class CastCall extends FunctionCall {
/**
* Name of the class that is the target of the cast. Must be a
* fully-qualified Java class Name.
*/
private String _className;
/**
* A reference to the expression being casted.
*/
private Expression _right;
/**
* Constructor.
*/
public CastCall(QName fname, Vector arguments) {
super(fname, arguments);
}
/**
* Type check the two parameters for this function
*/
public Type typeCheck(SymbolTable stable) throws TypeCheckError {
// Check that the function was passed exactly two arguments
if (argumentCount() != 2) {
throw new TypeCheckError(new ErrorMsg(ErrorMsg.ILLEGAL_ARG_ERR,
getName(), this));
}
// The first argument must be a literal String
Expression exp = argument(0);
if (exp instanceof LiteralExpr) {
_className = ((LiteralExpr) exp).getValue();
_type = new ObjectType(_className);
}
else {
throw new TypeCheckError(new ErrorMsg(ErrorMsg.NEED_LITERAL_ERR,
getName(), this));
}
// Second argument must be of type reference or object
_right = argument(1);
Type tright = _right.typeCheck(stable);
if (tright != Type.Reference &&
tright instanceof ObjectType == false)
{
throw new TypeCheckError(new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
tright, _type, this));
}
return _type;
}
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
_right.translate(classGen, methodGen);
il.append(new CHECKCAST(cpg.addClass(_className)));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org