Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ static void GenerateNativeTypeNameAttribute(PInvokeGenerator generator)
sw.WriteLine();

sw.Write("namespace ");
sw.WriteLine(generator.GetNamespace("NativeTypeName"));
sw.WriteLine(generator.GetNamespace("NativeTypeNameAttribute"));
sw.WriteLine('{');

sw.WriteLine(" /// <summary>Defines the type of a member as it was used in the native signature.</summary>");
Expand Down Expand Up @@ -449,11 +449,26 @@ static void GenerateTransparentStructs(PInvokeGenerator generator)
sw.WriteLine(config.HeaderText);
}

var targetNamespace = generator.GetNamespace(name);

sw.WriteLine("using System;");

if (kind == PInvokeGeneratorTransparentStructKind.HandleWin32)
{
var handleNamespace = generator.GetNamespace("HANDLE");

if (targetNamespace != handleNamespace)
{
sw.Write("using ");
sw.Write(handleNamespace);
sw.WriteLine(';');
}
}

sw.WriteLine();

sw.Write("namespace ");
sw.WriteLine(generator.GetNamespace(name));
sw.WriteLine(targetNamespace);
sw.WriteLine('{');

sw.Write(" public ");
Expand Down Expand Up @@ -3577,7 +3592,9 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue)
}
}

if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(qualifiedName.Replace("::", ".")))
var dottedQualifiedName = qualifiedName.Replace("::", ".");

if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(dottedQualifiedName))
{
if (_config.LogExclusions)
{
Expand Down Expand Up @@ -3626,6 +3643,15 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue)
return true;
}

if ((_config.IncludedNames.Length != 0) && !_config.IncludedNames.Contains(qualifiedName) && !_config.IncludedNames.Contains(dottedQualifiedName) && !_config.IncludedNames.Contains(name))
{
if (_config.LogExclusions)
{
AddDiagnostic(DiagnosticLevel.Info, $"Excluded {kind} '{qualifiedName}' as it was not in the include list");
}
return true;
}

if ((isExcludedValue & 0b10) != 0)
{
if (_config.LogExclusions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ public sealed class PInvokeGeneratorConfiguration

private PInvokeGeneratorConfigurationOptions _options;

public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, string outputLocation, string testOutputLocation, PInvokeGeneratorOutputMode outputMode = PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions options = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, string headerFile = null, string methodClassName = null, string methodPrefixToStrip = null, IReadOnlyDictionary<string, string> remappedNames = null, string[] traversalNames = null, IReadOnlyDictionary<string, string> withAccessSpecifiers = null, IReadOnlyDictionary<string, IReadOnlyList<string>> withAttributes = null, IReadOnlyDictionary<string, string> withCallConvs = null, IReadOnlyDictionary<string, string> withLibraryPaths = null, IReadOnlyDictionary<string, string> withNamespaces = null, string[] withSetLastErrors = null, IReadOnlyDictionary<string, (string, PInvokeGeneratorTransparentStructKind)> withTransparentStructs = null, IReadOnlyDictionary<string, string> withTypes = null, IReadOnlyDictionary<string, IReadOnlyList<string>> withUsings = null)
public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, string outputLocation, string testOutputLocation, PInvokeGeneratorOutputMode outputMode = PInvokeGeneratorOutputMode.CSharp, PInvokeGeneratorConfigurationOptions options = PInvokeGeneratorConfigurationOptions.None, string[] excludedNames = null, string[] includedNames = null, string headerFile = null, string methodClassName = null, string methodPrefixToStrip = null, IReadOnlyDictionary<string, string> remappedNames = null, string[] traversalNames = null, IReadOnlyDictionary<string, string> withAccessSpecifiers = null, IReadOnlyDictionary<string, IReadOnlyList<string>> withAttributes = null, IReadOnlyDictionary<string, string> withCallConvs = null, IReadOnlyDictionary<string, string> withLibraryPaths = null, IReadOnlyDictionary<string, string> withNamespaces = null, string[] withSetLastErrors = null, IReadOnlyDictionary<string, (string, PInvokeGeneratorTransparentStructKind)> withTransparentStructs = null, IReadOnlyDictionary<string, string> withTypes = null, IReadOnlyDictionary<string, IReadOnlyList<string>> withUsings = null)
{
if (excludedNames is null)
{
excludedNames = Array.Empty<string>();
}

if (includedNames is null)
{
includedNames = Array.Empty<string>();
}

if (string.IsNullOrWhiteSpace(libraryPath))
{
libraryPath = string.Empty;
Expand Down Expand Up @@ -101,6 +106,7 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s

ExcludedNames = excludedNames;
HeaderText = string.IsNullOrWhiteSpace(headerFile) ? string.Empty : File.ReadAllText(headerFile);
IncludedNames = includedNames;
LibraryPath = $@"""{libraryPath}""";
MethodClassName = methodClassName;
MethodPrefixToStrip = methodPrefixToStrip;
Expand Down Expand Up @@ -153,6 +159,8 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s

public string[] ExcludedNames { get; }

public string[] IncludedNames { get; }

public bool GenerateAggressiveInlining => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateAggressiveInlining);

public bool GenerateCompatibleCode => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode);
Expand Down
17 changes: 16 additions & 1 deletion sources/ClangSharpPInvokeGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public static async Task<int> Main(params string[] args)
AddFileOption(s_rootCommand);
AddFileDirectoryOption(s_rootCommand);
AddHeaderOption(s_rootCommand);
AddIncludeOption(s_rootCommand);
AddIncludeDirectoryOption(s_rootCommand);
AddLanguageOption(s_rootCommand);
AddLibraryOption(s_rootCommand);
Expand Down Expand Up @@ -133,6 +134,7 @@ public static int Run(InvocationContext context)
var files = context.ParseResult.ValueForOption<string[]>("--file");
var fileDirectory = context.ParseResult.ValueForOption<string>("--file-directory");
var headerFile = context.ParseResult.ValueForOption<string>("--headerFile");
var includedNames = context.ParseResult.ValueForOption<string[]>("--include");
var includeDirectories = context.ParseResult.ValueForOption<string[]>("--include-directory");
var language = context.ParseResult.ValueForOption<string>("--language");
var libraryPath = context.ParseResult.ValueForOption<string>("--libraryPath");
Expand Down Expand Up @@ -530,7 +532,7 @@ public static int Run(InvocationContext context)
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, outputMode, configOptions, excludedNames, headerFile, methodClassName, methodPrefixToStrip, remappedNames, traversalNames, withAccessSpecifiers, withAttributes, withCallConvs, withLibraryPath, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings);
var config = new PInvokeGeneratorConfiguration(libraryPath, namespaceName, outputLocation, testOutputLocation, outputMode, configOptions, excludedNames, includedNames, headerFile, methodClassName, methodPrefixToStrip, remappedNames, traversalNames, withAccessSpecifiers, withAttributes, withCallConvs, withLibraryPath, withNamespaces, withSetLastErrors, withTransparentStructs, withTypes, withUsings);

if (config.GenerateMacroBindings)
{
Expand Down Expand Up @@ -810,6 +812,19 @@ private static void AddHeaderOption(RootCommand rootCommand)
rootCommand.AddOption(option);
}

private static void AddIncludeOption(RootCommand rootCommand)
{
var option = new Option(
aliases: new string[] { "--include", "-i" },
description: "A declaration name to include in binding generation.",
argumentType: typeof(string),
getDefaultValue: Array.Empty<string>,
arity: ArgumentArity.OneOrMore
);

rootCommand.AddOption(option);
}

private static void AddIncludeDirectoryOption(RootCommand rootCommand)
{
var option = new Option(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private static async Task ValidateGeneratedBindingsAsync(string inputContents, s
using var unsavedFile = CXUnsavedFile.Create(DefaultInputFileName, inputContents);

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

using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream))
{
Expand Down