Exemplo n.º 1
0
        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);
        }