public void Generate(string dest) { if (dest == null) { throw new ArgumentNullException(nameof(dest)); } Directory.CreateDirectory(dest); foreach (var eocObjectClass in EocObjectClasses) { eocObjectClass.ParseCode(); eocObjectClass.Optimize(); } foreach (var eocStaticClass in EocStaticClasses) { eocStaticClass.ParseCode(); eocStaticClass.Optimize(); } //分析依赖图 Array.ForEach(EocConstants, x => x.AnalyzeDependencies(DependencyGraph)); Array.ForEach(EocStructs, x => x.AnalyzeDependencies(DependencyGraph)); Array.ForEach(EocGlobalVariables, x => x.AnalyzeDependencies(DependencyGraph)); Array.ForEach(EocDllDeclares, x => x.AnalyzeDependencies(DependencyGraph)); Array.ForEach(EocObjectClasses, x => x.AnalyzeDependencies(DependencyGraph)); Array.ForEach(EocStaticClasses, x => x.AnalyzeDependencies(DependencyGraph)); if (Source.InitEcSectionInfo != null) { DependencyGraph.AddVerticesAndEdgeRange(Source.InitEcSectionInfo.InitMethod.Select(x => new Edge <string>("[Root]", GetCppMethodName(x)))); } if (Source.Code.MainMethod != 0) { DependencyGraph.AddVerticesAndEdge(new Edge <string>("[Root]", GetCppMethodName(Source.Code.MainMethod))); } else { DependencyGraph.AddVerticesAndEdge(new Edge <string>("[Root]", "e::user::cmd::_启动子程序")); } //生成依赖列表 this.Dependencies = new HashSet <string>(); GraphUtils.AnalyzeDependencies(DependencyGraph, "[Root]", this.Dependencies); //删除未使用代码 EocConstants = EocConstants.Where(x => Dependencies.Contains(x.RefId)).ToArray(); EocStructs = EocStructs.Where(x => Dependencies.Contains(x.RefId)).ToArray(); EocGlobalVariables = EocGlobalVariables.Where(x => Dependencies.Contains(x.RefId)).ToArray(); EocDllDeclares = EocDllDeclares.Where(x => Dependencies.Contains(x.RefId)).ToArray(); EocObjectClasses = EocObjectClasses.Where(x => Dependencies.Contains(x.RefId)).ToArray(); Array.ForEach(EocObjectClasses, x => x.RemoveUnusedCode(Dependencies)); Array.ForEach(EocStaticClasses, x => x.RemoveUnusedCode(Dependencies)); EocStaticClasses = EocStaticClasses.Where(x => x.Method.Count != 0).ToArray(); //依赖信息 File.WriteAllText(Path.Combine(dest, "Dependencies.txt"), string.Join("\r\n", this.Dependencies), Encoding.UTF8); File.WriteAllBytes(Path.Combine(dest, "DependencyGraph.gv"), Encoding.UTF8.GetBytes(GraphUtils.WriteGraphvizScript(DependencyGraph, "DependencyGraph"))); string fileName; //常量 fileName = GetFileNameByNamespace(dest, ConstantNamespace, "h"); using (var writer = new CodeWriter(fileName)) EocConstant.Define(this, writer, EocConstants); //声明自定义数据类型(结构/对象类) fileName = GetFileNameByNamespace(dest, TypeNamespace, "h"); using (var writer = new CodeWriter(fileName)) { DefineAllTypes(writer); } //实现 对象类 foreach (var item in EocObjectClasses) { fileName = GetFileNameByNamespace(dest, item.CppName, "cpp"); using (var writer = new CodeWriter(fileName)) item.ImplementRawObjectClass(writer); } //静态类 foreach (var item in EocStaticClasses) { fileName = GetFileNameByNamespace(dest, item.CppName, "h"); using (var writer = new CodeWriter(fileName)) item.Define(writer); fileName = GetFileNameByNamespace(dest, item.CppName, "cpp"); using (var writer = new CodeWriter(fileName)) item.Implement(writer); } //全局变量 fileName = GetFileNameByNamespace(dest, GlobalNamespace, "h"); using (var writer = new CodeWriter(fileName)) EocGlobalVariable.Define(this, writer, EocGlobalVariables); fileName = GetFileNameByNamespace(dest, GlobalNamespace, "cpp"); using (var writer = new CodeWriter(fileName)) EocGlobalVariable.Implement(this, writer, EocGlobalVariables); //DLL fileName = GetFileNameByNamespace(dest, DllNamespace, "h"); using (var writer = new CodeWriter(fileName)) EocDll.Define(this, writer, EocDllDeclares); fileName = GetFileNameByNamespace(dest, DllNamespace, "cpp"); using (var writer = new CodeWriter(fileName)) EocDll.Implement(this, writer, EocDllDeclares); //预编译头 fileName = GetFileNameByNamespace(dest, "stdafx", "h"); using (var writer = new CodeWriter(fileName)) MakeStandardHeader(writer); //程序入口 fileName = GetFileNameByNamespace(dest, "entry", "cpp"); using (var writer = new CodeWriter(fileName)) MakeProgramEntry(writer); //CMake项目配置文件 fileName = Path.Combine(dest, "CMakeLists.txt"); using (var writer = new StreamWriter(File.Create(fileName), Encoding.Default)) MakeCMakeLists(writer); //VSCode配置文件 fileName = Path.Combine(dest, ".vscode", "settings.json"); Directory.CreateDirectory(Path.GetDirectoryName(fileName)); using (var writer = new StreamWriter(File.Create(fileName), Encoding.Default)) MakeVSCodeSettings(writer); }