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; }
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++; } }); } }
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++; } }); } }
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"); }
public static string GetABIConstructorName(this AST.Constructor ctor, AST.Object owner) { int index = owner.Constructors.IndexOf(ctor) + 1; return($"Create_{owner.FullName("_")}_{index}"); }