Ejemplo n.º 1
0
        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++;
        }
Ejemplo n.º 2
0
        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++;
        }
Ejemplo n.º 3
0
        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");
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        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++;
        }