Ejemplo n.º 1
0
        private TranslationUnit(CXTranslationUnit handle)
        {
            Handle = handle;
            TranslationUnitDecl = new TranslationUnitDecl(Handle.Cursor);

            _createdCursors = new Dictionary <CXCursor, Cursor>();
            _createdTypes   = new Dictionary <CXType, Type>();
        }
Ejemplo n.º 2
0
        public static TokenGroup GetTokens(CXTranslationUnit tu, CXSourceRange range)
        {
            IntPtr tokens;
            uint count;
            clang.tokenize (tu, range, out tokens, out count);

            return new TokenGroup (tu, tokens, count);
        }
Ejemplo n.º 3
0
        private TranslationUnit(CXTranslationUnit handle)
        {
            Handle = handle;

            _createdCursors = new Dictionary <CXCursor, WeakReference <Cursor> >();
            _createdTypes   = new Dictionary <CXType, WeakReference <Type> >();

            _translationUnitDecl = new Lazy <TranslationUnitDecl>(() => GetOrCreate <TranslationUnitDecl>(Handle.Cursor));
        }
Ejemplo n.º 4
0
        private TokenGroup(CXTranslationUnit tu, IntPtr memory, uint count)
        {
            this.memory = memory;
            this.count = count;
            this.tu = tu;

            Tokens = new CXToken[(int)count];
            for (int i = 0; i < count; i++)
                Tokens [i] = Marshal.PtrToStructure<CXToken> (memory + i * Marshal.SizeOf<CXToken> ());
        }
Ejemplo n.º 5
0
        private TranslationUnit(CXTranslationUnit handle)
        {
            Handle = handle;

            _createdCursors              = new Dictionary <CXCursor, WeakReference <Cursor> >();
            _createdTemplateArguments    = new Dictionary <CX_TemplateArgument, WeakReference <TemplateArgument> >();
            _createdTemplateArgumentLocs = new Dictionary <CX_TemplateArgumentLoc, WeakReference <TemplateArgumentLoc> >();
            _createdTemplateNames        = new Dictionary <CX_TemplateName, WeakReference <TemplateName> >();
            _createdTypes = new Dictionary <CXType, WeakReference <Type> >();

            _translationUnitDecl = new Lazy <TranslationUnitDecl>(() => GetOrCreate <TranslationUnitDecl>(Handle.Cursor));
        }
Ejemplo n.º 6
0
        public static int reparseTranslationUnit(CXTranslationUnit @TU, uint @num_unsaved_files, CXUnsavedFile[] @unsaved_files, uint @options)
        {
            var arr = new _CXUnsavedFile[unsaved_files.Length];

            try
            {
                BeginCXUnsavedFileMarshal(ref arr, ref unsaved_files);
                return(reparseTranslationUnit(TU, num_unsaved_files, arr, options));
            }
            finally
            {
                EndCXUnsavedFileMarshal(ref arr);
            }
        }
Ejemplo n.º 7
0
        public static IntPtr codeCompleteAt(CXTranslationUnit @TU, string @complete_filename, uint @complete_line, uint @complete_column, CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options)
        {
            var arr = new _CXUnsavedFile[unsaved_files.Length];

            try
            {
                BeginCXUnsavedFileMarshal(ref arr, ref unsaved_files);
                return(codeCompleteAt(TU, complete_filename, complete_line, complete_column, arr, num_unsaved_files, options));
            }
            finally
            {
                EndCXUnsavedFileMarshal(ref arr);
            }
        }
Ejemplo n.º 8
0
 public static extern IntPtr codeCompleteAt(CXTranslationUnit @TU, [MarshalAs(UnmanagedType.LPStr)] string @complete_filename, uint @complete_line, uint @complete_column, out CXUnsavedFile @unsaved_files, uint @num_unsaved_files, uint @options);
Ejemplo n.º 9
0
 public static extern void annotateTokens(CXTranslationUnit @TU, out CXToken @Tokens, uint @NumTokens, out CXCursor @Cursors);
Ejemplo n.º 10
0
 public static extern CXSourceRange getTokenExtent(CXTranslationUnit @param0, CXToken @param1);
Ejemplo n.º 11
0
 public static extern CXString getTokenSpelling(CXTranslationUnit @param0, CXToken @param1);
Ejemplo n.º 12
0
        public static int Run(InvocationContext context)
        {
            var additionalArgs         = context.ParseResult.ValueForOption <string[]>("additional");
            var configSwitches         = context.ParseResult.ValueForOption <string[]>("config");
            var defines                = context.ParseResult.ValueForOption <string[]>("define");
            var excludedNames          = context.ParseResult.ValueForOption <string[]>("exclude");
            var files                  = context.ParseResult.ValueForOption <string[]>("file");
            var headerFile             = context.ParseResult.ValueForOption <string>("headerFile");
            var includeDirs            = context.ParseResult.ValueForOption <string[]>("include");
            var libraryPath            = context.ParseResult.ValueForOption <string>("libraryPath");
            var methodClassName        = context.ParseResult.ValueForOption <string>("methodClassName");
            var methodPrefixToStrip    = context.ParseResult.ValueForOption <string>("prefixStrip");
            var namespaceName          = context.ParseResult.ValueForOption <string>("namespace");
            var outputLocation         = context.ParseResult.ValueForOption <string>("output");
            var remappedNameValuePairs = context.ParseResult.ValueForOption <string[]>("remap");
            var traversalNames         = context.ParseResult.ValueForOption <string[]>("traverse");

            var errorList = new List <string>();

            if (!files.Any())
            {
                errorList.Add("Error: No input C/C++ files provided. Use --file or -f");
            }

            if (string.IsNullOrWhiteSpace(libraryPath))
            {
                errorList.Add("Error: No library path location provided. Use --libraryPath or -l");
            }

            if (string.IsNullOrWhiteSpace(namespaceName))
            {
                errorList.Add("Error: No namespace provided. Use --namespace or -n");
            }

            if (string.IsNullOrWhiteSpace(outputLocation))
            {
                errorList.Add("Error: No output file location provided. Use --output or -o");
            }

            var remappedNames = new Dictionary <string, string>();

            foreach (var remappedNameValuePair in remappedNameValuePairs)
            {
                var parts = remappedNameValuePair.Split('=');

                if (parts.Length != 2)
                {
                    errorList.Add($"Error: Invalid remap argument: {remappedNameValuePair}. Expected 'name=value'");
                    continue;
                }

                remappedNames[parts[0].TrimEnd()] = parts[1].TrimStart();
            }

            var configOptions = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PInvokeGeneratorConfigurationOptions.None : PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;

            foreach (var configSwitch in configSwitches)
            {
                switch (configSwitch)
                {
                case "default-remappings":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.NoDefaultRemappings;
                    break;
                }

                case "multi-file":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles;
                    break;
                }

                case "no-default-remappings":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.NoDefaultRemappings;
                    break;
                }

                case "single-file":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles;
                    break;
                }

                case "unix-types":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;
                    break;
                }

                case "windows-types":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;
                    break;
                }

                default:
                {
                    errorList.Add($"Error: Unrecognized config switch: {configSwitch}.");
                    break;
                }
                }
            }

            if (errorList.Any())
            {
                foreach (var error in errorList)
                {
                    context.Console.Error.WriteLine(error);
                }
                context.Console.Error.WriteLine();

                new HelpBuilder(context.Console).Write(s_rootCommand);
                return(-1);
            }

            var clangCommandLineArgs = new string[]
            {
                "-std=c++11",                           // The input files should be compiled for C++ 11
                "-xc++",                                // The input files are C++
                "-Wno-pragma-once-outside-header"       // We are processing files which may be header files
            };

            clangCommandLineArgs = clangCommandLineArgs.Concat(includeDirs.Select(x => "-I" + x)).ToArray();
            clangCommandLineArgs = clangCommandLineArgs.Concat(defines.Select(x => "-D" + x)).ToArray();
            clangCommandLineArgs = clangCommandLineArgs.Concat(additionalArgs).ToArray();

            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 config = new PInvokeGeneratorConfiguration(libraryPath, namespaceName, outputLocation, configOptions, excludedNames, headerFile, methodClassName, methodPrefixToStrip, remappedNames, traversalNames);

            int exitCode = 0;

            using (var pinvokeGenerator = new PInvokeGenerator(config))
            {
                foreach (var file in files)
                {
                    var translationUnitError = CXTranslationUnit.TryParse(pinvokeGenerator.IndexHandle, file, clangCommandLineArgs, Array.Empty <CXUnsavedFile>(), translationFlags, out CXTranslationUnit handle);
                    var 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(CXDiagnosticDisplayOptions.CXDiagnostic_DisplayOption).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}'");
                    pinvokeGenerator.GenerateBindings(translationUnit);
                }

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

                    foreach (var diagnostic in pinvokeGenerator.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);
        }
Ejemplo n.º 13
0
 public static extern void annotateTokens(CXTranslationUnit @TU, [MarshalAs(UnmanagedType.LPArray)] CXToken[] @Tokens, uint @NumTokens, [MarshalAs(UnmanagedType.LPArray)] CXCursor[] @Cursors);
Ejemplo n.º 14
0
        public static CXErrorCode parseTranslationUnit2FullArgv(CXIndex @CIdx, string @source_filename, string[] @command_line_args, int @num_command_line_args, CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options, out CXTranslationUnit @out_TU)
        {
            var arr = new _CXUnsavedFile[unsaved_files.Length];

            try
            {
                BeginCXUnsavedFileMarshal(ref arr, ref unsaved_files);
                return(parseTranslationUnit2FullArgv(CIdx, source_filename, command_line_args, num_command_line_args, arr, num_unsaved_files, options, out out_TU));
            }
            finally
            {
                EndCXUnsavedFileMarshal(ref arr);
            }
        }
Ejemplo n.º 15
0
 public static extern int saveTranslationUnit(CXTranslationUnit @TU, [MarshalAs(UnmanagedType.LPStr)] string @FileName, uint @options);
Ejemplo n.º 16
0
 private static extern IntPtr codeCompleteAt(CXTranslationUnit @TU, [MarshalAs(UnmanagedType.LPStr)] string @complete_filename, uint @complete_line, uint @complete_column, [MarshalAs(UnmanagedType.LPArray)] _CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options);
Ejemplo n.º 17
0
 private static extern int indexSourceFileFullArgv(CXIndexAction @param0, CXClientData @client_data, IntPtr @index_callbacks, uint @index_callbacks_size, uint @index_options, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] _CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, out CXTranslationUnit @out_TU, uint @TU_options);
Ejemplo n.º 18
0
 private static extern int reparseTranslationUnit(CXTranslationUnit @TU, uint @num_unsaved_files, [MarshalAs(UnmanagedType.LPArray)] _CXUnsavedFile[] @unsaved_files, uint @options);
Ejemplo n.º 19
0
 private static extern CXErrorCode parseTranslationUnit2FullArgv(CXIndex @CIdx, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] _CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options, out CXTranslationUnit @out_TU);
Ejemplo n.º 20
0
        public static int indexSourceFileFullArgv(CXIndexAction @param0, CXClientData @client_data, IndexerCallbacks[] @index_callbacks, uint @index_callbacks_size, uint @index_options, string @source_filename, string[] @command_line_args, int @num_command_line_args, CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, out CXTranslationUnit @out_TU, uint @TU_options)
        {
            var    arr    = new _CXUnsavedFile[unsaved_files.Length];
            IntPtr result = IntPtr.Zero;

            try
            {
                BeginCXUnsavedFileMarshal(ref arr, ref unsaved_files);
                BeginIndexerCallbacksMarshal(out result, ref index_callbacks);

                return(indexSourceFileFullArgv(param0, client_data, result, index_callbacks_size, index_options, source_filename, command_line_args, num_command_line_args, arr, num_unsaved_files, out out_TU, TU_options));
            }
            finally
            {
                EndCXUnsavedFileMarshal(ref arr);
                EndIndexerCallbacksMarshal(result);
            }
        }
Ejemplo n.º 21
0
 public static extern CXResult findIncludesInFile(CXTranslationUnit @TU, CXFile @file, CXCursorAndRangeVisitor @visitor);
Ejemplo n.º 22
0
 public static extern uint defaultReparseOptions(CXTranslationUnit @TU);
Ejemplo n.º 23
0
 public static extern int indexTranslationUnit(CXIndexAction @param0, CXClientData @client_data, out IndexerCallbacks @index_callbacks, uint @index_callbacks_size, uint @index_options, CXTranslationUnit @param5);
Ejemplo n.º 24
0
 public static extern CXTUResourceUsage getCXTUResourceUsage(CXTranslationUnit @TU);
Ejemplo n.º 25
0
 public static extern CXErrorCode parseTranslationUnit2(CXIndex @CIdx, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, out CXUnsavedFile @unsaved_files, uint @num_unsaved_files, uint @options, out CXTranslationUnit @out_TU);
Ejemplo n.º 26
0
 public static extern void disposeTokens(CXTranslationUnit @TU, [MarshalAs(UnmanagedType.LPArray)] CXToken[] @Tokens, uint @NumTokens);
Ejemplo n.º 27
0
 public static extern void disposeTranslationUnit(CXTranslationUnit @param0);
Ejemplo n.º 28
0
 public static extern CXCursor getCursor(CXTranslationUnit @param0, CXSourceLocation @param1);
Ejemplo n.º 29
0
 public static extern int reparseTranslationUnit(CXTranslationUnit @TU, uint @num_unsaved_files, out CXUnsavedFile @unsaved_files, uint @options);
Ejemplo n.º 30
0
 public static extern uint Module_getNumTopLevelHeaders(CXTranslationUnit @param0, CXModule @Module);
Ejemplo n.º 31
0
 public static extern CXCursor getTranslationUnitCursor(CXTranslationUnit @param0);
Ejemplo n.º 32
0
 public static extern void tokenize(CXTranslationUnit @TU, CXSourceRange @Range, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] out CXToken[] @Tokens, out uint @NumTokens);
Ejemplo n.º 33
0
 public static extern CXModule getModuleForFile(CXTranslationUnit @param0, CXFile @param1);
Ejemplo n.º 34
0
 public static CXErrorCode ParseFullArgv(CXIndex index, string sourceFileName, string[] commandLineArgs, CXUnsavedFile[] unsavedFiles, CXTranslationUnit_Flags options, out CXTranslationUnit translationUnit) => clang.parseTranslationUnit2FullArgv(index, sourceFileName, commandLineArgs, commandLineArgs.Length, unsavedFiles, (uint)unsavedFiles.Length, (uint)options, out translationUnit);
Ejemplo n.º 35
0
 public static extern CXFile Module_getTopLevelHeader(CXTranslationUnit @param0, CXModule @Module, uint @Index);
Ejemplo n.º 36
0
 public static CXErrorCode Create(CXIndex index, string astFileName, out CXTranslationUnit translationUnit) => clang.createTranslationUnit2(index, astFileName, out translationUnit);
Ejemplo n.º 37
0
 public static extern CXSourceLocation getTokenLocation(CXTranslationUnit @param0, CXToken @param1);
Ejemplo n.º 38
0
 public static extern IntPtr getSkippedRanges(CXTranslationUnit @tu, CXFile @file);
Ejemplo n.º 39
0
 public static extern void tokenize(CXTranslationUnit @TU, CXSourceRange @Range, out IntPtr @Tokens, out uint @NumTokens);
Ejemplo n.º 40
0
 public static extern uint getNumDiagnostics(CXTranslationUnit @Unit);
Ejemplo n.º 41
0
 public static extern void disposeTokens(CXTranslationUnit @TU, out CXToken @Tokens, uint @NumTokens);
Ejemplo n.º 42
0
 public static extern CXDiagnostic getDiagnostic(CXTranslationUnit @Unit, uint @Index);
Ejemplo n.º 43
0
 public static extern void getInclusions(CXTranslationUnit @tu, CXInclusionVisitor @visitor, CXClientData @client_data);
Ejemplo n.º 44
0
 public static extern CXDiagnosticSet getDiagnosticSetFromTU(CXTranslationUnit @Unit);
Ejemplo n.º 45
0
 public static extern int indexSourceFile(CXIndexAction @param0, CXClientData @client_data, out IndexerCallbacks @index_callbacks, uint @index_callbacks_size, uint @index_options, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, out CXUnsavedFile @unsaved_files, uint @num_unsaved_files, out CXTranslationUnit @out_TU, uint @TU_options);
Ejemplo n.º 46
0
 public static extern CXString getTranslationUnitSpelling(CXTranslationUnit @CTUnit);
Ejemplo n.º 47
0
        public static int Run(InvocationContext context)
        {
            var additionalArgs         = context.ParseResult.ValueForOption <string[]>("additional");
            var configSwitches         = context.ParseResult.ValueForOption <string[]>("config");
            var defineMacros           = context.ParseResult.ValueForOption <string[]>("define-macro");
            var excludedNames          = context.ParseResult.ValueForOption <string[]>("exclude");
            var files                  = context.ParseResult.ValueForOption <string[]>("file");
            var fileDirectory          = context.ParseResult.ValueForOption <string>("file-directory");
            var headerFile             = context.ParseResult.ValueForOption <string>("headerFile");
            var includeDirectories     = context.ParseResult.ValueForOption <string[]>("include-directory");
            var language               = context.ParseResult.ValueForOption <string>("language");
            var libraryPath            = context.ParseResult.ValueForOption <string>("libraryPath");
            var methodClassName        = context.ParseResult.ValueForOption <string>("methodClassName");
            var methodPrefixToStrip    = context.ParseResult.ValueForOption <string>("prefixStrip");
            var namespaceName          = context.ParseResult.ValueForOption <string>("namespace");
            var outputLocation         = context.ParseResult.ValueForOption <string>("output");
            var remappedNameValuePairs = context.ParseResult.ValueForOption <string[]>("remap");
            var std = context.ParseResult.ValueForOption <string>("std");
            var testOutputLocation            = context.ParseResult.ValueForOption <string>("test-output");
            var traversalNames                = context.ParseResult.ValueForOption <string[]>("traverse");
            var withAttributeNameValuePairs   = context.ParseResult.ValueForOption <string[]>("with-attribute");
            var withCallConvNameValuePairs    = context.ParseResult.ValueForOption <string[]>("with-callconv");
            var withLibraryPathNameValuePairs = context.ParseResult.ValueForOption <string[]>("with-librarypath");
            var withSetLastErrors             = context.ParseResult.ValueForOption <string[]>("with-setlasterror");
            var withTypeNameValuePairs        = context.ParseResult.ValueForOption <string[]>("with-type");
            var withUsingNameValuePairs       = context.ParseResult.ValueForOption <string[]>("with-using");

            var errorList = new List <string>();

            if (!files.Any())
            {
                errorList.Add("Error: No input C/C++ files provided. Use --file or -f");
            }

            if (string.IsNullOrWhiteSpace(namespaceName))
            {
                errorList.Add("Error: No namespace provided. Use --namespace or -n");
            }

            if (string.IsNullOrWhiteSpace(outputLocation))
            {
                errorList.Add("Error: No output file location provided. Use --output or -o");
            }

            ParseKeyValuePairs(remappedNameValuePairs, errorList, out Dictionary <string, string> remappedNames);
            ParseKeyValuePairs(withAttributeNameValuePairs, errorList, out Dictionary <string, IReadOnlyList <string> > withAttributes);
            ParseKeyValuePairs(withCallConvNameValuePairs, errorList, out Dictionary <string, string> withCallConvs);
            ParseKeyValuePairs(withLibraryPathNameValuePairs, errorList, out Dictionary <string, string> withLibraryPath);
            ParseKeyValuePairs(withTypeNameValuePairs, errorList, out Dictionary <string, string> withTypes);
            ParseKeyValuePairs(withUsingNameValuePairs, errorList, out Dictionary <string, IReadOnlyList <string> > withUsings);

            var configOptions = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PInvokeGeneratorConfigurationOptions.None : PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;

            foreach (var configSwitch in configSwitches)
            {
                switch (configSwitch)
                {
                case "compatible-codegen":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GeneratePreviewCode;
                    break;
                }

                case "default-remappings":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.NoDefaultRemappings;
                    break;
                }

                case "exclude-com-proxies":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeComProxies;
                    break;
                }

                case "exclude-empty-records":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeEmptyRecords;
                    break;
                }

                case "exclude-enum-operators":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.ExcludeEnumOperators;
                    break;
                }

                case "explicit-vtbls":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls;
                    break;
                }

                case "generate-macro-bindings":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateMacroBindings;
                    break;
                }

                case "generate-tests-nunit":
                {
                    if (string.IsNullOrWhiteSpace(testOutputLocation))
                    {
                        errorList.Add("Error: No test output file location provided. Use --test-output or -to");
                    }

                    if (configOptions.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit))
                    {
                        errorList.Add("Cannot generate both NUnit and XUnit tests.");
                    }
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit;
                    break;
                }

                case "generate-tests-xunit":
                {
                    if (string.IsNullOrWhiteSpace(testOutputLocation))
                    {
                        errorList.Add("Error: No test output file location provided. Use --test-output or -to");
                    }

                    if (configOptions.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit))
                    {
                        errorList.Add("Cannot generate both NUnit and XUnit tests.");
                    }
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit;
                    break;
                }

                case "implicit-vtbls":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateExplicitVtbls;
                    break;
                }

                case "latest-codegen":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GeneratePreviewCode;
                    break;
                }

                case "log-exclusions":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.LogExclusions;
                    break;
                }

                case "log-visited-files":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.LogVisitedFiles;
                    break;
                }

                case "multi-file":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles;
                    break;
                }

                case "no-default-remappings":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.NoDefaultRemappings;
                    break;
                }

                case "preview-codegen":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
                    configOptions |= PInvokeGeneratorConfigurationOptions.GeneratePreviewCode;
                    break;
                }

                case "preview-codegen-nint":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
                    configOptions |= PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeNint;
                    break;
                }

                case "preview-codegen-fnptr":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode;
                    configOptions |= PInvokeGeneratorConfigurationOptions.GeneratePreviewCodeFnptr;
                    break;
                }

                case "single-file":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles;
                    break;
                }

                case "unix-types":
                {
                    configOptions |= PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;
                    break;
                }

                case "windows-types":
                {
                    configOptions &= ~PInvokeGeneratorConfigurationOptions.GenerateUnixTypes;
                    break;
                }

                default:
                {
                    errorList.Add($"Error: Unrecognized config switch: {configSwitch}.");
                    break;
                }
                }
            }

            if (!string.IsNullOrWhiteSpace(testOutputLocation) && !configOptions.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit) && !configOptions.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit))
            {
                errorList.Add("Error: No test format provided. Use --config generate-tests-nunit or --config generate-tests-xunit");
            }

            if (errorList.Any())
            {
                foreach (var error in errorList)
                {
                    context.Console.Error.Write(error);
                    context.Console.Error.Write(Environment.NewLine);
                }
                context.Console.Error.Write(Environment.NewLine);

                new HelpBuilder(context.Console).Write(s_rootCommand);
                return(-1);
            }

            var clangCommandLineArgs = new string[]
            {
                $"--language={language}",               // Treat subsequent input files as having type <language>
                $"--std={std}",                         // Language standard to compile for
                "-Wno-pragma-once-outside-header"       // We are processing files which may be header files
            };

            clangCommandLineArgs = clangCommandLineArgs.Concat(includeDirectories.Select(x => "--include-directory=" + x)).ToArray();
            clangCommandLineArgs = clangCommandLineArgs.Concat(defineMacros.Select(x => "--define-macro=" + x)).ToArray();
            clangCommandLineArgs = clangCommandLineArgs.Concat(additionalArgs).ToArray();

            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 config = new PInvokeGeneratorConfiguration(libraryPath, namespaceName, outputLocation, testOutputLocation, configOptions, excludedNames, headerFile, methodClassName, methodPrefixToStrip, remappedNames, traversalNames, withAttributes, withCallConvs, withLibraryPath, withSetLastErrors, withTypes, withUsings);

            if (config.GenerateMacroBindings)
            {
                translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord;
            }

            int exitCode = 0;

            using (var pinvokeGenerator = new PInvokeGenerator(config))
            {
                foreach (var file in files)
                {
                    var filePath = Path.Combine(fileDirectory, file);

                    var translationUnitError = CXTranslationUnit.TryParse(pinvokeGenerator.IndexHandle, filePath, clangCommandLineArgs, Array.Empty <CXUnsavedFile>(), translationFlags, out CXTranslationUnit handle);
                    var skipProcessing       = false;

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

                        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 '{filePath}' due to one or more errors listed above.");
                        Console.WriteLine();

                        exitCode = -1;
                        continue;
                    }

                    using var translationUnit = TranslationUnit.GetOrCreate(handle);

                    Console.WriteLine($"Processing '{filePath}'");
                    pinvokeGenerator.GenerateBindings(translationUnit, filePath, clangCommandLineArgs, translationFlags);
                }

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

                    foreach (var diagnostic in pinvokeGenerator.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);
        }
Ejemplo n.º 48
0
 public static extern CXErrorCode createTranslationUnit2(CXIndex @CIdx, [MarshalAs(UnmanagedType.LPStr)] string @ast_filename, out CXTranslationUnit @out_TU);