using System; using System.Collections.Generic; using System.IO; using System.Text; using Mono.Cecil; using Xamarin.Bundler; using Registrar; namespace Xamarin.Bundler { class PInvokeWrapperGenerator { public Application App; public Dictionary signatures = new Dictionary (); public List exceptions = new List (); public StringBuilder signature = new StringBuilder (); public HashSet names = new HashSet (); public AutoIndentStringBuilder sb = new AutoIndentStringBuilder (); AutoIndentStringBuilder hdr = new AutoIndentStringBuilder (); AutoIndentStringBuilder decls = new AutoIndentStringBuilder (); AutoIndentStringBuilder mthds = new AutoIndentStringBuilder (); AutoIndentStringBuilder ifaces = new AutoIndentStringBuilder (); public StaticRegistrar Registrar; public string HeaderPath; public string SourcePath; bool first; public bool Started { get { return first; } } public void Start () { if (App.EnableDebug) hdr.WriteLine ("#define DEBUG 1"); hdr.WriteLine ("#include "); hdr.WriteLine ("#include "); hdr.WriteLine ("#include "); hdr.WriteLine ("#include "); hdr.WriteLine ("#include "); Registrar.GeneratePInvokeWrappersStart (hdr, decls, mthds, ifaces); mthds.WriteLine ($"#include \"{Path.GetFileName (HeaderPath)}\""); sb.WriteLine ("extern \"C\" {"); // Disable "control reaches end of non-void function" // we throw exceptions in many code paths, which clang doesn't know about, triggering this warning. sb.WriteLine ("#pragma clang diagnostic ignored \"-Wreturn-type\""); // Disable "warning: 'X' is only available on xOS Y.Z or newer" sb.WriteLine ("#pragma clang diagnostic ignored \"-Wunguarded-availability-new\""); } public void End () { if (!first) throw new Exception ("Generator not started"); sb.WriteLine ("}"); Registrar.GeneratePInvokeWrappersEnd (); Driver.WriteIfDifferent (HeaderPath, hdr.ToString () + "\n" + decls.ToString () + "\n" + ifaces.ToString () + "\n", true); Driver.WriteIfDifferent (SourcePath, mthds.ToString () + "\n" + sb.ToString () + "\n", true); } public void ProcessMethod (MethodDefinition method) { if (!first) { Start (); first = true; } Registrar.GeneratePInvokeWrapper (this, method); } } }