public int Run() { var source = new EProjectFile.EProjectFile(); var logger = new StreamLoggerWithContext(Console.Out, Console.Error, Debug); source.Load(File.OpenRead(Input)); if (!Force && source.ESystemInfo.FileType != 3) { throw new Exception("源文件应为ECom(*.ec)文件"); } new ProjectConverter(source, Type, default, logger).Generate(Output);
private void ConvertButton_Click(object sender, EventArgs e) { var logWriter = new StringWriter(); var logger = new StreamLoggerWithContext(logWriter, logWriter, false); try { if (!EocEnv.IsValid) { logger.Error("环境变量EOC_HOME未正确配置"); return; } var srcFile = textBox1.Text; var destFile = textBox2.Text; var source = new EProjectFile.EProjectFile(); source.Load(File.OpenRead(srcFile)); ProjectConverter.EocProjectType projectType; switch (comboBox1.SelectedIndex) { case 0: projectType = ProjectConverter.EocProjectType.Windows; break; case 1: projectType = ProjectConverter.EocProjectType.Console; break; case 2: projectType = ProjectConverter.EocProjectType.Dll; break; default: throw new Exception("请选择正确的项目类型"); } if (source.ESystemInfo.FileType != 3 && !checkBox1.Checked) { throw new Exception("源文件应为ECom(*.ec)文件"); } new ProjectConverter(source, projectType, null, logger).Generate(destFile); logger.Info("操作完成"); } catch (Exception exception) { logger.Error("处理程序不正常退出,异常信息:{0}", exception); } finally { MessageBox.Show(logWriter.ToString(), "Log"); } }
private async Task<bool> ExecuteJob(StepwiseLog log) { var eocLogWriter = new StringWriter(); var eocLogger = new StreamLoggerWithContext(eocLogWriter, eocLogWriter, false); var step = new SpecificStepLog() { Description = "转换为C++/CMake工程", }; log.Steps.Add(step); try { if (!EocEnv.IsValid) { eocLogger.Error("环境变量EOC_HOME未正确配置"); step.State = StepState.Failed; } var source = new EProjectFile.EProjectFile(); source.Load(File.OpenRead(ViewModel.SourcePath)); if (source.ESystemInfo.FileType != 3 && !ViewModel.Force) { eocLogger.Error("源文件应为ECom(*.ec)文件"); step.State = StepState.Failed; } else { await Task.Run(() => { new ProjectConverter(source, ViewModel.ProjectType, null, eocLogger).Generate(ViewModel.OutputPath); eocLogger.Info("完成"); }); } } catch (Exception exception) { eocLogger.Error("处理程序不正常退出,异常信息:{0}", exception); step.State = StepState.Failed; } step.Content = new TextBlock() { TextWrapping = TextWrapping.Wrap, Text = eocLogWriter.ToString() }; if (step.State == StepState.Failed) { return false; } step.State = StepState.Success; if (!ViewModel.Build) { return false; } step = new SpecificStepLog() { Description = "初始化CMake环境", }; log.Steps.Add(step); if (CMakeEnv.DefaultInstance == null) { step.State = StepState.Failed; step.Content = new TextBlock() { TextWrapping = TextWrapping.Wrap, Text = "Error: 未找到CMake编译环境" }; return false; } if (ViewModel.CMakeKit == null || ViewModel.ProjectConfig == null) { step.State = StepState.Failed; step.Content = new TextBlock() { TextWrapping = TextWrapping.Wrap, Text = "Error: 工具链参数不完整" }; return false; } step.Content = new TextBlock() { TextWrapping = TextWrapping.Wrap, Text = $"CMake Detected: {CMakeEnv.DefaultInstance.CMakeBin}" }; CMakeKit cmakeKit; try { cmakeKit = new CMakeKit(ViewModel.CMakeKit); } catch (Exception) { step.State = StepState.Failed; step.Content = new TextBlock() { TextWrapping = TextWrapping.Wrap, Text = $"Error: 初始化工具链 (${ViewModel.CMakeKit?.Name}) 失败" }; return false; } step.State = StepState.Success; var success = await RunProcessAsync(log, "配置CMake工程", startInfoHelper => cmakeKit.StartConfigure( CMakeEnv.DefaultInstance, ViewModel.OutputPath, ViewModel.BuildPath, new Dictionary<string, CMakeSetting>() { {"CMAKE_BUILD_TYPE", new CMakeSetting(ViewModel.ProjectConfig, "STRING") } }, startInfoHelper)); if (!success) { return false; } success = await RunProcessAsync(log, "编译CMake工程", startInfoHelper => cmakeKit.StartBuild( CMakeEnv.DefaultInstance, ViewModel.BuildPath, new CMakeBuildConfig() { Config = ViewModel.ProjectConfig }, startInfoHelper)); if (!success) { return false; } return true; }
public static void Convert(EProjectFile.EProjectFile source, string dest, EocProjectType projectType = EocProjectType.Console, string projectNamespace = "e::user") { new ProjectConverter(source, projectType, projectNamespace).Generate(dest); }
public ProjectConverter(EProjectFile.EProjectFile source, EocProjectType projectType = EocProjectType.Console, string projectNamespace = "e::user", ILoggerWithContext logger = null) { this.Logger = logger ?? new NullLoggerWithContext(); if (source == null) { throw new ArgumentNullException(nameof(source)); } this.IdToNameMap = new IdToNameMap(source.Code, source.Resource, source.LosableSection); this.ClassIdMap = source.Code.Classes.ToDictionary(x => x.Id); this.MethodIdMap = source.Code.Methods.ToDictionary(x => x.Id); this.DllIdMap = source.Code.DllDeclares.ToDictionary(x => x.Id); this.StructIdMap = source.Code.Structs.ToDictionary(x => x.Id); this.GlobalVarIdMap = source.Code.GlobalVariables.ToDictionary(x => x.Id); this.ConstantIdMap = source.Resource.Constants.ToDictionary(x => x.Id); this.ClassVarIdMap = new Dictionary <int, ClassVariableInfo>(); this.MethodIdToClassMap = new Dictionary <int, ClassInfo>(); foreach (var item in source.Code.Classes) { Array.ForEach(item.Method, x => MethodIdToClassMap.Add(x, item)); Array.ForEach(item.Variables, x => ClassVarIdMap.Add(x.Id, x)); } projectNamespace = projectNamespace ?? "e::user"; this.ProjectNamespace = projectNamespace; this.TypeNamespace = projectNamespace + "::type"; this.CmdNamespace = projectNamespace + "::cmd"; this.DllNamespace = projectNamespace + "::dll"; this.ConstantNamespace = projectNamespace + "::constant"; this.GlobalNamespace = projectNamespace + "::global"; this.Source = source; this.Libs = source.Code.Libraries.Select( x => { try { return(LibInfo.Load(x)); } catch (Exception ex) { Logger.Warn("加载fne信息失败,请检查易语言环境,支持库:{0},异常信息:{1}", x.Name, ex); return(null); } }).ToArray(); this.EocLibs = source.Code.Libraries.Select( x => { try { return(EocLibInfo.Load(x)); } catch (Exception ex) { Logger.Warn("加载eoc库信息失败,请检查eoc环境,支持库:{0},异常信息:{1}", x.Name, ex); return(null); } }).ToArray(); this.EocHelperLibId = Array.FindIndex(source.Code.Libraries, x => x.FileName.ToLower() == "EocHelper".ToLower()); this.DataTypeId_IntPtr = this.EocHelperLibId == -1 ? -1 : EplSystemId.MakeLibDataTypeId((short)this.EocHelperLibId, 0); this.ProjectType = projectType; this.EocConstants = EocConstant.Translate(this, Source.Resource.Constants); this.EocStructs = EocStruct.Translate(this, Source.Code.Structs); this.EocGlobalVariables = EocGlobalVariable.Translate(this, Source.Code.GlobalVariables); this.EocDllDeclares = EocDll.Translate(this, Source.Code.DllDeclares); this.EocObjectClasses = EocObjectClass.Translate(this, Source.Code.Classes.Where(x => EplSystemId.GetType(x.Id) == EplSystemId.Type_Class)); this.EocStaticClasses = EocStaticClass.Translate(this, Source.Code.Classes.Where(x => EplSystemId.GetType(x.Id) != EplSystemId.Type_Class)); }
public ProjectConverter(EProjectFile.EProjectFile source, EocProjectType projectType = EocProjectType.Console, string projectNamespace = "e::user", ILoggerWithContext logger = null) { this.Logger = logger ?? new NullLoggerWithContext(); if (source == null) { throw new ArgumentNullException(nameof(source)); } this.IdToNameMap = new IdToNameMap(source.Code, source.Resource, source.LosableSection); this.MethodIdMap = source.Code.Methods.ToDictionary(x => x.Id); this.MethodIdToClassMap = new Dictionary <int, ClassInfo>(); foreach (var item in source.Code.Classes) { Array.ForEach(item.Method, x => MethodIdToClassMap.Add(x, item)); } projectNamespace = projectNamespace ?? "e::user"; this.ProjectNamespace = projectNamespace; this.TypeNamespace = projectNamespace + "::type"; this.CmdNamespace = projectNamespace + "::cmd"; this.DllNamespace = projectNamespace + "::dll"; this.ConstantNamespace = projectNamespace + "::constant"; this.GlobalNamespace = projectNamespace + "::global"; this.Source = source; this.Libs = source.Code.Libraries.Select( x => { try { return(LibInfo.Load(x)); } catch (Exception ex) { Logger.Warn("加载fne信息失败,请检查易语言环境,支持库:{0},异常信息:{1}", x.Name, ex); return(null); } }).ToArray(); this.EocLibs = source.Code.Libraries.Select( x => { try { return(EocLibInfo.Load(x)); } catch (Exception ex) { Logger.Warn("加载eoc库信息失败,请检查eoc环境,支持库:{0},异常信息:{1}", x.Name, ex); return(null); } }).ToArray(); LibCmdToDeclaringTypeMap = Libs.Select(lib => { var r = new Dictionary <int, int>(); for (int i = 0; i < lib?.DataType?.Length; i++) { if (lib.DataType[i].Method != null) { Array.ForEach(lib.DataType[i].Method, x => r[x] = i); } } return(r); }).ToList().AsReadOnly(); this.EocHelperLibId = Array.FindIndex(source.Code.Libraries, x => x.FileName.ToLower() == "EocHelper".ToLower()); this.DataTypeId_IntPtr = this.EocHelperLibId == -1 ? -1 : EplSystemId.MakeLibDataTypeId((short)this.EocHelperLibId, 0); this.ProjectType = projectType; this.EocConstantMap = EocConstant.Translate(this, Source.Resource.Constants); this.EocStructMap = EocStruct.Translate(this, Source.Code.Structs); this.EocGlobalVariableMap = EocGlobalVariable.Translate(this, Source.Code.GlobalVariables); this.EocDllDeclareMap = EocDll.Translate(this, Source.Code.DllDeclares); this.EocObjectClassMap = EocObjectClass.Translate(this, Source.Code.Classes.Where(x => EplSystemId.GetType(x.Id) == EplSystemId.Type_Class)); this.EocStaticClassMap = EocStaticClass.Translate(this, Source.Code.Classes.Where(x => EplSystemId.GetType(x.Id) != EplSystemId.Type_Class)); this.EocMemberMap = this.EocObjectClassMap.Values.SelectMany(x => x.MemberInfoMap) .Concat(this.EocStaticClassMap.Values.SelectMany(x => x.MemberInfoMap)) .Concat(this.EocStructMap.Values.SelectMany(x => x.MemberInfoMap)) .ToSortedDictionary(); this.EocMethodMap = this.EocObjectClassMap.Values.SelectMany(x => x.Method) .Concat(this.EocStaticClassMap.Values.SelectMany(x => x.Method)) .ToSortedDictionary(); if (ProjectType == EocProjectType.Dll) { this.EocDllExportMap = EocDllExport.Translate(this, Source.Code.Methods.Where(x => x.IsStatic && x.Public).Select(x => x.Id)); } }