feat: implement analyzer and code fixer for identifying and fixing when a sync flag is not propagated correctly.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
root = true
|
||||
|
||||
[*.cs]
|
||||
dotnet_diagnostic.SYNC001.additional_sync_names = runSynchronously, isSync
|
||||
|
||||
dotnet_diagnostic.CA2007.severity = none
|
||||
dotnet_diagnostic.CA1707.severity = none
|
||||
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
@@ -0,0 +1,70 @@
|
||||
internal static class Program
|
||||
{
|
||||
public static async Task Main()
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IDataService
|
||||
{
|
||||
Task<string> GetDataAsync(string name, bool sync = false);
|
||||
Task<string> GetMoreDataAsync(bool runSynchronously, string name);
|
||||
Task<string> FetchAsync(int id, bool sync = false, bool cache = true);
|
||||
}
|
||||
|
||||
internal class BusinessLogic(IDataService dataService)
|
||||
{
|
||||
private readonly IDataService _dataService = dataService;
|
||||
|
||||
// ── Good patterns (no SYNC001) ──────────────────────────
|
||||
|
||||
/// <summary>Passes the default 'sync' variable positionally.</summary>
|
||||
public async Task<string> Good_ForwardSync(bool sync)
|
||||
{
|
||||
return await _dataService.GetDataAsync("Stevan", sync);
|
||||
}
|
||||
|
||||
/// <summary>Passes a custom 'runSynchronously' variable positionally.</summary>
|
||||
public async Task<string> Good_ForwardCustomFlag(bool runSynchronously)
|
||||
{
|
||||
return await _dataService.GetMoreDataAsync(runSynchronously, "Freeborn");
|
||||
}
|
||||
|
||||
// ── Bad patterns (SYNC001, demonstrating code fix) ──────
|
||||
|
||||
/// <summary>Omits the sync argument entirely.
|
||||
/// Code fix: inserts `sync` at ordinal 1.</summary>
|
||||
public async Task<string> Bad_OmittedSync(bool sync)
|
||||
{
|
||||
return await _dataService.GetDataAsync("Stevan");
|
||||
}
|
||||
|
||||
/// <summary>Hardcodes `false` as a positional argument.
|
||||
/// Code fix: replaces arg at ordinal 1 with `sync`.</summary>
|
||||
public async Task<string> Bad_HardcodedValue(bool sync)
|
||||
{
|
||||
return await _dataService.GetDataAsync("Stevan", false);
|
||||
}
|
||||
|
||||
/// <summary>Hardcodes a value using a named argument.
|
||||
/// Code fix: replaces expression in the named arg, keeping `sync:`.</summary>
|
||||
public async Task<string> Bad_NamedHardcoded(bool sync)
|
||||
{
|
||||
return await _dataService.GetDataAsync("Stevan", sync: false);
|
||||
}
|
||||
|
||||
/// <summary>Omits sync when it's not the last parameter.
|
||||
/// Code fix: inserts `sync` at ordinal 1 (before `cache`).</summary>
|
||||
public async Task<string> Bad_OmittedSyncNotLast(bool sync)
|
||||
{
|
||||
return await _dataService.FetchAsync(17);
|
||||
}
|
||||
|
||||
/// <summary>Hardcodes `false` at ordinal 0 where the target expects `runSynchronously`.
|
||||
/// Code fix: replaces arg at ordinal 0 with `sync` (value = enclosing name).</summary>
|
||||
public async Task<string> Bad_HardcodedAtOrdinalZero(bool sync)
|
||||
{
|
||||
return await _dataService.GetMoreDataAsync(false, "Freeborn");
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net11.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\StevanFreeborn.AsyncSyncFlagAnalyzer\StevanFreeborn.AsyncSyncFlagAnalyzer.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||
<ProjectReference Include="..\..\src\StevanFreeborn.AsyncSyncFlagAnalyzer.CodeFixes\StevanFreeborn.AsyncSyncFlagAnalyzer.CodeFixes.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user