This is the mail archive of the kawa@sourceware.cygnus.com mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

OVERRIDE Multiple methods with the same name and argument types



Did my mail get through ? I received this error:

  -----  The following recipients were processed by MTA
laguna.tiscalinet.it...

mikrub@tiscalinet.it; Action: Failed; Status: 5.2.2 (mailbox full)
    Remote MTA nplex1c.mx.tiscalinet.it: SMTP Diagnostic 552 RCPT
<mikrub@tiscalinet.it> ERROR. Exceeded storage allocation



Anyway, I did several mistakes in the previous mail (no diff -u, and a bug
in PrimProcedure).
Furthermore:
* I think there was a bug in ClassType.getInterfaces
The current version doesn't look for interfaces if one has a superclass. I
suppose this was a typo.

* I needed an overload of ClassType.writeToFile that takes a java.lan.File

So let's start from scratch again:

gnu.bytecode.ClassType currently allows to have several methods with the
same name and argument types, even when using the
addMethod(String name, int flags, Type[] arg_types, Type return_type)
that pretends to check if the method already exists.
The problem is that addMethod creates a new one if the old has different
return type and/or access flags. I consider this is a bug, since the
classfile generated will be invalid.

I encountered this problem using new PrimProcedure(ClassType classtype,
Type[] argTypes). It led to several constructors in the same class with just
differing flags (when a public constructor already existed, it created a new
one).

I propose:
* Add a getDeclaredMethod(String name, Type[] arg_types, Type return_type)
to ClassType. This is a convenient method that calls
getDeclaredMethod(String name, Type[] arg_types) and then if a method was
found, it verifies that its return type is the same, otherwise throws an
Error.

* Modify PrimProcedure, so that it first checks if the method exists (in
that case verify the static flag is correct), and if not creates a new one.

Here are the patches against the CVS version (I learned diff's -D now option
:)




RCS file: /cvs/kawa/kawa/gnu/bytecode/ClassType.java,v
retrieving revision 1.31
diff -u -r1.31 ClassType.java
--- ClassType.java      2000/02/13 05:01:11     1.31
+++ ClassType.java      2000/02/17 19:26:35
@@ -120,7 +120,7 @@
    */
   public ClassType[] getInterfaces()
   {
-    if (superClass == null && reflectClass != null)
+    if (interfaces == null && reflectClass != null)
       {
        Class[] reflectInterfaces = reflectClass.getInterfaces();
        interfaces = new ClassType[reflectInterfaces.length];
@@ -353,6 +353,26 @@
     return meth;
   }

+  /**
+      Return a method with the given name and arguments types,
+      or null if none exists.
+      Checks that the return type is the same as that given in argument,
+      or throws an error.
+  */
+  public Method getDeclaredMethod(String name,
+                                 Type[] arg_types, Type return_type)
+  {
+    Method method = getDeclaredMethod(name, arg_types);
+
+    if (method!=null &&
+       !return_type.equals(method.getReturnType()))
+      throw new Error("Method "+getName()+"."+name+
+                     " has two implementations with same arguments"+
+                     "but different return types");
+
+    return method;
+  }
+
   public Method getDeclaredMethod(String name, Type[] arg_types)
   {
     if ((flags & (ADD_METHODS_DONE|EXISTING_CLASS)) == EXISTING_CLASS)
@@ -590,9 +610,15 @@

   public void writeToFile (String filename)
     throws java.io.IOException
- {
+  {
+    writeToFile(new File(filename));
+  }
+
+  public void writeToFile (File file)
+    throws java.io.IOException
+  {
     OutputStream stream
-      = new BufferedOutputStream(new FileOutputStream (filename));
+      = new BufferedOutputStream(new FileOutputStream (file));
     writeToStream (stream);
     stream.close ();
   }

Index: PrimProcedure.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/expr/PrimProcedure.java,v
retrieving revision 1.15
diff -u -r1.15 PrimProcedure.java
--- PrimProcedure.java  2000/01/24 06:55:22     1.15
+++ PrimProcedure.java  2000/02/17 19:22:22
@@ -192,8 +192,20 @@
     this.op_code = op_code;
     if (op_code == 185) // invokeinterface
       classtype.access_flags |= Access.INTERFACE;
-    method = classtype.addMethod (name, argTypes, retType,
-                                  op_code == 184 ? Access.STATIC : 0);
+
+    method = classtype.getDeclaredMethod(name, argTypes, retType);
+
+    if (method == null)
+      method = classtype.addMethod(name,
+                                  op_code == 184 ? Access.STATIC : 0,
+                                  argTypes, retType);
+    else
+      if ((op_code == 184) != method.getStaticFlag())
+         throw new Error("Method "+method+
+                         " should "+
+                         (op_code == 184 ? "" : "not ")+
+                         "be static");
+
     this.retType = retType;
     this.argTypes= argTypes;
   }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]