From d1350d6f287dec8a788f4a5812975dfb01b38cc0 Mon Sep 17 00:00:00 2001 From: spikeuci Date: Fri, 28 Oct 2011 20:35:43 +0000 Subject: [PATCH] This completes the barebones versions of inner class, we are now able to access fields of surrounding classes in any level, need to check for compatibility with language spec especially use of statics and so forth --- Robust/src/IR/ClassDescriptor.java | 10 +++++ Robust/src/IR/Tree/BuildIR.java | 1 + Robust/src/IR/Tree/SemanticCheck.java | 55 +++++++++++++++++++++++++- Robust/src/Tests/innerclass/inner.java | 6 +-- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index 43923d0c..1e66308d 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -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; diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 99f1291a..bfeb388f 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -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 ); } } diff --git a/Robust/src/IR/Tree/SemanticCheck.java b/Robust/src/IR/Tree/SemanticCheck.java index d13a7650..84645e8e 100644 --- a/Robust/src/IR/Tree/SemanticCheck.java +++ b/Robust/src/IR/Tree/SemanticCheck.java @@ -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); } } } diff --git a/Robust/src/Tests/innerclass/inner.java b/Robust/src/Tests/innerclass/inner.java index bb429367..ba4a54ea 100644 --- a/Robust/src/Tests/innerclass/inner.java +++ b/Robust/src/Tests/innerclass/inner.java @@ -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); } } -- 2.34.1