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
3 changes: 2 additions & 1 deletion README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ If you are already using other analyzers, you can check [which rules are duplica
|[MA0151](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0151.md)|Usage|DebuggerDisplay must contain valid members|⚠️|✔️|❌|
|[MA0152](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0152.md)|Performance|Use Unwrap instead of using await twice|ℹ️|✔️|❌|
|[MA0153](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0153.md)|Design|Do not log symbols decorated with DataClassificationAttribute directly|⚠️|✔️|❌|
|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|❌|
|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|ℹ️|✔️|✔️|
|[MA0155](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0155.md)|Design|Do not use async void methods|⚠️|❌|❌|

<!-- rules -->

Expand Down
9 changes: 8 additions & 1 deletion docs/README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@
|[MA0151](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0151.md)|Usage|DebuggerDisplay must contain valid members|<span title='Warning'>⚠️</span>|✔️|❌|
|[MA0152](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0152.md)|Performance|Use Unwrap instead of using await twice|<span title='Info'>ℹ️</span>|✔️|❌|
|[MA0153](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0153.md)|Design|Do not log symbols decorated with DataClassificationAttribute directly|<span title='Warning'>⚠️</span>|✔️|❌|
|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|<span title='Info'>ℹ️</span>|✔️|❌|
|[MA0154](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md)|Design|Use langword in XML comment|<span title='Info'>ℹ️</span>|✔️|✔️|
|[MA0155](https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0155.md)|Design|Do not use async void methods|<span title='Warning'>⚠️</span>|❌|❌|

|Id|Suppressed rule|Justification|
|--|---------------|-------------|
Expand Down Expand Up @@ -622,6 +623,9 @@ dotnet_diagnostic.MA0153.severity = warning

# MA0154: Use langword in XML comment
dotnet_diagnostic.MA0154.severity = suggestion

# MA0155: Do not use async void methods
dotnet_diagnostic.MA0155.severity = none
```

# .editorconfig - all rules disabled
Expand Down Expand Up @@ -1085,4 +1089,7 @@ dotnet_diagnostic.MA0153.severity = none

# MA0154: Use langword in XML comment
dotnet_diagnostic.MA0154.severity = none

# MA0155: Do not use async void methods
dotnet_diagnostic.MA0155.severity = none
```
15 changes: 15 additions & 0 deletions docs/Rules/MA0155.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# MA0155 - Do not use async void methods

```c#
// not-compliant
async void SomeMethod()
{
await Task.Delay(1000);
}

// ok
async Task SomeMethod()
{
await Task.Delay(1000);
}
```
38 changes: 38 additions & 0 deletions src/Meziantou.Analyzer/Rules/DoNotUseAsyncVoidAnalyzer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace Meziantou.Analyzer.Rules;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class DoNotUseAsyncVoidAnalyzer : DiagnosticAnalyzer
{
private static readonly DiagnosticDescriptor Rule = new(
RuleIdentifiers.DoNotUseAsyncVoid,
title: "Do not use async void methods",
messageFormat: "Do not use async void methods",
RuleCategories.Design,
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
description: "",
helpLinkUri: RuleIdentifiers.GetHelpUri(RuleIdentifiers.DoNotUseAsyncVoid));

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method);
}

private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var symbol = (IMethodSymbol)context.Symbol;
if (symbol is { ReturnsVoid: true, IsAsync: true })
{
context.ReportDiagnostic(Rule, symbol);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Threading.Tasks;
using Meziantou.Analyzer.Rules;
using TestHelper;
using Xunit;

namespace Meziantou.Analyzer.Test.Rules;
public sealed class DoNotUseAsyncVoidAnalyzerTests
{
private static ProjectBuilder CreateProjectBuilder()
{
return new ProjectBuilder()
.WithAnalyzer<DoNotUseAsyncVoidAnalyzer>()
.WithTargetFramework(TargetFramework.Net8_0);
}

[Fact]
public async Task Method_Void()
{
await CreateProjectBuilder()
.WithSourceCode("""
class Sample
{
void A() => throw null;
}
""")
.ValidateAsync();
}

[Fact]
public async Task Method_AsyncVoid()
{
await CreateProjectBuilder()
.WithSourceCode("""
class Sample
{
async void [|A|]() => throw null;
}
""")
.ValidateAsync();
}

[Fact]
public async Task Method_AsyncTask()
{
await CreateProjectBuilder()
.WithSourceCode("""
class Sample
{
async System.Threading.Tasks.Task A() => throw null;
}
""")
.ValidateAsync();
}

}