Skip to content

Commit

Permalink
Generate NullSafeHandle.NullHandle helper field
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Feb 16, 2021
1 parent 89267f2 commit b34a12d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
37 changes: 37 additions & 0 deletions src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ public class Generator : IDisposable
private readonly CSharpCompilation? compilation;
private readonly CSharpParseOptions? parseOptions;

private bool nullSafeHandleGenerated;

/// <summary>
/// Initializes a new instance of the <see cref="Generator"/> class.
/// </summary>
Expand Down Expand Up @@ -820,6 +822,8 @@ internal void GenerateConstant(FieldDefinitionHandle fieldDefHandle)

internal TypeSyntax? GenerateSafeHandle(string releaseMethod)
{
this.GenerateNullSafeHandleHelper();

if (this.releaseMethodsWithSafeHandleTypesGenerating.TryGetValue(releaseMethod, out TypeSyntax? safeHandleType))
{
return safeHandleType;
Expand Down Expand Up @@ -1413,6 +1417,39 @@ private static bool IsAnsiFunction(string methodName)
return false;
}

private void GenerateNullSafeHandleHelper()
{
if (this.nullSafeHandleGenerated)
{
return;
}

this.nullSafeHandleGenerated = true;

const string className = "NullSafeHandle";
string fullName = $"{this.Namespace}.{className}";
if (this.FindSymbolIfAlreadyAvailable(fullName) is object)
{
return;
}

// static readonly SafeHandle NullHandle = new SafeFileHandle(IntPtr.Zero, ownsHandle: false);
FieldDeclarationSyntax nullHandle = FieldDeclaration(
VariableDeclaration(SafeHandleTypeSyntax)
.AddVariables(VariableDeclarator("NullHandle").WithInitializer(EqualsValueClause(
ObjectCreationExpression(ParseTypeName("Microsoft.Win32.SafeHandles.SafeFileHandle")).AddArgumentListArguments(
Argument(DefaultExpression(IntPtrTypeSyntax)),
Argument(LiteralExpression(SyntaxKind.FalseLiteralExpression)))))))
.AddModifiers(Token(this.Visibility), Token(SyntaxKind.StaticKeyword), Token(SyntaxKind.ReadOnlyKeyword));

// static class NullSafeHandle { ... }
ClassDeclarationSyntax helper = ClassDeclaration(className)
.AddModifiers(Token(this.Visibility), Token(SyntaxKind.StaticKeyword))
.AddMembers(nullHandle);

this.safeHandleTypes.Add(helper);
}

private FunctionPointerTypeSyntax FunctionPointer(CallingConvention callingConvention, MethodSignature<TypeSyntax> signature, string delegateName)
=> FunctionPointerType(
FunctionPointerCallingConvention(Token(SyntaxKind.UnmanagedKeyword), FunctionPointerUnmanagedCallingConventionList(SingletonSeparatedList(ToUnmanagedCallingConventionSyntax(callingConvention)))),
Expand Down
2 changes: 1 addition & 1 deletion test/GenerationSandbox.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public void CreateFile()
lpSecurityAttributes: null,
FILE_CREATE_FLAGS.CREATE_NEW,
FILE_FLAGS_AND_ATTRIBUTES.FILE_ATTRIBUTE_TEMPORARY | (FILE_FLAGS_AND_ATTRIBUTES)FILE_FLAG_DELETE_ON_CLOSE,
hTemplateFile: CloseHandleSafeHandle.Null);
hTemplateFile: NullSafeHandle.NullHandle);
Assert.True(File.Exists(path));
fileHandle.Dispose();
Assert.False(File.Exists(path));
Expand Down

0 comments on commit b34a12d

Please sign in to comment.