private async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions configOptions, string[] excludedNames, IReadOnlyDictionary <string, string> remappedNames, IReadOnlyDictionary <string, IReadOnlyList <string> > withAttributes, IReadOnlyDictionary <string, string> withCallConvs, IReadOnlyDictionary <string, string> withLibraryPaths, string[] withSetLastErrors, IReadOnlyDictionary <string, string> withTypes, IReadOnlyDictionary <string, IReadOnlyList <string> > withUsings, IEnumerable <Diagnostic> expectedDiagnostics, string libraryPath)
        {
            Assert.True(File.Exists(DefaultInputFileName));

            using var outputStream = new MemoryStream();
            using var unsavedFile  = CXUnsavedFile.Create(DefaultInputFileName, inputContents);

            var unsavedFiles = new CXUnsavedFile[] { unsavedFile };
            var config       = new PInvokeGeneratorConfiguration(libraryPath, DefaultNamespaceName, Path.GetRandomFileName(), testOutputLocation: null, configOptions, excludedNames, headerFile: null, methodClassName: null, methodPrefixToStrip: null, remappedNames, traversalNames: null, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings);

            using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream))
            {
                var handle = CXTranslationUnit.Parse(pinvokeGenerator.IndexHandle, DefaultInputFileName, DefaultClangCommandLineArgs, unsavedFiles, DefaultTranslationUnitFlags);
                using var translationUnit = TranslationUnit.GetOrCreate(handle);

                pinvokeGenerator.GenerateBindings(translationUnit);

                if (expectedDiagnostics is null)
                {
                    Assert.Empty(pinvokeGenerator.Diagnostics);
                }
                else
                {
                    Assert.Equal(expectedDiagnostics, pinvokeGenerator.Diagnostics);
                }
            }
            outputStream.Position = 0;

            var actualOutputContents = await new StreamReader(outputStream).ReadToEndAsync();

            Assert.Equal(expectedOutputContents, actualOutputContents);
        }
Exemple #2
0
        private void AddNativeTypeNameAttribute(string nativeTypeName, string prefix = null, string postfix = null, string attributePrefix = null)
        {
            if (string.IsNullOrWhiteSpace(nativeTypeName))
            {
                return;
            }

            if (prefix is null)
            {
                WriteIndentation();
            }
            else
            {
                WriteNewlineIfNeeded();
                Write(prefix);
            }

            Write('[');

            if (attributePrefix != null)
            {
                Write(attributePrefix);
            }

            Write("NativeTypeName(\"");
            Write(PInvokeGenerator.EscapeString(nativeTypeName));
            Write("\")]");

            if (postfix is null)
            {
                NeedsNewline = true;
            }
            else
            {
                Write(postfix);
            }
        }
Exemple #3
0
        private void AddNativeInheritanceAttribute(string inheritedFromName, string prefix = null, string postfix = null, string attributePrefix = null)
        {
            if (prefix is null)
            {
                WriteIndentation();
            }
            else
            {
                WriteNewlineIfNeeded();
                Write(prefix);
            }

            Write('[');

            if (attributePrefix != null)
            {
                Write(attributePrefix);
            }

            Write("NativeInheritance");
            Write('(');
            Write('"');
            Write(PInvokeGenerator.EscapeString(inheritedFromName));
            Write('"');
            Write(')');
            Write(']');

            if (postfix is null)
            {
                NeedsNewline = true;
            }
            else
            {
                Write(postfix);
            }
        }
Exemple #4
0
        static int Main()
        {
            SetupPath();

            string includeRoot =
                Path.Combine(
                    Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
                    "include");

            var config = new PInvokeGeneratorConfiguration(
                libraryPath: "openxr_loader",
                namespaceName: "OpenXR.PInvoke",
                options: PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles,
                outputLocation: "gen",
                methodClassName: "XR",
                methodPrefixToStrip: "xr"
                );

            string[] files = new[] { "openxr/openxr.h" }
            .Select(name => Path.Combine(includeRoot, name))
            .ToArray();
            int exitCode = 0;

            var translationFlags = CXTranslationUnit_Flags.CXTranslationUnit_None;

            translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes;               // Include attributed types in CXType
            translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes;              // Implicit attributes should be visited

            var clangCommandLineArgs = new List <string> {
                "--include-directory=" + includeRoot,
                "--include-directory=" + Path.Combine(NugetPackagesRoot,
                                                      "cppsharp", "0.10.1", "output", "lib", "clang", "9.0.0", "include"),
                "--language=c++",
            };

            using (var generator = new PInvokeGenerator(config)) {
                foreach (string file in files)
                {
                    var translationUnitError = CXTranslationUnit.TryParse(generator.IndexHandle,
                                                                          file,
                                                                          clangCommandLineArgs.ToArray().AsSpan(),
                                                                          Array.Empty <CXUnsavedFile>(),
                                                                          translationFlags,
                                                                          out CXTranslationUnit handle);
                    bool skipProcessing = false;

                    if (translationUnitError != CXErrorCode.CXError_Success)
                    {
                        Console.WriteLine($"Error: Parsing failed for '{file}' due to '{translationUnitError}'.");
                        skipProcessing = true;
                    }
                    else if (handle.NumDiagnostics != 0)
                    {
                        Console.WriteLine($"Diagnostics for '{file}':");

                        for (uint i = 0; i < handle.NumDiagnostics; ++i)
                        {
                            using var diagnostic = handle.GetDiagnostic(i);

                            Console.Write("    ");
                            Console.WriteLine(diagnostic.Format(CXDiagnostic.DefaultDisplayOptions).ToString());

                            skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Error);
                            skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Fatal);
                        }
                    }

                    if (skipProcessing)
                    {
                        Console.WriteLine($"Skipping '{file}' due to one or more errors listed above.");
                        Console.WriteLine();

                        exitCode = -1;
                        continue;
                    }

                    using var translationUnit = TranslationUnit.GetOrCreate(handle);

                    Console.WriteLine($"Processing '{file}'");
                    generator.GenerateBindings(translationUnit);
                }

                if (generator.Diagnostics.Count != 0)
                {
                    Console.WriteLine("Diagnostics for binding generation:");

                    foreach (var diagnostic in generator.Diagnostics)
                    {
                        Console.Write("    ");
                        Console.WriteLine(diagnostic);

                        if (diagnostic.Level == DiagnosticLevel.Warning)
                        {
                            if (exitCode >= 0)
                            {
                                exitCode++;
                            }
                        }
                        else if (diagnostic.Level == DiagnosticLevel.Error)
                        {
                            if (exitCode >= 0)
                            {
                                exitCode = -1;
                            }
                            else
                            {
                                exitCode--;
                            }
                        }
                    }
                }
            }

            return(exitCode);
        }