示例#1
0
        public void GenerateClassDeclaration(AST.Object type, bool fullIntellisense = false, Action additionalDeclarations = null)
        {
            // Set up generator state, figure out the class ID, other vars
            Strata = ApiStrata.Normal;

            // Class Signature
            Line($"class comid(\"{type.PrivateId}\")");
            Code("{0} : public ComObject<{0}, {1}, {2}",
                 type.Name, type.BaseType != null ? TypeRef(type.BaseType) : "Object", TypeRef(type, true));

            foreach (var iface in type.Interfaces)
            {
                Code($", {TypeRef(iface, true)}");
            }

            Line(">");
            Line("{");
            GenerateClassHeaderMembers(type, fullIntellisense);

            if (additionalDeclarations != null)
            {
                Spacer();
                additionalDeclarations();
            }
            Code("};");
        }
示例#2
0
        public void GenerateMethodDeclaration(AST.Object type, AST.Method method)
        {
            bool isOverride = type.IsMethodOverride(method);

            if (method.IsAbstract || (method.IsVirtual && !isOverride))
            {
                Code("virtual ");
            }

            Code("{0} {1}({2})", VariableType(method.Return), method.Name, DeclParameters(true, method.Parameters));

            if (method.IsConst)
            {
                Code(" const");
            }

            if (isOverride)
            {
                Line(" override;");
            }
            else if (method.IsAbstract)
            {
                Line(" = 0;");
            }
            else
            {
                Line(";");
            }
        }
示例#3
0
        public void EventABIImplementation(AST.Event ev, AST.Object owner)
        {
            Debug.Assert(Strata == ApiStrata.ABI);

            Line("HRESULT {0}::_Add{1}Handler({2} handler, IObject* context)", TypeRef(owner, false), ev.Name, TypeRef(ev.HandlerType));
            Block(() =>
            {
                Code("try ");
                Block(() =>
                {
                    Line("{0} += ABIUtil<{1}>::FromABI(handler, context);", ev.Name, TypeRef(ev.HandlerType, false));
                    Line("return S_OK;");
                }, " TRANSLATE_EXCEPTIONS");
            });

            Line("HRESULT {0}::_Remove{1}Handler({2} handler, IObject* context)", TypeRef(owner, false), ev.Name, TypeRef(ev.HandlerType));
            Block(() =>
            {
                Code("try ");
                Block(() =>
                {
                    Line("{0} -= ABIUtil<{1}>::FromABI(handler, context);", ev.Name, TypeRef(ev.HandlerType, false));
                    Line("return S_OK;");
                }, " TRANSLATE_EXCEPTIONS");
            });
        }
示例#4
0
        private void WriteInterfaceMembersUsingComImport(AST.Object type)
        {
            foreach (var m in type.Methods)
            {
                if (type.IsMethodOverride(m))
                {
                    continue;
                }
                WriteInterfaceMemberUsingComImport(m);
            }

            foreach (var p in type.Properties)
            {
                var getter = p.CreateGetter();
                if (!type.IsMethodOverride(getter))
                {
                    WriteInterfaceMemberUsingVTableWrapper(getter);
                }

                if (!p.IsReadOnly)
                {
                    var setter = p.CreateSetter();
                    if (!type.IsMethodOverride(setter))
                    {
                        WriteInterfaceMemberUsingVTableWrapper(p.CreateSetter());
                    }
                }
            }

            foreach (var e in type.Events)
            {
                WriteInterfaceMemberUsingComImport(e.CreateAdder());
                WriteInterfaceMemberUsingComImport(e.CreateRemover());
            }
        }
示例#5
0
 public void GenerateInterface(AST.Object type, bool fullIntellisense = false)
 {
     Strata = ApiStrata.ABI;
     Line($"cominterface comid(\"{type.Id}\") {type.Name} : public IUnknown");
     Block(() =>
     {
         GenerateInterfaceMembers(type, true, fullIntellisense);
     }, ";");
 }
示例#6
0
 public void DeclareABIConstructors(AST.Object type)
 {
     Strata = ApiStrata.ABI;
     if (!type.IsAbstract)
     {
         foreach (var constructor in type.Constructors)
         {
             Line($"ABI_CONSTRUCTOR {constructor.GetABIConstructorName(type)}({DeclParameters(constructor.GetABIParametersCpp(), $"{TypeRef(type, true)}** outInstance")});");
         }
     }
 }
示例#7
0
        public void WrapperConstructorImplementation(AST.Constructor c, AST.Object owner)
        {
            Line($"{TypeRef(owner)} {owner.Namespace.FullName("::")}::Create{owner.Name}({DeclParameters(c.Parameters)})");
            Block(() =>
            {
                Line($"{TypeRef(owner, true)}* instance;");

                CallToABIMethodBody(c.Rename(c.GetABIConstructorName(owner)));

                Line($"return ::ABI::Wrap<{TypeRef(owner)}>(instance);");
            });
        }
示例#8
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);
        }
示例#9
0
        public void GenerateInterfaceMembers(AST.Object type, bool pure, bool fullIntellisense = false)
        {
            var suffix = pure ? " = 0" : "";

            if (!fullIntellisense)
            {
                Directive("#ifndef __INTELLISENSE__");
            }

            Region(() =>
            {
                Action <AST.Method> declare = m =>
                {
                    if (type.IsMethodOverride(m))
                    {
                        return;
                    }

                    Line($"METHOD _{m.GetComCompatibleName()}({DeclParameters(m.GetABIParametersCpp())}){suffix};");
                };

                foreach (var method in type.Methods)
                {
                    declare(method);
                }
                Spacer();

                foreach (var prop in type.Properties)
                {
                    declare(prop.CreateGetter());

                    if (!prop.IsReadOnly)
                    {
                        declare(prop.CreateSetter());
                    }
                }
                Spacer();

                foreach (var ev in type.Events)
                {
                    declare(ev.CreateAdder());
                    declare(ev.CreateRemover());
                }
            });

            if (!fullIntellisense)
            {
                Directive("#endif");
            }
        }
示例#10
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;
                }
示例#11
0
        public void DefineClass(AST.Object type)
        {
            bool useabi = Strata == ApiStrata.ABI;

            Namespace(type.Namespace, useabi, () =>
            {
                if (!useabi)
                {
                    DefineWrapperClass(type);
                }
                else
                {
                    DefineInterfaceUsingVTableWrapper(type);
                }
            });
        }
示例#12
0
        public static void Validate(this AST.Object x)
        {
            foreach (var p in x.Properties)
            {
                p.Validate();
            }

            foreach (var c in x.Constructors)
            {
                c.Validate();
            }

            foreach (var m in x.Methods)
            {
                m.Validate();
            }
        }
示例#13
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++;
                    }
                });
            }
        }
示例#14
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());
                    }
                }
            });
        }
示例#15
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++;
                    }
                });
            }
        }
示例#16
0
        public void GenerateWrapperDeclaration(AST.Object type, Action additionalDeclarations = null)
        {
            Strata = ApiStrata.Normal;

            foreach (var ctor in type.Constructors.Where(c => c.Access == AST.Access.Public))
            {
                WriteXmlDocumentation(ctor.XmlDoc);
                Line($"{type.Name} Create{type.Name}({DeclParameters(ctor.Parameters)});");
            }
            Spacer();
            WriteXmlDocumentation(type.XmlDoc);
            Line($"class {type.Name} : public {(type.BaseType != null ? TypeRef(type.BaseType) : "ABI::Wrapper")}");
            Line("{");
            GenerateWrapperHeaderMembers(type);

            if (additionalDeclarations != null)
            {
                Spacer();
                additionalDeclarations();
            }
            Code("};");
        }
示例#17
0
        public static string GetABIConstructorName(this AST.Constructor ctor, AST.Object owner)
        {
            int index = owner.Constructors.IndexOf(ctor) + 1;

            return($"Create_{owner.FullName("_")}_{index}");
        }
示例#18
0
        public void ConstructorImplementation(AST.Constructor c, AST.Object owner, Action implementation = null, IEnumerable <string> initializers = null)
        {
            if (Strata == ApiStrata.Normal)
            {
                Code("{0}::{1}({2})", TypeRef(owner), owner.Name, DeclParameters(c.Parameters));

                if (owner.BaseType != null && owner.BaseType.Constructors.Count != 0 && owner.BaseType.Constructors[0].Parameters.Count != 0)
                {
                    Code(" : ");

                    List(() =>
                    {
                        if (Settings.Mode == CppMode.PimplWrapper)
                        {
                            Line($"{owner.BaseType.Name}(nullptr)");
                        }
                        else
                        {
                            Code("Base(");

                            List(() =>
                            {
                                var bc = owner.BaseType.Constructors[0];
                                foreach (var bcarg in bc.Parameters)
                                {
                                    ListItem("DEFAULT_({0})", TypeRef(bcarg));
                                }
                            });
                            Line(")");
                            NextListItem();

                            if (initializers != null)
                            {
                                foreach (var str in initializers)
                                {
                                    ListItem(str);
                                }
                            }
                        }
                    });
                }
                else
                {
                    Line();
                }

                if (implementation == null)
                {
                    Block(() => Line("Not_Implemented_Warning"));
                }
                else
                {
                    Block(() => implementation());
                }
            }
            else
            {
                Line($"ABI_CONSTRUCTOR {c.GetABIConstructorName(owner)}({DeclParameters(c.GetABIParametersCpp(), $"{TypeRef(owner, true)}** outInstance")})");
                Block(() =>
                {
                    if (implementation != null)
                    {
                        implementation();
                        return;
                    }

                    Code("try ");
                    Block(() =>
                    {
                        ABIWrapperParameterValidation(c);

                        Line("if(!outInstance) return E_POINTER;");
                        Line($"*outInstance = new {TypeRef(owner, false)}(");


                        List(CodeListStyle.MultiLine, () =>
                        {
                            Indent++;
                            foreach (var arg in c.Parameters)
                            {
                                string extra = "";

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

                                ListItem($"ABIUtil<{TypeRef(arg, false)}>::{(arg.IsWriteable() ? "Ref" : "FromABI")}({arg.Name}{extra})");
                            }
                            Indent--;
                        });
                        Line(");");

                        Line("return S_OK;");
                    }, " TRANSLATE_EXCEPTIONS");
                });
            }
        }
示例#19
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");
        }
示例#20
0
 public void GenerateClass(CsTreeWriter file, AST.Object type)
 {
     file.DefineClass(type);
 }
示例#21
0
        public void GenerateClassHeaderMembers(AST.Object type, bool fullIntellisense = false)
        {
            if (type.Origin != TypeOrigin.MappedIntermediary)
            {
                Line("#pragma region Gluon Maintained");
                Line("// clang-format off");
            }

            Region(() =>
            {
                Indent++;

                var localTranslations = GenerateLocalTranslations(type);

                Indent--;
                Spacer();

                LocalTranslationsBlock(localTranslations, () =>
                {
                    Line("public:");
                    Indent++;

                    // ABI type declaration
                    Line("typedef {0} ABIType;", TypeRef(type, true));
                    Spacer();

                    AST.Access currentAccess       = AST.Access.Public;
                    AST.Construct currentConstruct = AST.Construct.Void;

                    foreach (var member in type.Members.OrderBy(m => m.Access))
                    {
                        var access = member.Access;

                        if (access == AST.Access.Internal)
                        {
                            access = AST.Access.Public;
                        }

                        if (access != currentAccess)
                        {
                            currentAccess = access;
                            Indent--;
                            Spacer();

                            Line(access.ToString().ToLower() + ":");
                            Indent++;
                        }

                        var construct = member.ConstructType;

                        if (construct != currentConstruct)
                        {
                            Spacer();
                            currentConstruct = construct;
                        }

                        switch (construct)
                        {
                        case AST.Construct.Constructor:
                            {
                                var constructor = (AST.Constructor)member;

                                Line("{0}({1});", type.Name, DeclParameters(true, constructor.Parameters));
                            }
                            break;

                        case AST.Construct.Event:
                            {
                                var ev = (AST.Event)member;
                                if (ev.IsAbstract || ev.IsVirtual)
                                {
                                    Line("VirtualEvent<{0}, {1}> {2}", Signature(ev), type.Name, ev.Name);
                                    Line("    {{ this, &{0}::Add{1}Handler, &{0}::Remove{1}Handler }};", type.Name, ev.Name);
                                }
                                else
                                {
                                    Line("Event<{0}> {1} {{_{1}}};", Signature(ev), ev.Name);
                                }
                            }
                            break;

                        case AST.Construct.Property:
                            {
                                var prop = (AST.Property)member;


                                Spacer();
                                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());

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

                        case AST.Construct.Method:
                            {
                                var method = (AST.Method)member;
                                GenerateMethodDeclaration(type, method);
                            }
                            break;

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

                    Spacer();
                    if (currentAccess != AST.Access.Public)
                    {
                        Indent--;
                        Line("public:");
                        Indent++;
                        currentAccess = AST.Access.Public;
                    }

                    // Wrapped Interface Implementation
                    foreach (var iface in type.Interfaces)
                    {
                        if (iface.Origin == TypeOrigin.Native)
                        {
                            continue;
                        }

                        BlockComment(() => Code(iface.Name));

                        foreach (var method in iface.Methods)
                        {
                            GenerateMethodDeclaration(type, method);
                        }
                        Spacer();
                    }


                    Spacer();
                    foreach (var ev in type.Events)
                    {
                        if (currentAccess != AST.Access.Private)
                        {
                            Indent--;
                            Line("private:");
                            Indent++;
                            currentAccess = AST.Access.Private;
                        }

                        if (ev.IsAbstract || ev.IsVirtual)
                        {
                            Line("virtual void Add{0}Handler(const Delegate<{1}>& handler){2};", ev.Name, Signature(ev), ev.IsAbstract ? " = 0" : "");
                            Line("virtual void Remove{0}Handler(const Delegate<{1}>& handler){2};", ev.Name, Signature(ev), ev.IsAbstract ? " = 0" : "");
                        }
                        else
                        {
                            Line("EventTrigger<{0}> _{1};", Signature(ev), ev.Name);
                        }
                    }
                    Spacer();

                    Strata = ApiStrata.ABI;

                    if (currentAccess != AST.Access.Private)
                    {
                        Indent--;
                        Line("private:");
                        Indent++;
                        currentAccess = AST.Access.Private;
                    }

                    // ABI interface members
                    GenerateInterfaceMembers(type, false, fullIntellisense);
                    Spacer();

                    foreach (var iface in type.Interfaces)
                    {
                        if (iface.Origin == TypeOrigin.Native)
                        {
                            continue;
                        }

                        GenerateInterfaceMembers(iface, false, fullIntellisense);
                        Spacer();
                    }

                    Strata = ApiStrata.Normal;
                });
            });

            Indent--;

            if (type.Origin != TypeOrigin.MappedIntermediary)
            {
                Line("// clang-format on");
                Line("#pragma endregion");
            }
        }