From b9299937e1f902199ac28e203cf5fea92b5ba427 Mon Sep 17 00:00:00 2001 From: jzhou Date: Wed, 23 Nov 2011 00:25:49 +0000 Subject: [PATCH] Fix another inner class bug: an inner class which is declared in a *static context* should not have lexically enclosing instances, instead, if it is immediately declared within a static method or static initializer then the inner class does have an enclosing block, which is the innermost block statement lexically enclosing the declaration of the inner class. --- Robust/src/IR/ClassDescriptor.java | 18 +++ Robust/src/IR/Tree/BuildIR.java | 183 ++++++++++++---------- Robust/src/IR/Tree/SemanticCheck.java | 16 +- Robust/src/IR/TypeUtil.java | 8 +- Robust/src/Tests/inner.java | 13 ++ Robust/src/Tests/output/inner.output.goal | 1 + 6 files changed, 144 insertions(+), 95 deletions(-) diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index 00a2e45c..e6122e0b 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -40,6 +40,8 @@ public class ClassDescriptor extends Descriptor { int innerDepth = 0; ClassDescriptor surroundingdesc=null; SymbolTable surroundingNameTable = null; + MethodDescriptor surroundingBlock=null; + boolean inStaticContext=false; SymbolTable innerdescs; @@ -478,4 +480,20 @@ public class ClassDescriptor extends Descriptor { public SymbolTable getSurroundingNameTable() { return this.surroundingNameTable; } + + public void setSurroundingBlock(MethodDescriptor md) { + this.surroundingBlock = md; + } + + public MethodDescriptor getSurroundingBlock() { + return this.surroundingBlock; + } + + public void setInStaticContext() { + this.inStaticContext = true; + } + + public boolean getInStaticContext() { + return this.inStaticContext; + } } diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index 34bad80c..a12dcf0a 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -375,7 +375,7 @@ public class BuildIR { md.getModifiers().addModifier(Modifiers.PUBLIC); md.getModifiers().addModifier(Modifiers.ABSTRACT); try { - BlockNode bn=parseBlock(cn, bodyn); + BlockNode bn=parseBlock(cn, md, md.isStatic()||md.isStaticBlock(), bodyn); cn.addMethod(md); state.addTreeCode(md,bn); } catch (Exception e) { @@ -392,7 +392,7 @@ public class BuildIR { public TaskDescriptor parseTaskDecl(ParseNode pn) { TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal()); ParseNode bodyn=pn.getChild("body"); - BlockNode bn=parseBlock(null, bodyn); + BlockNode bn=parseBlock(null, null, false, bodyn); parseParameterList(td, pn); state.addTreeCode(td,bn); if (pn.getChild("flag_effects_list")!=null) @@ -636,7 +636,7 @@ private void addOuterClassParam( ClassDescriptor cn, int depth ) for(Iterator it=cn.getInnerClasses(); it.hasNext(); ) { ClassDescriptor icd=(ClassDescriptor)it.next(); - if(icd.isStatic()) { + if(icd.isStatic()||icd.getInStaticContext()) { continue; } @@ -683,6 +683,9 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) for(Iterator it=cn.getInnerClasses(); it.hasNext(); ) { ClassDescriptor icd=(ClassDescriptor)it.next(); + if(icd.isStatic() || icd.getInStaticContext()) { + continue; + } parseFieldDecl( icd, theNode ); /*if( true ) { SymbolTable fieldTable = icd.getFieldTable(); @@ -969,7 +972,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) ExpressionNode en=null; if (epn!=null) { - en=parseExpression(cn, epn.getFirstChild()); + en=parseExpression(cn, null, m.isStatic(), epn.getFirstChild()); en.setNumLine(epn.getFirstChild().getLine()); if(m.isStatic()) { // for static field, the initializer should be considered as a @@ -1025,11 +1028,11 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) int innerCount=0; - private ExpressionNode parseExpression(ClassDescriptor cn, ParseNode pn) { + private ExpressionNode parseExpression(ClassDescriptor cn, MethodDescriptor md, boolean isStaticContext, ParseNode pn) { if (isNode(pn,"assignment")) { //System.out.println( "parsing a field decl in my class that has assignment in initialization " + pn.PPrint( 0, true ) + "\n"); - return parseAssignmentExpression(cn, pn); + return parseAssignmentExpression(cn, md, isStaticContext, pn); } else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")|| isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")|| @@ -1045,7 +1048,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) ParseNode left=pnv.elementAt(0); ParseNode right=pnv.elementAt(1); Operation op=new Operation(pn.getLabel()); - OpNode on=new OpNode(parseExpression(cn, left),parseExpression(cn, right),op); + OpNode on=new OpNode(parseExpression(cn, md, isStaticContext, left),parseExpression(cn, md, isStaticContext, right),op); on.setNumLine(pn.getLine()); return on; } else if (isNode(pn,"unaryplus")|| @@ -1054,14 +1057,14 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) isNode(pn,"comp")) { ParseNode left=pn.getFirstChild(); Operation op=new Operation(pn.getLabel()); - OpNode on=new OpNode(parseExpression(cn, left),op); + OpNode on=new OpNode(parseExpression(cn, md, isStaticContext, left),op); on.setNumLine(pn.getLine()); return on; } else if (isNode(pn,"postinc")|| isNode(pn,"postdec")) { ParseNode left=pn.getFirstChild(); AssignOperation op=new AssignOperation(pn.getLabel()); - AssignmentNode an=new AssignmentNode(parseExpression(cn, left),null,op); + AssignmentNode an=new AssignmentNode(parseExpression(cn, md, isStaticContext, left),null,op); an.setNumLine(pn.getLine()); return an; @@ -1069,7 +1072,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) isNode(pn,"predec")) { ParseNode left=pn.getFirstChild(); AssignOperation op=isNode(pn,"preinc")?new AssignOperation(AssignOperation.PLUSEQ):new AssignOperation(AssignOperation.MINUSEQ); - AssignmentNode an=new AssignmentNode(parseExpression(cn, left), + AssignmentNode an=new AssignmentNode(parseExpression(cn, md, isStaticContext, left), new LiteralNode("integer",new Integer(1)),op); an.setNumLine(pn.getLine()); return an; @@ -1083,7 +1086,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) } else if (isNode(pn, "createobject")) { TypeDescriptor td = parseTypeDescriptor(pn); - Vector args = parseArgumentList(cn, pn); + Vector args = parseArgumentList(cn, md, isStaticContext, pn); boolean isglobal = pn.getChild("global") != null || pn.getChild("scratch") != null; String disjointId = null; if (pn.getChild("disjoint") != null) { @@ -1096,14 +1099,14 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) if( null != idChild && null != idChild.getFirstChild() ) { idChild = idChild.getFirstChild(); //System.out.println( "\nThe object passed has this expression " + idChild.PPrint( 0, true ) ); - ExpressionNode en = parseExpression(cn, idChild ); + ExpressionNode en = parseExpression(cn, md, isStaticContext, idChild ); //System.out.println( "\nThe object passed has this expression " + en.printNode( 0 ) ); con.setSurroundingExpression( en ); } else if( null != baseChild && null != baseChild.getFirstChild() ) { baseChild = baseChild.getFirstChild(); //System.out.println( "\nThe object passed has this expression " + baseChild.PPrint( 0, true ) ); - ExpressionNode en = parseExpression(cn, baseChild ); + ExpressionNode en = parseExpression(cn, md, isStaticContext, baseChild ); //System.out.println( "\nThe object passed has this expression " + en.printNode( 0 ) ); con.setSurroundingExpression( en ); } @@ -1138,11 +1141,19 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) cnnew.setSurroundingClass(cn.getSymbol()); cnnew.setSurrounding(cn); cn.addInnerClass(cnnew); + // Note that if the inner class is declared in a static context, it does NOT + // have lexically enclosing instances. + if((null!=md)&&(md.isStatic()||md.isStaticBlock())) { + cnnew.setSurroundingBlock(md); + cnnew.setInStaticContext(); + } else if (isStaticContext) { + cnnew.setInStaticContext(); + } parseClassBody(cnnew, pn.getChild("decl").getChild("classbody")); boolean hasConstructor = false; for(Iterator method_it=cnnew.getMethods(); method_it.hasNext(); ) { - MethodDescriptor md=(MethodDescriptor)method_it.next(); - hasConstructor |= md.isConstructor(); + MethodDescriptor cmd=(MethodDescriptor)method_it.next(); + hasConstructor |= cmd.isConstructor(); } if(hasConstructor) { // anonymous class should not have explicit constructors @@ -1157,7 +1168,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) } TypeDescriptor tdnew=state.getTypeDescriptor(cnnew.getSymbol()); - Vector args=parseArgumentList(cn, pn); + Vector args=parseArgumentList(cn, md, isStaticContext, pn); ParseNode idChild = pn.getChild( "id" ); ParseNode baseChild = pn.getChild( "base" ); //System.out.println("\n to print idchild and basechild for "); @@ -1187,7 +1198,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) disjointId = pn.getChild("disjoint").getTerminal(); } TypeDescriptor td=parseTypeDescriptor(pn); - Vector args=parseDimExprs(cn, pn); + Vector args=parseDimExprs(cn, md, isStaticContext, pn); int num=0; if (pn.getChild("dims_opt").getLiteral()!=null) num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue(); @@ -1210,7 +1221,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) CreateObjectNode con=new CreateObjectNode(td, false, null); con.setNumLine(pn.getLine()); ParseNode ipn = pn.getChild("initializer"); - Vector initializers=parseVariableInitializerList(cn, ipn); + Vector initializers=parseVariableInitializerList(cn, md, isStaticContext, ipn); ArrayInitializerNode ain = new ArrayInitializerNode(initializers); ain.setNumLine(pn.getLine()); con.addArrayInitializer(ain); @@ -1240,7 +1251,7 @@ private void addOuterClassReferences( ClassDescriptor cn, int depth ) return new OpNode(nn,null,new Operation(Operation.ISAVAILABLE)); } else if (isNode(pn,"methodinvoke1")) { NameDescriptor nd=parseName(pn.getChild("name")); - Vector args=parseArgumentList(cn, pn); + Vector args=parseArgumentList(cn, md, isStaticContext, pn); MethodInvokeNode min=new MethodInvokeNode(nd); min.setNumLine(pn.getLine()); for(int i=0; i