示例#1
0
文件: CppRender.cs 项目: ETLang/Gluon
        private string SignatureOf(AST.ICallSignature d, bool?abi = null)
        {
            var writer = new CppRender();
            var useabi = abi ?? Strata == ApiStrata.ABI;

            if (useabi)
            {
                writer.Code("HRESULT(");
            }
            else
            {
                writer.Code(GetParameterType(d.Return.InContext(AST.VariableContext.Return), abi));
                writer.Code("(");
            }

            writer.BeginList(useabi ? CodeListStyle.Compact : CodeListStyle.SingleLine);

            foreach (var arg in useabi ? d.GetABIParametersCpp(true) : d.Parameters)
            {
                writer.ListItem(GetParameterType(arg, useabi));
            }

            writer.EndList();
            writer.Code(")");

            return(writer.ToString());
        }
示例#2
0
        private void PreprocessDefinition()
        {
            Definition.ApplyTypeSubstitutions(Settings.TargetId);
            Definition.ApplyNamespaceSubsitutions(Settings.TargetId);

            foreach (var type in Definition.AllTypes)
            {
                if (type.Origin != TypeOrigin.Mapped)
                {
                    if (type.IsObject && type.Origin != TypeOrigin.Managed && type.Assembly == Definition.Assembly)
                    {
                        AllGeneratedClasses.Add((AST.Object)type);
                    }
                    else if (type.IsStruct)
                    {
                        AllGeneratedStructs.Add((AST.Struct)type);
                    }
                    else if (type.IsEnum && type.Origin != TypeOrigin.Managed && type.Assembly == Definition.Assembly)
                    {
                        AllGeneratedEnums.Add((AST.Enum)type);
                    }
                    else if (type.IsDelegate && !((AST.Delegate)type).IsGeneric)
                    {
                        AllGeneratedDelegates.Add((AST.Delegate)type);
                    }
                }
            }

            foreach (var type in Definition.AllTypes)
            {
                if (type.IsDelegate)
                {
                    AllTranslatedDelegates.Add((AST.Delegate)type);
                }
                else if (type.IsStruct && CppRender.RequiresABITranslation(type.ToVariable()))
                {
                    AllTranslatedStructs.Add((AST.Struct)type);
                }
            }

            Definition.StripAllGluonAttributes();
            Definition.PutDefaultConstructorsFirst();
            Definition.InsertDefaultConstructorsWhereNoneAreDefined();

            var builder = new AST.Builder(Definition);

            _assemblyNS = builder.Resolve(Definition.Assembly.Name);
            _gluonNS    = builder.Resolve("Gluon");
            builder.Resolve(typeof(DllImportAttribute));
            builder.Resolve(typeof(MarshalAsAttribute));
            builder.Resolve(typeof(GluonObject));
            builder.Resolve(typeof(DelegateBlob));
        }
示例#3
0
        public Dictionary <AST.Type, string> GenerateLocalTranslations(AST.Object type)
        {
            var localTranslations = CppRender.GetLocalTranslations(type);

            UseLocalTranslations = false;
            foreach (var kvp in localTranslations)
            {
                Line("using {0} = {1};", kvp.Value, TypeRef(kvp.Key, false));
            }
            UseLocalTranslations = true;

            return(localTranslations);
        }
示例#4
0
        public void GenerateWrapperImplementation(AST.Object type)
        {
            var localTranslations = CppRender.GetLocalTranslations(type);

            LocalTranslationsBlock(localTranslations, () =>
            {
                foreach (var ctor in type.Constructors.Where(c => c.Access == AST.Access.Public))
                {
                    WrapperConstructorImplementation(ctor, type);
                }

                Spacer();

                foreach (var member in type.Members.OrderBy(m => m.ConstructType))
                {
                    switch (member)
                    {
                    case AST.Constructor ctor:
                        break;

                    case AST.Property prop:
                        MethodImplementation(prop.CreateGetter().AsConst(), type);

                        if (!prop.IsReadOnly)
                        {
                            MethodImplementation(prop.CreateSetter().AsConst(), type);
                        }
                        break;

                    case AST.Event ev:
                        MethodImplementation(ev.CreateAdder().AsConst(), type);
                        MethodImplementation(ev.CreateRemover().AsConst(), type);
                        break;

                    case AST.Method method:
                        MethodImplementation(method.AsConst(), type);
                        break;

                    default:
                        throw new Exception("Oops, unhandled member type: " + member.ConstructType.ToString());
                    }
                }
            });
        }
示例#5
0
        public void GenerateStruct(AST.Struct type, bool abi)
        {
            var  strata = Strata;
            Guid id     = (strata == ApiStrata.ABI ? type.Id : type.PrivateId);

            Namespace(type.Namespace, abi, () =>
            {
                var localTranslations = CppRender.GetLocalTranslations(type);

                if (strata == ApiStrata.ABI)
                {
                    localTranslations = null;
                }

                var fields = type.Fields;

                Spacer();

                WriteXmlDocumentation(type.XmlDoc);
                Line("struct comid(\"{0}\") {1}", id, type.Name);
                Block(() =>
                {
                    if (strata == ApiStrata.Normal && CppRender.RequiresABITranslation(type.ToVariable()))
                    {
                        Line("typedef {0} ABIType;", TypeRef(type, true));
                        Spacer();
                    }

                    if (localTranslations != null)
                    {
                        UseLocalTranslations = false;
                        foreach (var kvp in localTranslations)
                        {
                            Line("using {0} = {1};", kvp.Value, TypeRef(kvp.Key, false));
                        }
                        UseLocalTranslations = true;
                        Spacer();
                    }

                    LocalTranslationsBlock(localTranslations, () =>
                    {
                        foreach (var field in fields)
                        {
                            WriteXmlDocumentation(field.XmlDoc);
                            Line("{0} {1};", VariableType(field, AST.VariableContext.Member), field.Name);
                        }

                        Spacer();

                        // Default constructor
                        Line("{0}() {{ }}", type.Name);

                        // Full constructor
                        var constructorArgs = fields.Select(f => f.Morph("_" + f.Name, AST.VariableContext.In));
                        if (strata == ApiStrata.ABI)
                        {
                            constructorArgs = constructorArgs.GetABIParametersCpp();
                        }

                        Line("{0}({1}) : ", type.Name, DeclParameters(constructorArgs));
                        Indent++;
                        List(() =>
                        {
                            foreach (var field in fields)
                            {
                                if (strata == ApiStrata.ABI && field.IsArray)
                                {
                                    ListItem("{0}(_{0}, _{0}_count)", field.Name);
                                }
                                else if (strata == ApiStrata.ABI && field.Type.IsDelegate)
                                {
                                    ListItem("{0}(_{0}, _{0}_context)", field.Name);
                                }
                                else
                                {
                                    ListItem("{0}(_{0})", field.Name);
                                }
                            }
                        });
                        Indent--;
                        Line();
                        Line("{ }");
                    });
                }, ";");
            });

            var prefix = (abi ? "::ABI" : "");

            if (type.Namespace.IsGlobal)
            {
                Line(@"IS_VALUETYPE({0}::{1}, ""{2}"");", prefix, type.Name, id);
            }
            else
            {
                Line(@"IS_VALUETYPE({0}::{1}::{2}, ""{3}"");", prefix, type.Namespace.FullName("::"), type.Name, id);
            }
        }
示例#6
0
        public void ABIWrappedCall(AST.ICallSignature m, string returnArg = null, string callNameOverride = null)
        {
            string name = m.Name;

            if (!string.IsNullOrEmpty(callNameOverride))
            {
                name = callNameOverride;
            }

            if (returnArg == null)
            {
                returnArg = m.Return.Name;
            }

            Code("try ");
            Block(() =>
            {
                var args = m.Parameters;

                if (!m.Return.IsVoid)
                {
                    if (m.Return.IsArray)
                    {
                        string refType = VariableType(m.Return.Type.ToVariable(), true);
                        Code("ABI::ArrayRef<{0}>({1}, {1}_count) = ABIUtil<{2}>::ToABI({3}(",
                             refType, returnArg, TypeRef(m.Return, false), name);
                    }
                    else if (m.Return.Type.IsDelegate)
                    {
                        string refType = TypeRef(m.Return.Type, true);
                        Code("ABI::DelegateRef<{0}>({1}, {1}_context) = ABIUtil<{2}>::ToABI({3}(",
                             refType, returnArg, TypeRef(m.Return, false), name);
                    }
                    else if (CppRender.RequiresABITranslation(m.Return))
                    {
                        Code("*{0} = ABIUtil<{1}>::ToABI({2}(", returnArg, TypeRef(m.Return, false), name);
                    }
                    else
                    {
                        Code("*{0} = {1}(", returnArg, name);
                    }
                }
                else
                {
                    Code($"{name}(");
                }

                if (args.Count > 1)
                {
                    Line();
                }

                List(args.Count > 1 ? CodeListStyle.MultiLine : CodeListStyle.SingleLine, () =>
                {
                    if (args.Count > 1)
                    {
                        Indent++;
                    }

                    foreach (var arg in args)
                    {
                        if (CppRender.RequiresABITranslation(arg))
                        {
                            string fwd;

                            if (arg.IsArray)
                            {
                                fwd = arg.Name + ", " + arg.Name + "_count";
                            }
                            else if (arg.Type.IsDelegate)
                            {
                                fwd = "(void**)" + arg.Name + ", " + arg.Name + "_context";
                            }
                            else
                            {
                                fwd = arg.Name;
                            }

                            if (arg.IsOut || arg.IsRef)
                            {
                                ListItem($"ABIUtil<{TypeRef(arg, false)}>::Ref({fwd})");
                            }
                            else
                            {
                                ListItem($"ABIUtil<{TypeRef(arg, false)}>::FromABI({fwd})");
                            }
                        }
                        else
                        {
                            ListItem(arg.Name);
                        }
                    }

                    if (args.Count > 1)
                    {
                        Indent--;
                    }
                });

                if (!m.Return.IsVoid && CppRender.RequiresABITranslation(m.Return))
                {
                    Line("));");
                }
                else
                {
                    Line(");");
                }
                Line("return S_OK;");
            }, " TRANSLATE_EXCEPTIONS");
        }
示例#7
0
        public void CallToABIMethodBody(AST.ICallSignature m, params string[] prependArgs)
        {
            AST.IVariable returnArg;

            bool isCtor = m.Return == null;

            if (!isCtor)
            {
                returnArg = m.Return.Morph("___ret", AST.VariableContext.Out);
            }
            else
            {
                returnArg = new AST.Parameter(BasicTypes.Void, "", AST.VariableContext.Return, false);
            }

            foreach (var arg in m.Parameters)
            {
                if (arg.IsArray || arg.Type.IsDelegate)
                {
                    if (arg.IsWriteable())
                    {
                        Line("ABICallbackRef<{0}> {1}_abi({1});", TypeRef(arg), arg.Name);
                    }
                    else
                    {
                        Line("auto {0}_abi = ABIUtil<{1}>::ToABI({0});", arg.Name, TypeRef(arg));
                    }
                }
            }

            if (!returnArg.IsVoid)
            {
                Line("{0} {1};", VariableType(returnArg, AST.VariableContext.Member, isCtor), returnArg.Name);

                if (returnArg.IsArray || returnArg.Type.IsDelegate)
                {
                    Line("{");
                    Indent++;
                    Line("ABICallbackRef<{0}> {1}_abi({1});", TypeRef(returnArg), returnArg.Name);
                }
            }

            Line($"TRANSLATE_TO_EXCEPTIONS({m.Name}(");
            Indent++;
            List(CodeListStyle.MultiLine, () =>
            {
                foreach (var arg in prependArgs)
                {
                    ListItem(arg);
                }

                Action <AST.IVariable, string> translateArg = (arg, name) =>
                {
                    if (arg.IsArray || arg.Type.IsDelegate)
                    {
                        name += "_abi";
                    }

                    if (arg.IsArray)
                    {
                        if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return)
                        {
                            ListItem("&{0}.Data, &{0}.Count", name);
                        }
                        else
                        {
                            ListItem("{0}.begin(), {0}.size()", name);
                        }
                    }
                    else if (arg.Type.IsDelegate)
                    {
                        if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return)
                        {
                            ListItem("({0}*)&{1}.Fn, &{1}.Ctx", TypeRef(arg, true), name);
                        }
                        else
                        {
                            ListItem("({0}){1}.Fn, {1}.Ctx", TypeRef(arg, true), name);
                        }
                    }
                    else if (arg.IsWriteable() || arg.Context == AST.VariableContext.Return)
                    {
                        ListItem("ABICallbackRef<{0}>({1})", TypeRef(arg), name);
                    }
                    else if (CppRender.RequiresABITranslation(arg))
                    {
                        ListItem("ABIUtil<{0}>::ToABI({1})", TypeRef(arg), name);
                    }
                    else
                    {
                        ListItem(name);
                    }
                };

                foreach (var arg in m.Parameters)
                {
                    translateArg(arg, arg.Name);
                }

                if (isCtor)
                {
                    ListItem("&instance");
                }
                else if (!returnArg.IsVoid)
                {
                    translateArg(returnArg, returnArg.Name);
                }
            });

            Indent--;
            Line("));");

            //if (!returnArg.IsVoid)
            //{
            //    Line("{0} {1};", VariableType(returnArg, AST.VariableContext.Member, isCtor), returnArg.Name);

            //    if (returnArg.IsArray || returnArg.Type.IsDelegate)
            if (!returnArg.IsVoid)
            {
                if (returnArg.IsArray || returnArg.Type.IsDelegate)
                {
                    Indent--;
                    Line("}");
                }
                Line("return {0};", returnArg.Name);
            }
        }