Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BindingWriter"/> class.
        /// </summary>
        /// <param name="generatorSettings">The generator settings.</param>
        /// <param name="profile">The profile.</param>
        /// <param name="documentation">The documentation for the profile.</param>
        public BindingWriter
        (
            [NotNull] IGeneratorSettings generatorSettings,
            [NotNull] ApiProfile profile,
            [NotNull] ProfileDocumentation documentation
        )
        {
            _generatorSettings = generatorSettings ?? throw new ArgumentNullException(nameof(generatorSettings));
            _profile           = profile ?? throw new ArgumentNullException(nameof(profile));
            _documentation     = documentation ?? throw new ArgumentNullException(nameof(documentation));

            var allFunctions      = profile.NativeSignatures.Concat(profile.Overloads).ToList();
            var enumerationUsages = new Dictionary <EnumerationSignature, IReadOnlyList <FunctionSignature> >();

            foreach (var e in profile.Enumerations)
            {
                // Initialize the dictionary
                var functionsUsingThisEnum = allFunctions
                                             .Where(f => f.Parameters.Any(p => p.Type.Name == e.Name))
                                             .ToList();

                enumerationUsages.Add(e, functionsUsingThisEnum);
            }

            _enumerationUsages = enumerationUsages;

            _entrypointSlots = profile.NativeSignatures
                               .Select((ns, i) => (ns.NativeEntrypoint, i))
                               .ToDictionary(t1 => t1.Item1, t2 => t2.Item2);

            _identifierTranslator = new NativeIdentifierTranslator();
        }
Example #2
0
        private static IEnumerable <(string, IEnumerable <Interface>, IEnumerable <(FunctionSignature, StringBuilder)>)> GetWithoutEnums(IEnumerable <FunctionSignature> fns)
        {
            // extension or core, (interface name, functions)
            var projects = new Dictionary <string, Dictionary <string, List <FunctionSignature> > >();

            foreach (var function in fns)
            {
                foreach (var category in function.Categories)
                {
                    // check that the root project exists
                    if (!projects.ContainsKey("Core"))
                    {
                        projects.Add
                        (
                            "Core",
                            new Dictionary <string, List <FunctionSignature> >()
                        );
                    }

                    // check that the extension project exists, if applicable
                    if (function.Extension != "Core" && !projects.ContainsKey(category))
                    {
                        projects.Add
                        (
                            category,
                            new Dictionary <string, List <FunctionSignature> >()
                        );
                    }

                    // check that the interface exists
                    if (!projects[function.Extension == "Core" ? "Core" : category]
                        .ContainsKey("I" + NativeIdentifierTranslator.TranslateIdentifierName(category)))
                    {
                        projects[function.Extension == "Core" ? "Core" : category]
                        .Add
                        (
                            "I" + NativeIdentifierTranslator.TranslateIdentifierName(category),
                            new List <FunctionSignature>()
                        );
                    }

                    // add the function to the interface
                    projects[function.Extension == "Core" ? "Core" : category][
                        "I" + NativeIdentifierTranslator.TranslateIdentifierName(category)]
                    .Add(function);
                }
            }

            return(projects.Select
                   (
                       x =>
                       (
                           x.Key,
                           x.Value.Select(y => new Interface(y.Key, y.Value)),
                           x.Value.SelectMany(y => OverloadBaker.GetOverloads(y.Value))
                       )
                   ));
        }
Example #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProfileMapper"/> class.
 /// </summary>
 /// <param name="typemap">The typemap to use.</param>
 public ProfileMapper(IReadOnlyDictionary <TypeSignature, TypeSignature> typemap)
 {
     _glFunctionMapper     = new FunctionMapper(typemap);
     _identifierTranslator = new NativeIdentifierTranslator();
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="DocumentationBaker"/> class.
        /// </summary>
        /// <param name="apiProfile">The profile that the documentation should be baked against.</param>
        public DocumentationBaker([NotNull] ApiProfile apiProfile)
        {
            _apiProfile = apiProfile ?? throw new ArgumentNullException(nameof(apiProfile));

            _identifierTranslator = new NativeIdentifierTranslator();
        }
Example #5
0
        private static async Task WriteNativeMixedModePartAsync(Project project, IGeneratorSettings settings)
        {
            var ns = project.Extension == "Core"
                ? settings.Namespace
                : settings.ExtensionNamespace + "." + Utilities.ConvertExtensionNameToNamespace(project.Extension);
            var dir = project.Extension == "Core"
                ? Path.Combine(Program.Arguments.OutputPath, settings.OutputSubfolder, settings.Namespace, settings.ClassName)
                : Path.Combine(Program.Arguments.OutputPath, settings.OutputSubfolder, ProfileWriter.ExtensionsFolder, ns);
            var file = project.Extension == "Core"
                ? settings.ClassName
                : NativeIdentifierTranslator.TranslateIdentifierName(project.Extension);

            using (var sw = new StreamWriter(File.Open(Path.Combine(dir, file + ".Native.cs"), FileMode.Create, FileAccess.ReadWrite, FileShare.Inheritable)))
            {
                sw.WriteLine("// <auto-generated />");
                sw.WriteLine(EmbeddedResources.LicenseText(Path.GetFileName(file)));
                sw.WriteLine("using AdvancedDLSupport;");
                sw.WriteLine("using OpenToolkit.Core.Native;");
                sw.WriteLine("using OpenToolkit.Core.Loader;");
                sw.WriteLine("using OpenToolkit.Core.Extensions;");
                sw.WriteLine("using " + settings.Namespace + ";");
                sw.WriteLine("using System;");
                sw.WriteLine("using System.Runtime.InteropServices;");
                sw.WriteLine("using System.Text;");
                sw.WriteLine();
                sw.WriteLine("namespace " + ns);
                sw.WriteLine("{");
                if (project.Extension != "Core")
                {
                    sw.WriteLine($"    [Extension(\"{settings.ConstantPrefix}{project.Extension}\")]");
                }

                sw.Write("    public abstract partial class " + file);
                if (project.Extension != "Core")
                {
                    sw.WriteLine(" : ExtensionBase, I" + file);
                    sw.WriteLine("    {");
                    sw.WriteLine("        /// <inheritdoc cref=\"ExtensionBase\"/>");
                    sw.WriteLine($"        protected {file}(string path, ImplementationOptions options)");
                    sw.WriteLine("            : base(path, options)");
                    sw.WriteLine("        {");
                    sw.WriteLine("        }");
                    sw.WriteLine();
                }
                else
                {
                    sw.WriteLine();
                    sw.WriteLine("    {");
                }

                foreach (var function in project.Interfaces.SelectMany(x => x.Functions))
                {
                    sw.WriteLine("        /// <inheritdoc/>");

                    if (function.IsDeprecated)
                    {
                        var str = "Deprecated";
                        if (function.DeprecatedIn != null)
                        {
                            str += " since " + function.DeprecatedIn.ToString(2);
                        }

                        if (!string.IsNullOrWhiteSpace(function.DeprecationReason))
                        {
                            str += " - " + function.DeprecationReason;
                        }

                        sw.WriteLine($"        [Obsolete(\"{str}\")]");
                    }

                    sw.Write("        public abstract ");
                    sw.WriteLine(Utilities.GetDeclarationString(function) + ";");
                    sw.WriteLine();
                }

                sw.WriteLine("    }");
                sw.WriteLine("}");
                await sw.FlushAsync();
            }
        }
Example #6
0
        private static async Task WriteOverloadsMixedModePartAsync(Project project, IGeneratorSettings settings, ProfileDocumentation docs)
        {
            var file = project.Extension == "Core"
                ? settings.ClassName
                : NativeIdentifierTranslator.TranslateIdentifierName(project.Extension);
            var ns = project.Extension == "Core"
                ? settings.Namespace
                : settings.ExtensionNamespace + "." + Utilities.ConvertExtensionNameToNamespace(project.Extension);
            var dir = project.Extension == "Core"
                ? Path.Combine(Program.Arguments.OutputPath, settings.OutputSubfolder, settings.Namespace, settings.ClassName)
                : Path.Combine(Program.Arguments.OutputPath, settings.OutputSubfolder, ProfileWriter.ExtensionsFolder, ns);

            using (var sw = new StreamWriter(File.Open(Path.Combine(dir, file + ".Overloads.cs"), FileMode.Create, FileAccess.ReadWrite, FileShare.Inheritable)))
            {
                sw.WriteLine("// <auto-generated />");
                sw.WriteLine(EmbeddedResources.LicenseText(Path.GetFileName(file)));
                sw.WriteLine("using AdvancedDLSupport;");
                sw.WriteLine("using OpenToolkit.Core.Native;");
                sw.WriteLine("using OpenToolkit.Core.Extensions;");
                sw.WriteLine("using System;");
                sw.WriteLine("using System.Runtime.InteropServices;");
                sw.WriteLine("using System.Text;");
                sw.WriteLine("using " + settings.Namespace + ";");
                sw.WriteLine();
                sw.WriteLine("namespace " + ns);
                sw.WriteLine("{");
                sw.WriteLine("    /// <summary>");
                sw.WriteLine("    /// Contains bindings to the " + settings.APIIdentifier + " API.");
                sw.WriteLine("    /// </summary>");
                sw.WriteLine("    public partial class " + file);
                sw.WriteLine("    {");
                foreach (var overload in project.Overloads)
                {
                    sw.WriteLine("        /// <summary>");
                    if (docs.HasDocumentation(overload.Item1))
                    {
                        sw.WriteLine("        /// " + docs.GetDocumentation(overload.Item1)?.Purpose);
                    }
                    else
                    {
                        sw.WriteLine("        /// To be added.");
                    }

                    sw.WriteLine("        /// </summary>");

                    if (overload.Item1.IsDeprecated)
                    {
                        var str = "Deprecated";
                        if (overload.Item1.DeprecatedIn != null)
                        {
                            str += " since " + overload.Item1.DeprecatedIn.ToString(2);
                        }

                        if (!string.IsNullOrWhiteSpace(overload.Item1.DeprecationReason))
                        {
                            str += " - " + overload.Item1.DeprecationReason;
                        }

                        sw.WriteLine($"        [Obsolete(\"{str}\")]");
                    }

                    sw.WriteLine(
                        "        " +
                        "[AutoGenerated(" +
                        $"Category = \"{overload.Item1.Categories.First()}\", " +
                        $"Version = \"{overload.Item1.IntroducedIn}\", " +
                        $"EntryPoint = \"{settings.FunctionPrefix}{overload.Item1.NativeEntrypoint}\", " +
                        $"Source = \"{overload.Item1.Source}\"" +
                        ")]");

                    sw.Write("        public ");
                    var decl = Utilities.GetDeclarationString(overload.Item1);
                    if (!decl.Contains("unsafe "))
                    {
                        sw.Write("unsafe ");
                    }

                    sw.WriteLine(decl);
                    sw.WriteLine("        {");
                    foreach (var line in overload.Item2.ToString()
                             .Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        sw.Write("            " + line);
                    }

                    sw.WriteLine("        }");
                    sw.WriteLine();
                }

                sw.WriteLine("    }");
                sw.WriteLine("}");
                await sw.FlushAsync();
            }
        }