Skip to content

Commit 9a82694

Browse files
Merge pull request #290 from tannergooding/main
Adding support for explicitly including members to bind
2 parents a3907bb + 6d51dbf commit 9a82694

File tree

4 files changed

+55
-6
lines changed

4 files changed

+55
-6
lines changed

sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ static void GenerateNativeTypeNameAttribute(PInvokeGenerator generator)
362362
sw.WriteLine();
363363

364364
sw.Write("namespace ");
365-
sw.WriteLine(generator.GetNamespace("NativeTypeName"));
365+
sw.WriteLine(generator.GetNamespace("NativeTypeNameAttribute"));
366366
sw.WriteLine('{');
367367

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

452+
var targetNamespace = generator.GetNamespace(name);
453+
452454
sw.WriteLine("using System;");
455+
456+
if (kind == PInvokeGeneratorTransparentStructKind.HandleWin32)
457+
{
458+
var handleNamespace = generator.GetNamespace("HANDLE");
459+
460+
if (targetNamespace != handleNamespace)
461+
{
462+
sw.Write("using ");
463+
sw.Write(handleNamespace);
464+
sw.WriteLine(';');
465+
}
466+
}
467+
453468
sw.WriteLine();
454469

455470
sw.Write("namespace ");
456-
sw.WriteLine(generator.GetNamespace(name));
471+
sw.WriteLine(targetNamespace);
457472
sw.WriteLine('{');
458473

459474
sw.Write(" public ");
@@ -3577,7 +3592,9 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue)
35773592
}
35783593
}
35793594

3580-
if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(qualifiedName.Replace("::", ".")))
3595+
var dottedQualifiedName = qualifiedName.Replace("::", ".");
3596+
3597+
if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(dottedQualifiedName))
35813598
{
35823599
if (_config.LogExclusions)
35833600
{
@@ -3626,6 +3643,15 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue)
36263643
return true;
36273644
}
36283645

3646+
if ((_config.IncludedNames.Length != 0) && !_config.IncludedNames.Contains(qualifiedName) && !_config.IncludedNames.Contains(dottedQualifiedName) && !_config.IncludedNames.Contains(name))
3647+
{
3648+
if (_config.LogExclusions)
3649+
{
3650+
AddDiagnostic(DiagnosticLevel.Info, $"Excluded {kind} '{qualifiedName}' as it was not in the include list");
3651+
}
3652+
return true;
3653+
}
3654+
36293655
if ((isExcludedValue & 0b10) != 0)
36303656
{
36313657
if (_config.LogExclusions)

sources/ClangSharp.PInvokeGenerator/PInvokeGeneratorConfiguration.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ public sealed class PInvokeGeneratorConfiguration
2525

2626
private PInvokeGeneratorConfigurationOptions _options;
2727

28-
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)
28+
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)
2929
{
3030
if (excludedNames is null)
3131
{
3232
excludedNames = Array.Empty<string>();
3333
}
3434

35+
if (includedNames is null)
36+
{
37+
includedNames = Array.Empty<string>();
38+
}
39+
3540
if (string.IsNullOrWhiteSpace(libraryPath))
3641
{
3742
libraryPath = string.Empty;
@@ -101,6 +106,7 @@ public PInvokeGeneratorConfiguration(string libraryPath, string namespaceName, s
101106

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

154160
public string[] ExcludedNames { get; }
155161

162+
public string[] IncludedNames { get; }
163+
156164
public bool GenerateAggressiveInlining => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateAggressiveInlining);
157165

158166
public bool GenerateCompatibleCode => _options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateCompatibleCode);

sources/ClangSharpPInvokeGenerator/Program.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public static async Task<int> Main(params string[] args)
9797
AddFileOption(s_rootCommand);
9898
AddFileDirectoryOption(s_rootCommand);
9999
AddHeaderOption(s_rootCommand);
100+
AddIncludeOption(s_rootCommand);
100101
AddIncludeDirectoryOption(s_rootCommand);
101102
AddLanguageOption(s_rootCommand);
102103
AddLibraryOption(s_rootCommand);
@@ -133,6 +134,7 @@ public static int Run(InvocationContext context)
133134
var files = context.ParseResult.ValueForOption<string[]>("--file");
134135
var fileDirectory = context.ParseResult.ValueForOption<string>("--file-directory");
135136
var headerFile = context.ParseResult.ValueForOption<string>("--headerFile");
137+
var includedNames = context.ParseResult.ValueForOption<string[]>("--include");
136138
var includeDirectories = context.ParseResult.ValueForOption<string[]>("--include-directory");
137139
var language = context.ParseResult.ValueForOption<string>("--language");
138140
var libraryPath = context.ParseResult.ValueForOption<string>("--libraryPath");
@@ -530,7 +532,7 @@ public static int Run(InvocationContext context)
530532
translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes; // Include attributed types in CXType
531533
translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes; // Implicit attributes should be visited
532534

533-
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);
535+
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);
534536

535537
if (config.GenerateMacroBindings)
536538
{
@@ -810,6 +812,19 @@ private static void AddHeaderOption(RootCommand rootCommand)
810812
rootCommand.AddOption(option);
811813
}
812814

815+
private static void AddIncludeOption(RootCommand rootCommand)
816+
{
817+
var option = new Option(
818+
aliases: new string[] { "--include", "-i" },
819+
description: "A declaration name to include in binding generation.",
820+
argumentType: typeof(string),
821+
getDefaultValue: Array.Empty<string>,
822+
arity: ArgumentArity.OneOrMore
823+
);
824+
825+
rootCommand.AddOption(option);
826+
}
827+
813828
private static void AddIncludeDirectoryOption(RootCommand rootCommand)
814829
{
815830
var option = new Option(

tests/ClangSharp.PInvokeGenerator.UnitTests/PInvokeGeneratorTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private static async Task ValidateGeneratedBindingsAsync(string inputContents, s
6464
using var unsavedFile = CXUnsavedFile.Create(DefaultInputFileName, inputContents);
6565

6666
var unsavedFiles = new CXUnsavedFile[] { unsavedFile };
67-
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);
67+
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);
6868

6969
using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream))
7070
{

0 commit comments

Comments
 (0)