// for interfaces
Vector<String> 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);
this.packagename=packagename;
superinterfaces = new Vector<String>();
superIFdesc = new SymbolTable();
+ this.innerdescs = new SymbolTable();
}
public int getId() {
}
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();
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;
+ }
+ }*/
}
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)
private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
ParseNode fieldnode=pn.getChild("field");
-
if (fieldnode!=null) {
parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
return;
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"));
}
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<pnv.size(); i++) {
+ ParseNode decl=pnv.elementAt(i);
+ if (isNode(decl,"type")) {
+ NameDescriptor nd=parseName(decl.getChild("class").getChild("name"));
+ icn.addSuperInterface(nd.toString());
+ }
+ }
+ }
+ 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"));
+ return icn;
+ }
private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
ParseNode tn=pn.getChild("type");
RESULT=(new ParseNode("method")).addChild(method).getRoot();
:}
/* repeat the prod for 'class_declaration' here: */
-// | modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so interfaces_opt:ifo class_body:body
-// {:
-// ParseNode pn=new ParseNode("inner_class_declaration");
-// pn.addChild("modifiers").addChild(mo);
-// pn.addChild("name").addChild(id);
-// pn.addChild("super").addChild(so);
-// pn.addChild("superIF").addChild(ifo);
-// pn.addChild("classbody").addChild(body);
-// RESULT=pn;
-// :}
- | interface_declaration:interfaced {:
- RESULT=(new ParseNode("interface")).addChild(interfaced).getRoot();
+ | modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so interfaces_opt:ifo class_body:body
+ {:
+ ParseNode pn=new ParseNode("inner_class_declaration");
+ pn.addChild("modifiers").addChild(mo);
+ pn.addChild("name").addChild(id);
+ pn.addChild("super").addChild(so);
+ pn.addChild("superIF").addChild(ifo);
+ pn.addChild("classbody").addChild(body);
+ RESULT=pn;
:}
+// | interface_declaration:interfaced {:
+// RESULT=(new ParseNode("interface")).addChild(interfaced).getRoot();
+// :}
| SEMICOLON {: RESULT=new ParseNode("empty"); :}
;