| File: Microsoft.NetCore.Analyzers\Performance\CSharpConstantExpectedAnalyzer.cs | Web Access |
| Project: src\sdk\src\Microsoft.CodeAnalysis.NetAnalyzers\src\Microsoft.CodeAnalysis.CSharp.NetAnalyzers\Microsoft.CodeAnalysis.CSharp.NetAnalyzers.csproj (Microsoft.CodeAnalysis.CSharp.NetAnalyzers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.NetCore.Analyzers.Performance; namespace Microsoft.NetCore.CSharp.Analyzers.Performance { [DiagnosticAnalyzer(LanguageNames.CSharp)] public sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer { private static readonly CSharpDiagnosticHelper s_diagnosticHelper = new(); private static readonly IdentifierNameSyntax s_constantExpectedIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpected); private static readonly IdentifierNameSyntax s_constantExpectedAttributeIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedAttribute); protected override DiagnosticHelper Helper => s_diagnosticHelper; protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext context, ConstantExpectedContext constantExpectedContext) { context.RegisterSyntaxNodeAction(context => OnAttributeNode(context, constantExpectedContext), SyntaxKind.Attribute); } private void OnAttributeNode(SyntaxNodeAnalysisContext context, ConstantExpectedContext constantExpectedContext) { var attributeSyntax = (AttributeSyntax)context.Node; var attributeName = attributeSyntax.Name; if (!attributeName.IsEquivalentTo(s_constantExpectedIdentifier) && !attributeName.IsEquivalentTo(s_constantExpectedAttributeIdentifier)) { return; } if (attributeSyntax.Parent?.Parent is ParameterSyntax parameter) { var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter)!; OnParameterWithConstantExpectedAttribute(parameterSymbol, constantExpectedContext, context.ReportDiagnostic); } } private sealed class CSharpDiagnosticHelper : DiagnosticHelper { private readonly IdentifierNameSyntax _constantExpectedMinIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedMin); private readonly IdentifierNameSyntax _constantExpectedMaxIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedMax); public override Location? GetMaxLocation(SyntaxNode attributeSyntax) => GetArgumentLocation(attributeSyntax, _constantExpectedMaxIdentifier); public override Location? GetMinLocation(SyntaxNode attributeSyntax) => GetArgumentLocation(attributeSyntax, _constantExpectedMinIdentifier); private static Location? GetArgumentLocation(SyntaxNode attributeNode, IdentifierNameSyntax targetNameSyntax) { var attributeSyntax = (AttributeSyntax)attributeNode; if (attributeSyntax.ArgumentList is null) { return null; } var targetArg = attributeSyntax.ArgumentList.Arguments.FirstOrDefault(arg => arg.NameEquals?.Name.IsEquivalentTo(targetNameSyntax, true) == true); return targetArg?.GetLocation(); } } } } ;