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: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to