X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FIR%2FTree%2FBuildIR.java;h=a12dcf0a36aa0595d9c70d0598a4969b12f15c0b;hb=b9299937e1f902199ac28e203cf5fea92b5ba427;hp=e31d6d14f50b06db2bb234f4bc5e30d5aa99a7de;hpb=79c84f3bffb5dc9e14f9d72726164c9e2354eadb;p=IRC.git diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index e31d6d14..a12dcf0a 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -1,23 +1,26 @@ package IR.Tree; import IR.*; import Util.Lattice; +import Util.Pair; import java.io.File; import java.util.*; - +import java.io.*; +import java.lang.Throwable; public class BuildIR { State state; - + private boolean isRunningRecursiveInnerClass; private int m_taskexitnum; public BuildIR(State state) { this.state=state; this.m_taskexitnum = 0; + this.isRunningRecursiveInnerClass = false; } public void buildtree(ParseNode pn, Set toanalyze, String sourcefile) { parseFile(pn, toanalyze, sourcefile); - + // numering the interfaces int if_num = 0; Iterator it_classes = state.getClassSymbolTable().getValueSet().iterator(); @@ -30,25 +33,40 @@ public class BuildIR { } //This is all single imports and a subset of the - //multi imports that have been resolved. - Hashtable mandatoryImports; + //multi imports that have been resolved. + ChainHashMap mandatoryImports; //maps class names in file to full name - //Note may map a name to an ERROR. - Hashtable multiimports; - NameDescriptor packages; + //Note may map a name to an ERROR. + ChainHashMap multiimports; + String packageName; + + String currsourcefile; + Set analyzeset; + + void pushChainMaps() { + mandatoryImports=mandatoryImports.makeChild(); + multiimports=multiimports.makeChild(); + } + + void popChainMaps() { + mandatoryImports=mandatoryImports.getParent(); + multiimports=multiimports.getParent(); + } /** Parse the classes in this file */ public void parseFile(ParseNode pn, Set toanalyze, String sourcefile) { - mandatoryImports = new Hashtable(); - multiimports = new Hashtable(); - + mandatoryImports = new ChainHashMap(); + multiimports = new ChainHashMap(); + currsourcefile=sourcefile; + analyzeset=toanalyze; + if(state.JNI) { //add java.lang as our default multi-import this.addMultiImport(sourcefile, "java.lang", false); } - + ParseNode ipn = pn.getChild("imports").getChild("import_decls_list"); - if (ipn != null) { + if ((ipn != null) && !state.MGC) { ParseNodeVector pnv = ipn.getChildren(); for (int i = 0; i < pnv.size(); i++) { ParseNode pnimport = pnv.elementAt(i); @@ -59,26 +77,25 @@ public class BuildIR { mandatoryImports.put(nd.getIdentifier(), nd.getPathFromRootToHere()); } else { throw new Error("An ambiguous class "+ nd.getIdentifier() +" has been found. It is included for " + - ((String)mandatoryImports.get(nd.getIdentifier())) + " and " + - nd.getPathFromRootToHere()); + ((String)mandatoryImports.get(nd.getIdentifier())) + " and " + + nd.getPathFromRootToHere()); } - } - else { + } else { addMultiImport(sourcefile, nd.getPathFromRootToHere(), false); } } } - + ParseNode ppn=pn.getChild("packages").getChild("package"); - String packageName = null; - if (ppn!=null) { + packageName = null; + if ((ppn!=null) && !state.MGC){ NameDescriptor nd = parseClassName(ppn.getChild("name")); - packageName = nd.getPathFromRootToHere(); - //Trick -> import the package directory as a multi-import and it'll + packageName = nd.getPathFromRootToHere(); + //Trick -> import the package directory as a multi-import and it'll //automatically recognize files in the same directory. addMultiImport(sourcefile, packageName, true); } - + ParseNode tpn=pn.getChild("type_declaration_list"); if (tpn != null) { ParseNodeVector pnv = tpn.getChildren(); @@ -87,12 +104,9 @@ public class BuildIR { if (isEmpty(type_pn)) /* Skip the semicolon */ continue; if (isNode(type_pn, "class_declaration")) { - ClassDescriptor cn = parseTypeDecl(type_pn, packageName); - cn.setSourceFileName(sourcefile); + ClassDescriptor cn = parseTypeDecl(type_pn); parseInitializers(cn); - if (toanalyze != null) - toanalyze.add(cn); - state.addClass(cn); + // for inner classes/enum HashSet tovisit = new HashSet(); Iterator it_icds = cn.getInnerClasses(); @@ -104,36 +118,11 @@ public class BuildIR { ClassDescriptor cd = (ClassDescriptor) tovisit.iterator().next(); tovisit.remove(cd); parseInitializers(cd); - if (toanalyze != null) { - toanalyze.add(cd); - } - cd.setSourceFileName(sourcefile); - state.addClass(cd); Iterator it_ics = cd.getInnerClasses(); while (it_ics.hasNext()) { tovisit.add(it_ics.next()); } - - Iterator it_ienums = cd.getEnum(); - while (it_ienums.hasNext()) { - ClassDescriptor iecd = (ClassDescriptor) it_ienums.next(); - if (toanalyze != null) { - toanalyze.add(iecd); - } - iecd.setSourceFileName(sourcefile); - state.addClass(iecd); - } - } - - Iterator it_enums = cn.getEnum(); - while (it_enums.hasNext()) { - ClassDescriptor ecd = (ClassDescriptor) it_enums.next(); - if (toanalyze != null) { - toanalyze.add(ecd); - } - ecd.setSourceFileName(sourcefile); - state.addClass(ecd); } } else if (isNode(type_pn, "task_declaration")) { TaskDescriptor td = parseTaskDecl(type_pn); @@ -142,44 +131,21 @@ public class BuildIR { state.addTask(td); } else if (isNode(type_pn, "interface_declaration")) { // TODO add version for normal Java later - ClassDescriptor cn = parseInterfaceDecl(type_pn, packageName); - if (toanalyze != null) - toanalyze.add(cn); - cn.setSourceFileName(sourcefile); - state.addClass(cn); - - // for enum - Iterator it_enums = cn.getEnum(); - while (it_enums.hasNext()) { - ClassDescriptor ecd = (ClassDescriptor) it_enums.next(); - if (toanalyze != null) { - toanalyze.add(ecd); - } - ecd.setSourceFileName(sourcefile); - state.addClass(ecd); - } + ClassDescriptor cn = parseInterfaceDecl(type_pn, null); } else if (isNode(type_pn, "enum_declaration")) { // TODO add version for normal Java later ClassDescriptor cn = parseEnumDecl(null, type_pn); - if (toanalyze != null) - toanalyze.add(cn); - cn.setSourceFileName(sourcefile); - state.addClass(cn); - } else if(isNode(type_pn,"annotation_type_declaration")){ + + } else if(isNode(type_pn,"annotation_type_declaration")) { ClassDescriptor cn=parseAnnotationTypeDecl(type_pn); - if (toanalyze != null) - toanalyze.add(cn); - cn.setSourceFileName(sourcefile); - state.addClass(cn); } else { throw new Error(type_pn.getLabel()); } } } } - - - + + //This kind of breaks away from tradition a little bit by doing the file checks here // instead of in Semantic check, but doing it here is easier because we have a mapping early on // if I wait until semantic check, I have to change ALL the type descriptors to match the new @@ -197,7 +163,7 @@ public class BuildIR { String classname = file.substring(0, file.length() - 5); // single imports have precedence over multi-imports if (!mandatoryImports.containsKey(classname)) { - //package files have precedence over multi-imports. + //package files have precedence over multi-imports. if (multiimports.containsKey(classname) && !isPackageDirectory) { // put error in for later, in case we try to import multiimports.put(classname, new Error("Error: class " + classname + " is defined more than once in a multi-import in " + currentSource)); @@ -209,38 +175,48 @@ public class BuildIR { } } } - - + if(!found) { throw new Error("Import package " + importPath + " in " + currentSource - + " cannot be resolved."); + + " cannot be resolved."); } } - public void parseInitializers(ClassDescriptor cn){ + public void parseInitializers(ClassDescriptor cn) { Vector fv=cn.getFieldVec(); int pos = 0; - for(int i=0;i locOrder = - new Lattice("_top_","_bottom_"); - Set spinLocSet=new HashSet(); - for (int i = 0; i < pnv.size(); i++) { - ParseNode loc = pnv.elementAt(i); - if(isNode(loc,"location_property")){ - String spinLoc=loc.getChildren().elementAt(0).getLabel(); - spinLocSet.add(spinLoc); - } else { - String lowerLoc=loc.getChildren().elementAt(0).getLabel(); - String higherLoc= loc.getChildren().elementAt(1).getLabel(); - locOrder.put(higherLoc, lowerLoc); - if (locOrder.isIntroducingCycle(higherLoc)) { - throw new Error("Error: the order relation " + lowerLoc + " < " + higherLoc - + " introduces a cycle."); - } - } - } - if(spinLocSet.size()>0){ - //checking if location is actually defined in the hierarchy - for (Iterator iterator = spinLocSet.iterator(); iterator.hasNext();) { - String locID = (String) iterator.next(); - if(!locOrder.containsKey(locID)){ - throw new Error("Error: The spinning location '"+ - locID + "' is not defined in the hierarchy of the class '"+cd +"'."); - } + ParseNode decl=pnv.elementAt(i); + if (isNode(decl,"member")) { + parseClassMember(cn,decl); + } else if (isNode(decl,"constructor")) { + parseConstructorDecl(cn,decl.getChild("constructor_declaration")); + } else if (isNode(decl, "static_block")) { + parseStaticBlockDecl(cn, decl.getChild("static_block_declaration")); + } else if (isNode(decl,"block")) { + } else throw new Error(); } - state.addLocationPropertySet(cd, spinLocSet); } - state.addLocationOrder(cd, locOrder); } - + private void parseClassMember(ClassDescriptor cn, ParseNode pn) { ParseNode fieldnode=pn.getChild("field"); if (fieldnode!=null) { + //System.out.println( pn.PPrint( 0, true ) ); parseFieldDecl(cn,fieldnode.getChild("field_declaration")); return; } @@ -678,9 +731,15 @@ public class BuildIR { parseInnerClassDecl(cn,innerclassnode); return; } + ParseNode innerinterfacenode=pn.getChild("interface_declaration"); + if (innerinterfacenode!=null) { + parseInterfaceDecl(innerinterfacenode, cn); + return; + } + ParseNode enumnode=pn.getChild("enum_declaration"); if (enumnode!=null) { - parseEnumDecl(cn,enumnode); + ClassDescriptor ecn=parseEnumDecl(cn,enumnode); return; } ParseNode flagnode=pn.getChild("flag"); @@ -693,24 +752,36 @@ public class BuildIR { if(emptynode != null) { return; } + System.out.println("Unrecognized node:"+pn.PPrint(2,true)); throw new Error(); } - + +//10/9/2011 changed this function to enable creation of default constructor for inner classes. +//the change was refactoring this function with the corresponding version for normal classes. sganapat private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) { - ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false); - icn.setImports(mandatoryImports); - icn.setAsInnerClass(); + String basename=pn.getChild("name").getTerminal(); + String classname=cn.getClassName()+"$"+basename; + + if (cn.getPackage()==null) + cn.getSingleImportMappings().put(basename,classname); + else + cn.getSingleImportMappings().put(basename,cn.getPackage()+"."+classname); + + ClassDescriptor icn=new ClassDescriptor(cn.getPackage(), classname, false); + pushChainMaps(); + icn.setImports(mandatoryImports, multiimports); icn.setSurroundingClass(cn.getSymbol()); icn.setSurrounding(cn); cn.addInnerClass(icn); - if (!isEmpty(pn.getChild("super").getTerminal())) { + + if (!isEmpty(pn.getChild("super").getTerminal())) { /* parse superclass name */ ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name"); NameDescriptor nd=parseClassName(snn); icn.setSuper(nd.toString()); } else { if (!(icn.getSymbol().equals(TypeUtil.ObjectClass)|| - icn.getSymbol().equals(TypeUtil.TagClass))) + icn.getSymbol().equals(TypeUtil.TagClass))) icn.setSuper(TypeUtil.ObjectClass); } // check inherited interfaces @@ -727,11 +798,34 @@ public class BuildIR { } } icn.setModifiers(parseModifiersList(pn.getChild("modifiers"))); - if(!icn.isStatic()) { - throw new Error("Error: inner class " + icn.getSymbol() + " in Class " + - cn.getSymbol() + " is not a nested class and is not supported yet!"); - } + + if (!icn.isStatic()) + icn.setAsInnerClass(); + parseClassBody(icn, pn.getChild("classbody")); + + boolean hasConstructor = false; + for(Iterator method_it=icn.getMethods(); method_it.hasNext(); ) { + MethodDescriptor md=(MethodDescriptor)method_it.next(); + hasConstructor |= md.isConstructor(); + } +//sganapat adding change to allow proper construction of inner class objects + if((!hasConstructor) && (!icn.isEnum())) { + // add a default constructor for this class + MethodDescriptor md = new MethodDescriptor(new Modifiers(Modifiers.PUBLIC), + icn.getSymbol(), false); + BlockNode bn=new BlockNode(); + state.addTreeCode(md,bn); + md.setDefaultConstructor(); + icn.addMethod(md); + } + popChainMaps(); + + if (analyzeset != null) + analyzeset.add(icn); + icn.setSourceFileName(currsourcefile); + state.addClass(icn); + return icn; } @@ -762,7 +856,7 @@ public class BuildIR { TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype")); Integer numdims=(Integer)nn.getChild("dims").getLiteral(); for(int i=0; i annotations=modifiers.getAnnotations(); for(int i=0; i