Make the compiler to support super.X/L.super.X which access super class' fields....
authorjzhou <jzhou>
Fri, 11 Nov 2011 21:08:41 +0000 (21:08 +0000)
committerjzhou <jzhou>
Fri, 11 Nov 2011 21:08:41 +0000 (21:08 +0000)
Robust/src/IR/Tree/BuildIR.java
Robust/src/IR/Tree/FieldAccessNode.java
Robust/src/IR/Tree/NameNode.java
Robust/src/IR/Tree/SemanticCheck.java
Robust/src/Parse/java14.cup
Robust/src/Tests/DoTests
Robust/src/Tests/inner.java
Robust/src/Tests/output/inner.output.goal [new file with mode: 0644]

index a6005bd38f8c97a2762392652715aa02dceb289d..6f3ed520c4f21eb96f52667005807ab026bb9654 100644 (file)
@@ -636,6 +636,9 @@ private void addOuterClassParam( ClassDescriptor cn, int depth )
        
        for(Iterator it=cn.getInnerClasses(); it.hasNext(); ) {
                ClassDescriptor icd=(ClassDescriptor)it.next();
+               if(icd.isStatic()) {
+                   continue;
+               }
                
                //iterate over all ctors of I.Cs and add a new param
                for(Iterator method_it=icd.getMethods(); method_it.hasNext(); ) {
@@ -1240,6 +1243,22 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth )
       FieldAccessNode fan=new FieldAccessNode(en,fieldname);
       fan.setNumLine(pn.getLine());
       return fan;
+    } else if (isNode(pn,"superfieldaccess")) {
+       ExpressionNode en=new NameNode(new NameDescriptor("super"));
+       String fieldname=pn.getChild("field").getTerminal();
+
+       FieldAccessNode fan=new FieldAccessNode(en,fieldname);
+       fan.setNumLine(pn.getLine());
+       return fan;
+    } else if (isNode(pn,"supernamefieldaccess")) {
+       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
+       ExpressionNode exp = new FieldAccessNode(en, "super");
+       exp.setNumLine(pn.getLine());
+       String fieldname=pn.getChild("field").getTerminal();
+
+       FieldAccessNode fan=new FieldAccessNode(exp,fieldname);
+       fan.setNumLine(pn.getLine());
+       return fan;
     } else if (isNode(pn,"arrayaccess")) {
       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
       ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
index e764bb0d7dec71342e300bb4d892603000f8c55a..66c7238d75a9d5f1cdf18c0e50babc21f3fbe294 100644 (file)
@@ -6,10 +6,12 @@ public class FieldAccessNode extends ExpressionNode {
   ExpressionNode left;
   String fieldname;
   FieldDescriptor field;
+  boolean issuper;
 
   public FieldAccessNode(ExpressionNode l, String field) {
     fieldname=field;
     left=l;
+    this.issuper = false;
   }
 
   public void setField(FieldDescriptor fd) {
@@ -44,6 +46,14 @@ public class FieldAccessNode extends ExpressionNode {
   public TypeDescriptor getType() {
     return getField().getType();
   }
+  
+  public void setIsSuper() {
+      this.issuper = true;
+  }
+  
+  public boolean isSuper() {
+      return issuper;
+  }
 
   public Long evaluate() {
     // if the field is a constant value then OK
index 77cdbcded6ec02d28a20f3676107d430adae5712..bad7b7b682c00d9a33b546c28c833ece546b6e10 100644 (file)
@@ -13,12 +13,22 @@ public class NameNode extends ExpressionNode {
   FieldDescriptor fd;
   ExpressionNode en;
   ClassDescriptor cd;
+  boolean issuper;
 
   public NameNode(NameDescriptor nd) {
     this.name=nd;
     this.vd=null;
     this.fd=null;
     this.cd = null;
+    this.issuper= false;
+  }
+  
+  public boolean isSuper() {
+      return this.issuper;
+  }
+  
+  public void setIsSuper() {
+      this.issuper = true;
   }
 
   public ExpressionNode getExpression() {
index 76443900cbc8d8d1dca25643cc58532d252c3911..22f9546f9fb4adccbdedebacf9fd82c27c90e514 100644 (file)
@@ -664,14 +664,17 @@ public class SemanticCheck {
     FieldDescriptor fd=null;
     if (ltd.isArray()&&fieldname.equals("length"))
       fd=FieldDescriptor.arrayLength;
-    else {
+    else if(((left instanceof NameNode) && ((NameNode)left).isSuper())
+           ||((left instanceof FieldAccessNode) && ((FieldAccessNode)left).isSuper())){
+      fd = (FieldDescriptor) ltd.getClassDesc().getSuperDesc().getFieldTable().get(fieldname);
+    } else {
       fd=(FieldDescriptor) ltd.getClassDesc().getFieldTable().get(fieldname);
     }
     if(ltd.isClassNameRef()) {
       // the field access is using a class name directly
       if (fd==null) {
        // check if it is to access a surrounding class in an inner class
-       if(fieldname.equals("this")) {
+       if(fieldname.equals("this") || fieldname.equals("super")) {
           ClassDescriptor icd = ((VarDescriptor)nametable.get("this")).getType().getClassDesc();
           if(icd.isInnerClass()) {
               NameNode nn = new NameNode(new NameDescriptor("this"));
@@ -686,10 +689,13 @@ public class SemanticCheck {
                   // this is an inner class this operation 
                   fd = new FieldDescriptor(new Modifiers(),new TypeDescriptor(icd),"this",null,false);
               }
+              if(fieldname.equals("super")) {
+                  fan.setIsSuper();
+              }
               fan.setField(fd);
               return;
           }
-       }
+       } 
        ClassDescriptor surroundingCls=ltd.getClassDesc().getSurroundingDesc();
        
        while(surroundingCls!=null) {
@@ -899,9 +905,12 @@ public class SemanticCheck {
       checkExpressionNode(md,nametable,en,td);
     } else {
       String varname=nd.toString();
-      if(varname.equals("this")) {
+      if(varname.equals("this") || varname.equals("super")) {
         // "this"
         nn.setVar((VarDescriptor)nametable.get("this"));
+        if(varname.equals("super")) {
+            nn.setIsSuper();
+        }
         return;
       }
       Descriptor d=(Descriptor)nametable.get(varname);
index 9416a94bd4a742cd8e65e64563f3e50fd34c1979..762cf7945bed458cdb33a378ec4e7e3f5caf19c6 100644 (file)
@@ -2204,8 +2204,17 @@ field_access ::=
                pn.addChild("field").addChild(id);
                RESULT=pn;
     :}
-//     |       SUPER DOT IDENTIFIER
-//     |       name DOT SUPER DOT IDENTIFIER
+       |       SUPER DOT IDENTIFIER:id {: 
+               ParseNode pn=new ParseNode("superfieldaccess",parser.lexer.line_num);
+               pn.addChild("field").addChild(id);
+               RESULT=pn;
+    :}
+       |       name:name DOT SUPER DOT IDENTIFIER:id {: 
+               ParseNode pn=new ParseNode("supernamefieldaccess",parser.lexer.line_num);
+               pn.addChild("base").addChild(name);
+               pn.addChild("field").addChild(id);
+               RESULT=pn;
+    :}
        ;
 method_invocation ::=
                name:name LPAREN argument_list_opt:args RPAREN {: 
index 37a4aff46902298916b5c3a6cea8293edee61100..0cfd99df3b56206450542ba0dab8e715c95723a3 100755 (executable)
@@ -24,3 +24,4 @@ dotest StaticInnerClassTest StaticInnerClassTest.java
 dotest StaticTest StaticTest.java
 dotest SwitchCaseTest SwitchCaseTest.java
 dotest TryCatchTest TryCatchTest.java
+dotest inner inner.java innerp.java innerpt.java
index ca5b94e8c4515a51146ccbce29c0ff03dcd0cc4b..6000c3e385a852ef33b674f6ab2a5a38ed52e808 100644 (file)
@@ -38,6 +38,9 @@ public class inner extends innerp {
       System.out.println("\t Inner class print: ");
       System.out.println(outer);
       System.out.println(super.outer);
+      t.super.outer = 1;
+      System.out.println(outer);
+      System.out.println(t.super.outer);
       System.out.println(inner.this.outer);
       System.out.println(inner.super.outer);
       System.out.println(f1);
diff --git a/Robust/src/Tests/output/inner.output.goal b/Robust/src/Tests/output/inner.output.goal
new file mode 100644 (file)
index 0000000..31735e7
--- /dev/null
@@ -0,0 +1,12 @@
+Outer class print: 35; 0
+        Inner class print: 
+4
+0
+4
+1
+35
+31
+2
+3
+4
+Outer class print: 35; 3