public void Visit(AST ast) { StatementList originalInterfaceDeclarations = new StatementList(); StatementList originalClassDeclarations = new StatementList(); StatementList reorderedInterfaceDeclarations = new StatementList(); StatementList reorderedClassDeclarations = new StatementList(); // move interface declarations from ast.StmtList to originalInterfaceDeclarations for (int i = 0; i < ast.StmtList.Count(); i++) { Statement stmt = ast.StmtList.Get(i); if (stmt is INTERFACE_DECLARATION) { ast.StmtList.Remove(stmt); i--; originalInterfaceDeclarations.Add(stmt); } } // move class declarations from ast.StmtList to originalClassDeclarations for (int i = 0; i < ast.StmtList.Count(); i++) { Statement stmt = ast.StmtList.Get(i); if (stmt is CLASS_DECLARATION) { ast.StmtList.Remove(stmt); i--; originalClassDeclarations.Add(stmt); } } // reorder interface declarations ArrayList parentsAvailable = new ArrayList(); ArrayList newParents = new ArrayList(); // start with interfaces with no parents specified and wich have an external type as parent for (int i = 0; i < originalInterfaceDeclarations.Count(); i++) { INTERFACE_DECLARATION id = (INTERFACE_DECLARATION)originalInterfaceDeclarations.Get(i); // no parents specified if (id.Extends == null) { originalInterfaceDeclarations.Remove(id); i--; reorderedInterfaceDeclarations.Add(id); newParents.Add(id.Name); } // external parents specified else { bool onlyExternalParents = true; foreach (string type in id.Extends) { Type t = mPHPRuntime.GetType(type); if (t == null) { onlyExternalParents = false; break; } } if (onlyExternalParents) { originalInterfaceDeclarations.Remove(id); i--; reorderedInterfaceDeclarations.Add(id); newParents.Add(id.Name); } } } parentsAvailable.AddRange(newParents); while (originalInterfaceDeclarations.Count() > 0) { // in each iteration, add those interface delcarations which inherit from interfaces processed in a previous iteration newParents = new ArrayList(); for (int i = 0; i < originalInterfaceDeclarations.Count(); i++) { INTERFACE_DECLARATION id = (INTERFACE_DECLARATION)originalInterfaceDeclarations.Get(i); bool containsAll = true; foreach (string s in id.Extends) if (!parentsAvailable.Contains(s)) { containsAll = false; break; } if (containsAll) { originalInterfaceDeclarations.Remove(id); i--; reorderedInterfaceDeclarations.Add(id); newParents.Add(id.Name); } } // if there are still classes left, but no new parents were added, a parent wasn't declared or there is a cycle in inheritance if (originalInterfaceDeclarations.Count() > 0 && newParents.Count == 0) Report.Error(100); parentsAvailable.AddRange(newParents); } // reorder class declarations parentsAvailable = new ArrayList(); newParents = new ArrayList(); // start with classes with no parent specified and wich have an external type as parent for (int i = 0; i < originalClassDeclarations.Count(); i++) { CLASS_DECLARATION cd = (CLASS_DECLARATION)originalClassDeclarations.Get(i); // no parent specified if (cd.Extends == null) { originalClassDeclarations.Remove(cd); i--; reorderedClassDeclarations.Add(cd); newParents.Add(cd.Name); } // external parent specified else { Type t = mPHPRuntime.GetType(cd.Extends); if (t != null) { originalClassDeclarations.Remove(cd); i--; reorderedClassDeclarations.Add(cd); newParents.Add(cd.Name); } } } parentsAvailable.AddRange(newParents); while (originalClassDeclarations.Count() > 0) { // in each iteration, add those class delcarations which inherit from classes processed in a previous iteration newParents = new ArrayList(); for (int i = 0; i < originalClassDeclarations.Count(); i++) { CLASS_DECLARATION cd = (CLASS_DECLARATION)originalClassDeclarations.Get(i); if (parentsAvailable.Contains(cd.Extends)) { originalClassDeclarations.Remove(cd); i--; reorderedClassDeclarations.Add(cd); newParents.Add(cd.Name); } } // if there are still classes left, but no new parents were added, a parent wasn't declared or there is a cycle in inheritance if (originalClassDeclarations.Count() > 0 && newParents.Count == 0) Report.Error(100); parentsAvailable.AddRange(newParents); } // add reordered interface and class declarations to ast.StmtList ast.StmtList.AddRange(reorderedInterfaceDeclarations); ast.StmtList.AddRange(reorderedClassDeclarations); }
protected void Visit(ASTNode node) { if (node == null) return; else if (node is CLASS_DECLARATION) { CLASS_DECLARATION cd = (CLASS_DECLARATION)node; foreach (Statement stmt in cd.StmtList) Visit(stmt); } else if (node is FUNCTION_DECLARATION) { FUNCTION_DECLARATION fd = (FUNCTION_DECLARATION)node; bool returnReached = false; StatementList newStmtList = new StatementList(); // copy each statement to newStmtList until top return is reached if (fd.StmtList != null) { foreach (Statement stmt in fd.StmtList) { if (stmt is RETURN) { newStmtList.Add(stmt); returnReached = true; break; } else newStmtList.Add(stmt); } // if there was no return statement, add one if (!returnReached) newStmtList.Add(new RETURN(null, 0, 0)); // replace statement list of function with new one fd.StmtList = newStmtList; } } }