Skip to content

Commit

Permalink
Resolve #39 Add OmitNullableDirective property to the CreateSyncVersi…
Browse files Browse the repository at this point in the history
…on attribute
  • Loading branch information
virzak committed Feb 12, 2024
1 parent 2114be3 commit ffe34ce
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ A list of changes applied to the new synchronized method:
- Remove `CreateSyncVersionAttribute`
- Update XML documentation

#### Properties

##### OmitNullableDirective

This source generator detects language version during the compilation. By default it will generate `#nullable enable` directive if and only if the language version is 8 or above. Since it is [impossible](https://github.com/dotnet/roslyn/issues/49555) to reliably determine whether nullable context is turned on or not, `OmitNullableDirective` property is available to omit that directive from generating.

```cs
[Zomp.SyncMethodGenerator.CreateSyncVersion(OmitNullableDirective = true)]
public async Task MethodAsync()
{
string f = null;
}
```

### SYNC_ONLY symbol

In case there is logic which should only be executed in the synchronized version of the method, wrap it in `SYNC_ONLY` #if directive.
Expand Down Expand Up @@ -123,7 +137,7 @@ Other than required packages to run `act` itself, GitHub Actions script installs

To build the project using act follow these instructions:

### Windows
#### Windows

Install [chocolatey](https://chocolatey.org/install) if missing.

Expand All @@ -141,7 +155,7 @@ In the project directory run:
act -P windows-latest=-self-hosted --artifact-server-path /tmp/artifacts
```

### Linux
#### Linux

Install act by following these [instructions](https://lindevs.com/install-act-on-ubuntu).

Expand Down
8 changes: 6 additions & 2 deletions src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
/// </summary>
public static class SourceGenerationHelper
{
internal const string CreateSyncVersionAttributeSource = """
internal const string CreateSyncVersionAttributeSource = $$"""
// <auto-generated/>
namespace Zomp.SyncMethodGenerator
{
/// <summary>
/// An attribute that can be used to automatically generate a synchronous version of an async method. Must be used in a partial class.
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Method)]
internal class CreateSyncVersionAttribute : System.Attribute
internal class {{SyncMethodSourceGenerator.CreateSyncVersionAttribute}} : System.Attribute
{
/// <summary>
/// Gets or sets a value indicating whether "#nullable enable" directive will be omitted from generated code. False by default.
/// </summary>
public bool {{SyncMethodSourceGenerator.OmitNullableDirective}} { get; set; }
}
}
""";
Expand Down
8 changes: 8 additions & 0 deletions src/Zomp.SyncMethodGenerator/SyncMethodSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class SyncMethodSourceGenerator : IIncrementalGenerator
public const string CreateSyncVersionAttribute = "CreateSyncVersionAttribute";
internal const string QualifiedCreateSyncVersionAttribute = $"{ThisAssembly.RootNamespace}.{CreateSyncVersionAttribute}";

internal const string OmitNullableDirective = "OmitNullableDirective";

private static MethodToGenerate? last;

/// <inheritdoc/>
Expand Down Expand Up @@ -117,16 +119,22 @@ private static (MethodToGenerate MethodToGenerate, string Path, string Content)
return null;
}

AttributeData syncMethodGeneratorAttributeData = null!;

foreach (AttributeData attributeData in methodSymbol.GetAttributes())
{
if (!attribute.Equals(attributeData.AttributeClass, SymbolEqualityComparer.Default))
{
continue;
}

syncMethodGeneratorAttributeData = attributeData;
break;
}

var explicitDisableNullable = syncMethodGeneratorAttributeData.NamedArguments.FirstOrDefault(c => c.Key == OmitNullableDirective) is { Value.Value: true };
disableNullable |= explicitDisableNullable;

var classes = ImmutableArray.CreateBuilder<ClassDeclaration>();
SyntaxNode? node = methodDeclarationSyntax;
while (node.Parent is not null)
Expand Down
17 changes: 17 additions & 0 deletions tests/Generator.Tests/NullabilityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ public async Task DoNothingAsync(string l)
await Task.CompletedTask;
}
}
""".Verify(sourceType: SourceType.Full);

[Fact]
public Task NullableOmitExplicit() => """
#nullable disable

namespace Test;

partial class MyClass
{
[Obsolete]
[CreateSyncVersion(OmitNullableDirective = true)]
public async Task MethodAsync()
{
string f = null;
}
}
""".Verify(sourceType: SourceType.Full);

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//HintName: Test.MyClass.MethodAsync.g.cs
// <auto-generated/>
namespace Test;
partial class MyClass
{
[global::System.ObsoleteAttribute]
public void Method()
{
string f = null;
}
}

0 comments on commit ffe34ce

Please sign in to comment.