-
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
- Loading branch information
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,74 +9,73 @@ | |
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace FluentAssertions.Analyzers | ||
namespace FluentAssertions.Analyzers; | ||
|
||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
public class AsyncVoidAnalyzer : DiagnosticAnalyzer | ||
{ | ||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
public class AsyncVoidAnalyzer : DiagnosticAnalyzer | ||
{ | ||
public const string DiagnosticId = Constants.CodeSmell.AsyncVoid; | ||
public const string Title = "Code Smell"; | ||
public const string Message = "The assertions might not be executed when assigning an async void lambda to a Action"; | ||
public const string DiagnosticId = Constants.CodeSmell.AsyncVoid; | ||
public const string Title = "Code Smell"; | ||
public const string Message = "The assertions might not be executed when assigning an async void lambda to a Action"; | ||
|
||
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, Message, Constants.CodeSmell.Category, DiagnosticSeverity.Warning, true); | ||
public static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, Message, Constants.CodeSmell.Category, DiagnosticSeverity.Warning, true); | ||
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (ubuntu-latest, Debug)
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (ubuntu-latest, Release)
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (windows-latest, Debug)
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (windows-latest, Release)
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (macos-latest, Debug)
Check warning on line 21 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (macos-latest, Release)
|
||
|
||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule); | ||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule); | ||
|
||
public sealed override void Initialize(AnalysisContext context) | ||
{ | ||
context.EnableConcurrentExecution(); | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.RegisterCodeBlockAction(AnalyzeCodeBlock); | ||
} | ||
public sealed override void Initialize(AnalysisContext context) | ||
{ | ||
context.EnableConcurrentExecution(); | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.RegisterCodeBlockAction(AnalyzeCodeBlock); | ||
} | ||
|
||
private void AnalyzeCodeBlock(CodeBlockAnalysisContext context) | ||
{ | ||
var method = context.CodeBlock as MethodDeclarationSyntax; | ||
if (method == null) return; | ||
private void AnalyzeCodeBlock(CodeBlockAnalysisContext context) | ||
{ | ||
var method = context.CodeBlock as MethodDeclarationSyntax; | ||
if (method == null) return; | ||
|
||
if (method.Body != null) | ||
if (method.Body != null) | ||
{ | ||
foreach (var statement in method.Body.Statements.OfType<LocalDeclarationStatementSyntax>()) | ||
{ | ||
foreach (var statement in method.Body.Statements.OfType<LocalDeclarationStatementSyntax>()) | ||
{ | ||
|
||
var diagnostic = AnalyzeStatement(context.SemanticModel, statement); | ||
if (diagnostic != null) | ||
{ | ||
context.ReportDiagnostic(diagnostic); | ||
} | ||
var diagnostic = AnalyzeStatement(context.SemanticModel, statement); | ||
if (diagnostic != null) | ||
{ | ||
context.ReportDiagnostic(diagnostic); | ||
} | ||
return; | ||
} | ||
return; | ||
} | ||
} | ||
|
||
protected virtual Diagnostic AnalyzeStatement(SemanticModel semanticModel, LocalDeclarationStatementSyntax statement) | ||
{ | ||
var symbolInfo = semanticModel.GetSymbolInfo(statement.Declaration.Type); | ||
if (symbolInfo.Symbol?.Name != nameof(Action)) return null; | ||
protected virtual Diagnostic AnalyzeStatement(SemanticModel semanticModel, LocalDeclarationStatementSyntax statement) | ||
{ | ||
var symbolInfo = semanticModel.GetSymbolInfo(statement.Declaration.Type); | ||
if (symbolInfo.Symbol?.Name != nameof(Action)) return null; | ||
|
||
foreach (var variable in statement.Declaration.Variables) | ||
{ | ||
if (variable.Initializer == null) continue; | ||
foreach (var variable in statement.Declaration.Variables) | ||
{ | ||
if (variable.Initializer == null) continue; | ||
|
||
if (!(variable.Initializer.Value is ParenthesizedLambdaExpressionSyntax lambda)) continue; | ||
if (!(variable.Initializer.Value is ParenthesizedLambdaExpressionSyntax lambda)) continue; | ||
|
||
if (lambda.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword)) | ||
{ | ||
return Diagnostic.Create(descriptor: Rule, location: statement.GetLocation()); | ||
} | ||
if (lambda.AsyncKeyword.IsKind(SyntaxKind.AsyncKeyword)) | ||
{ | ||
return Diagnostic.Create(descriptor: Rule, location: statement.GetLocation()); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AsyncVoidCodeFix)), Shared] | ||
public class AsyncVoidCodeFix : CodeFixProvider | ||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AsyncVoidCodeFix)), Shared] | ||
public class AsyncVoidCodeFix : CodeFixProvider | ||
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (ubuntu-latest, Debug)
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (ubuntu-latest, Release)
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (windows-latest, Debug)
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (windows-latest, Release)
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (macos-latest, Debug)
Check warning on line 74 in src/FluentAssertions.Analyzers/Tips/AsyncVoid.cs GitHub Actions / build (macos-latest, Release)
|
||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(AsyncVoidAnalyzer.DiagnosticId); | ||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(AsyncVoidAnalyzer.DiagnosticId); | ||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
return Task.CompletedTask; | ||
} | ||
return Task.CompletedTask; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,20 @@ | ||
using FluentAssertions.Analyzers.Utilities; | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace FluentAssertions.Analyzers | ||
namespace FluentAssertions.Analyzers; | ||
|
||
public abstract class CollectionAnalyzer : FluentAssertionsAnalyzer | ||
{ | ||
public abstract class CollectionAnalyzer : FluentAssertionsAnalyzer | ||
protected override bool ShouldAnalyzeVariableNamedType(INamedTypeSymbol type, SemanticModel semanticModel) | ||
{ | ||
protected override bool ShouldAnalyzeVariableNamedType(INamedTypeSymbol type, SemanticModel semanticModel) | ||
{ | ||
return type.SpecialType != SpecialType.System_String | ||
&& type.IsTypeOrConstructedFromTypeOrImplementsType(SpecialType.System_Collections_Generic_IEnumerable_T); | ||
} | ||
|
||
override protected bool ShouldAnalyzeVariableType(ITypeSymbol type, SemanticModel semanticModel) | ||
{ | ||
return type.SpecialType != SpecialType.System_String | ||
&& type.IsTypeOrConstructedFromTypeOrImplementsType(SpecialType.System_Collections_Generic_IEnumerable_T); | ||
} | ||
return type.SpecialType != SpecialType.System_String | ||
&& type.IsTypeOrConstructedFromTypeOrImplementsType(SpecialType.System_Collections_Generic_IEnumerable_T); | ||
} | ||
|
||
override protected bool ShouldAnalyzeVariableType(ITypeSymbol type, SemanticModel semanticModel) | ||
{ | ||
return type.SpecialType != SpecialType.System_String | ||
&& type.IsTypeOrConstructedFromTypeOrImplementsType(SpecialType.System_Collections_Generic_IEnumerable_T); | ||
} | ||
|
||
} |