public override void Generate(GenerationInfo generationInfo) { generationInfo.CurrentType = QualifiedName; var sw = generationInfo.Writer = generationInfo.OpenStream(Name, Namespace); base.Generate(generationInfo); if (GetMethod("GetType") == null && GetMethod("GetGType") == null) { sw.WriteLine("\t\tprivate static GLib.GType GType {"); sw.WriteLine("\t\t\tget { return GLib.GType.Pointer; }"); sw.WriteLine("\t\t}"); } sw.WriteLine("#endregion"); sw.WriteLine("\t}"); sw.WriteLine("}"); sw.Close(); generationInfo.Writer = null; Statistics.StructCount++; }
public override void Generate(GenerationInfo generationInfo) { generationInfo.CurrentType = QualifiedName; var streamWriter = generationInfo.Writer = generationInfo.OpenStream(Name, Namespace); streamWriter.WriteLine($"namespace {Namespace} {{"); streamWriter.WriteLine(); streamWriter.WriteLine("\tusing System;"); streamWriter.WriteLine("\tusing System.Collections;"); streamWriter.WriteLine("\tusing System.Collections.Generic;"); streamWriter.WriteLine("\tusing System.Runtime.InteropServices;"); streamWriter.WriteLine(); streamWriter.WriteLine("#region Autogenerated code"); var table = SymbolTable.Table; GetSpecialMethods(out var refMethod, out var unrefMethod, out var disposeMethod, out var setGValueMethod); if (IsDeprecated) { streamWriter.WriteLine("\t[Obsolete]"); } streamWriter.Write("\t{0} partial {1}class {2}", IsInternal ? "internal" : "public", IsAbstract ? "abstract " : string.Empty, Name); var csParent = table.GetCsType(Element.GetAttribute(Constants.Parent)); streamWriter.Write(!string.IsNullOrEmpty(csParent) ? $" : {csParent}" : " : GLib.Opaque"); foreach (var @interface in ManagedInterfaces) { if (Parent != null && Parent.Implements(@interface)) { continue; } streamWriter.Write($", {@interface}"); } streamWriter.WriteLine(" {"); streamWriter.WriteLine(); GenerateConstants(generationInfo); GenerateFields(generationInfo); GenerateMethods(generationInfo, null, null); GenerateConstructors(generationInfo); if (refMethod != null) { refMethod.GenerateImport(streamWriter); streamWriter.WriteLine("\t\tprotected override void Ref (IntPtr raw)"); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine("\t\t\tif (!Owned) {"); streamWriter.WriteLine($"\t\t\t\t{refMethod.CName} (raw);"); streamWriter.WriteLine("\t\t\t\tOwned = true;"); streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); if (refMethod.IsDeprecated) { streamWriter.WriteLine($"\t\t[Obsolete(\"{QualifiedName} is now refcounted automatically\")]"); streamWriter.WriteLine(refMethod.ReturnType == "void" ? "\t\tpublic void Ref () {}" : $"\t\tpublic {Name} Ref () {{ return this; }}"); streamWriter.WriteLine(); } } var finalizerNeeded = false; if (unrefMethod != null) { unrefMethod.GenerateImport(streamWriter); streamWriter.WriteLine("\t\tprotected override void Unref (IntPtr raw)"); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine("\t\t\tif (Owned) {"); streamWriter.WriteLine($"\t\t\t\t{unrefMethod.CName} (raw);"); streamWriter.WriteLine("\t\t\t\tOwned = false;"); streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); if (unrefMethod.IsDeprecated) { streamWriter.WriteLine($"\t\t[Obsolete(\"{QualifiedName} is now refcounted automatically\")]"); streamWriter.WriteLine("\t\tpublic void Unref () {}"); streamWriter.WriteLine(); } finalizerNeeded = true; } if (disposeMethod != null) { disposeMethod.GenerateImport(streamWriter); streamWriter.WriteLine("\t\tprotected override void Free (IntPtr raw)"); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine($"\t\t\t{disposeMethod.CName} (raw);"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); if (disposeMethod.IsDeprecated) { streamWriter.WriteLine($"\t\t[Obsolete(\"{QualifiedName} is now freed automatically\")]"); streamWriter.WriteLine($"\t\tpublic void {disposeMethod.Name} () {{}}"); streamWriter.WriteLine(); } finalizerNeeded = true; } if (finalizerNeeded) { streamWriter.WriteLine("\t\tclass FinalizerInfo {"); streamWriter.WriteLine("\t\t\tIntPtr handle;"); streamWriter.WriteLine(); streamWriter.WriteLine("\t\t\tpublic FinalizerInfo (IntPtr handle)"); streamWriter.WriteLine("\t\t\t{"); streamWriter.WriteLine("\t\t\t\tthis.handle = handle;"); streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine(); streamWriter.WriteLine("\t\t\tpublic bool Handler ()"); streamWriter.WriteLine("\t\t\t{"); streamWriter.WriteLine("\t\t\t\t{0} (handle);", disposeMethod != null ? disposeMethod.CName : unrefMethod.CName); streamWriter.WriteLine("\t\t\t\treturn false;"); streamWriter.WriteLine("\t\t\t}"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); streamWriter.WriteLine("\t\t~{0} ()", Name); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine("\t\t\tif (!Owned)"); streamWriter.WriteLine("\t\t\t\treturn;"); streamWriter.WriteLine("\t\t\tFinalizerInfo info = new FinalizerInfo (Handle);"); streamWriter.WriteLine("\t\t\tGLib.Timeout.Add (50, new GLib.TimeoutHandler (info.Handler));"); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); } #if false Method copy = Methods ["Copy"] as Method; if (copy != null && copy.Parameters.Count == 0) { sw.WriteLine("\t\tprotected override GLib.Opaque Copy (IntPtr raw)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tGLib.Opaque result = new " + QualifiedName + " (" + copy.CName + " (raw));"); sw.WriteLine("\t\t\tresult.Owned = true;"); sw.WriteLine("\t\t\treturn result;"); sw.WriteLine("\t\t}"); sw.WriteLine(); } #endif if (setGValueMethod != null) { streamWriter.WriteLine("\t\tdelegate IntPtr d_{0}(ref GLib.Value val, IntPtr obj);", setGValueMethod.CName); streamWriter.WriteLine("\t\tstatic d_{0} {0} = FuncLoader.LoadFunction<d_{0}>(FuncLoader.GetProcAddress(GLibrary.Load({1}), \"{0}\"));", setGValueMethod.CName, LibraryName); streamWriter.WriteLine(); streamWriter.WriteLine("\t\tpublic void SetGValue (ref GLib.Value val)"); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine("\t\t\t{0} (ref val, Handle);", setGValueMethod.CName); streamWriter.WriteLine("\t\t}"); streamWriter.WriteLine(); } GenerateStructAbi(generationInfo); streamWriter.WriteLine("#endregion"); streamWriter.WriteLine("\t}"); streamWriter.WriteLine("}"); streamWriter.Close(); generationInfo.Writer = null; Statistics.OpaqueCount++; }
public string GenerateWrapper(GenerationInfo generationInfo) { var wrapper = $"{Name}Native"; if (!Validate()) { return(string.Empty); } var log = new LogWriter(MarshalType); _body = new MethodBody(_parameters, log); var savedWriter = generationInfo.Writer; var sw = generationInfo.Writer = generationInfo.OpenStream(MarshalType, Namespace); sw.WriteLine($"namespace {Namespace}Sharp {{"); sw.WriteLine(); sw.WriteLine("\tusing System;"); sw.WriteLine("\tusing System.Runtime.InteropServices;"); sw.WriteLine(); sw.WriteLine("#region Autogenerated code"); //sw.WriteLine ("\t[UnmanagedFunctionPointer (CallingConvention.Cdecl)]"); sw.WriteLine($"\tinternal delegate {_returnValue.MarshalType} {wrapper}({_parameters.ImportSignature});"); sw.WriteLine(); GenerateInvoker(generationInfo, sw); sw.WriteLine($"\tinternal class {Name}Wrapper {{"); sw.WriteLine(); var managedCall = new ManagedCallString(_parameters); sw.WriteLine($"\t\tpublic {_returnValue.MarshalType} NativeCallback ({_parameters.ImportSignature})"); sw.WriteLine("\t\t{"); var unconditional = managedCall.Unconditional("\t\t\t"); if (unconditional.Length > 0) { sw.WriteLine(unconditional); } sw.WriteLine("\t\t\ttry {"); var setup = managedCall.Setup("\t\t\t\t"); if (setup.Length > 0) { sw.WriteLine(setup); } if (_returnValue.CsType == "void") { sw.WriteLine("\t\t\t\tmanaged ({0});", managedCall); } else { sw.WriteLine("\t\t\t\t{0} __ret = managed ({1});", _returnValue.CsType, managedCall); } var finish = managedCall.Finish("\t\t\t\t"); if (finish.Length > 0) { sw.WriteLine(finish); } sw.WriteLine("\t\t\t\tif (release_on_call)\n\t\t\t\t\tgch.Free ();"); var countParameter = _returnValue.CountParameter; if (countParameter != null) { sw.WriteLine("\t\t\t\t{0} = {1}{2};", countParameter.Name, countParameter.CsType == "int" ? string.Empty : $"({countParameter.MarshalType})({countParameter.CsType})", "__ret.Length"); } if (_returnValue.CsType != "void") { sw.WriteLine("\t\t\t\treturn {0};", _returnValue.ToNative("__ret")); } /* * If the function expects one or more "out" parameters (error parameters are excluded) * or has a return value different from void and bool, exceptions thrown in the managed function * have to be considered fatal meaning that an exception is to be thrown and the function call cannot not return */ var fatal = _returnValue.MarshalType != "void" && _returnValue.MarshalType != "bool" || managedCall.HasOutParam; sw.WriteLine("\t\t\t} catch (Exception e) {"); sw.WriteLine($"\t\t\t\tGLib.ExceptionManager.RaiseUnhandledException (e, {(fatal ? "true" : "false")});"); if (fatal) { sw.WriteLine("\t\t\t\t// NOTREACHED: Above call does not return."); sw.WriteLine("\t\t\t\tthrow e;"); } else if (_returnValue.MarshalType == "bool") { sw.WriteLine("\t\t\t\treturn false;"); } sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine("\t\tbool release_on_call = false;"); sw.WriteLine("\t\tGCHandle gch;"); sw.WriteLine(); sw.WriteLine("\t\tpublic void PersistUntilCalled ()"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\trelease_on_call = true;"); sw.WriteLine("\t\t\tgch = GCHandle.Alloc (this);"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine($"\t\tinternal {wrapper} NativeDelegate;"); sw.WriteLine($"\t\t{Namespace}.{Name} managed;"); sw.WriteLine(); sw.WriteLine($"\t\tpublic {Name}Wrapper ({Namespace}.{Name} managed)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tthis.managed = managed;"); sw.WriteLine("\t\t\tif (managed != null)"); sw.WriteLine($"\t\t\t\tNativeDelegate = new {wrapper} (NativeCallback);"); sw.WriteLine("\t\t}"); sw.WriteLine(); sw.WriteLine($"\t\tpublic static {Namespace}.{Name} GetManagedDelegate ({wrapper} native)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tif (native == null)"); sw.WriteLine("\t\t\t\treturn null;"); sw.WriteLine($"\t\t\t{Name}Wrapper wrapper = ({Name}Wrapper) native.Target;"); sw.WriteLine("\t\t\tif (wrapper == null)"); sw.WriteLine("\t\t\t\treturn null;"); sw.WriteLine("\t\t\treturn wrapper.managed;"); sw.WriteLine("\t\t}"); sw.WriteLine("\t}"); sw.WriteLine("#endregion"); sw.WriteLine("}"); sw.Close(); generationInfo.Writer = savedWriter; return($"{Namespace}Sharp.{Name}Wrapper"); }
public override void Generate(GenerationInfo generationInfo) { var needClose = false; if (generationInfo.Writer == null) { generationInfo.Writer = generationInfo.OpenStream(Name, Namespace); needClose = true; } var sw = generationInfo.Writer; sw.WriteLine($"namespace {Namespace} {{"); sw.WriteLine(); sw.WriteLine("\tusing System;"); sw.WriteLine("\tusing System.Collections;"); sw.WriteLine("\tusing System.Collections.Generic;"); sw.WriteLine("\tusing System.Runtime.InteropServices;"); sw.WriteLine(); sw.WriteLine("#region Autogenerated code"); if (IsDeprecated) { sw.WriteLine("\t[Obsolete]"); } sw.WriteLine(Union ? "\t[StructLayout(LayoutKind.Explicit)]" : "\t[StructLayout(LayoutKind.Sequential)]"); var access = IsInternal ? "internal" : "public"; sw.WriteLine("\t{1} partial struct {0} : IEquatable<{0}> {{", Name, access); sw.WriteLine(); _needReadNative = false; GenerateFields(generationInfo); sw.WriteLine(); GenerateConstructors(generationInfo); GenerateMethods(generationInfo, null, this); if (_needReadNative) { GenerateReadNative(sw); } GenerateEqualsAndHash(sw); if (!needClose) { return; } sw.WriteLine("#endregion"); sw.WriteLine("\t}"); sw.WriteLine("}"); sw.Close(); generationInfo.Writer = null; }
public override void Generate(GenerationInfo generationInfo) { generationInfo.CurrentType = QualifiedName; var assemblyName = generationInfo.AssemblyName.Length == 0 ? $"{Namespace.ToLower()}-sharp" : generationInfo.AssemblyName; var directoryInfo = GetDirectoryInfo(generationInfo.DirectoryPath, assemblyName); var streamWriter = generationInfo.Writer = generationInfo.OpenStream(Name, Namespace); streamWriter.WriteLine($"namespace {Namespace} {{"); streamWriter.WriteLine(); streamWriter.WriteLine("\tusing System;"); streamWriter.WriteLine("\tusing System.Collections;"); streamWriter.WriteLine("\tusing System.Collections.Generic;"); streamWriter.WriteLine("\tusing System.Runtime.InteropServices;"); streamWriter.WriteLine(); var table = SymbolTable.Table; streamWriter.WriteLine("#region Autogenerated code"); if (IsDeprecated) { streamWriter.WriteLine("\t[Obsolete]"); } foreach (var attribute in _customAttributes) { streamWriter.WriteLine($"\t{attribute}"); } streamWriter.Write("\t{0} {1}partial class {2}", IsInternal ? "internal" : "public", IsAbstract ? "abstract " : "", Name); var csParent = table.GetCsType(Element.GetAttribute(Constants.Parent)); if (csParent != "") { directoryInfo.Objects.Add(CName, QualifiedName); streamWriter.Write($" : {csParent}"); } foreach (var iface in Interfaces) { if (Parent != null && Parent.Implements(iface)) { continue; } streamWriter.Write($", {table.GetCsType(iface)}"); } foreach (var iface in ManagedInterfaces) { if (Parent != null && Parent.Implements(iface)) { continue; } streamWriter.Write($", {iface}"); } streamWriter.WriteLine(" {"); streamWriter.WriteLine(); GenerateConstructors(generationInfo); GenerateProperties(generationInfo, null); GenerateFields(generationInfo); GenerateChildProperties(generationInfo); var hasSignals = Signals != null && Signals.Count > 0; if (!hasSignals) { foreach (var iface in Interfaces) { if (!(table.GetClassGen(iface) is InterfaceGen interfaceGen) || interfaceGen.Signals == null) { continue; } hasSignals = true; break; } } if (hasSignals && Element.HasAttribute(Constants.Parent)) { GenerateSignals(generationInfo, null); } GenerateConstants(generationInfo); GenerateClassMembers(generationInfo); GenerateMethods(generationInfo, null, null); if (Interfaces.Count != 0) { var methods = new Dictionary <string, Method>(); foreach (var method in Methods.Values) { methods[method.Name] = method; } var collisions = new Dictionary <string, bool>(); foreach (var iface in Interfaces) { var classGen = table.GetClassGen(iface); foreach (var method in classGen.Methods.Values) { if (method.Name.StartsWith("Get") || method.Name.StartsWith("Set")) { if (GetProperty(method.Name.Substring(3)) != null) { collisions[method.Name] = true; continue; } } methods.TryGetValue(method.Name, out var collision); if (collision != null && collision.Signature.Types == method.Signature.Types) { collisions[method.Name] = true; } else { methods[method.Name] = method; } } } foreach (var iface in Interfaces) { if (Parent != null && Parent.Implements(iface)) { continue; } var interfaceGen = (InterfaceGen)table.GetClassGen(iface); interfaceGen.GenerateMethods(generationInfo, collisions, this); interfaceGen.GenerateProperties(generationInfo, this); interfaceGen.GenerateSignals(generationInfo, this); interfaceGen.GenerateVirtualMethods(generationInfo, this); } } foreach (var str in _staticStrings) { streamWriter.Write($"\t\tpublic static string {str.GetAttribute(Constants.Name)}"); streamWriter.WriteLine($" {{\n\t\t\t get {{ return \"{str.GetAttribute(Constants.Value)}\"; }}\n\t\t}}"); } if (csParent != string.Empty && GetExpected(CName) != QualifiedName) { streamWriter.WriteLine(); streamWriter.WriteLine($"\t\tstatic {Name} ()"); streamWriter.WriteLine("\t\t{"); streamWriter.WriteLine($"\t\t\tGtkSharp.{Studlify(assemblyName)}.ObjectManager.Initialize ();"); streamWriter.WriteLine("\t\t}"); } GenerateStructAbi(generationInfo); streamWriter.WriteLine("#endregion"); streamWriter.WriteLine("\t}"); streamWriter.WriteLine("}"); streamWriter.Close(); generationInfo.Writer = null; Statistics.ObjectCount++; }