You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by tm...@apache.org on 2002/07/31 00:07:53 UTC
cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util MultiHashtable.java
tmiller 2002/07/30 15:07:52
Modified: java/src/org/apache/xalan/xsltc/compiler CastExpr.java
FunctionCall.java
java/src/org/apache/xalan/xsltc/compiler/util
MultiHashtable.java
Log:
improved selection algorithm for overloaded methods and constructors in ext java funct calls
Revision Changes Path
1.14 +2 -2 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastExpr.java
Index: CastExpr.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CastExpr.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- CastExpr.java 25 Jul 2002 11:44:19 -0000 1.13
+++ CastExpr.java 30 Jul 2002 22:07:52 -0000 1.14
@@ -202,7 +202,7 @@
else if (tleft instanceof ResultTreeType) {
tleft = Type.ResultTree; // multiple instances
}
- if (InternalTypeMap.maps(tleft, _type)) {
+ if (InternalTypeMap.maps(tleft, _type) != null) {
return _type;
}
throw new TypeCheckError(this);
1.22 +95 -44 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionCall.java
Index: FunctionCall.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/FunctionCall.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- FunctionCall.java 30 Jul 2002 18:30:28 -0000 1.21
+++ FunctionCall.java 30 Jul 2002 22:07:52 -0000 1.22
@@ -133,12 +133,31 @@
private static final Hashtable _java2Internal = new Hashtable();
/**
+ * inner class to used in internal2Java mappings, contains
+ * the Java type and the distance between the internal type and
+ * the Java type.
+ */
+ static class JavaType {
+ public Class type;
+ public int distance;
+
+ public JavaType(Class type, int distance){
+ this.type = type;
+ this.distance = distance;
+ }
+ public boolean equals(Object query){
+ return query.equals(type);
+ }
+ }
+
+ /**
* Defines 2 conversion tables:
* 1. From internal types to Java types and
* 2. From Java types to internal types.
* These two tables are used when calling external (Java) functions.
*/
static {
+
try {
final Class objectClass = Class.forName("java.lang.Object");
final Class stringClass = Class.forName("java.lang.String");
@@ -146,43 +165,43 @@
final Class nodeListClass = Class.forName("org.w3c.dom.NodeList");
// Possible conversions between internal and Java types
- _internal2Java.put(Type.Boolean, Boolean.TYPE);
+ _internal2Java.put(Type.Boolean, new JavaType(Boolean.TYPE,0));
- _internal2Java.put(Type.Int, Character.TYPE);
- _internal2Java.put(Type.Int, Byte.TYPE);
- _internal2Java.put(Type.Int, Short.TYPE);
- _internal2Java.put(Type.Int, Integer.TYPE);
- _internal2Java.put(Type.Int, Long.TYPE);
- _internal2Java.put(Type.Int, Float.TYPE);
- _internal2Java.put(Type.Int, Double.TYPE);
-
- _internal2Java.put(Type.Real, Character.TYPE);
- _internal2Java.put(Type.Real, Byte.TYPE);
- _internal2Java.put(Type.Real, Short.TYPE);
- _internal2Java.put(Type.Real, Integer.TYPE);
- _internal2Java.put(Type.Real, Long.TYPE);
- _internal2Java.put(Type.Real, Float.TYPE);
- _internal2Java.put(Type.Real, Double.TYPE);
-
- _internal2Java.put(Type.String, stringClass);
-
- _internal2Java.put(Type.Node, nodeClass);
- _internal2Java.put(Type.Node, nodeListClass);
-
- _internal2Java.put(Type.NodeSet, Integer.TYPE);
- _internal2Java.put(Type.NodeSet, nodeClass);
- _internal2Java.put(Type.NodeSet, nodeListClass);
-
- _internal2Java.put(Type.ResultTree, nodeClass);
- _internal2Java.put(Type.ResultTree, nodeListClass);
- _internal2Java.put(Type.ResultTree, objectClass);
+ _internal2Java.put(Type.Int, new JavaType(Character.TYPE, 6));
+ _internal2Java.put(Type.Int, new JavaType(Byte.TYPE, 5));
+ _internal2Java.put(Type.Int, new JavaType(Short.TYPE, 4));
+ _internal2Java.put(Type.Int, new JavaType(Integer.TYPE, 0));
+ _internal2Java.put(Type.Int, new JavaType(Long.TYPE, 1));
+ _internal2Java.put(Type.Int, new JavaType(Float.TYPE, 2));
+ _internal2Java.put(Type.Int, new JavaType(Double.TYPE, 3));
+
+ _internal2Java.put(Type.Real, new JavaType(Character.TYPE, 6));
+ _internal2Java.put(Type.Real, new JavaType(Byte.TYPE, 5));
+ _internal2Java.put(Type.Real, new JavaType(Short.TYPE, 4));
+ _internal2Java.put(Type.Real, new JavaType(Integer.TYPE, 3));
+ _internal2Java.put(Type.Real, new JavaType(Long.TYPE, 2));
+ _internal2Java.put(Type.Real, new JavaType(Float.TYPE, 1));
+ _internal2Java.put(Type.Real, new JavaType(Double.TYPE, 0));
+
+ _internal2Java.put(Type.String, new JavaType(stringClass, 0));
+
+ _internal2Java.put(Type.Node, new JavaType(nodeClass, 0));
+ _internal2Java.put(Type.Node, new JavaType(nodeListClass, 1));
+
+ _internal2Java.put(Type.NodeSet, new JavaType(Integer.TYPE, 10));
+ _internal2Java.put(Type.NodeSet, new JavaType(nodeClass, 1));
+ _internal2Java.put(Type.NodeSet, new JavaType(nodeListClass,0));
+
+ _internal2Java.put(Type.ResultTree, new JavaType(nodeClass, 1));
+ _internal2Java.put(Type.ResultTree, new JavaType(nodeListClass,0));
+ _internal2Java.put(Type.ResultTree, new JavaType(objectClass,2));
- _internal2Java.put(Type.Reference, objectClass);
+ _internal2Java.put(Type.Reference, new JavaType(objectClass,0));
// Possible conversions between Java and internal types
- _java2Internal.put(Boolean.TYPE, Type.Boolean);
+ _java2Internal.put(Boolean.TYPE, Type.Boolean);
- _java2Internal.put(Character.TYPE, Type.Real);
+ _java2Internal.put(Character.TYPE, Type.Real);
_java2Internal.put(Byte.TYPE, Type.Real);
_java2Internal.put(Short.TYPE, Type.Real);
_java2Internal.put(Integer.TYPE, Type.Real);
@@ -339,6 +358,8 @@
final Vector argsType = typeCheckArgs(stable);
// Try all constructors
+ int bestConstrDistance = Integer.MAX_VALUE;
+ _type = null; // reset
for (int j, i = 0; i < nConstructors; i++) {
// Check if all parameters to this constructor can be converted
final Constructor constructor =
@@ -346,20 +367,34 @@
final Class[] paramTypes = constructor.getParameterTypes();
Class extType = null;
+ int currConstrDistance = 0;
for (j = 0; j < nArgs; j++) {
// Convert from internal (translet) type to external (Java) type
extType = paramTypes[j];
final Type intType = (Type)argsType.elementAt(j);
- if (!_internal2Java.maps(intType, extType)) break;
+ Object match = _internal2Java.maps(intType, extType);
+ if (match != null) {
+ currConstrDistance += ((JavaType)match).distance;
+ }
+ else {
+ // no mapping available
+ currConstrDistance = Integer.MAX_VALUE;
+ break;
+ }
}
- if (j == nArgs) {
+ if (j == nArgs && currConstrDistance < bestConstrDistance ) {
_chosenConstructor = constructor;
_isExtConstructor = true;
- return _type = new ObjectType(_className);
+ bestConstrDistance = currConstrDistance;
+ _type = new ObjectType(_className);
}
}
+ if (_type != null) {
+ return _type;
+ }
+
final StringBuffer buf = new StringBuffer(_className);
buf.append('.').append(_fname.getLocalPart()).append('(');
for (int i = 0; i < nArgs; i++) {
@@ -431,18 +466,30 @@
final int nMethods = methods.size();
final Vector argsType = typeCheckArgs(stable);
- // Try all methods with the same name as this function
+ // Try all methods to identify the best fit
+ int bestMethodDistance = Integer.MAX_VALUE;
+ _type = null; // reset internal type
for (int j, i = 0; i < nMethods; i++) {
// Check if all paramteters to this method can be converted
final Method method = (Method)methods.elementAt(i);
final Class[] paramTypes = method.getParameterTypes();
-
+
+ int currMethodDistance = 0;
for (j = 0; j < nArgs; j++) {
// Convert from internal (translet) type to external (Java) type
extType = paramTypes[j];
final Type intType = (Type)argsType.elementAt(j);
- if (!_internal2Java.maps(intType, extType)) break;
+ Object match = _internal2Java.maps(intType, extType);
+ if (match != null) {
+ currMethodDistance +=
+ ((JavaType)match).distance;
+ }
+ else {
+ // no mapping available
+ currMethodDistance = Integer.MAX_VALUE;
+ break;
+ }
}
if (j == nArgs) {
@@ -452,14 +499,18 @@
: (Type) _java2Internal.get(extType);
// Use this method if all parameters & return type match
- if (_type != null) {
+ if (_type != null && currMethodDistance < bestMethodDistance) {
_chosenMethod = method;
- if (_type == Type.NodeSet){
- getXSLTC().setMultiDocument(true);
- }
- return _type;
+ bestMethodDistance = currMethodDistance;
}
}
+ }
+
+ if (_type != null) {
+ if (_type == Type.NodeSet){
+ getXSLTC().setMultiDocument(true);
+ }
+ return _type;
}
final StringBuffer buf = new StringBuffer(_className);
1.3 +7 -6 xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/MultiHashtable.java
Index: MultiHashtable.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/MultiHashtable.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- MultiHashtable.java 20 Aug 2001 14:50:32 -0000 1.2
+++ MultiHashtable.java 30 Jul 2002 22:07:52 -0000 1.3
@@ -75,17 +75,18 @@
return vector;
}
- public boolean maps(Object from, Object to) {
- if (from == null) return false;
+ public Object maps(Object from, Object to) {
+ if (from == null) return null;
final Vector vector = (Vector) get(from);
if (vector != null) {
final int n = vector.size();
for (int i = 0; i < n; i++) {
- if (vector.elementAt(i).equals(to)) {
- return true;
+ final Object item = vector.elementAt(i);
+ if (item.equals(to)) {
+ return item;
}
}
}
- return false;
+ return null;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org