Пример #1
0
        private void DefineWrapperClass(AST.Object type)
        {
            var abiName = TypeRef(type, true);

            WriteXmlDocumentation(type.XmlDoc);

            Line($"[Guid(\"{type.PrivateId}\")]");
            Line($"[GluonGenerated(abi: typeof(global::ABI.{type.FullName(".")}))]");
            foreach (var attr in type.Attributes)
            {
                WriteAttribute(attr);
            }
            Line("{0} {3} class {1} : {2}", type.Access.ToString().ToLower(), type.Name, type.BaseType != null ? TypeRef(type.BaseType) : "GluonObject", type.IsAbstract ? "abstract partial" : "partial");
            Block(() =>
            {
                Line(
                    $@"static partial void StaticInit();
partial void Init();
partial void PartialDispose(bool finalizing);

static {type.Name}()
{{
    ABI.{type.Assembly.Name}.Native.RegisterTypes();
    StaticInit();
}}");
                Spacer();

                foreach (var c in type.Constructors)
                {
                    WriteXmlDocumentation(c.XmlDoc);

                    if (c.Parameters.Count == 0)
                    {
                        LineStyle = CodeLineStyle.SingleLine;
                    }

                    Line(
                        $@"{c.Access.ToString().ToLower()} {type.Name}({DeclParameters(c.Parameters)})
    : this(new AbiPtr(Make({List(c.Parameters, arg => {
        var adorn = arg.IsRef ? "ref " : arg.IsOut ? "out " : "";
        return $"{adorn}{arg.Name}"; })})))
{{
    {ForEach(type.Events, e => Line(
        $"_{e.Name}_abi = D{e.HandlerType.ShortId}.Unwrap(_Call_{e.Name});"))}
    Init();
}}");
                    Spacer();

                    LineStyle = CodeLineStyle.Standard;
                }
Пример #2
0
        private void DefineInterfaceUsingVTableWrapper(AST.Object type)
        {
            Strata = ApiStrata.ABI;

            foreach (var attr in type.Attributes)
            {
                WriteAttribute(attr);
            }

            Line("[Guid(\"{0}\")]", type.Id);
            Line("[StructLayout(LayoutKind.Sequential)]");
            Line("internal struct {0}", type.Name);
            Block(() =>
            {
                Line("public readonly VTUnknown Unknown;");
                Spacer();

                WriteInterfaceMembersUsingVTableWrapper(type);
            });

            if (!type.IsAbstract)
            {
                Line("internal static partial class Factory", type.Name);
                Block(() =>
                {
                    if (type.Constructors.Count == 0)
                    {
                        Line("[DllImport(Native.DllPath)]");
                        Line("public static extern int Create_{0}(out IntPtr newInstance);", type.FullName("_"));
                        Spacer();
                    }

                    int index = 1;
                    foreach (var c in type.Constructors)
                    {
                        Line("[DllImport(Native.DllPath)]");
                        Line("public static extern int Create_{0}_{1}({2});", type.FullName("_"), index,
                             DeclParameters(c.GetABIParametersCs(), "out IntPtr newInstance"));
                        Spacer();
                        index++;
                    }
                });
            }
        }
Пример #3
0
        private void DefineInterfaceUsingComImport(AST.Object type)
        {
            Strata = ApiStrata.ABI;

            foreach (var attr in type.Attributes)
            {
                WriteAttribute(attr);
            }

            Line("[ComImport, Guid(\"{0}\")]", type.Id);
            Line("[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]");
            Code("internal interface {0}", type.Name);
            Block(() =>
            {
                WriteInterfaceMembersUsingComImport(type);
            });

            if (!type.IsAbstract)
            {
                Line("internal static partial class Factory", type.Name);
                Block(() =>
                {
                    if (type.Constructors.Count == 0)
                    {
                        Line("[DllImport(Native.DllPath)]");
                        Line("public static extern int Create_{0}(out {1} newInstance);", type.FullName("_"), type.Name);
                        Spacer();
                    }

                    int index = 1;
                    foreach (var c in type.Constructors)
                    {
                        Line("[DllImport(Native.DllPath)]");
                        Line("public static extern int Create_{0}_{1}({2});", type.FullName("_"), index,
                             DeclParameters(c.GetABIParametersCs(), "out " + type.Name + " newInstance"));
                        Spacer();
                        index++;
                    }
                });
            }
        }
Пример #4
0
        public void GenerateWrapperHeaderMembers(AST.Object type)
        {
            Line("#pragma region Gluon Maintained");
            Line("// clang-format off");
            Line($"    typedef {(type.BaseType == null ? "ABI::Wrapper" : TypeRef(type.BaseType))} Base;");
            Line($"    WRAPPER_CORE({type.Name}, ::ABI::{type.FullName("::")})");

            AST.Construct currentConstruct = AST.Construct.Constructor;

            Indent++;
            Region(() =>
            {
                var localTranslations = GenerateLocalTranslations(type);
                UseLocalTranslations  = true;

                LocalTranslationsBlock(localTranslations, () =>
                {
                    //Spacer();
                    //Line($"{type.Name}();");
                    //Line($"{type.Name}(std::nullptr_t);");
                    //Line($"{type.Name}(const {type.Name}& copy);");
                    //Line($"{type.Name}({type.Name}&& move);");
                    var currentAccess = AST.Access.Private;

                    foreach (var member in type.Members /*.Where(m => m.Access == AST.Access.Public)*/.OrderBy(m => m.ConstructType).OrderBy(m => m.Access))
                    {
                        if (member is AST.Constructor)
                        {
                            continue;
                        }

                        if (member.ConstructType != currentConstruct)
                        {
                            Spacer();
                            currentConstruct = member.ConstructType;
                        }

                        if (member.Access != currentAccess)
                        {
                            Spacer();
                            Indent--;
                            Line($"{member.Access.ToString().ToLower()}:");
                            Indent++;
                            currentAccess = member.Access;
                        }

                        WriteXmlDocumentation(member.XmlDoc);

                        switch (member)
                        {
                        case AST.Constructor constructor:
                            //Line("{0}({1});", type.Name, DeclParameters(true, constructor.Parameters));
                            break;

                        case AST.Event ev:
                            Line($"VirtualEvent<{Signature(ev)}, {type.Name}> {ev.Name}");
                            Line("    {{ this, &{0}::Add{1}Handler, &{0}::Remove{1}Handler }};", type.Name, ev.Name);
                            break;

                        case AST.Property prop:
                            Line("PROPERTY{0}({1}, {2});", prop.IsReadOnly ? "_READONLY" : "",
                                 VariableType(prop, (prop.Type.IsStruct || prop.Type.IsDelegate || (prop.Type.IsObject && prop.IsFactory)) ?
                                              AST.VariableContext.Return : AST.VariableContext.In), prop.Name);

                            GenerateMethodDeclaration(type, prop.CreateGetter().AsConst());

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

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

                        default:
                            throw new Exception("Oops, unhandled member type: " + member.ConstructType.ToString());
                        }
                    }

                    var allEvents = type.Members.Where(m => m.Access == AST.Access.Public).OfType <AST.Event>().ToArray();

                    if (allEvents != null && allEvents.Length > 0)
                    {
                        Spacer();
                        Indent--;
                        Line("private:");
                        Indent++;
                        Spacer();

                        foreach (var ev in allEvents)
                        {
                            GenerateMethodDeclaration(type, ev.CreateAdder().AsConst());
                            GenerateMethodDeclaration(type, ev.CreateRemover().AsConst());
                        }
                    }
                });
            });
            Indent--;
            Spacer();

            Line("// clang-format on");
            Line("#pragma endregion");
        }
Пример #5
0
        public static string GetABIConstructorName(this AST.Constructor ctor, AST.Object owner)
        {
            int index = owner.Constructors.IndexOf(ctor) + 1;

            return($"Create_{owner.FullName("_")}_{index}");
        }