Exemplo n.º 1
0
        public static void DefineStructMarshaler(ProjectConverter P, CodeWriter writer, EocStruct[] collection)
        {
            //In e::system
            var map   = collection.ToDictionary(x => x.RawInfo.Id);
            var graph = new AdjacencyGraph <EocStruct, IEdge <EocStruct> >();

            foreach (var item in collection)
            {
                var hasDependentItem = false;
                foreach (var member in item.RawInfo.Member)
                {
                    if (EplSystemId.GetType(member.DataType) == EplSystemId.Type_Struct &&
                        map.TryGetValue(member.DataType, out var memberType))
                    {
                        graph.AddVerticesAndEdge(new Edge <EocStruct>(memberType, item));
                        hasDependentItem = true;
                    }
                }
                if (!hasDependentItem)
                {
                    graph.AddVertex(item);
                }
            }

            foreach (var item in graph.TopologicalSort())
            {
                item.DefineStructMarshaler(writer);
            }
        }
Exemplo n.º 2
0
        public static EocVariableExpression Translate(CodeConverter C, VariableExpression expr)
        {
            if (expr == null)
            {
                return(null);
            }
            switch (EplSystemId.GetType(expr.Id))
            {
            case EplSystemId.Type_Local:
                if (C.ParamIdMap.TryGetValue(expr.Id, out var parameterInfo))
                {
                    return(new EocVariableExpression(C, parameterInfo));
                }
                var localVarInfo = C.LocalIdMap[expr.Id];
                return(new EocVariableExpression(C, localVarInfo));

            case EplSystemId.Type_ClassMember:
                var classVar = C.P.ClassVarIdMap[expr.Id];
                return(new EocVariableExpression(C, classVar));

            case EplSystemId.Type_Global:
                var globalVar = C.P.GlobalVarIdMap[expr.Id];
                return(new EocVariableExpression(C, globalVar));

            case int x:
                throw new Exception("未知变量类型:0x" + x.ToString("X8"));
            }
        }
Exemplo n.º 3
0
 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 override void ToTextCode(IdToNameMap nameMap, StringBuilder result, int indent = 0)
 {
     if (Target is VariableExpression varExpr &&
         EplSystemId.GetType(varExpr.Id) == EplSystemId.Type_FormSelf)
     {
         // 在窗口程序集直接访问窗口系统属性的情况
         // Do nothing
     }
Exemplo n.º 5
0
        public EocCmdInfo GetEocCmdInfo(int id)
        {
            switch (EplSystemId.GetType(id))
            {
            case EplSystemId.Type_Method:
                return(EocMethodMap[id].Info);

            case EplSystemId.Type_Dll:
                return(EocDllDeclareMap[id].Info);

            default:
                throw new Exception();
            }
        }
Exemplo n.º 6
0
        public EocCmdInfo GetEocCmdInfo(int id)
        {
            switch (EplSystemId.GetType(id))
            {
            case EplSystemId.Type_Method:
                return(GetEocCmdInfo(MethodIdMap[id]));

            case EplSystemId.Type_Dll:
                return(GetEocCmdInfo(DllIdMap[id]));

            default:
                throw new Exception();
            }
        }
Exemplo n.º 7
0
 public EocClass(ProjectConverter p, ClassInfo rawInfo)
 {
     P       = p ?? throw new ArgumentNullException(nameof(p));
     RawInfo = rawInfo ?? throw new ArgumentNullException(nameof(rawInfo));
     Name    = P.GetUserDefinedName_SimpleCppName(RawInfo.Id);
     if (EplSystemId.GetType(rawInfo.Id) == EplSystemId.Type_Class)
     {
         CppName = $"{P.TypeNamespace}::{Name}";
     }
     else
     {
         CppName = $"{P.CmdNamespace}::{Name}";
     }
     Method = RawInfo.Method.Select(x => P.MethodIdMap[x]).Select(x => new CodeConverter(P, this, x)).ToList();
 }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        public string GetCppMethodName(int id)
        {
            switch (EplSystemId.GetType(id))
            {
            case EplSystemId.Type_Method:
                if (EplSystemId.GetType(MethodIdToClassMap[id].Id) == EplSystemId.Type_Class)
                {
                    return(GetUserDefinedName_SimpleCppName(id));
                }
                else
                {
                    return(CmdNamespace + "::" + GetUserDefinedName_SimpleCppName(id));
                }

            case EplSystemId.Type_Dll:
                return(DllNamespace + "::" + GetUserDefinedName_SimpleCppName(id));

            default:
                throw new Exception();
            }
        }
Exemplo n.º 11
0
 public int TranslateDataTypeId(int dataType)
 {
     if (dataType == 0)
     {
         return(EplSystemId.DataType_Int);
     }
     if (EplSystemId.IsLibDataType(dataType))
     {
         EplSystemId.DecomposeLibDataTypeId(dataType, out var libId, out var typeId);
         try
         {
             if (EocLibs[libId].Enum.ContainsKey(Libs[libId].DataType[typeId].Name))
             {
                 return(EplSystemId.DataType_Int);
             }
         }
         catch (Exception)
         {
         }
     }
     return(dataType);
 }
Exemplo n.º 12
0
        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));
        }
Exemplo n.º 13
0
        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));
            }
        }
Exemplo n.º 14
0
 public override void ToTextCode(IdToNameMap nameMap, StringBuilder result, int indent = 0)
 {
     if (Target != null)
     {
         Target.ToTextCode(nameMap, result, indent);
         result.Append(".");
     }
     if (InvokeSpecial && LibraryId == -2)
     {
         if (nameMap.MethodIdToClassId.TryGetValue(MethodId, out var classId) && EplSystemId.GetType(classId) == EplSystemId.Type_Class)
         {
             result.Append(nameMap.GetUserDefinedName(classId));
             result.Append(".");
         }
     }
     result.Append(LibraryId == -2 || LibraryId == -3 ? nameMap.GetUserDefinedName(MethodId) : nameMap.GetLibCmdName(LibraryId, MethodId));
     result.Append(" ");
     ParamList.ToTextCode(nameMap, result, indent);
 }
Exemplo n.º 15
0
        private static EocCmdInfo InferEocCmdInfo(ProjectConverter P, MethodInfo rawInfo, StatementBlock rawStatementBlock)
        {
            var autoParam = new HashSet <int>();

            for (int i = 0; i < rawStatementBlock.Count;)
            {
                if (rawStatementBlock[i] is ExpressionStatement exprStat)
                {
                    var callExpr = exprStat.Expression;
                    if (callExpr != null && callExpr.LibraryId == P.EocHelperLibId)
                    {
                        var cmdName = P.IdToNameMap.GetLibCmdName(callExpr.LibraryId, callExpr.MethodId);
                        switch (cmdName)
                        {
                        case "EOC标记_自适应参数":
                            if (callExpr.ParamList.FirstOrDefault() is VariableExpression varExpr)
                            {
                                autoParam.Add(varExpr.Id);
                            }
                            rawStatementBlock.RemoveAt(i);
                            continue;
                        }
                    }
                }
                i++;
            }

            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) =>
                {
                    CppTypeName dataType;
                    if (autoParam.Contains(x.Id))
                    {
                        dataType = x.ArrayParameter ? EocDataTypes.ArrayOf(EocDataTypes.Auto) : EocDataTypes.Auto;
                    }
                    else
                    {
                        dataType = EocDataTypes.Translate(P, x.DataType, x.ArrayParameter);
                    }
                    if (dataType == EocDataTypes.Any && !x.ByRef)
                    {
                        //考虑到可空、参考(非基本类型强制参考、基本类型非参考)等问题,实现起来过于麻烦,暂时搁置
                        throw new NotImplementedException("暂不支持非参考自适应参数,请勾选 参考 或 贡献代码实现相应功能");
                    }
                    return new EocParameterInfo()
                    {
                        ByRef = x.ByRef || x.ArrayParameter || (!EocDataTypes.IsValueType(dataType) && dataType != EocDataTypes.Any),
                        Optional = x.OptionalParameter,
                        VarArgs = false,
                        DataType = dataType,
                        CppName = P.GetUserDefinedName_SimpleCppName(x.Id)
                    };
                }).ToList()
            });
        }