This is the mail archive of the
kawa@sourceware.cygnus.com
mailing list for the Kawa project.
OVERRIDE Multiple methods with the same name and argument types
- To: "Kawa" <kawa at sourceware dot cygnus dot com>
- Subject: OVERRIDE Multiple methods with the same name and argument types
- From: "Daniel Bonniot" <bonniot at cma dot ensmp dot fr>
- Date: Thu, 17 Feb 2000 20:29:48 +0100
- Cc: "Per Bothner" <per at bothner dot com>
- Organization: d.bonniot@mail.dotcom.fr
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;
}