[Jastadd] [bug report] problems in ClassInstanceExpr.typeCheckEnclosingInstance() in Java1.4Frontend/TypeCheck.jrag
Hello JastAddJ developers,
Compiling the following to codes with JastAddJ JavaCompiler (rev. 9267)
produces no error messages.
-=-=-= E004100.java
public class E004100 {
public static void main( String [] args ) {
new StaticNested().m();
}
class Inner {}
static class StaticNested {
void m() { new Inner(); }
}
}
-=-=-=
-=-=-= E004101.java
public class E004101 {
public static void main( String [] args ) {
}
class Inner {}
static {
class StaticNested {
void m() { new Inner(); }
}
new StaticNested().m();
}
}
-=-=-=
But, running the generated classes produces the following run-time error
messages:
-=-=-=
hina_at_ns:~/myWork/test$ java E004100
Exception in thread "main" java.lang.NoSuchFieldError: this$0
at E004100$StaticNested.m(E004100.java:9)
at E004100.main(E004100.java:3)
hina_at_ns:~/myWork/test$ java E004101
Exception in thread "main" java.lang.NoSuchFieldError: this$0
at E004101$1StaticNested.m(E004101.java:9)
at E004101.<clinit>(E004101.java:11)
Could not find the main class: E004101. Program will exit.
-=-=-=
The problem is, as you can easily seen, JastAddJ typechecker does not reject
the cases where
an inner class is instantiated within a static context (but, the class
instance expression itself is not in a static context).
The cause of this problem seems to be in
ClassInstanceExpr.typeCheckEnclosingInstance() in
Java1.4Frontend/TypeCheck.jrag.
The following code shows how I modified the code:
-=-=-=
public void ClassInstanceExpr.typeCheckEnclosingInstance() {
.
else if(C.isMemberType()) {
if(!isQualified()) {
if(noEnclosingInstance()) {
error("No enclosing instance to initialize " + C.typeName() + "
with");
//System.err.println("ClassInstanceExpr: Non qualified MemberType
" + C.typeName() + " is in a static context when instantiated in " + this);
enclosing = unknownType();
}
else {
TypeDecl nest = hostType();
/*
while(nest != null && !nest.instanceOf(C.enclosingType()))
// !!!
nest = nest.enclosingType();
// !!!
replaced with the following while-block */
while(nest != null && !nest.instanceOf(C.enclosingType())) {
if ( nest.isStatic() || nest.inStaticContext() ) {
nest = unknownType();
break;
}
nest = nest.enclosingType();
}
enclosing = nest == null ? unknownType() : nest;
}
}
else {
enclosing = enclosingInstance();
}
}
//if(enclosing != null && !enclosing.instanceOf(type().enclosingType()))
{ // !!! replaced with the following line
if(enclosing != null && enclosing != type().enclosingType()) {
String msg = enclosing == null ? "None" : enclosing.typeName();
error("*** Can not instantiate " + type().typeName() + " with the
enclosing instance " + msg + " due to incorrect enclosing instance");
}
.
-=-=-=
The three lines marked with "!!!" were replaced as shown above.
( Note that unknownType().instanceOf(T) is true for every type T, so we need
to replace the instanceOf with reference comparison )
After rebuilding the compiler with this modification, the compiler rejects
the above two examples as expected.
Cheers.
- Hyunik.
Received on Fri Jun 01 2012 - 06:07:44 CEST
This archive was generated by hypermail 2.3.0
: Wed Apr 16 2014 - 17:19:06 CEST