[Jastadd] [bug report] two bugs related to inner classes.

From: Na, Hyunik <hina_at_kaist.ac.kr>
Date: Tue, 5 Jun 2012 16:12:38 +0900

Hello JastAddJ developers,

 

Now I’m reading JastAddJ source code related to inner class implementation

because my language extension has something to do with it.

 

I’ve found two minor bugs so far.

 

Bug #1.

 

The comment in MethodAccess.transformation() in Transformations.jrag in
Java1.4Backend says

 

     /* Access to private methods in enclosing types:

      The original MethodAccess is replaced with an access to an accessor
method

      built by createAccessor(). This method is built lazily and differs
from

      normal MethodDeclarations in the following ways:

      1) The method in the class file should always be static and the
signature

         is thus changed to include a possible this reference as the first
argument.

      2) The method is always invoked using INVOKESTATIC

      3) The flags must indicate that the method is static and package
private

      */

 

But, MethodDecl.createAccessor() does not follow the above ‘1)’

It makes the following program work incorrectly.

 

-=-=-=

class CO {

  private void m() { System.out.println( "in CO.m() " ); }

  class C {

    void callm() {

      m();

    }

  }

}

 

class DO extends CO {

  private void m() { System.out.println( "in DO.m() " ); }

  class D {

    void callm() {

      m();

    }

  }

}

 

public class Test {

  public static void main( String [] args ) {

    new DO().new C().callm();

  }

}

-=-=-=

 

The correct result of the above program is “in CO.m()”,

but running JastAddJ-generated class file results in “in DO.m()”.

 

Bug #2.

 

It seems that the following second condition in
SuperConstructorAccess.nameCheck() in TypeHierarchyCheck.jrag in
Java1.4Frontend

is too strong.

 

-=-=-=

public void SuperConstructorAccess.nameCheck() {

    …

    …

    if(!isQualified() && s.isInnerType()) {

      if(!c.isInnerType()) { // ß this condition.

        error("no enclosing instance for " + s.typeName() + " when accessed
in " + this);

      }

    }

    …

-=-=-=

 

Probably, it should be “!c.isAnonymous()” if it is only to bypass the error
check in

synthesized anonymous constructor.

( I guess that the condition is there to bypass an error check

of unqualified super constructor call generated by the compiler.

Note that there are cases in which the generated super constructor calls
should be qualified,

 but JastAddJ does not handle them in the Frontend.

 (see JLS2. 15.9.5.1. Anonymous Constructors and the rewrite clause in
AnonymousClasses.jrag in Java1.4Frontend).

)

 

The current JavaChecker accepts the following erroneous class definitions:

 

-=-=-=

class CO {

  class C {

  }

}

 

class DO {

  class D extends CO.C {

    D() {

      super(); // NOTE: should be qualified.

    }

  }

}

-=-=-=

 

and the JavaCompiler produces a NullPointerException when run on this
definitions.

 

Cheers,

- Hyunik
Received on Tue Jun 05 2012 - 09:13:00 CEST

This archive was generated by hypermail 2.3.0 : Wed Apr 16 2014 - 17:19:06 CEST