Miranda methods and Methods added by Code Generators

Andrew Dinn adinn at redhat.com
Mon Aug 9 01:50:53 PDT 2010


Hi Maurizio,

On 08/07/2010 06:39 PM, maurizio cimadamore wrote:
> the compiler internally uses the IPROXY flag to mark Miranda methods:
>
> 146 /** Flag is set for compiler-generated abstract methods that implement
>
> 147 * an interface method (Miranda methods).
>
> 148 */
>
> 149 public static final int IPROXY = 1<<21;
>
>
> The code you are looking at discards SYNTHETIC methods because this
> method is meant to return an user-defined implementation of a given
> method symbol in a given class - and a SYNTEHTIC method is, by
> definition, not a user-defined method. This check turns out particularly
> useful when the class contains one or more bridge methods (the method
> that javac has to emit to preserve overriding in the face of type-erasure).
>
> In other words, javac is not complaining because it thinks that
> getAdvisor() is a Miranda method - it just complains because it sees a
> class not overriding all methods from its superinterfaces.

Yes, I noted that javac adds the IPROXY method attribute to any Miranda 
methods it generates during the compile. But in this case I am referring 
to a Miranda method generated during a previous compile then written to 
the bytecode file for the class. Are you sugesting that Miranda methods 
do not get written to the abstract class's bytecode file? As far as I 
coudl tell they are written out as ABSTRACT SYNTHETIC methods but 
without the IPROXY attribute (this attribute is private to javac).

Anyway, your comment merely provides an account of why the check is made 
but this does not really address its validity. You are absolutely right 
that in the circumstances I highlighted the purpose of the check is to 
see whether the class has overridden all methods inherited from its 
superinterfaces. Well, in this case the answer is that the class is 
valid and the check is wrong. The situation is as follows. We have a 
POJO class parent

abstract class Parent {
   public abstract Foo getFoo();
   . . .
}

AOP transforms this class as follows

abstract class Parent implements Advised {
   // synthetic method added by AOP
   public Advisor getAdvisor() {
     . . .
   }
   public abstract Foo getFoo();
   . . .
}

interface Advised {
   public Advisor getAdvisor()
}

The bytecode file for this class contains an implementation of 
getAdvisor() but it is tagged with the SYNTHETIC attribute.

Now we define a class Child as follows

class Child extends  Parent {
   public Foo getFoo() {
     . . .
}

Now javac is asked to compile Child and the AOP transformed bytecode for 
Parent is placed in the class path. javac complains that Child  does not 
implement getAdvisor(). Well, it does not need to because the 
transformed code for Parent implements it. The immediate reason why the 
parent implementation of getAdvisor() is discounted is because the 
generated code for getAdvisor() is SYNTHETIC and the check I highlighted 
ignores SYNTHETIC methods.

Now you may be right that this is nothing to do with Miranda methods. I 
cannot really look into the minds of whoever originally designed the 
code in order to argue a case. But javac is plainly wrong in stating 
that Child does not have an implementation for getAdvisor(). This method 
is defined by Parent and has perfectly valid, executable code. So, Child 
ought to inherit this implementation.

In fact when Parent is not an abstract class the SYNTHETIC code is 
inherited and executed without any problem. It is only in the case where 
the parent is abstract that this issue arises (I'll just note that this 
is because the check is only made when there may be Miranda methods to 
look for). So, irrespective of motive can you explain to me why it is 
correct to disregard this SYNTHETIC implementation?

regards,


Andrew Dinn
-----------



More information about the compiler-dev mailing list