This completes the barebones versions of inner class, we are now able to access field...
authorspikeuci <spikeuci>
Fri, 28 Oct 2011 20:35:43 +0000 (20:35 +0000)
committerspikeuci <spikeuci>
Fri, 28 Oct 2011 20:35:43 +0000 (20:35 +0000)
Robust/src/IR/ClassDescriptor.java
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Tests/innerclass/inner.java

index 43923d0cff3830e103b83e33840300a2232723a0..1e66308d1ddb2799c6d516ff2f00fefadafe2376 100644 (file)
@@ -37,6 +37,8 @@ public class ClassDescriptor extends Descriptor {
 
   // 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;
 
@@ -338,6 +340,14 @@ public class ClassDescriptor extends Descriptor {
   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;
index 99f1291a4da5f2ad91651790b7442ba417656459..bfeb388f7a2867cd54c397b4a297f7e51264eef9 100644 (file)
@@ -685,6 +685,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth )
                        SymbolTable fieldTable = icd.getFieldTable();
                        //System.out.println( fieldTable.toString() );
                }*/
+               icd.setInnerDepth( depth );
                addOuterClassReferences( icd, depth + 1 );      
        }
 }
index d13a76503753857712cc7f122a524ef87a7fc05b..84645e8e631a45948298508a56bc785b7bba627f 100644 (file)
@@ -656,7 +656,6 @@ public class SemanticCheck {
       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()) {
@@ -764,6 +763,48 @@ public class SemanticCheck {
       }
   }
 
+  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) {
@@ -782,6 +823,16 @@ public class SemanticCheck {
       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();
@@ -828,7 +879,7 @@ public class SemanticCheck {
             nn.setClassDesc(cd);
             return;
           } else {
-            throw new Error("Name "+varname+" undefined in: "+md);
+            throw new Error("Name "+varname+" undefined in: "+md);         
           }
         }
       }
index bb429367e1be85166c363dd16f15edc84b7fc5bf..ba4a54ea364f8b0edcad5aea313f754ab7db1385 100644 (file)
@@ -24,10 +24,10 @@ public class inner{
        }
 
   public class t {
-    int outer;
+   // int outer;
     int f3 = 23;
     public t() {
-       this.outer=4;
+       //this.outer=4;
        //f2=3;
       f3=4;
 
@@ -36,7 +36,7 @@ public class inner{
     public void print() {
       //should print 4 0 3
       System.out.println(outer);
-      System.out.println(this$0.outer);
+     // System.out.println(this$0.outer);
 
     }
   }