| File: CallAnalysis\Throws.cs | Web Access |
| Project: src\src\Analyzers\Microsoft.Analyzers.Local\Microsoft.Analyzers.Local.csproj (Microsoft.Analyzers.Local) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.Extensions.LocalAnalyzers.CallAnalysis; /// <summary> /// Recommends using Throw helpers. /// </summary> internal sealed class Throws { private static readonly string[] _useThrowsExceptionTypes = new[] { "System.ArgumentException", "System.ArgumentNullException", "System.ArgumentOutOfRangeException", }; public Throws(CallAnalyzer.Registrar reg) { reg.RegisterExceptionTypes(_useThrowsExceptionTypes, Handle); static void Handle(OperationAnalysisContext context, IThrowOperation op) { var convOp = (IConversionOperation?)op.Exception; var creationOp = (IObjectCreationOperation?)convOp?.Operand; if (creationOp?.Type != null) { if (op.Syntax.IsKind(SyntaxKind.ThrowStatement)) { var diagnostic = Diagnostic.Create( DiagDescriptors.ThrowsStatement, op.Syntax.GetLocation(), $"Microsoft.Shared.Diagnostics.Throws.{creationOp.Type.Name}"); context.ReportDiagnostic(diagnostic); } else if (op.Syntax.IsKind(SyntaxKind.ThrowExpression)) { if (creationOp.Type.Name == "ArgumentNullException") { var throwExpression = (ThrowExpressionSyntax)op.Syntax; if (throwExpression.Parent is BinaryExpressionSyntax binaryExpression) { var diagnostic = Diagnostic.Create( DiagDescriptors.ThrowsExpression, binaryExpression.GetLocation(), "Microsoft.Shared.Diagnostics.Throws.IfNull"); context.ReportDiagnostic(diagnostic); } } } } } } }