Пример #1
0
		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);
		}
Пример #2
0
		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;
				}
			}
		}