From 1e3592cf43dc30654d012beae56a1d65546a59ad Mon Sep 17 00:00:00 2001 From: jzhou Date: Fri, 29 Oct 2010 00:15:37 +0000 Subject: [PATCH] Add support for static inner classes in mgc version. Currently we only implemented limited features. Do not support Outer.Inner yet. Also only use inner class's name to identify the class instead of Outer.Inner which may cause bugs if there are two inner classes with the same name but with different surrounding classes. --- Robust/src/IR/ClassDescriptor.java | 71 +++++++++++++++++++++++++++++ Robust/src/IR/Tree/BuildIR.java | 73 +++++++++++++++++++++++++++++- Robust/src/Parse/java14.cup | 24 +++++----- 3 files changed, 155 insertions(+), 13 deletions(-) diff --git a/Robust/src/IR/ClassDescriptor.java b/Robust/src/IR/ClassDescriptor.java index d16940e4..8e00b5bf 100644 --- a/Robust/src/IR/ClassDescriptor.java +++ b/Robust/src/IR/ClassDescriptor.java @@ -23,6 +23,12 @@ public class ClassDescriptor extends Descriptor { // for interfaces Vector superinterfaces; SymbolTable superIFdesc; + + // for inner classes + boolean isInnerClass=false; + String surroundingclass=null; + ClassDescriptor surroudingdesc=null; + SymbolTable innerdescs; public ClassDescriptor(String classname, boolean isInterface) { this("", classname, isInterface); @@ -43,6 +49,7 @@ public class ClassDescriptor extends Descriptor { this.packagename=packagename; superinterfaces = new Vector(); superIFdesc = new SymbolTable(); + this.innerdescs = new SymbolTable(); } public int getId() { @@ -126,6 +133,14 @@ public class ClassDescriptor extends Descriptor { } if (printcr) st+="\n"; + + for(Iterator it=this.getInnerClasses(); it.hasNext();) { + ClassDescriptor icd=(ClassDescriptor)it.next(); + st+=icd.printTree(state)+"\n"; + printcr=true; + } + if (printcr) + st+="\n"; for(Iterator it=getMethods(); it.hasNext();) { MethodDescriptor md=(MethodDescriptor)it.next(); @@ -217,4 +232,60 @@ public class ClassDescriptor extends Descriptor { public boolean isInterface() { return this.classid == -2; } + + public boolean isStatic() { + return this.modifiers.isStatic(); + } + + public void setAsInnerClass() { + this.isInnerClass = true; + } + + public boolean isInnerClass() { + return this.isInnerClass; + } + + public void setSurroundingClass(String sclass) { + this.surroundingclass=sclass; + } + + public String getSurrounding() { + return this.surroundingclass; + } + + public ClassDescriptor getSurroundingDesc() { + return this.surroudingdesc; + } + + public void setSurrounding(ClassDescriptor scd) { + this.surroudingdesc=scd; + } + + public void addInnerClass(ClassDescriptor icd) { + this.innerdescs.add(icd); + } + + public Iterator getInnerClasses() { + return this.innerdescs.getDescriptorsIterator(); + } + + public SymbolTable getInnerClassTable() { + return this.innerdescs; + } + + /*public String getSymbol() { + if(this.isInnerClass) { + return this.surroudingdesc.getSymbol() + "." + name; + } else { + return name; + } + } + + public String getSafeSymbol() { + if(this.isInnerClass) { + return this.surroudingdesc.getSafeSymbol()+ "." + safename; + } else { + return safename; + } + }*/ } diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index f1372753..cf43c80c 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -55,6 +55,30 @@ public class BuildIR { if (toanalyze!=null) toanalyze.add(cn); state.addClass(cn); + // for inner classes + if(state.MGC) { + // TODO add version for normal Java later + HashSet tovisit = new HashSet(); + Iterator it_icds = cn.getInnerClasses(); + while(it_icds.hasNext()) { + tovisit.add(it_icds.next()); + } + + while(!tovisit.isEmpty()) { + ClassDescriptor cd = (ClassDescriptor)tovisit.iterator().next(); + tovisit.remove(cd); + + if(toanalyze != null) { + toanalyze.add(cd); + } + state.addClass(cd); + + Iterator it_ics = cd.getInnerClasses(); + while(it_ics.hasNext()) { + tovisit.add(it_ics.next()); + } + } + } } else if (isNode(type_pn,"task_declaration")) { TaskDescriptor td=parseTaskDecl(type_pn); if (toanalyze!=null) @@ -361,7 +385,6 @@ public class BuildIR { private void parseClassMember(ClassDescriptor cn, ParseNode pn) { ParseNode fieldnode=pn.getChild("field"); - if (fieldnode!=null) { parseFieldDecl(cn,fieldnode.getChild("field_declaration")); return; @@ -371,6 +394,16 @@ public class BuildIR { parseMethodDecl(cn,methodnode.getChild("method_declaration")); return; } + ParseNode innerclassnode=pn.getChild("inner_class_declaration"); + if (innerclassnode!=null) { + if(state.MGC){ + parseInnerClassDecl(cn,innerclassnode); + return; + } else { + // TODO add version for noraml Java later + throw new Error("Error: inner class in Class " + cn.getSymbol() + " is not supported yet"); + } + } ParseNode flagnode=pn.getChild("flag"); if (flagnode!=null) { parseFlagDecl(cn, flagnode.getChild("flag_declaration")); @@ -378,6 +411,44 @@ public class BuildIR { } throw new Error(); } + + private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) { + ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false); + icn.setAsInnerClass(); + icn.setSurroundingClass(cn.getSymbol()); + icn.setSurrounding(cn); + cn.addInnerClass(icn); + if (!isEmpty(pn.getChild("super").getTerminal())) { + /* parse superclass name */ + ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name"); + NameDescriptor nd=parseName(snn); + icn.setSuper(nd.toString()); + } else { + if (!(icn.getSymbol().equals(TypeUtil.ObjectClass)|| + icn.getSymbol().equals(TypeUtil.TagClass))) + icn.setSuper(TypeUtil.ObjectClass); + } + // check inherited interfaces + if (!isEmpty(pn.getChild("superIF").getTerminal())) { + /* parse inherited interface name */ + ParseNode snlist=pn.getChild("superIF").getChild("interface_type_list"); + ParseNodeVector pnv=snlist.getChildren(); + for(int i=0; i