//This is all single imports and a subset of the
//multi imports that have been resolved.
- Hashtable mandatoryImports;
+ ChainHashMap mandatoryImports;
//maps class names in file to full name
//Note may map a name to an ERROR.
- Hashtable multiimports;
- NameDescriptor packages;
+ 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
}
ParseNode ppn=pn.getChild("packages").getChild("package");
- String packageName = null;
+ packageName = null;
if ((ppn!=null) && !state.MGC){
NameDescriptor nd = parseClassName(ppn.getChild("name"));
packageName = nd.getPathFromRootToHere();
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();
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);
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")) {
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
}
}
-
if(!found) {
throw new Error("Import package " + importPath + " in " + currentSource
+ " cannot be resolved.");
}
}
}
+
+ private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
+ String basename=pn.getChild("name").getTerminal();
+ String classname=(cn!=null)?cn.getClassName()+"$"+basename:basename;
+ ClassDescriptor ecd=new ClassDescriptor(cn!=null?cn.getPackage():null, classname, false);
+
+ if (cn!=null) {
+ if (packageName==null)
+ cn.getSingleImportMappings().put(basename,classname);
+ else
+ cn.getSingleImportMappings().put(basename,packageName+"."+classname);
+ }
- private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
- ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+ pushChainMaps();
ecd.setImports(mandatoryImports, multiimports);
ecd.setAsEnum();
if(cn != null) {
}
ecd.setModifiers(parseModifiersList(pn.getChild("modifiers")));
parseEnumBody(ecd, pn.getChild("enumbody"));
+
+ if (analyzeset != null)
+ analyzeset.add(ecd);
+ ecd.setSourceFileName(currsourcefile);
+ state.addClass(ecd);
+
+ popChainMaps();
return ecd;
}
private ClassDescriptor parseAnnotationTypeDecl(ParseNode pn) {
ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
+ pushChainMaps();
cn.setImports(mandatoryImports, multiimports);
ParseNode modifiers=pn.getChild("modifiers");
if(modifiers!=null) {
cn.setModifiers(parseModifiersList(modifiers));
}
parseAnnotationTypeBody(cn,pn.getChild("body"));
+ popChainMaps();
+
+ if (analyzeset != null)
+ analyzeset.add(cn);
+ cn.setSourceFileName(currsourcefile);
+ state.addClass(cn);
+
return cn;
}
}
}
- public ClassDescriptor parseInterfaceDecl(ParseNode pn, String packageName) {
- ClassDescriptor cn;
- if(packageName == null) {
- cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
- } else {
- String newClassname = packageName + "." + pn.getChild("name").getTerminal();
- cn= new ClassDescriptor(packageName, newClassname, true);
+ public ClassDescriptor parseInterfaceDecl(ParseNode pn, ClassDescriptor outerclass) {
+ String basename=pn.getChild("name").getTerminal();
+ String classname=((outerclass==null)?"":(outerclass.getClassName()+"$"))+basename;
+ if (outerclass!=null) {
+ if (packageName==null)
+ outerclass.getSingleImportMappings().put(basename,classname);
+ else
+ outerclass.getSingleImportMappings().put(basename,packageName+"."+classname);
}
+ ClassDescriptor cn= new ClassDescriptor(packageName, classname, true);
+ pushChainMaps();
cn.setImports(mandatoryImports, multiimports);
//cn.setAsInterface();
if (!isEmpty(pn.getChild("superIF").getTerminal())) {
if (isNode(decl,"type")) {
NameDescriptor nd=parseClassName(decl.getChild("class").getChild("name"));
cn.addSuperInterface(nd.toString());
- }
+ } else if (isNode(decl, "interface_declaration")) {
+ ClassDescriptor innercn = parseInterfaceDecl(decl, cn);
+ } else throw new Error();
}
}
cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
parseInterfaceBody(cn, pn.getChild("interfacebody"));
+ if (analyzeset != null)
+ analyzeset.add(cn);
+ cn.setSourceFileName(currsourcefile);
+ state.addClass(cn);
+ popChainMaps();
return cn;
}
parseInterfaceConstant(cn,decl);
} else if (isNode(decl,"method")) {
parseInterfaceMethod(cn,decl.getChild("method_declaration"));
- } else throw new Error();
+ } else if (isNode(decl, "interface_declaration")) {
+ parseInterfaceDecl(decl, cn);
+ } else throw new Error(decl.PPrint(2, true));
}
}
}
BlockNode bn=parseBlock(bodyn);
cn.addMethod(md);
state.addTreeCode(md,bn);
-
- // this is a hack for investigating new language features
- // at the AST level, someday should evolve into a nice compiler
- // option *wink*
- //if( cn.getSymbol().equals( ***put a class in here like: "Test" ) &&
- // md.getSymbol().equals( ***put your method in here like: "main" )
- //) {
- // bn.setStyle( BlockNode.NORMAL );
- // System.out.println( bn.printNode( 0 ) );
- //}
-
} catch (Exception e) {
System.out.println("Error with method:"+md.getSymbol());
e.printStackTrace();
return tel;
}
- public ClassDescriptor parseTypeDecl(ParseNode pn, String packageName) {
- ClassDescriptor cn;
- // if is in no package, then create a class descriptor with just the name.
- // else add the package on
- if(packageName == null) {
- cn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
- } else {
- String newClassname = packageName + "." + pn.getChild("name").getTerminal();
- cn= new ClassDescriptor(packageName, newClassname, false);
- }
+ public ClassDescriptor parseTypeDecl(ParseNode pn) {
+ ClassDescriptor cn=new ClassDescriptor(packageName, pn.getChild("name").getTerminal(), false);
+ pushChainMaps();
cn.setImports(mandatoryImports, multiimports);
if (!isEmpty(pn.getChild("super").getTerminal())) {
/* parse superclass name */
md.setDefaultConstructor();
cn.addMethod(md);
}
+ popChainMaps();
+
+ cn.setSourceFileName(currsourcefile);
+ if (analyzeset != null)
+ analyzeset.add(cn);
+ state.addClass(cn);
+
return cn;
}
parseInnerClassDecl(cn,innerclassnode);
return;
}
+
+ ParseNode innerinterfacenode=pn.getChild("interface_declaration");
+ if (innerinterfacenode!=null) {
+ parseInterfaceDecl(innerinterfacenode, cn);
+ }
+
ParseNode enumnode=pn.getChild("enum_declaration");
if (enumnode!=null) {
- parseEnumDecl(cn,enumnode);
+ ClassDescriptor ecn=parseEnumDecl(cn,enumnode);
return;
}
ParseNode flagnode=pn.getChild("flag");
}
private ClassDescriptor parseInnerClassDecl(ClassDescriptor cn, ParseNode pn) {
- ClassDescriptor icn=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+ 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.setAsInnerClass();
icn.setSurroundingClass(cn.getSymbol());
}
}
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!");
- }
+
parseClassBody(icn, pn.getChild("classbody"));
+ popChainMaps();
+ if (analyzeset != null)
+ analyzeset.add(icn);
+ icn.setSourceFileName(currsourcefile);
+ state.addClass(icn);
+
return icn;
}
//TODO::: FIX BUG!!! static fields in caller context need to become parameters
TypeDescriptor td=parseTypeDescriptor(pn);
innerCount++;
- ClassDescriptor cnnew=new ClassDescriptor(td.getSymbol()+"$"+innerCount, false);
+ ClassDescriptor cnnew=new ClassDescriptor(packageName,td.getSymbol()+"$"+innerCount, false);
+ pushChainMaps();
cnnew.setImports(mandatoryImports, multiimports);
cnnew.setSuper(td.getSymbol());
parseClassBody(cnnew, pn.getChild("decl").getChild("classbody"));
for(int i=0; i<args.size(); i++) {
con.addArgument((ExpressionNode)args.get(i));
}
+ popChainMaps();
+
+ if (analyzeset != null)
+ analyzeset.add(cnnew);
+ cnnew.setSourceFileName(currsourcefile);
+ state.addClass(cnnew);
return con;
} else if (isNode(pn,"createarray")) {
NameNode nn=new NameNode(nd);
nn.setNumLine(pn.getLine());
return nn;
+ } else if (isNode(pn,"parentclass")) {
+ NameDescriptor nd=new NameDescriptor("this");
+ NameNode nn=new NameNode(nd);
+ nn.setNumLine(pn.getLine());
+
+ FieldAccessNode fan=new FieldAccessNode(nn,"this$parent");
+ fan.setNumLine(pn.getLine());
+ return fan;
} else if (isNode(pn,"isavailable")) {
NameDescriptor nd=new NameDescriptor(pn.getTerminal());
NameNode nn=new NameNode(nd);