From c3a0909f5e873c80dbd8d4162663c4731593c0d4 Mon Sep 17 00:00:00 2001 From: qiqiworld <1354092549@qq.com> Date: Mon, 6 Jul 2020 16:30:19 +0800 Subject: [PATCH] enhance: reconstruct the type system and the reference system [breaking change] --- EplOnCppCore/CodeConverter.cs | 98 ++- EplOnCppCore/EocClass.cs | 15 +- EplOnCppCore/EocConstant.cs | 77 +- EplOnCppCore/EocConstantInfo.cs | 20 +- EplOnCppCore/EocDataTypes.cs | 303 ++++++++ EplOnCppCore/EocDll.cs | 46 +- EplOnCppCore/EocDllExport.cs | 21 +- EplOnCppCore/EocGlobalVariable.cs | 42 +- EplOnCppCore/EocLocalVariableInfo.cs | 7 + EplOnCppCore/EocMemberInfo.cs | 5 +- EplOnCppCore/EocObjectClass.cs | 59 +- EplOnCppCore/EocParameterInfo.cs | 5 +- EplOnCppCore/EocStaticClass.cs | 40 +- EplOnCppCore/EocStruct.cs | 47 +- EplOnCppCore/EocVariableInfo.cs | 14 + EplOnCppCore/EplOnCppCore.csproj | 2 +- .../Expressions/EocAccessArrayExpression.cs | 8 +- .../Expressions/EocArrayLiteralExpression.cs | 14 +- EplOnCppCore/Expressions/EocBoolLiteral.cs | 2 +- EplOnCppCore/Expressions/EocCallExpression.cs | 2 +- .../Expressions/EocDateTimeLiteral.cs | 2 +- EplOnCppCore/Expressions/EocExpression.cs | 18 +- .../Expressions/EocMethodPtrExpression.cs | 2 +- EplOnCppCore/Expressions/EocNumberLiteral.cs | 2 +- EplOnCppCore/Expressions/EocStringLiteral.cs | 2 +- .../Expressions/EocVariableExpression.cs | 76 +- EplOnCppCore/ProjectConverter.cs | 724 +++--------------- .../Statements/EocDoWhileStatement.cs | 2 +- EplOnCppCore/Statements/EocIfElseStatement.cs | 4 +- EplOnCppCore/Statements/EocIfStatement.cs | 4 +- EplOnCppCore/Statements/EocSwitchStatement.cs | 2 +- EplOnCppCore/Statements/EocWhileStatement.cs | 2 +- EplOnCppCore/{ => Utils}/GraphUtils.cs | 2 +- EplOnCppCore/Utils/LinqEx.cs | 50 ++ 34 files changed, 849 insertions(+), 870 deletions(-) create mode 100644 EplOnCppCore/EocDataTypes.cs create mode 100644 EplOnCppCore/EocLocalVariableInfo.cs create mode 100644 EplOnCppCore/EocVariableInfo.cs rename EplOnCppCore/{ => Utils}/GraphUtils.cs (97%) create mode 100644 EplOnCppCore/Utils/LinqEx.cs diff --git a/EplOnCppCore/CodeConverter.cs b/EplOnCppCore/CodeConverter.cs index 4ce1ad4..130a8a3 100644 --- a/EplOnCppCore/CodeConverter.cs +++ b/EplOnCppCore/CodeConverter.cs @@ -1,5 +1,6 @@ using QIQI.EplOnCpp.Core.Expressions; using QIQI.EplOnCpp.Core.Statements; +using QIQI.EplOnCpp.Core.Utils; using QIQI.EProjectFile; using QuickGraph; using System; @@ -13,31 +14,73 @@ public class CodeConverter public ProjectConverter P { get; } public string Name { get; } public string RefId { get; } - public EocCmdInfo EocCmdInfo { get; } + public EocCmdInfo Info { get; } public bool IsClassMember { get; } public EocClass ClassItem { get; } public MethodInfo MethodItem { get; } public ILoggerWithContext Logger => P.Logger; - public MethodParameterInfo[] Parameters { get; } - public Dictionary ParamIdMap { get; } - public Dictionary LocalIdMap { get; } + public SortedDictionary ParamMap { get; } + public SortedDictionary LocalMap { get; } public EocStatementBlock StatementBlock { get; set; } + private static EocCmdInfo InferEocCmdInfo(ProjectConverter P, MethodInfo rawInfo) + { + var name = P.GetUserDefinedName_SimpleCppName(rawInfo.Id); + string cppName; + if (EplSystemId.GetType(P.MethodIdToClassMap[rawInfo.Id].Id) == EplSystemId.Type_Class) + { + cppName = name; + } + else + { + cppName = $"{P.CmdNamespace}::{name}"; + } + return new EocCmdInfo() + { + ReturnDataType = rawInfo.ReturnDataType == 0 ? null : EocDataTypes.Translate(P, rawInfo.ReturnDataType), + CppName = cppName, + Parameters = rawInfo.Parameters.Select((x) => + { + var dataType = EocDataTypes.Translate(P, x.DataType, x.ArrayParameter); + return new EocParameterInfo() + { + ByRef = x.ByRef || x.ArrayParameter || !EocDataTypes.IsValueType(dataType), + Optional = x.OptionalParameter, + VarArgs = false, + DataType = dataType, + CppName = P.GetUserDefinedName_SimpleCppName(x.Id) + }; + }).ToList() + }; + } + public CodeConverter(ProjectConverter projectConverter, EocClass classItem, MethodInfo methodItem) { this.P = projectConverter; this.Name = P.GetUserDefinedName_SimpleCppName(methodItem.Id); - this.EocCmdInfo = P.GetEocCmdInfo(methodItem); + this.Info = InferEocCmdInfo(P, methodItem); this.IsClassMember = classItem is EocObjectClass; this.ClassItem = classItem; this.MethodItem = methodItem; - this.Parameters = methodItem.Parameters; - this.ParamIdMap = methodItem.Parameters.ToDictionary(x => x.Id); - this.LocalIdMap = methodItem.Variables.ToDictionary(x => x.Id); - if(IsClassMember) - this.RefId = $"{ClassItem.CppName}|{EocCmdInfo.CppName}"; + this.ParamMap = new SortedDictionary(); + for (int i = 0; i < Info.Parameters.Count; i++) + { + this.ParamMap.Add(methodItem.Parameters[i].Id, Info.Parameters[i]); + } + this.LocalMap = methodItem.Variables.ToSortedDictionary(x => x.Id, x => new EocLocalVariableInfo() + { + CppName = P.GetUserDefinedName_SimpleCppName(x.Id), + DataType = EocDataTypes.Translate(P, x.DataType, x.UBound), + UBound = x.UBound.ToList() + }); + if (IsClassMember) + { + this.RefId = $"{ClassItem.CppName}|{Info.CppName}"; + } else - this.RefId = EocCmdInfo.CppName; + { + this.RefId = Info.CppName; + } } public void RemoveUnusedCode(HashSet dependencies) @@ -70,44 +113,43 @@ public CodeConverter Optimize() private void WriteOptionalParameterReader(CodeWriter writer) { - foreach (var x in Parameters.Where(x => x.OptionalParameter)) + foreach (var x in Info.Parameters.Where(x => x.Optional)) { - var name = P.GetUserDefinedName_SimpleCppName(x.Id); - var realValueType = P.GetCppTypeName(x.DataType, x.ArrayParameter); - var nullParameter = P.GetNullParameter(x.DataType, x.ArrayParameter); - var initValue = P.GetInitValue(x.DataType, x.ArrayParameter); + var name = x.CppName; + var nullParameter = EocDataTypes.GetNullParameter(x.DataType); + var initValue = EocDataTypes.GetInitValue(x.DataType); writer.NewLine(); writer.Write($"bool eoc_isNull_{name} = !{name}.has_value();"); - if (x.ByRef || x.ArrayParameter || !P.IsValueType(x.DataType)) + if (x.ByRef) { writer.NewLine(); if (string.IsNullOrWhiteSpace(nullParameter)) { - writer.Write($"{realValueType} eoc_default_{name};"); + writer.Write($"{x.DataType} eoc_default_{name};"); } else { - writer.Write($"{realValueType} eoc_default_{name}({nullParameter});"); + writer.Write($"{x.DataType} eoc_default_{name}({nullParameter});"); } writer.NewLine(); - writer.Write($"{realValueType}& eoc_value_{name} = eoc_isNull_{name} ? (eoc_default_{name} = {initValue}) : {name}.value().get();"); + writer.Write($"{x.DataType}& eoc_value_{name} = eoc_isNull_{name} ? (eoc_default_{name} = {initValue}) : {name}.value().get();"); } else { writer.NewLine(); - writer.Write($"{realValueType} eoc_value_{name} = eoc_isNull_{name} ? {initValue} : {name}.value();"); + writer.Write($"{x.DataType} eoc_value_{name} = eoc_isNull_{name} ? {initValue} : {name}.value();"); } } } public void AnalyzeDependencies(AdjacencyGraph> graph) { - P.AnalyzeDependencies(graph, EocCmdInfo, RefId); - foreach (var x in MethodItem.Variables) + P.AnalyzeDependencies(graph, Info, RefId); + foreach (var x in LocalMap.Values) { - var varRefId = $"{RefId}|{P.GetUserDefinedName_SimpleCppName(x.Id)}"; - P.AnalyzeDependencies(graph, varRefId, P.GetCppTypeName(x)); + var varRefId = $"{RefId}|{x.CppName}"; + P.AnalyzeDependencies(graph, varRefId, x.DataType); } StatementBlock.AnalyzeDependencies(graph); } @@ -130,7 +172,7 @@ internal void DefineItem(CodeWriter writer) writer.Write(accessModifier); writer.Write(":"); } - P.DefineMethod(writer, EocCmdInfo, Name, isVirtual); + P.DefineMethod(writer, Info, Name, isVirtual); } internal void ImplementItem(CodeWriter writer) @@ -142,10 +184,10 @@ internal void ImplementItem(CodeWriter writer) string classRawName = null; if (ClassItem is EocObjectClass x) classRawName = x.RawName; - P.WriteMethodHeader(writer, EocCmdInfo, Name, false, classRawName, false); + P.WriteMethodHeader(writer, Info, Name, false, classRawName, false); using (writer.NewBlock()) { - P.DefineVariable(writer, null, MethodItem.Variables); + P.DefineVariable(writer, null, LocalMap.Values); WriteOptionalParameterReader(writer); StatementBlock.WriteTo(writer); } diff --git a/EplOnCppCore/EocClass.cs b/EplOnCppCore/EocClass.cs index 4aa2e21..f48aa95 100644 --- a/EplOnCppCore/EocClass.cs +++ b/EplOnCppCore/EocClass.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System; using System.Collections.Generic; @@ -13,7 +14,8 @@ public abstract class EocClass public ClassInfo RawInfo { get; } public string Name { get; } public string CppName { get; } - public List Method { get; } + public SortedDictionary Method { get; set; } + public SortedDictionary MemberInfoMap { get; set; } public abstract void AnalyzeDependencies(AdjacencyGraph> graph); public abstract void RemoveUnusedCode(HashSet dependencies); @@ -31,12 +33,12 @@ public EocClass(ProjectConverter p, ClassInfo rawInfo) { CppName = $"{P.CmdNamespace}::{Name}"; } - Method = RawInfo.Method.Select(x => P.MethodIdMap[x]).Select(x => new CodeConverter(P, this, x)).ToList(); + Method = RawInfo.Method.Select(x => P.MethodIdMap[x]).ToSortedDictionary(x => x.Id, x => new CodeConverter(P, this, x)); } public void ParseCode() { - foreach (var item in Method) + foreach (var item in Method.Values) { item.ParseCode(); } @@ -44,9 +46,10 @@ public void ParseCode() public void Optimize() { - for (int i = 0; i < Method.Count; i++) + var keys = Method.Keys.ToList(); + foreach (var id in keys) { - Method[i] = Method[i].Optimize(); + Method[id] = Method[id].Optimize(); } } } diff --git a/EplOnCppCore/EocConstant.cs b/EplOnCppCore/EocConstant.cs index 32c8bf1..51d18be 100644 --- a/EplOnCppCore/EocConstant.cs +++ b/EplOnCppCore/EocConstant.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System; using System.Collections.Generic; @@ -23,7 +24,7 @@ public EocConstant(ProjectConverter p, string name, EocConstantInfo info) public void AnalyzeDependencies(AdjacencyGraph> graph) { - if(RefId != null) + if (RefId != null) { graph.AddVertex(RefId); P.AnalyzeDependencies(graph, RefId, Info.DataType); @@ -113,36 +114,92 @@ private void ImplementItem(CodeWriter writer) } } - public static EocConstant[] Translate(ProjectConverter P, IEnumerable constantInfos) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return constantInfos.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } - public static EocConstant Translate(ProjectConverter P, ConstantInfo constantInfo) + public static EocConstant Translate(ProjectConverter P, ConstantInfo rawInfo) { - return new EocConstant(P, P.GetUserDefinedName_SimpleCppName(constantInfo.Id), P.GetEocConstantInfo(constantInfo.Id)); + var name = P.GetUserDefinedName_SimpleCppName(rawInfo.Id); + var cppName = $"{P.ConstantNamespace}::{name}"; + string getter = null; + CppTypeName dataType; + switch (rawInfo.Value) + { + case double v: + if ((int)v == v) + { + dataType = EocDataTypes.Int; + } + else if ((long)v == v) + { + dataType = EocDataTypes.Long; + } + else + { + dataType = EocDataTypes.Double; + } + break; + + case bool _: + dataType = EocDataTypes.Bool; + break; + + case DateTime _: + dataType = EocDataTypes.DateTime; + break; + + case string _: + dataType = EocDataTypes.String; + getter = cppName; + cppName = null; + break; + + case byte[] _: + dataType = EocDataTypes.Bin; + getter = cppName; + cppName = null; + break; + + case null: + return null; + + default: + throw new Exception(); + } + + var info = new EocConstantInfo() + { + CppName = cppName, + Getter = getter, + DataType = dataType, + Value = rawInfo.Value + }; + + return new EocConstant(P, name, info); } - public static void Define(ProjectConverter P, CodeWriter writer, EocConstant[] eocDlls) + public static void Define(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#pragma once"); writer.NewLine(); writer.Write("#include "); using (writer.NewNamespace(P.ConstantNamespace)) { - foreach (var item in eocDlls) + foreach (var item in map.Values) { item.DefineItem(writer); } } } - public static void Implement(ProjectConverter P, CodeWriter writer, EocConstant[] eocDlls) + public static void Implement(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#include \"constant.h\""); using (writer.NewNamespace(P.ConstantNamespace)) { - foreach (var item in eocDlls) + foreach (var item in map.Values) { item.ImplementItem(writer); } diff --git a/EplOnCppCore/EocConstantInfo.cs b/EplOnCppCore/EocConstantInfo.cs index c3c3356..c5ab26a 100644 --- a/EplOnCppCore/EocConstantInfo.cs +++ b/EplOnCppCore/EocConstantInfo.cs @@ -12,18 +12,18 @@ public class EocConstantInfo public string RefId => CppName ?? Getter; public string CppName { get; set; } public string Getter { get; set; } - public CppTypeName DataType { get; set; } = ProjectConverter.CppTypeName_Int; - public object Value { get ; set; } + public CppTypeName DataType { get; set; } = EocDataTypes.Int; + public object Value { get; set; } private static readonly Dictionary> ProcessorForNormalization = new Dictionary> { - { ProjectConverter.CppTypeName_Bool, x => Convert.ToBoolean(x) }, - { ProjectConverter.CppTypeName_Byte, x => Convert.ToByte(x) }, - { ProjectConverter.CppTypeName_Short, x => Convert.ToInt16(x) }, - { ProjectConverter.CppTypeName_Int, x => Convert.ToInt32(x) }, - { ProjectConverter.CppTypeName_Long, x => Convert.ToInt64(x) }, - { ProjectConverter.CppTypeName_Float, x => Convert.ToSingle(x) }, - { ProjectConverter.CppTypeName_Double, x => Convert.ToDouble(x) }, - { ProjectConverter.CppTypeName_String, x => Convert.ToString(x) } + { EocDataTypes.Bool, x => Convert.ToBoolean(x) }, + { EocDataTypes.Byte, x => Convert.ToByte(x) }, + { EocDataTypes.Short, x => Convert.ToInt16(x) }, + { EocDataTypes.Int, x => Convert.ToInt32(x) }, + { EocDataTypes.Long, x => Convert.ToInt64(x) }, + { EocDataTypes.Float, x => Convert.ToSingle(x) }, + { EocDataTypes.Double, x => Convert.ToDouble(x) }, + { EocDataTypes.String, x => Convert.ToString(x) } }; public void Normalize() diff --git a/EplOnCppCore/EocDataTypes.cs b/EplOnCppCore/EocDataTypes.cs new file mode 100644 index 0000000..159423c --- /dev/null +++ b/EplOnCppCore/EocDataTypes.cs @@ -0,0 +1,303 @@ +using QIQI.EProjectFile; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace QIQI.EplOnCpp.Core +{ + public static class EocDataTypes + { + public static CppTypeName Bin { get; } = new CppTypeName(false, "e::system::bin"); + public static CppTypeName Bool { get; } = new CppTypeName(false, "bool"); + public static CppTypeName Byte { get; } = new CppTypeName(false, "uint8_t"); + public static CppTypeName DateTime { get; } = new CppTypeName(false, "e::system::datetime"); + public static CppTypeName Double { get; } = new CppTypeName(false, "double"); + public static CppTypeName Float { get; } = new CppTypeName(false, "float"); + public static CppTypeName Int { get; } = new CppTypeName(false, "int32_t"); + public static CppTypeName Long { get; } = new CppTypeName(false, "int64_t"); + public static CppTypeName Short { get; } = new CppTypeName(false, "int16_t"); + public static CppTypeName IntPtr { get; } = new CppTypeName(false, "intptr_t"); + public static CppTypeName MethodPtr { get; } = new CppTypeName(false, "e::system::methodptr"); + public static CppTypeName String { get; } = new CppTypeName(false, "e::system::string"); + public static CppTypeName Any { get; } = new CppTypeName(false, "e::system::any"); + public static CppTypeName Auto { get; } = new CppTypeName(false, "*"); + public static CppTypeName ErrorType { get; } = new CppTypeName(false, "EOC_ERROR_TYPE"); + + public static Dictionary BasicTypeMap { get; } = new Dictionary { + { EplSystemId.DataType_Bin , Bin }, + { EplSystemId.DataType_Bool , Bool }, + { EplSystemId.DataType_Byte , Byte }, + { EplSystemId.DataType_DateTime , DateTime }, + { EplSystemId.DataType_Double , Double }, + { EplSystemId.DataType_Float , Float }, + { EplSystemId.DataType_Int , Int }, + { EplSystemId.DataType_Long , Long }, + { EplSystemId.DataType_Short , Short }, + { EplSystemId.DataType_MethodPtr , MethodPtr }, + { EplSystemId.DataType_String , String }, + { EplSystemId.DataType_Any , Any } + }; + + private static Dictionary ConstTypeMap { get; } = new Dictionary() + { + { typeof(byte), Byte }, + { typeof(short), Short }, + { typeof(int), Int }, + { typeof(long), Long }, + { typeof(float), Float }, + { typeof(double), Double }, + { typeof(IntPtr), IntPtr }, + { typeof(DateTime), DateTime }, + { typeof(string), String }, + { typeof(bool), Bool } + }; + + public static CppTypeName GetConstValueType(object value) + { + var type = value.GetType(); + var isArray = type.IsArray; + while (type.IsArray) + { + type = type.GetElementType(); + } + + return isArray + ? new CppTypeName(false, "e::system::array", new[] { ConstTypeMap[type] }) + : ConstTypeMap[type]; + } + + + public static int NormalizeDataTypeId(ProjectConverter P, int dataType) + { + if (dataType == 0) + return EplSystemId.DataType_Int; + if (EplSystemId.IsLibDataType(dataType) && dataType != P.DataTypeId_IntPtr) + { + EplSystemId.DecomposeLibDataTypeId(dataType, out var libId, out var typeId); + try + { + if (P.Libs[libId].DataType[typeId].IsEnum) + return EplSystemId.DataType_Int; + } + catch (Exception) + { + } + try + { + if (P.EocLibs[libId].Enum.ContainsKey(P.Libs[libId].DataType[typeId].Name)) + return EplSystemId.DataType_Int; + } + catch (Exception) + { + } + } + return dataType; + } + + /// + /// 不保证与字节数相等,只保证数值大的类型大 + /// + /// + /// + public static int GetIntNumberTypeSize(CppTypeName dataType) + { + if (dataType == Byte) + { + return 1; + } + else if (dataType == Short) + { + return 2; + } + else if (dataType == Int) + { + return 4; + } + else if (dataType == Long) + { + return 8; + } + else + { + throw new ArgumentException(); + } + } + + /// + /// 不保证与字节数相等,只保证数值大的类型大 + /// + /// + /// + public static int GetFloatNumberTypeSize(CppTypeName dataType) + { + if (dataType == Float) + { + return 4; + } + else if (dataType == Double) + { + return 8; + } + else + { + throw new ArgumentException(); + } + } + + public static bool IsFloatNumberType(CppTypeName dataType) + { + if (dataType == Float + || dataType == Double) + { + return true; + } + else + { + return false; + } + } + + public static bool IsIntNumberType(CppTypeName dataType) + { + if (dataType == Byte + || dataType == Short + || dataType == Int + || dataType == Long) + { + return true; + } + else + { + return false; + } + } + + public static bool IsArithmeticType(CppTypeName dataType) + { + return IsIntNumberType(dataType) || IsFloatNumberType(dataType) || dataType == IntPtr; + } + + public static bool IsValueType(CppTypeName dataType) + { + if (dataType == Bool + || dataType == DateTime + || dataType == MethodPtr + || IsArithmeticType(dataType)) + { + return true; + } + else + { + return false; + } + } + + public static CppTypeName Translate(ProjectConverter P, int id, int[] uBound) + { + return Translate(P, id, uBound != null && uBound.Length != 0); + } + + public static CppTypeName Translate(ProjectConverter P, int id, bool isArray = false) + { + id = NormalizeDataTypeId(P, id); + if (id == P.DataTypeId_IntPtr) + { + return IntPtr; + } + if (!BasicTypeMap.TryGetValue(id, out var result)) + { + if (EplSystemId.GetType(id) == EplSystemId.Type_Class + || EplSystemId.GetType(id) == EplSystemId.Type_Struct) + { + result = new CppTypeName(false, P.TypeNamespace + "::" + P.GetUserDefinedName_SimpleCppName(id)); + } + else + { + EplSystemId.DecomposeLibDataTypeId(id, out var libId, out var typeId); + + if (P.Libs[libId] == null) + { + return ErrorType; + } + if (typeId >= P.Libs[libId].DataType.Length) + { + return ErrorType; + } + var name = P.Libs[libId].DataType[typeId].Name; + if (P.EocLibs[libId] == null) + { + return ErrorType; + } + if (!P.EocLibs[libId].Type.ContainsKey(name)) + { + return ErrorType; + } + result = P.EocLibs[libId].Type[name].CppName; + } + } + if (isArray) + result = new CppTypeName(false, "e::system::array", new[] { result }); + return result; + } + + public static string GetInitValue(CppTypeName dataType, List uBound = null) + { + return $"{dataType}({GetInitParameter(dataType, uBound)})"; + } + + public static string GetInitParameter(CppTypeName dataType, List uBound = null) + { + if (dataType.Name == "e::system::array") + { + if (uBound != null && uBound.Count != 0 && uBound[0] != 0) + { + return string.Join(", ", uBound.Select(x => x + "u")); + } + return "nullptr"; + } + if (dataType == Bool) + { + return "false"; + } + if (IsArithmeticType(dataType)) + { + return "0"; + } + if (dataType == DateTime) + { + return "0"; + } + if (dataType == MethodPtr) + { + return "nullptr"; + } + return ""; + } + + public static string GetNullParameter(CppTypeName dataType) + { + if (dataType.Name == "e::system::array") + { + return "nullptr"; + } + if (dataType == Bool) + { + return "false"; + } + if (IsArithmeticType(dataType)) + { + return "0"; + } + if (dataType == DateTime) + { + return "0"; + } + if (dataType == MethodPtr) + { + return "nullptr"; + } + return "nullptr"; + } + } +} diff --git a/EplOnCppCore/EocDll.cs b/EplOnCppCore/EocDll.cs index 825707b..0369901 100644 --- a/EplOnCppCore/EocDll.cs +++ b/EplOnCppCore/EocDll.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System; using System.Collections.Generic; @@ -74,37 +75,55 @@ private void ImplementItem(CodeWriter writer, Dictionary moduleM } } - public static EocDll[] Translate(ProjectConverter P, IEnumerable dllDeclare) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return dllDeclare.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } - public static EocDll Translate(ProjectConverter P, DllDeclareInfo dllDeclare) + public static EocDll Translate(ProjectConverter P, DllDeclareInfo rawInfo) { - var libraryName = dllDeclare.LibraryName; - var entryPoint = dllDeclare.EntryPoint; + var libraryName = rawInfo.LibraryName; + var entryPoint = rawInfo.EntryPoint; if (string.IsNullOrEmpty(entryPoint)) { - entryPoint = P.IdToNameMap.GetUserDefinedName(dllDeclare.Id); + entryPoint = P.IdToNameMap.GetUserDefinedName(rawInfo.Id); } - return new EocDll(P, P.GetUserDefinedName_SimpleCppName(dllDeclare.Id), P.GetEocCmdInfo(dllDeclare), libraryName, entryPoint); + var name = P.GetUserDefinedName_SimpleCppName(rawInfo.Id); + var info = new EocCmdInfo() + { + ReturnDataType = rawInfo.ReturnDataType == 0 ? null : EocDataTypes.Translate(P, rawInfo.ReturnDataType), + CppName = $"{P.DllNamespace}::{name}", + Parameters = rawInfo.Parameters.Select((x) => + { + var dataType = EocDataTypes.Translate(P, x.DataType, x.ArrayParameter); + return new EocParameterInfo() + { + ByRef = x.ByRef || x.ArrayParameter || !EocDataTypes.IsValueType(dataType), + Optional = false, + VarArgs = false, + DataType = dataType, + CppName = P.GetUserDefinedName_SimpleCppName(x.Id) + }; + }).ToList() + }; + return new EocDll(P, name, info, libraryName, entryPoint); } - public static void Define(ProjectConverter P, CodeWriter writer, EocDll[] eocDlls) + public static void Define(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#pragma once"); writer.NewLine(); writer.Write("#include \"type.h\""); using (writer.NewNamespace(P.DllNamespace)) { - foreach (var item in eocDlls) + foreach (var item in map.Values) { item.DefineItem(writer); } } } - public static void Implement(ProjectConverter P, CodeWriter writer, EocDll[] eocDlls) + public static void Implement(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#include \"dll.h\""); writer.NewLine(); @@ -115,7 +134,8 @@ public static void Implement(ProjectConverter P, CodeWriter writer, EocDll[] eoc { var moduleMap = new Dictionary(StringComparer.OrdinalIgnoreCase); var funcMap = new Dictionary, string>(); - for (int i = 0, j = 0, k = 0; i < eocDlls.Length; i++) + var eocDlls = map.Values.ToList(); + for (int i = 0, j = 0, k = 0; i < eocDlls.Count; i++) { var item = eocDlls[i]; if (!moduleMap.TryGetValue(item.LibraryName, out var dllIdInCpp)) @@ -142,7 +162,7 @@ public static void Implement(ProjectConverter P, CodeWriter writer, EocDll[] eoc foreach (var item in funcMap) { var entryPointExpr = item.Key.Item2; - if (entryPointExpr.StartsWith("#")) + if (entryPointExpr.StartsWith("#")) { entryPointExpr = $"reinterpret_cast({Convert.ToInt32(entryPointExpr.Substring(1))})"; } diff --git a/EplOnCppCore/EocDllExport.cs b/EplOnCppCore/EocDllExport.cs index b5023a6..872cec5 100644 --- a/EplOnCppCore/EocDllExport.cs +++ b/EplOnCppCore/EocDllExport.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System; using System.Collections.Generic; @@ -43,7 +44,7 @@ private void ImplementItem(ProjectConverter P, CodeWriter writer) writer.Write(paramName[i]); } writer.Write(")"); - using(writer.NewBlock()) + using (writer.NewBlock()) { writer.NewLine(); writer.Write("return e::system::MethodPtrPackager<"); @@ -58,14 +59,14 @@ private void ImplementItem(ProjectConverter P, CodeWriter writer) } } - public static void Implement(ProjectConverter P, CodeWriter writer, EocDllExport[] dllExports) + public static void Implement(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#include \"stdafx.h\""); writer.NewLine(); writer.Write("extern \"C\""); using (writer.NewBlock()) { - foreach (var item in dllExports) + foreach (var item in map.Values) { item.ImplementItem(P, writer); } @@ -77,22 +78,22 @@ private void MakeDefItem(ProjectConverter p, StreamWriter writer) writer.WriteLine($"{Name} = eoc_export_{ExportId}"); } - public static void MakeDef(ProjectConverter P, StreamWriter writer, EocDllExport[] dllExports) + public static void MakeDef(ProjectConverter P, StreamWriter writer, SortedDictionary map) { writer.WriteLine("EXPORTS"); - foreach (var item in dllExports) + foreach (var item in map.Values) { item.MakeDefItem(P, writer); } } - public static EocDllExport[] Translate(ProjectConverter P, IEnumerable methods) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable ids) { - return methods.Select(x => Translate(P, x)).ToArray(); + return ids.ToSortedDictionary(x => x, x => Translate(P, x)); } - public static EocDllExport Translate(ProjectConverter P, MethodInfo methodInfo) + public static EocDllExport Translate(ProjectConverter P, int id) { - return new EocDllExport(P, P.IdToNameMap.GetUserDefinedName(methodInfo.Id), P.GetEocCmdInfo(methodInfo), methodInfo.Id.ToString("X8")); + return new EocDllExport(P, P.IdToNameMap.GetUserDefinedName(id), P.GetEocCmdInfo(id), id.ToString("X8")); } } } diff --git a/EplOnCppCore/EocGlobalVariable.cs b/EplOnCppCore/EocGlobalVariable.cs index ef5bfef..6848dfe 100644 --- a/EplOnCppCore/EocGlobalVariable.cs +++ b/EplOnCppCore/EocGlobalVariable.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System; using System.Collections.Generic; @@ -9,66 +10,67 @@ namespace QIQI.EplOnCpp.Core { public class EocGlobalVariable { - public string RefId => CppName; + public string RefId => Info.CppName; public ProjectConverter P { get; } - public string Name { get; } - public string CppName { get; } - public GlobalVariableInfo RawInfo { get; } + public EocVariableInfo Info { get; } - public EocGlobalVariable(ProjectConverter p, GlobalVariableInfo rawInfo) + public EocGlobalVariable(ProjectConverter p, EocVariableInfo info) { P = p ?? throw new ArgumentNullException(nameof(p)); - RawInfo = rawInfo ?? throw new ArgumentNullException(nameof(rawInfo)); - Name = P.GetUserDefinedName_SimpleCppName(RawInfo.Id); - CppName = $"{P.GlobalNamespace}::{Name}"; + Info = info ?? throw new ArgumentNullException(nameof(info)); } public void AnalyzeDependencies(AdjacencyGraph> graph) { graph.AddVertex(RefId); - P.AnalyzeDependencies(graph, RefId, P.GetCppTypeName(RawInfo)); + P.AnalyzeDependencies(graph, RefId, Info.DataType); } private void DefineItem(CodeWriter writer) { - P.DefineVariable(writer, new string[] { "extern" }, RawInfo, false); + P.DefineVariable(writer, new string[] { "extern" }, Info, false); } private void ImplementItem(CodeWriter writer) { - P.DefineVariable(writer, null, RawInfo); + P.DefineVariable(writer, null, Info); } - public static EocGlobalVariable[] Translate(ProjectConverter P, IEnumerable rawInfo) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return rawInfo.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } - public static EocGlobalVariable Translate(ProjectConverter P, GlobalVariableInfo rawInfo) + public static EocGlobalVariable Translate(ProjectConverter P, GlobalVariableInfo x) { - return new EocGlobalVariable(P, rawInfo); + return new EocGlobalVariable(P, new EocVariableInfo() + { + CppName = $"{P.GlobalNamespace}::{P.GetUserDefinedName_SimpleCppName(x.Id)}", + DataType = EocDataTypes.Translate(P, x.DataType, x.UBound), + UBound = x.UBound.ToList() + }); } - public static void Define(ProjectConverter P, CodeWriter writer, EocGlobalVariable[] collection) + public static void Define(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#pragma once"); writer.NewLine(); writer.Write("#include \"type.h\""); using (writer.NewNamespace(P.GlobalNamespace)) { - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineItem(writer); } } } - public static void Implement(ProjectConverter P, CodeWriter writer, EocGlobalVariable[] collection) + public static void Implement(ProjectConverter P, CodeWriter writer, SortedDictionary map) { writer.Write("#include \"global.h\""); using (writer.NewNamespace(P.GlobalNamespace)) { - foreach (var item in collection) + foreach (var item in map.Values) { item.ImplementItem(writer); } diff --git a/EplOnCppCore/EocLocalVariableInfo.cs b/EplOnCppCore/EocLocalVariableInfo.cs new file mode 100644 index 0000000..3ebd600 --- /dev/null +++ b/EplOnCppCore/EocLocalVariableInfo.cs @@ -0,0 +1,7 @@ +namespace QIQI.EplOnCpp.Core +{ + public class EocLocalVariableInfo : EocVariableInfo + { + + } +} \ No newline at end of file diff --git a/EplOnCppCore/EocMemberInfo.cs b/EplOnCppCore/EocMemberInfo.cs index 4d53045..fd469c3 100644 --- a/EplOnCppCore/EocMemberInfo.cs +++ b/EplOnCppCore/EocMemberInfo.cs @@ -1,9 +1,8 @@ namespace QIQI.EplOnCpp.Core { - public class EocMemberInfo + public class EocMemberInfo : EocVariableInfo { - public string CppName { get; set; } - public CppTypeName DataType { get; set; } + public bool Static { get; set; } = false; public string Getter { get; set; } public string Setter { get; set; } public bool Referencable { get; set; } = true; diff --git a/EplOnCppCore/EocObjectClass.cs b/EplOnCppCore/EocObjectClass.cs index 6c7b472..807d8f8 100644 --- a/EplOnCppCore/EocObjectClass.cs +++ b/EplOnCppCore/EocObjectClass.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using QuickGraph.Algorithms; using System; @@ -27,24 +28,30 @@ public EocObjectClass(ProjectConverter p, ClassInfo rawInfo) : base(p, rawInfo) else { BaseClassName = P.GetUserDefinedName_SimpleCppName(rawInfo.BaseClass); - BaseClassCppName = P.GetCppTypeName(rawInfo.BaseClass).ToString(); + BaseClassCppName = EocDataTypes.Translate(P, rawInfo.BaseClass).ToString(); BaseClassRawName = $"raw_{BaseClassName}"; BaseClassRawCppName = $"{P.TypeNamespace}::eoc_internal::{BaseClassRawName}"; } + MemberInfoMap = RawInfo.Variables.ToSortedDictionary(x => x.Id, x => new EocMemberInfo() + { + CppName = P.GetUserDefinedName_SimpleCppName(x.Id), + DataType = EocDataTypes.Translate(P, x.DataType, x.UBound), + UBound = x.UBound.ToList() + }); } - public override void AnalyzeDependencies(AdjacencyGraph> graph) + public override void AnalyzeDependencies(AdjacencyGraph> graph) { graph.AddVertex(RefId); if (BaseClassCppName != null) graph.AddVerticesAndEdge(new Edge(RefId, BaseClassCppName)); - foreach (var x in RawInfo.Variables) + foreach (var x in MemberInfoMap.Values) { - var varRefId = $"{RefId}|{P.GetUserDefinedName_SimpleCppName(x.Id)}"; + var varRefId = $"{RefId}|{x.CppName}"; graph.AddVerticesAndEdge(new Edge(RefId, varRefId)); - P.AnalyzeDependencies(graph, varRefId, P.GetCppTypeName(x)); + P.AnalyzeDependencies(graph, varRefId, x.DataType); } - foreach (var x in Method) + foreach (var x in Method.Values) { graph.AddVerticesAndEdge(new Edge(RefId, x.RefId)); x.AnalyzeDependencies(graph); @@ -53,7 +60,7 @@ public override void AnalyzeDependencies(AdjacencyGraph> gr public override void RemoveUnusedCode(HashSet dependencies) { - foreach (var item in Method) + foreach (var item in Method.Values) { item.RemoveUnusedCode(dependencies); } @@ -87,10 +94,10 @@ private void DefineRawObjectClass(CodeWriter writer) using (writer.NewBlock()) { writer.NewLine(); - if (RawInfo.Variables.Length != 0) + if (MemberInfoMap.Count != 0) { writer.Write("private:"); - P.DefineVariable(writer, null, RawInfo.Variables, false); + P.DefineVariable(writer, null, MemberInfoMap.Values, false); } writer.NewLine(); writer.Write("public:"); @@ -102,7 +109,7 @@ private void DefineRawObjectClass(CodeWriter writer) writer.Write($"virtual ~{RawName}();"); writer.NewLine(); writer.Write($"virtual e::system::basic_object* __stdcall clone();"); - foreach (var item in Method) + foreach (var item in Method.Values) { item.DefineItem(writer); } @@ -115,16 +122,16 @@ public void ImplementRawObjectClass(CodeWriter writer) writer.Write("#include \"../../../stdafx.h\""); using (writer.NewNamespace(P.TypeNamespace)) { - var initMethod = Method.Where(x => x.MethodItem.Name == "_初始化").FirstOrDefault(); - var destroyMethod = Method.Where(x => x.MethodItem.Name == "_销毁").FirstOrDefault(); + var initMethod = Method.Values.Where(x => x.MethodItem.Name == "_初始化").FirstOrDefault(); + var destroyMethod = Method.Values.Where(x => x.MethodItem.Name == "_销毁").FirstOrDefault(); using (writer.NewNamespace("eoc_internal")) { writer.NewLine(); writer.Write($"{RawName}::{RawName}()"); - if (RawInfo.Variables.Length != 0) + if (MemberInfoMap.Count != 0) { writer.Write(": "); - P.InitMembersInConstructor(writer, RawInfo.Variables); + P.InitMembersInConstructor(writer, MemberInfoMap.Values); } using (writer.NewBlock()) { @@ -156,7 +163,7 @@ public void ImplementRawObjectClass(CodeWriter writer) writer.Write($"return new {RawName}(*this);"); } - foreach (var item in Method) + foreach (var item in Method.Values) { item.ImplementItem(writer); } @@ -164,32 +171,32 @@ public void ImplementRawObjectClass(CodeWriter writer) } } - public static void DefineRawName(ProjectConverter P, CodeWriter writer, EocObjectClass[] collection) + public static void DefineRawName(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type::eoc_internal - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineRawName(writer); } } - public static void DefineName(ProjectConverter P, CodeWriter writer, EocObjectClass[] collection) + public static void DefineName(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineName(writer); } } - public static void DefineRawObjectClass(ProjectConverter P, CodeWriter writer, EocObjectClass[] collection) + public static void DefineRawObjectClass(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type::eoc_internal - var map = collection.ToDictionary(x => x.CppName); + var nameMap = map.ToDictionary(x => x.Value.CppName, x => x.Value); var graph = new AdjacencyGraph>(); - foreach (var item in collection) + foreach (var item in map.Values) { - if (item.BaseClassCppName != null && map.TryGetValue(item.BaseClassCppName, out var baseEocClass)) + if (item.BaseClassCppName != null && nameMap.TryGetValue(item.BaseClassCppName, out var baseEocClass)) { graph.AddVerticesAndEdge(new Edge(baseEocClass, item)); } @@ -205,9 +212,9 @@ public static void DefineRawObjectClass(ProjectConverter P, CodeWriter writer, E } } - public static EocObjectClass[] Translate(ProjectConverter P, IEnumerable rawInfo) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return rawInfo.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } public static EocObjectClass Translate(ProjectConverter P, ClassInfo rawInfo) diff --git a/EplOnCppCore/EocParameterInfo.cs b/EplOnCppCore/EocParameterInfo.cs index 6a6c00c..6819c23 100644 --- a/EplOnCppCore/EocParameterInfo.cs +++ b/EplOnCppCore/EocParameterInfo.cs @@ -1,12 +1,9 @@ namespace QIQI.EplOnCpp.Core { - public class EocParameterInfo + public class EocParameterInfo : EocVariableInfo { public bool Optional { get; set; } = false; public bool ByRef { get; set; } = false; public bool VarArgs { get; set; } = false; - public CppTypeName DataType { get; set; } - - public string Name { get; set; } //可选 } } \ No newline at end of file diff --git a/EplOnCppCore/EocStaticClass.cs b/EplOnCppCore/EocStaticClass.cs index da17241..da57cfc 100644 --- a/EplOnCppCore/EocStaticClass.cs +++ b/EplOnCppCore/EocStaticClass.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using System.Collections.Generic; using System.Linq; @@ -9,6 +10,13 @@ public class EocStaticClass : EocClass { public EocStaticClass(ProjectConverter p, ClassInfo rawInfo) : base(p, rawInfo) { + MemberInfoMap = RawInfo.Variables.ToSortedDictionary(x => x.Id, x => new EocMemberInfo() + { + CppName = $"{this.CppName}::{P.GetUserDefinedName_SimpleCppName(x.Id)}", + DataType = EocDataTypes.Translate(P, x.DataType, x.UBound), + UBound = x.UBound.ToList(), + Static = true + }); } public void Define(CodeWriter writer) @@ -18,7 +26,7 @@ public void Define(CodeWriter writer) writer.Write("#include \"../type.h\""); using (writer.NewNamespace(P.CmdNamespace)) { - foreach (var item in Method) + foreach (var item in Method.Values) { item.DefineItem(writer); } @@ -27,12 +35,12 @@ public void Define(CodeWriter writer) public override void AnalyzeDependencies(AdjacencyGraph> graph) { - foreach (var x in RawInfo.Variables) + foreach (var x in MemberInfoMap.Values) { - var varRefId = $"{RefId}::{P.GetUserDefinedName_SimpleCppName(x.Id)}"; - P.AnalyzeDependencies(graph, varRefId, P.GetCppTypeName(x)); + var varRefId = x.CppName; + P.AnalyzeDependencies(graph, varRefId, x.DataType); } - foreach (var x in Method) + foreach (var x in Method.Values) { x.AnalyzeDependencies(graph); } @@ -40,13 +48,9 @@ public override void AnalyzeDependencies(AdjacencyGraph> g public override void RemoveUnusedCode(HashSet dependencies) { - RawInfo.Variables = RawInfo.Variables.Where(x => dependencies.Contains($"{RefId}::{P.GetUserDefinedName_SimpleCppName(x.Id)}")).ToArray(); - for (int i = Method.Count - 1; i >= 0; i--) - { - if (!dependencies.Contains(Method[i].RefId)) - Method.RemoveAt(i); - } - foreach (var item in Method) + MemberInfoMap = MemberInfoMap.FilterSortedDictionary(x => dependencies.Contains(x.Value.CppName)); + Method = Method.FilterSortedDictionary(x => dependencies.Contains(x.Value.RefId)); + foreach (var item in Method.Values) { item.RemoveUnusedCode(dependencies); } @@ -57,23 +61,23 @@ public void Implement(CodeWriter writer) writer.Write("#include \"../../../stdafx.h\""); using (writer.NewNamespace(P.CmdNamespace)) { - if (RawInfo.Variables.Length > 0) + if (MemberInfoMap.Count > 0) { using (writer.NewNamespace(Name)) { - P.DefineVariable(writer, new string[] { "static" }, RawInfo.Variables); + P.DefineVariable(writer, new string[] { "static" }, MemberInfoMap.Values); } } - foreach (var item in Method) + foreach (var item in Method.Values) { item.ImplementItem(writer); } } } - public static EocStaticClass[] Translate(ProjectConverter P, IEnumerable rawInfo) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return rawInfo.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } public static EocStaticClass Translate(ProjectConverter P, ClassInfo rawInfo) diff --git a/EplOnCppCore/EocStruct.cs b/EplOnCppCore/EocStruct.cs index ec89884..9a7e2d4 100644 --- a/EplOnCppCore/EocStruct.cs +++ b/EplOnCppCore/EocStruct.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QuickGraph; using QuickGraph.Algorithms; using System; @@ -14,7 +15,8 @@ public class EocStruct public ProjectConverter P { get; } public string RefId => CppName; public StructInfo RawInfo { get; } - public string Name { get; } + public SortedDictionary MemberInfoMap { get; set; } + public string Name { get; } public string CppName { get; } public string RawName { get; } public string RawCppName { get; } @@ -26,16 +28,22 @@ public EocStruct(ProjectConverter p, StructInfo rawInfo) Name = P.GetUserDefinedName_SimpleCppName(RawInfo.Id); RawName = "raw_" + Name; RawCppName = $"{P.TypeNamespace}::eoc_internal::{RawName}"; - CppName = P.GetCppTypeName(rawInfo.Id).ToString(); + CppName = EocDataTypes.Translate(P, rawInfo.Id).ToString(); + MemberInfoMap = RawInfo.Member.ToSortedDictionary(x => x.Id, x => new EocMemberInfo() + { + CppName = P.GetUserDefinedName_SimpleCppName(x.Id), + DataType = EocDataTypes.Translate(P, x.DataType, x.UBound), + UBound = x.UBound.ToList() + }); } public void AnalyzeDependencies(AdjacencyGraph> graph) { graph.AddVertex(RefId); - foreach (var x in RawInfo.Member) + foreach (var x in MemberInfoMap.Values) { - var varRefId = $"{RefId}|{P.GetUserDefinedName_SimpleCppName(x.Id)}"; + var varRefId = $"{RefId}|{x.CppName}"; graph.AddVerticesAndEdge(new Edge(RefId, varRefId)); - P.AnalyzeDependencies(graph, varRefId, P.GetCppTypeName(x)); + P.AnalyzeDependencies(graph, varRefId, x.DataType); } } @@ -56,14 +64,14 @@ private void DefineRawStructInfo(CodeWriter writer) writer.Write($"struct {RawName}"); using (writer.NewBlock()) { - P.DefineVariable(writer, null, RawInfo.Member, false); + P.DefineVariable(writer, null, MemberInfoMap.Values, false); writer.NewLine(); writer.Write($"{RawName}()"); - if (RawInfo.Member.Length != 0) + if (MemberInfoMap.Count != 0) { writer.Write(": "); - P.InitMembersInConstructor(writer, RawInfo.Member); + P.InitMembersInConstructor(writer, MemberInfoMap.Values); } using (writer.NewBlock()) { @@ -137,38 +145,37 @@ private void WriteStructMarshalerCodeBlock(CodeWriter writer, string cmd) } } } - public static void DefineRawName(ProjectConverter P, CodeWriter writer, EocStruct[] collection) + public static void DefineRawName(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type::eoc_internal - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineRawName(writer); } } - public static void DefineName(ProjectConverter P, CodeWriter writer, EocStruct[] collection) + public static void DefineName(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineName(writer); } } - public static void DefineRawStructInfo(ProjectConverter P, CodeWriter writer, EocStruct[] collection) + public static void DefineRawStructInfo(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::user::type::eoc_internal - foreach (var item in collection) + foreach (var item in map.Values) { item.DefineRawStructInfo(writer); } } - public static void DefineStructMarshaler(ProjectConverter P, CodeWriter writer, EocStruct[] collection) + public static void DefineStructMarshaler(ProjectConverter P, CodeWriter writer, SortedDictionary map) { //In e::system - var map = collection.ToDictionary(x => x.RawInfo.Id); var graph = new AdjacencyGraph>(); - foreach (var item in collection) + foreach (var item in map.Values) { var hasDependentItem = false; foreach (var member in item.RawInfo.Member) @@ -192,9 +199,9 @@ public static void DefineStructMarshaler(ProjectConverter P, CodeWriter writer, } } - public static EocStruct[] Translate(ProjectConverter P, IEnumerable rawInfo) + public static SortedDictionary Translate(ProjectConverter P, IEnumerable rawInfos) { - return rawInfo.Select(x => Translate(P, x)).ToArray(); + return rawInfos.ToSortedDictionary(x => x.Id, x => Translate(P, x)); } public static EocStruct Translate(ProjectConverter P, StructInfo rawInfo) diff --git a/EplOnCppCore/EocVariableInfo.cs b/EplOnCppCore/EocVariableInfo.cs new file mode 100644 index 0000000..be0aa4b --- /dev/null +++ b/EplOnCppCore/EocVariableInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace QIQI.EplOnCpp.Core +{ + public class EocVariableInfo + { + public string CppName { get; set; } + public CppTypeName DataType { get; set; } + // 用于数组变量/可空数组参数的初始化 + public List UBound { get; set; } + } +} diff --git a/EplOnCppCore/EplOnCppCore.csproj b/EplOnCppCore/EplOnCppCore.csproj index 185f537..808659a 100644 --- a/EplOnCppCore/EplOnCppCore.csproj +++ b/EplOnCppCore/EplOnCppCore.csproj @@ -18,7 +18,7 @@ QIQI QIQI.EplOnCpp.Core QIQI.EplOnCpp.Core - 1.4.0 + 2.0.0 MIT https://github.com/1354092549/EplOnCppCore diff --git a/EplOnCppCore/Expressions/EocAccessArrayExpression.cs b/EplOnCppCore/Expressions/EocAccessArrayExpression.cs index dc8b629..9978f0c 100644 --- a/EplOnCppCore/Expressions/EocAccessArrayExpression.cs +++ b/EplOnCppCore/Expressions/EocAccessArrayExpression.cs @@ -34,12 +34,12 @@ public override CppTypeName GetResultType() return x.TypeParam[0]; case null: - case CppTypeName sc when sc == ProjectConverter.CppTypeName_SkipCheck: - case CppTypeName any when any == ProjectConverter.CppTypeName_Any: + case CppTypeName sc when sc == EocDataTypes.Auto: + case CppTypeName any when any == EocDataTypes.Any: return arrayItemType; - case CppTypeName x when x == ProjectConverter.CppTypeName_Bin: - return ProjectConverter.CppTypeName_Byte; + case CppTypeName x when x == EocDataTypes.Bin: + return EocDataTypes.Byte; default: throw new NotImplementedException(); diff --git a/EplOnCppCore/Expressions/EocArrayLiteralExpression.cs b/EplOnCppCore/Expressions/EocArrayLiteralExpression.cs index 5c62432..e45148d 100644 --- a/EplOnCppCore/Expressions/EocArrayLiteralExpression.cs +++ b/EplOnCppCore/Expressions/EocArrayLiteralExpression.cs @@ -25,12 +25,12 @@ public override CppTypeName GetResultType() foreach (var item in Item) { var elemType = item.GetResultType(); - if (elemType != ProjectConverter.CppTypeName_SkipCheck) + if (elemType != EocDataTypes.Auto) { return new CppTypeName(false, "e::system::array", new[] { elemType }); } } - return ProjectConverter.CppTypeName_Bin; + return EocDataTypes.Bin; } public override void WriteTo(CodeWriter writer) @@ -40,15 +40,15 @@ public override void WriteTo(CodeWriter writer) public override void WriteToWithCast(CodeWriter writer, CppTypeName cast) { - if (cast == null || cast == ProjectConverter.CppTypeName_SkipCheck || cast == ProjectConverter.CppTypeName_Any) + if (cast == null || cast == EocDataTypes.Auto || cast == EocDataTypes.Any) { cast = GetResultType(); } var resultType = cast; CppTypeName elemType; - if (cast == ProjectConverter.CppTypeName_Bin) + if (cast == EocDataTypes.Bin) { - elemType = ProjectConverter.CppTypeName_Byte; + elemType = EocDataTypes.Byte; } else if (cast.Name == "e::system::array") { @@ -89,9 +89,9 @@ public override bool TryGetConstValueWithCast(CppTypeName cast, out object value { var resultType = cast; CppTypeName elemType; - if (cast == ProjectConverter.CppTypeName_Bin) + if (cast == EocDataTypes.Bin) { - elemType = ProjectConverter.CppTypeName_Byte; + elemType = EocDataTypes.Byte; } else if (cast.Name == "e::system::array") { diff --git a/EplOnCppCore/Expressions/EocBoolLiteral.cs b/EplOnCppCore/Expressions/EocBoolLiteral.cs index 5d75d88..ea7c4be 100644 --- a/EplOnCppCore/Expressions/EocBoolLiteral.cs +++ b/EplOnCppCore/Expressions/EocBoolLiteral.cs @@ -19,7 +19,7 @@ public EocBoolLiteral(CodeConverter c, bool value) : base(c) public override CppTypeName GetResultType() { - return ProjectConverter.CppTypeName_Bool; + return EocDataTypes.Bool; } public override void WriteTo(CodeWriter writer) diff --git a/EplOnCppCore/Expressions/EocCallExpression.cs b/EplOnCppCore/Expressions/EocCallExpression.cs index 873acb3..a651ada 100644 --- a/EplOnCppCore/Expressions/EocCallExpression.cs +++ b/EplOnCppCore/Expressions/EocCallExpression.cs @@ -105,7 +105,7 @@ public override void WriteTo(CodeWriter writer) writer.Write("std::reference_wrapper("); writer.Write("BYREF"); - if (eocParameterInfo.DataType != ProjectConverter.CppTypeName_SkipCheck) + if (eocParameterInfo.DataType != EocDataTypes.Auto) { writer.Write("("); writer.Write(eocParameterInfo.DataType.ToString()); diff --git a/EplOnCppCore/Expressions/EocDateTimeLiteral.cs b/EplOnCppCore/Expressions/EocDateTimeLiteral.cs index 42350c5..ce9f996 100644 --- a/EplOnCppCore/Expressions/EocDateTimeLiteral.cs +++ b/EplOnCppCore/Expressions/EocDateTimeLiteral.cs @@ -20,7 +20,7 @@ public EocDateTimeLiteral(CodeConverter c, DateTime value) : base(c) public override CppTypeName GetResultType() { - return ProjectConverter.CppTypeName_DateTime; + return EocDataTypes.DateTime; } public override void WriteTo(CodeWriter writer) diff --git a/EplOnCppCore/Expressions/EocExpression.cs b/EplOnCppCore/Expressions/EocExpression.cs index a2f93c7..b55a93e 100644 --- a/EplOnCppCore/Expressions/EocExpression.cs +++ b/EplOnCppCore/Expressions/EocExpression.cs @@ -21,7 +21,7 @@ public EocExpression(CodeConverter c) public virtual void WriteToWithCast(CodeWriter writer, CppTypeName cast) { var exprType = GetResultType(); - if (cast == null || cast == ProjectConverter.CppTypeName_SkipCheck || cast == exprType) + if (cast == null || cast == EocDataTypes.Auto || cast == exprType) { WriteTo(writer); return; @@ -50,18 +50,18 @@ public virtual bool TryGetConstValueWithCast(CppTypeName cast, out object value) { if (!TryGetConstValue(out value)) return false; - var type = ProjectConverter.GetConstValueType(value); + var type = EocDataTypes.GetConstValueType(value); if (type == cast) return true; - if (P.IsArithmeticType(type) && P.IsArithmeticType(cast)) + if (EocDataTypes.IsArithmeticType(type) && EocDataTypes.IsArithmeticType(cast)) { var NumberConverter = new Dictionary> { - { ProjectConverter.CppTypeName_Byte, x => Convert.ToByte(x) }, - { ProjectConverter.CppTypeName_Short, x => Convert.ToInt16(x) }, - { ProjectConverter.CppTypeName_Int, x => Convert.ToInt32(x) }, - { ProjectConverter.CppTypeName_Long, x => Convert.ToInt64(x) }, - { ProjectConverter.CppTypeName_Float, x => Convert.ToSingle(x) }, - { ProjectConverter.CppTypeName_Double, x => Convert.ToDouble(x) }, + { EocDataTypes.Byte, x => Convert.ToByte(x) }, + { EocDataTypes.Short, x => Convert.ToInt16(x) }, + { EocDataTypes.Int, x => Convert.ToInt32(x) }, + { EocDataTypes.Long, x => Convert.ToInt64(x) }, + { EocDataTypes.Float, x => Convert.ToSingle(x) }, + { EocDataTypes.Double, x => Convert.ToDouble(x) }, }; if (NumberConverter.TryGetValue(cast, out var converter)) { diff --git a/EplOnCppCore/Expressions/EocMethodPtrExpression.cs b/EplOnCppCore/Expressions/EocMethodPtrExpression.cs index 3d12148..e766645 100644 --- a/EplOnCppCore/Expressions/EocMethodPtrExpression.cs +++ b/EplOnCppCore/Expressions/EocMethodPtrExpression.cs @@ -21,7 +21,7 @@ public EocMethodPtrExpression(CodeConverter c, EocCmdInfo cmdInfo) : base(c) public override CppTypeName GetResultType() { - return ProjectConverter.CppTypeName_MethodPtr; + return EocDataTypes.MethodPtr; } public override void WriteTo(CodeWriter writer) diff --git a/EplOnCppCore/Expressions/EocNumberLiteral.cs b/EplOnCppCore/Expressions/EocNumberLiteral.cs index 19976b5..c6abf16 100644 --- a/EplOnCppCore/Expressions/EocNumberLiteral.cs +++ b/EplOnCppCore/Expressions/EocNumberLiteral.cs @@ -40,7 +40,7 @@ public override CppTypeName GetResultType() { if (!TryGetConstValue(out var v)) throw new Exception(); - return ProjectConverter.GetConstValueType(v); + return EocDataTypes.GetConstValueType(v); } public override void WriteTo(CodeWriter writer) diff --git a/EplOnCppCore/Expressions/EocStringLiteral.cs b/EplOnCppCore/Expressions/EocStringLiteral.cs index 0e4a6b6..6400e4e 100644 --- a/EplOnCppCore/Expressions/EocStringLiteral.cs +++ b/EplOnCppCore/Expressions/EocStringLiteral.cs @@ -19,7 +19,7 @@ public EocStringLiteral(CodeConverter c, string value) : base(c) public override CppTypeName GetResultType() { - return ProjectConverter.CppTypeName_String; + return EocDataTypes.String; } public override void WriteTo(CodeWriter writer) diff --git a/EplOnCppCore/Expressions/EocVariableExpression.cs b/EplOnCppCore/Expressions/EocVariableExpression.cs index 803d1e4..a147523 100644 --- a/EplOnCppCore/Expressions/EocVariableExpression.cs +++ b/EplOnCppCore/Expressions/EocVariableExpression.cs @@ -13,19 +13,19 @@ public static EocVariableExpression Translate(CodeConverter C, VariableExpressio switch (EplSystemId.GetType(expr.Id)) { case EplSystemId.Type_Local: - if (C.ParamIdMap.TryGetValue(expr.Id, out var parameterInfo)) + if (C.ParamMap.TryGetValue(expr.Id, out var parameterInfo)) { return new EocVariableExpression(C, parameterInfo); } - var localVarInfo = C.LocalIdMap[expr.Id]; + var localVarInfo = C.LocalMap[expr.Id]; return new EocVariableExpression(C, localVarInfo); case EplSystemId.Type_ClassMember: - var classVar = C.P.ClassVarIdMap[expr.Id]; + var classVar = C.P.EocMemberMap[expr.Id]; return new EocVariableExpression(C, classVar); case EplSystemId.Type_Global: - var globalVar = C.P.GlobalVarIdMap[expr.Id]; + var globalVar = C.P.EocGlobalVariableMap[expr.Id].Info; return new EocVariableExpression(C, globalVar); case int x: @@ -33,91 +33,55 @@ public static EocVariableExpression Translate(CodeConverter C, VariableExpressio } } - public EocVariableExpression(CodeConverter c, AbstractVariableInfo variableInfo) : base(c) + public EocVariableExpression(CodeConverter c, EocVariableInfo variableInfo) : base(c) { VariableInfo = variableInfo; } - public AbstractVariableInfo VariableInfo { get; } + public EocVariableInfo VariableInfo { get; } public override CppTypeName GetResultType() { - return P.GetCppTypeName(VariableInfo); + return VariableInfo.DataType; } public override void WriteTo(CodeWriter writer) { - var name = P.GetUserDefinedName_SimpleCppName(VariableInfo.Id); switch (VariableInfo) { - case MethodParameterInfo v: - if (v.OptionalParameter) - { - writer.Write("eoc_value_"); - } - writer.Write(name); - break; - - case LocalVariableInfo v: - writer.Write(name); - break; - - case ClassVariableInfo v: + case EocMemberInfo x when !x.Static: if (C.IsClassMember) { writer.Write("this->"); } - else - { - writer.Write(C.ClassItem.CppName); - writer.Write("::"); - } - writer.Write(name); break; - - case GlobalVariableInfo v: - writer.Write(P.GlobalNamespace); - writer.Write("::"); - writer.Write(name); + case EocParameterInfo x when x.Optional: + writer.Write("eoc_value_"); break; - default: - throw new Exception("未知变量访问:" + P.IdToNameMap.GetUserDefinedName(VariableInfo.Id)); + break; } + writer.Write(VariableInfo.CppName); } public override void AnalyzeDependencies(AdjacencyGraph> graph) { base.AnalyzeDependencies(graph); string varRefId; - var name = P.GetUserDefinedName_SimpleCppName(VariableInfo.Id); switch (VariableInfo) { - case MethodParameterInfo _: - varRefId = $"{C.RefId}|{name}"; + case EocMemberInfo x when !x.Static: + varRefId = $"{C.ClassItem.RefId}|{x.CppName}"; break; - - case LocalVariableInfo _: - varRefId = $"{C.RefId}|{name}"; + case EocParameterInfo x: + varRefId = $"{C.RefId}|{x.CppName}"; break; - - case ClassVariableInfo _: - if (C.IsClassMember) - { - varRefId = $"{C.ClassItem.CppName}|{name}"; - } - else - { - varRefId = $"{C.ClassItem.CppName}::{name}"; - } - break; - - case GlobalVariableInfo _: - varRefId = $"{P.GlobalNamespace}::{name}"; + case EocLocalVariableInfo x: + varRefId = $"{C.RefId}|{x.CppName}"; break; - default: - throw new Exception("未知变量访问:" + P.IdToNameMap.GetUserDefinedName(VariableInfo.Id)); + varRefId = VariableInfo.CppName; + break; } graph.AddVerticesAndEdge(new Edge(C.RefId, varRefId)); } diff --git a/EplOnCppCore/ProjectConverter.cs b/EplOnCppCore/ProjectConverter.cs index a2865f9..a2be19c 100644 --- a/EplOnCppCore/ProjectConverter.cs +++ b/EplOnCppCore/ProjectConverter.cs @@ -1,4 +1,5 @@ -using QIQI.EProjectFile; +using QIQI.EplOnCpp.Core.Utils; +using QIQI.EProjectFile; using QIQI.EProjectFile.Expressions; using QIQI.EProjectFile.LibInfo; using QuickGraph; @@ -12,66 +13,6 @@ namespace QIQI.EplOnCpp.Core { public class ProjectConverter { - public readonly static CppTypeName CppTypeName_Bin = new CppTypeName(false, "e::system::bin"); - public readonly static CppTypeName CppTypeName_Bool = new CppTypeName(false, "bool"); - public readonly static CppTypeName CppTypeName_Byte = new CppTypeName(false, "uint8_t"); - public readonly static CppTypeName CppTypeName_DateTime = new CppTypeName(false, "e::system::datetime"); - public readonly static CppTypeName CppTypeName_Double = new CppTypeName(false, "double"); - public readonly static CppTypeName CppTypeName_Float = new CppTypeName(false, "float"); - public readonly static CppTypeName CppTypeName_Int = new CppTypeName(false, "int32_t"); - public readonly static CppTypeName CppTypeName_Long = new CppTypeName(false, "int64_t"); - public readonly static CppTypeName CppTypeName_Short = new CppTypeName(false, "int16_t"); - public readonly static CppTypeName CppTypeName_IntPtr = new CppTypeName(false, "intptr_t"); - public readonly static CppTypeName CppTypeName_MethodPtr = new CppTypeName(false, "e::system::methodptr"); - public readonly static CppTypeName CppTypeName_String = new CppTypeName(false, "e::system::string"); - public readonly static CppTypeName CppTypeName_Any = new CppTypeName(false, "e::system::any"); - public readonly static CppTypeName CppTypeName_SkipCheck = CppTypeName.Parse("*"); - - public static readonly Dictionary ConstTypeMap = new Dictionary() - { - { typeof(byte), CppTypeName_Byte }, - { typeof(short), CppTypeName_Short }, - { typeof(int), CppTypeName_Int }, - { typeof(long), CppTypeName_Long }, - { typeof(float), CppTypeName_Float }, - { typeof(double), CppTypeName_Double }, - { typeof(IntPtr), CppTypeName_IntPtr }, - { typeof(DateTime), CppTypeName_DateTime }, - { typeof(string), CppTypeName_String }, - { typeof(bool), CppTypeName_Bool } - }; - - internal static CppTypeName GetConstValueType(object value) - { - var type = value.GetType(); - var isArray = type.IsArray; - while (type.IsArray) - { - type = type.GetElementType(); - } - - return isArray - ? new CppTypeName(false, "e::system::array", new[] { ConstTypeMap[type] }) - : ConstTypeMap[type]; - } - - public static readonly Dictionary BasicCppTypeNameMap = new Dictionary { - { EplSystemId.DataType_Bin , CppTypeName_Bin }, - { EplSystemId.DataType_Bool , CppTypeName_Bool }, - { EplSystemId.DataType_Byte , CppTypeName_Byte }, - { EplSystemId.DataType_DateTime , CppTypeName_DateTime }, - { EplSystemId.DataType_Double , CppTypeName_Double }, - { EplSystemId.DataType_Float , CppTypeName_Float }, - { EplSystemId.DataType_Int , CppTypeName_Int }, - { EplSystemId.DataType_Long , CppTypeName_Long }, - { EplSystemId.DataType_Short , CppTypeName_Short }, - { EplSystemId.DataType_MethodPtr , CppTypeName_MethodPtr }, - { EplSystemId.DataType_String , CppTypeName_String }, - { EplSystemId.DataType_Any , CppTypeName_Any } - }; - - public static readonly CppTypeName EocErrorType = new CppTypeName(false, "EOC_ERROR_TYPE"); - /// /// 使用new ProjectConverter(...).Generate(...)替代 /// @@ -90,21 +31,17 @@ public static void Convert(EProjectFile.EProjectFile source, string dest, EocPro public int EocHelperLibId { get; } public int DataTypeId_IntPtr { get; } public EocProjectType ProjectType { get; } - public EocConstant[] EocConstants { get; set; } - public EocStruct[] EocStructs { get; set; } - public EocGlobalVariable[] EocGlobalVariables { get; set; } - public EocDll[] EocDllDeclares { get; set; } - public EocObjectClass[] EocObjectClasses { get; set; } - public EocStaticClass[] EocStaticClasses { get; set; } - public EocDllExport[] EocDllExports { get; set; } + public SortedDictionary EocConstantMap { get; set; } + public SortedDictionary EocStructMap { get; set; } + public SortedDictionary EocGlobalVariableMap { get; set; } + public SortedDictionary EocDllDeclareMap { get; set; } + public SortedDictionary EocObjectClassMap { get; set; } + public SortedDictionary EocStaticClassMap { get; set; } + public SortedDictionary EocDllExportMap { get; set; } + public SortedDictionary EocMemberMap { get; set; } + public SortedDictionary EocMethodMap { get; set; } public IdToNameMap IdToNameMap { get; } - public Dictionary ClassIdMap { get; } public Dictionary MethodIdMap { get; } - public Dictionary DllIdMap { get; } - public Dictionary StructIdMap { get; } - public Dictionary GlobalVarIdMap { get; } - public Dictionary ConstantIdMap { get; } - public Dictionary ClassVarIdMap { get; } //MethodInfo.Class 似乎并不可靠 public Dictionary MethodIdToClassMap { get; } @@ -139,19 +76,12 @@ public ProjectConverter(EProjectFile.EProjectFile source, EocProjectType project } 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(); this.MethodIdToClassMap = new Dictionary(); 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"; @@ -192,15 +122,28 @@ public ProjectConverter(EProjectFile.EProjectFile source, EocProjectType project 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)); + 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.EocDllExports = EocDllExport.Translate(this, Source.Code.Methods.Where(x => x.IsStatic && x.Public)); + this.EocDllExportMap = EocDllExport.Translate(this, Source.Code.Methods.Where(x => x.IsStatic && x.Public).Select(x => x.Id)); } } @@ -220,28 +163,55 @@ public void Generate(string dest) Directory.CreateDirectory(dest); this.SourceFiles = new List(); - foreach (var eocObjectClass in EocObjectClasses) + foreach (var eocObjectClass in EocObjectClassMap.Values) { eocObjectClass.ParseCode(); - eocObjectClass.Optimize(); } - - foreach (var eocStaticClass in EocStaticClasses) + foreach (var eocStaticClass in EocStaticClassMap.Values) { eocStaticClass.ParseCode(); + } + + foreach (var eocObjectClass in EocObjectClassMap.Values) + { + eocObjectClass.Optimize(); + } + foreach (var eocStaticClass in EocStaticClassMap.Values) + { 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 (EocDllExports != null) + foreach (var x in EocConstantMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } + foreach (var x in EocStructMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } + foreach (var x in EocGlobalVariableMap.Values) { - Array.ForEach(EocDllExports, x => x.AnalyzeDependencies(DependencyGraph)); + x.AnalyzeDependencies(DependencyGraph); + } + foreach (var x in EocDllDeclareMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } + foreach (var x in EocObjectClassMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } + foreach (var x in EocStaticClassMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } + if (EocDllExportMap != null) + { + foreach (var x in EocDllExportMap.Values) + { + x.AnalyzeDependencies(DependencyGraph); + } } if (Source.InitEcSectionInfo != null) { @@ -261,14 +231,14 @@ public void Generate(string dest) 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(); + EocConstantMap = EocConstantMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId)); + EocStructMap = EocStructMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId)); + EocGlobalVariableMap = EocGlobalVariableMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId)); + EocDllDeclareMap = EocDllDeclareMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId)); + EocObjectClassMap = EocObjectClassMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId)); + foreach (var x in EocObjectClassMap.Values) { x.RemoveUnusedCode(Dependencies); } + foreach (var x in EocStaticClassMap.Values) { x.RemoveUnusedCode(Dependencies); } + EocStaticClassMap = EocStaticClassMap.FilterSortedDictionary(x => x.Value.Method.Count != 0); //依赖信息 File.WriteAllText(Path.Combine(dest, "Dependencies.txt"), string.Join("\r\n", this.Dependencies), Encoding.UTF8); @@ -278,9 +248,9 @@ public void Generate(string dest) //常量 using (var writer = NewCodeFileByCppName(dest, ConstantNamespace, "h")) - EocConstant.Define(this, writer, EocConstants); + EocConstant.Define(this, writer, EocConstantMap); using (var writer = NewCodeFileByCppName(dest, ConstantNamespace, "cpp")) - EocConstant.Implement(this, writer, EocConstants); + EocConstant.Implement(this, writer, EocConstantMap); //声明自定义数据类型(结构/对象类) using (var writer = NewCodeFileByCppName(dest, TypeNamespace, "h")) @@ -289,14 +259,14 @@ public void Generate(string dest) } //实现 对象类 - foreach (var item in EocObjectClasses) + foreach (var item in EocObjectClassMap.Values) { using (var writer = NewCodeFileByCppName(dest, item.CppName, "cpp")) item.ImplementRawObjectClass(writer); } //静态类 - foreach (var item in EocStaticClasses) + foreach (var item in EocStaticClassMap.Values) { using (var writer = NewCodeFileByCppName(dest, item.CppName, "h")) item.Define(writer); @@ -306,15 +276,15 @@ public void Generate(string dest) //全局变量 using (var writer = NewCodeFileByCppName(dest, GlobalNamespace, "h")) - EocGlobalVariable.Define(this, writer, EocGlobalVariables); + EocGlobalVariable.Define(this, writer, EocGlobalVariableMap); using (var writer = NewCodeFileByCppName(dest, GlobalNamespace, "cpp")) - EocGlobalVariable.Implement(this, writer, EocGlobalVariables); + EocGlobalVariable.Implement(this, writer, EocGlobalVariableMap); //DLL using (var writer = NewCodeFileByCppName(dest, DllNamespace, "h")) - EocDll.Define(this, writer, EocDllDeclares); + EocDll.Define(this, writer, EocDllDeclareMap); using (var writer = NewCodeFileByCppName(dest, DllNamespace, "cpp")) - EocDll.Implement(this, writer, EocDllDeclares); + EocDll.Implement(this, writer, EocDllDeclareMap); //预编译头 using (var writer = NewCodeFileByCppName(dest, "stdafx", "h")) @@ -325,14 +295,14 @@ public void Generate(string dest) MakeProgramEntry(writer); //Dll导出 - if (EocDllExports != null) + if (EocDllExportMap != null) { using (var writer = NewCodeFileByCppName(dest, "dll_export", "cpp")) - EocDllExport.Implement(this, writer, EocDllExports); + EocDllExport.Implement(this, writer, EocDllExportMap); fileName = Path.Combine(dest, "dll_export.def"); using (var writer = new StreamWriter(File.Create(fileName), Encoding.UTF8)) { - EocDllExport.MakeDef(this, writer, EocDllExports); + EocDllExport.MakeDef(this, writer, EocDllExportMap); } } @@ -361,7 +331,7 @@ private void MakeStandardHeader(CodeWriter writer) writer.Write("#include \"e/user/dll.h\""); writer.NewLine(); writer.Write("#include \"e/user/global.h\""); - foreach (var item in EocStaticClasses) + foreach (var item in EocStaticClassMap.Values) { var includeName = item.CppName.Replace("::", "/") + ".h"; writer.NewLine(); @@ -534,20 +504,20 @@ private void DefineAllTypes(CodeWriter writer) { using (writer.NewNamespace("eoc_internal")) { - EocStruct.DefineRawName(this, writer, EocStructs); - EocObjectClass.DefineRawName(this, writer, EocObjectClasses); + EocStruct.DefineRawName(this, writer, EocStructMap); + EocObjectClass.DefineRawName(this, writer, EocObjectClassMap); } - EocStruct.DefineName(this, writer, EocStructs); - EocObjectClass.DefineName(this, writer, EocObjectClasses); + EocStruct.DefineName(this, writer, EocStructMap); + EocObjectClass.DefineName(this, writer, EocObjectClassMap); using (writer.NewNamespace("eoc_internal")) { - EocStruct.DefineRawStructInfo(this, writer, EocStructs); - EocObjectClass.DefineRawObjectClass(this, writer, EocObjectClasses); + EocStruct.DefineRawStructInfo(this, writer, EocStructMap); + EocObjectClass.DefineRawObjectClass(this, writer, EocObjectClassMap); } } using (writer.NewNamespace("e::system")) { - EocStruct.DefineStructMarshaler(this, writer, EocStructs); + EocStruct.DefineStructMarshaler(this, writer, EocStructMap); } } @@ -584,13 +554,13 @@ public void AnalyzeDependencies(AdjacencyGraph> graph, Eoc AnalyzeDependencies(graph, refId, info.ReturnDataType); foreach (var x in info.Parameters) { - var varRefId = $"{refId}|{x.Name}"; + var varRefId = $"{refId}|{x.CppName}"; graph.AddVerticesAndEdge(new Edge(refId, varRefId)); AnalyzeDependencies(graph, varRefId, x.DataType); } } - internal void InitMembersInConstructor(CodeWriter writer, IEnumerable collection) + internal void InitMembersInConstructor(CodeWriter writer, IEnumerable collection) { bool first = true; foreach (var item in collection) @@ -599,15 +569,14 @@ internal void InitMembersInConstructor(CodeWriter writer, IEnumerable collection, bool initAtOnce = true) + internal void DefineVariable(CodeWriter writer, string[] modifiers, IEnumerable collection, bool initAtOnce = true) { foreach (var item in collection) { @@ -653,7 +622,7 @@ public string[] GetParamNameFromInfo(List infos) string[] result = new string[infos.Count]; for (int i = 0; i < infos.Count; i++) { - result[i] = infos[i].Name ?? $"_AnonymousParameter{i + 1}"; + result[i] = infos[i].CppName ?? $"_AnonymousParameter{i + 1}"; } return result; } @@ -765,17 +734,7 @@ public EocMemberInfo GetEocMemberInfo(int libId, int structId, int id) public EocMemberInfo GetEocMemberInfo(int structId, int id) { - var cppName = GetUserDefinedName_SimpleCppName(id); - - var structInfo = StructIdMap[structId]; - var memberInfo = Array.Find(structInfo.Member, x => x.Id == id); - var dataType = GetCppTypeName(memberInfo.DataType, memberInfo.UBound); - - return new EocMemberInfo() - { - CppName = cppName, - DataType = dataType - }; + return EocMemberMap[id]; } public EocConstantInfo GetEocConstantInfo(EmnuConstantExpression expr) @@ -796,7 +755,7 @@ public EocConstantInfo GetEocConstantInfo(EmnuConstantExpression expr) if (result.Value is long longValue) if ((int)longValue == longValue) result.Value = (int)longValue; - result.DataType = GetConstValueType(result.Value); + result.DataType = EocDataTypes.GetConstValueType(result.Value); } return result; } @@ -829,7 +788,7 @@ public EocConstantInfo GetEocConstantInfo(int libraryId, int id) if (result.Value is long longValue) if ((int)longValue == longValue) result.Value = (int)longValue; - result.DataType = GetConstValueType(result.Value); + result.DataType = EocDataTypes.GetConstValueType(result.Value); } return result; } @@ -837,61 +796,7 @@ public EocConstantInfo GetEocConstantInfo(int libraryId, int id) public EocConstantInfo GetEocConstantInfo(int id) { - var cppName = ConstantNamespace + "::" + GetUserDefinedName_SimpleCppName(id); - string getter = null; - var constantInfo = ConstantIdMap[id]; - CppTypeName dataType; - switch (constantInfo.Value) - { - case double v: - if ((int)v == v) - { - dataType = CppTypeName_Int; - } - else if ((long)v == v) - { - dataType = CppTypeName_Long; - } - else - { - dataType = CppTypeName_Double; - } - break; - - case bool _: - dataType = CppTypeName_Bool; - break; - - case DateTime _: - dataType = CppTypeName_DateTime; - break; - - case string _: - dataType = CppTypeName_String; - getter = cppName; - cppName = null; - break; - - case byte[] _: - dataType = CppTypeName_Bin; - getter = cppName; - cppName = null; - break; - - case null: - return null; - - default: - throw new Exception(); - } - - return new EocConstantInfo() - { - CppName = cppName, - Getter = getter, - DataType = dataType, - Value = constantInfo.Value - }; + return EocConstantMap[id].Info; } public EocCmdInfo GetEocCmdInfo(CallExpression expr) @@ -939,60 +844,16 @@ public EocCmdInfo GetEocCmdInfo(int id) switch (EplSystemId.GetType(id)) { case EplSystemId.Type_Method: - return GetEocCmdInfo(MethodIdMap[id]); + return EocMethodMap[id].Info; case EplSystemId.Type_Dll: - return GetEocCmdInfo(DllIdMap[id]); + return EocDllDeclareMap[id].Info; default: throw new Exception(); } } - public EocCmdInfo GetEocCmdInfo(DllDeclareInfo x) - { - return new EocCmdInfo() - { - ReturnDataType = x.ReturnDataType == 0 ? null : GetCppTypeName(x.ReturnDataType), - CppName = GetCppMethodName(x.Id), - Parameters = x.Parameters.Select(GetEocParameterInfo).ToList() - }; - } - - public EocCmdInfo GetEocCmdInfo(MethodInfo x) - { - return new EocCmdInfo() - { - ReturnDataType = x.ReturnDataType == 0 ? null : GetCppTypeName(x.ReturnDataType), - CppName = GetCppMethodName(x.Id), - Parameters = x.Parameters.Select(GetEocParameterInfo).ToList() - }; - } - - public EocParameterInfo GetEocParameterInfo(MethodParameterInfo x) - { - return new EocParameterInfo() - { - ByRef = x.ByRef || x.ArrayParameter || !IsValueType(x.DataType), - Optional = x.OptionalParameter, - VarArgs = false, - DataType = GetCppTypeName(x.DataType, x.ArrayParameter), - Name = GetUserDefinedName_SimpleCppName(x.Id) - }; - } - - public EocParameterInfo GetEocParameterInfo(DllParameterInfo x) - { - return new EocParameterInfo() - { - ByRef = x.ByRef || x.ArrayParameter || !IsValueType(x.DataType), - Optional = false, - VarArgs = false, - DataType = GetCppTypeName(x.DataType, x.ArrayParameter), - Name = GetUserDefinedName_SimpleCppName(x.Id) - }; - } - public string GetParameterTypeString(EocParameterInfo x) { var r = x.DataType.ToString(); @@ -1011,364 +872,5 @@ public string GetParameterTypeString(EocParameterInfo x) } #endregion MethodInfoHelper - - #region TypeInfoHelper - - public CppTypeName GetCppTypeName(AbstractVariableInfo x) - { - if (x is MethodParameterInfo parameterInfo) - return GetCppTypeName(parameterInfo.DataType, parameterInfo.ArrayParameter); - return GetCppTypeName(x.DataType, x.UBound); - } - - public CppTypeName GetCppTypeName(int id, int[] uBound) - { - return GetCppTypeName(id, uBound != null && uBound.Length != 0); - } - - public CppTypeName GetCppTypeName(int id, bool isArray = false) - { - id = TranslateDataTypeId(id); - if (id == DataTypeId_IntPtr) - { - return CppTypeName_IntPtr; - } - if (!BasicCppTypeNameMap.TryGetValue(id, out var result)) - { - if (EplSystemId.GetType(id) == EplSystemId.Type_Class - || EplSystemId.GetType(id) == EplSystemId.Type_Struct) - { - result = new CppTypeName(false, TypeNamespace + "::" + GetUserDefinedName_SimpleCppName(id)); - } - else - { - EplSystemId.DecomposeLibDataTypeId(id, out var libId, out var typeId); - - if (Libs[libId] == null) - { - return EocErrorType; - } - if (typeId >= Libs[libId].DataType.Length) - { - return EocErrorType; - } - var name = Libs[libId].DataType[typeId].Name; - if (EocLibs[libId] == null) - { - return EocErrorType; - } - if (!EocLibs[libId].Type.ContainsKey(name)) - { - return EocErrorType; - } - result = EocLibs[libId].Type[name].CppName; - } - } - if (isArray) - result = new CppTypeName(false, "e::system::array", new[] { result }); - return result; - } - - public int TranslateDataTypeId(int dataType) - { - if (dataType == 0) - return EplSystemId.DataType_Int; - if (EplSystemId.IsLibDataType(dataType) && dataType != DataTypeId_IntPtr) - { - EplSystemId.DecomposeLibDataTypeId(dataType, out var libId, out var typeId); - try - { - if (Libs[libId].DataType[typeId].IsEnum) - return EplSystemId.DataType_Int; - } - catch (Exception) - { - } - try - { - if (EocLibs[libId].Enum.ContainsKey(Libs[libId].DataType[typeId].Name)) - return EplSystemId.DataType_Int; - } - catch (Exception) - { - } - } - return dataType; - } - - /// - /// 不保证与字节数相等,只保证数值大的类型大 - /// - /// - /// - public int GetIntNumberTypeSize(CppTypeName dataType) - { - if (dataType == CppTypeName_Byte) - { - return 1; - } - else if (dataType == CppTypeName_Short) - { - return 2; - } - else if (dataType == CppTypeName_Int) - { - return 4; - } - else if (dataType == CppTypeName_Long) - { - return 8; - } - else - { - throw new ArgumentException(); - } - } - - /// - /// 不保证与字节数相等,只保证数值大的类型大 - /// - /// - /// - public int GetIntNumberTypeSize(int dataType) - { - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Byte: - return 1; - - case EplSystemId.DataType_Short: - return 2; - - case EplSystemId.DataType_Int: - return 4; - - case EplSystemId.DataType_Long: - return 8; - - default: - throw new ArgumentException(); - } - } - - /// - /// 不保证与字节数相等,只保证数值大的类型大 - /// - /// - /// - public int GetFloatNumberTypeSize(CppTypeName dataType) - { - if (dataType == CppTypeName_Float) - { - return 4; - } - else if (dataType == CppTypeName_Double) - { - return 8; - } - else - { - throw new ArgumentException(); - } - } - - /// - /// 不保证与字节数相等,只保证数值大的类型大 - /// - /// - /// - public int GetFloatNumberTypeSize(int dataType) - { - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Float: - return 4; - - case EplSystemId.DataType_Double: - return 8; - - default: - throw new ArgumentException(); - } - } - - public bool IsFloatNumberType(CppTypeName dataType) - { - if (dataType == CppTypeName_Float - || dataType == CppTypeName_Double) - { - return true; - } - else - { - return false; - } - } - - public bool IsFloatNumberType(int dataType) - { - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Float: - case EplSystemId.DataType_Double: - return true; - - default: - return false; - } - } - - public bool IsIntNumberType(CppTypeName dataType) - { - if (dataType == CppTypeName_Byte - || dataType == CppTypeName_Short - || dataType == CppTypeName_Int - || dataType == CppTypeName_Long) - { - return true; - } - else - { - return false; - } - } - - public bool IsIntNumberType(int dataType) - { - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Byte: - case EplSystemId.DataType_Int: - case EplSystemId.DataType_Long: - case EplSystemId.DataType_Short: - return true; - - default: - return false; - } - } - - public bool IsArithmeticType(CppTypeName dataType) - { - return IsIntNumberType(dataType) || IsFloatNumberType(dataType) || dataType == CppTypeName_IntPtr; - } - - public bool IsArithmeticType(int dataType) - { - return IsIntNumberType(dataType) || IsFloatNumberType(dataType) || dataType == DataTypeId_IntPtr; - } - - public bool IsValueType(CppTypeName dataType) - { - if (dataType == CppTypeName_Bool - || dataType == CppTypeName_DateTime - || dataType == CppTypeName_MethodPtr - || IsArithmeticType(dataType)) - { - return true; - } - else - { - return false; - } - } - - public bool IsValueType(int dataType) - { - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Bool: - case EplSystemId.DataType_DateTime: - case EplSystemId.DataType_MethodPtr: - case var x when IsArithmeticType(x): - return true; - - default: - return false; - } - } - - public string GetInitValue(int dataType, bool isArray) - { - return GetInitValue(dataType, isArray ? new int[] { 0 } : null); - } - - public string GetInitValue(int dataType, int[] uBound) - { - return GetCppTypeName(dataType, uBound != null && uBound.Length != 0) + "(" + GetInitParameter(dataType, uBound) + ")"; - } - - public string GetInitParameter(int dataType, bool isArray) - { - return GetInitParameter(dataType, isArray ? new int[] { 0 } : null); - } - - public string GetInitParameter(int dataType, int[] uBound) - { - if (uBound != null && uBound.Length != 0) - { - if (uBound[0] == 0) - { - return "nullptr"; - } - return string.Join(", ", uBound.Select(x => x + "u")); - } - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Bool: - return "false"; - - case EplSystemId.DataType_Byte: - case EplSystemId.DataType_DateTime: - case EplSystemId.DataType_Double: - case EplSystemId.DataType_Float: - case EplSystemId.DataType_Int: - case EplSystemId.DataType_Long: - case EplSystemId.DataType_Short: - case var x when x == DataTypeId_IntPtr: - return "0"; - - case EplSystemId.DataType_MethodPtr: - return "nullptr"; - - default: - return ""; - } - } - - public string GetNullParameter(int dataType, bool isArray = false) - { - if (isArray) - { - return "nullptr"; - } - dataType = TranslateDataTypeId(dataType); - switch (dataType) - { - case EplSystemId.DataType_Bool: - return "false"; - - case EplSystemId.DataType_Byte: - case EplSystemId.DataType_DateTime: - case EplSystemId.DataType_Double: - case EplSystemId.DataType_Float: - case EplSystemId.DataType_Int: - case EplSystemId.DataType_Long: - case EplSystemId.DataType_Short: - case var x when x == DataTypeId_IntPtr: - return "0"; - - default: - return "nullptr"; - } - } - - #endregion TypeInfoHelper } } \ No newline at end of file diff --git a/EplOnCppCore/Statements/EocDoWhileStatement.cs b/EplOnCppCore/Statements/EocDoWhileStatement.cs index 72c156d..db7cf94 100644 --- a/EplOnCppCore/Statements/EocDoWhileStatement.cs +++ b/EplOnCppCore/Statements/EocDoWhileStatement.cs @@ -71,7 +71,7 @@ public override void WriteTo(CodeWriter writer) Block.WriteTo(writer); } writer.Write("while ("); - Condition.WriteToWithCast(writer, ProjectConverter.CppTypeName_Bool); + Condition.WriteToWithCast(writer, EocDataTypes.Bool); writer.Write("); "); writer.AddComment(CommentOnEnd); } diff --git a/EplOnCppCore/Statements/EocIfElseStatement.cs b/EplOnCppCore/Statements/EocIfElseStatement.cs index e087f91..1a2ab55 100644 --- a/EplOnCppCore/Statements/EocIfElseStatement.cs +++ b/EplOnCppCore/Statements/EocIfElseStatement.cs @@ -36,7 +36,7 @@ public EocIfElseStatement(CodeConverter c, EocExpression condition, EocStatement public override EocStatement Optimize() { Condition = Condition?.Optimize(); - if (Condition.TryGetConstValueWithCast(ProjectConverter.CppTypeName_Bool, out var x)) + if (Condition.TryGetConstValueWithCast(EocDataTypes.Bool, out var x)) { if ((bool)x == true) { @@ -71,7 +71,7 @@ public override void WriteTo(CodeWriter writer) writer.Write("// "); writer.Write("if ("); - Condition.WriteToWithCast(writer, ProjectConverter.CppTypeName_Bool); + Condition.WriteToWithCast(writer, EocDataTypes.Bool); writer.Write(")"); writer.AddComment(Comment); using (writer.NewBlock()) diff --git a/EplOnCppCore/Statements/EocIfStatement.cs b/EplOnCppCore/Statements/EocIfStatement.cs index 1faee3c..552c313 100644 --- a/EplOnCppCore/Statements/EocIfStatement.cs +++ b/EplOnCppCore/Statements/EocIfStatement.cs @@ -25,7 +25,7 @@ public static EocIfStatement Translate(CodeConverter C, IfStatement stat) public override EocStatement Optimize() { Condition = Condition?.Optimize(); - if (!Mask && Condition.TryGetConstValueWithCast(ProjectConverter.CppTypeName_Bool, out var x)) + if (!Mask && Condition.TryGetConstValueWithCast(EocDataTypes.Bool, out var x)) { if ((bool)x == false) { @@ -61,7 +61,7 @@ public override void WriteTo(CodeWriter writer) if (Mask) writer.Write("// "); writer.Write("if ("); - Condition.WriteToWithCast(writer, ProjectConverter.CppTypeName_Bool); + Condition.WriteToWithCast(writer, EocDataTypes.Bool); writer.Write(")"); writer.AddComment(Comment); using (writer.NewBlock()) diff --git a/EplOnCppCore/Statements/EocSwitchStatement.cs b/EplOnCppCore/Statements/EocSwitchStatement.cs index 82e86ad..761fc75 100644 --- a/EplOnCppCore/Statements/EocSwitchStatement.cs +++ b/EplOnCppCore/Statements/EocSwitchStatement.cs @@ -70,7 +70,7 @@ public override void WriteTo(CodeWriter writer) writer.NewLine(); writer.Write(i == 0 ? "if" : "else if"); writer.Write(" ("); - Case[i].Condition.WriteToWithCast(writer, ProjectConverter.CppTypeName_Bool); + Case[i].Condition.WriteToWithCast(writer, EocDataTypes.Bool); writer.Write(")"); using (writer.NewBlock()) { diff --git a/EplOnCppCore/Statements/EocWhileStatement.cs b/EplOnCppCore/Statements/EocWhileStatement.cs index be2ef0d..f94b5ac 100644 --- a/EplOnCppCore/Statements/EocWhileStatement.cs +++ b/EplOnCppCore/Statements/EocWhileStatement.cs @@ -65,7 +65,7 @@ public override void WriteTo(CodeWriter writer) } writer.NewLine(); writer.Write("while ("); - Condition.WriteToWithCast(writer, ProjectConverter.CppTypeName_Bool); + Condition.WriteToWithCast(writer, EocDataTypes.Bool); writer.Write(")"); writer.AddComment(CommentOnStart); using (writer.NewBlock()) diff --git a/EplOnCppCore/GraphUtils.cs b/EplOnCppCore/Utils/GraphUtils.cs similarity index 97% rename from EplOnCppCore/GraphUtils.cs rename to EplOnCppCore/Utils/GraphUtils.cs index 826e204..9732d79 100644 --- a/EplOnCppCore/GraphUtils.cs +++ b/EplOnCppCore/Utils/GraphUtils.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; -namespace QIQI.EplOnCpp.Core +namespace QIQI.EplOnCpp.Core.Utils { public class GraphUtils { diff --git a/EplOnCppCore/Utils/LinqEx.cs b/EplOnCppCore/Utils/LinqEx.cs new file mode 100644 index 0000000..be7030c --- /dev/null +++ b/EplOnCppCore/Utils/LinqEx.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace QIQI.EplOnCpp.Core.Utils +{ + internal static class LinqEx + { + public static SortedDictionary ToSortedDictionary( + this IEnumerable> source) + { + var result = new SortedDictionary(); + foreach (var item in source) + { + result.Add(item.Key, item.Value); + } + return result; + } + + public static SortedDictionary ToSortedDictionary( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + var result = new SortedDictionary(); + foreach (var item in source) + { + result.Add(keySelector(item), elementSelector(item)); + } + return result; + } + + public static SortedDictionary FilterSortedDictionary( + this IDictionary source, + Func, bool> predicate) + { + var result = new SortedDictionary(); + foreach (var item in source) + { + if (predicate(item)) + { + result.Add(item.Key, item.Value); + } + } + return result; + } + } +}