// inner classes/enum can have these
String surroundingclass=null;
+ //adding another variable to indicate depth of this inner class
+ int innerDepth = 0;
ClassDescriptor surroudingdesc=null;
SymbolTable innerdescs;
public void setAsInnerClass() {
this.isInnerClass = true;
}
+ //Will have to call this whenever we are adding the this$ member, ideally should have used a single entrance to add the field. so that entrance could be used to set this flag.
+ public void setInnerDepth( int theDepth ) {
+ innerDepth = theDepth;
+ }
+
+ public int getInnerDepth() {
+ return innerDepth;
+ }
public boolean isInnerClass() {
return this.isInnerClass;
fd=FieldDescriptor.arrayLength;
else
fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
-
if(ltd.isClassNameRef()) {
// the field access is using a class name directly
if(ltd.getClassDesc().isEnum()) {
}
}
+ FieldDescriptor recurseSurroundingClasses( ClassDescriptor icd, String varname ) {
+ if( null == icd || false == icd.isInnerClass() )
+ return null;
+
+ ClassDescriptor surroundingDesc = icd.getSurroundingDesc();
+ if( null == surroundingDesc )
+ return null;
+
+ SymbolTable fieldTable = surroundingDesc.getFieldTable();
+ FieldDescriptor fd = ( FieldDescriptor ) fieldTable.get( varname );
+ if( null != fd )
+ return fd;
+ return recurseSurroundingClasses( surroundingDesc, varname );
+ }
+
+ FieldAccessNode fieldAccessExpression( ClassDescriptor icd, String varname, NameNode nn ) {
+ FieldDescriptor fd = recurseSurroundingClasses( icd, varname );
+ if( null == fd )
+ return null;
+
+ ClassDescriptor cd = fd.getClassDescriptor();
+ int depth = 0;
+ int startingDepth = icd.getInnerDepth();
+
+ if( true == cd.isInnerClass() )
+ depth = cd.getInnerDepth();
+
+ String composed = "this";
+ NameDescriptor runningDesc = new NameDescriptor( "this" );;
+
+ for ( int index = startingDepth; index >= depth; --index ) {
+ composed = "this$" + String.valueOf( index );
+ runningDesc = new NameDescriptor( runningDesc, composed );
+ }
+
+ NameDescriptor idDesc = new NameDescriptor( runningDesc, varname );
+
+
+ FieldAccessNode theFieldNode = ( FieldAccessNode )translateNameDescriptorintoExpression( idDesc, nn.getNumLine() );
+ return theFieldNode;
+ }
+
void checkNameNode(Descriptor md, SymbolTable nametable, NameNode nn, TypeDescriptor td) {
NameDescriptor nd=nn.getName();
if (nd.getBase()!=null) {
Descriptor d=(Descriptor)nametable.get(varname);
if (d==null) {
ClassDescriptor cd = null;
+ //check the inner class case first.
+ if((md instanceof MethodDescriptor) && false == ((MethodDescriptor)md).isStaticBlock()) {
+ cd = ((MethodDescriptor)md).getClassDesc();
+ FieldAccessNode theFieldNode = fieldAccessExpression( cd, varname, nn );
+ if( null != theFieldNode ) {
+ nn.setExpression(( ExpressionNode )theFieldNode);
+ checkExpressionNode(md,nametable,( ExpressionNode )theFieldNode,td);
+ return;
+ }
+ }
if((md instanceof MethodDescriptor) && ((MethodDescriptor)md).isStaticBlock()) {
// this is a static block, all the accessed fields should be static field
cd = ((MethodDescriptor)md).getClassDesc();
nn.setClassDesc(cd);
return;
} else {
- throw new Error("Name "+varname+" undefined in: "+md);
+ throw new Error("Name "+varname+" undefined in: "+md);
}
}
}