Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S6934 FP: Route attributes derived from IRouteTemplateProvider #9316

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ public sealed class SpecifyRouteAttribute() : SonarDiagnosticAnalyzer<SyntaxKind
{
private const string DiagnosticId = "S6934";

private static readonly ImmutableArray<KnownType> RouteTemplateAttributes = ImmutableArray.Create(
KnownType.Microsoft_AspNetCore_Mvc_Routing_HttpMethodAttribute,
KnownType.Microsoft_AspNetCore_Mvc_RouteAttribute);

protected override string MessageFormat => "Specify the RouteAttribute when an HttpMethodAttribute or RouteAttribute is specified at an action level.";
protected override ILanguageFacade<SyntaxKind> Language => CSharpFacade.Instance;

Expand All @@ -43,7 +39,7 @@ protected override void Initialize(SonarAnalysisContext context) =>
}
compilationStart.RegisterSymbolStartAction(symbolStart =>
{
if (symbolStart.Symbol.GetAttributesWithInherited().Any(x => x.AttributeClass.Is(KnownType.Microsoft_AspNetCore_Mvc_RouteAttribute)))
if (symbolStart.Symbol.GetAttributesWithInherited().Any(x => x.AttributeClass.DerivesOrImplements(KnownType.Microsoft_AspNetCore_Mvc_Routing_IRouteTemplateProvider)))
{
return;
}
Expand All @@ -54,7 +50,7 @@ protected override void Initialize(SonarAnalysisContext context) =>
if (nodeContext.SemanticModel.GetDeclaredSymbol(methodDeclaration, nodeContext.Cancel) is { } method
&& !method.ContainingType.IsAbstract
&& method.IsControllerActionMethod()
&& method.GetAttributesWithInherited().Any(x => !CanBeIgnored(x.GetAttributeRouteTemplate(RouteTemplateAttributes))))
&& method.GetAttributesWithInherited().Any(x => !CanBeIgnored(x.GetAttributeRouteTemplate())))
{
secondaryLocations.Push(methodDeclaration.Identifier.GetLocation());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public static bool HasName(this AttributeData attribute, string name) =>
public static bool HasAnyName(this AttributeData attribute, params string[] names) =>
names.Any(x => attribute.HasName(x));

public static string GetAttributeRouteTemplate(this AttributeData attribute, ImmutableArray<KnownType> attributeTypes) =>
attribute.AttributeClass.DerivesFromAny(attributeTypes)
public static string GetAttributeRouteTemplate(this AttributeData attribute) =>
attribute.AttributeClass.DerivesOrImplementsAny(AspNetMvcHelper.RouteTemplateProviders)
&& attribute.TryGetAttributeValue<string>("template", out var template)
? template
: null;
Expand Down
7 changes: 3 additions & 4 deletions analyzers/src/SonarAnalyzer.Common/Helpers/AspNetMvcHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,10 @@ namespace SonarAnalyzer.Helpers
{
public static class AspNetMvcHelper
{
public static readonly ImmutableArray<KnownType> RouteTemplateAttributes =
public static readonly ImmutableArray<KnownType> RouteTemplateProviders =
ImmutableArray.Create(
KnownType.Microsoft_AspNetCore_Mvc_Routing_HttpMethodAttribute,
KnownType.Microsoft_AspNetCore_Mvc_RouteAttribute,
KnownType.System_Web_Mvc_RouteAttribute);
KnownType.Microsoft_AspNetCore_Mvc_Routing_IRouteTemplateProvider,
KnownType.System_Web_Mvc_Routing_IRouteInfoProvider);

private static readonly ImmutableArray<KnownType> ControllerTypes =
ImmutableArray.Create(
Expand Down
2 changes: 2 additions & 0 deletions analyzers/src/SonarAnalyzer.Common/Helpers/KnownType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public sealed partial class KnownType
public static readonly KnownType Microsoft_AspNetCore_Mvc_RequestSizeLimitAttribute = new("Microsoft.AspNetCore.Mvc.RequestSizeLimitAttribute");
public static readonly KnownType Microsoft_AspNetCore_Mvc_RouteAttribute = new("Microsoft.AspNetCore.Mvc.RouteAttribute");
public static readonly KnownType Microsoft_AspNetCore_Mvc_Routing_HttpMethodAttribute = new("Microsoft.AspNetCore.Mvc.Routing.HttpMethodAttribute");
public static readonly KnownType Microsoft_AspNetCore_Mvc_Routing_IRouteTemplateProvider = new("Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider");
public static readonly KnownType Microsoft_AspNetCore_Razor_Hosting_RazorCompiledItemAttribute = new("Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute");
public static readonly KnownType Microsoft_Azure_Cosmos_CosmosClient = new("Microsoft.Azure.Cosmos.CosmosClient");
public static readonly KnownType Microsoft_Azure_Documents_Client_DocumentClient = new("Microsoft.Azure.Documents.Client.DocumentClient");
Expand Down Expand Up @@ -588,6 +589,7 @@ public sealed partial class KnownType
public static readonly KnownType System_Web_Mvc_HttpPostAttribute = new("System.Web.Mvc.HttpPostAttribute");
public static readonly KnownType System_Web_Mvc_NonActionAttribute = new("System.Web.Mvc.NonActionAttribute");
public static readonly KnownType System_Web_Mvc_RouteAttribute = new("System.Web.Mvc.RouteAttribute");
public static readonly KnownType System_Web_Mvc_Routing_IRouteInfoProvider = new("System.Web.Mvc.Routing.IRouteInfoProvider");
public static readonly KnownType System_Web_Mvc_RoutePrefixAttribute = new("System.Web.Mvc.RoutePrefixAttribute");
public static readonly KnownType System_Web_Mvc_ValidateInputAttribute = new("System.Web.Mvc.ValidateInputAttribute");
public static readonly KnownType System_Web_Script_Serialization_JavaScriptSerializer = new("System.Web.Script.Serialization.JavaScriptSerializer");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ private static Dictionary<Location, string> RouteAttributeTemplateArguments(Immu
var templates = new Dictionary<Location, string>();
foreach (var attribute in attributes)
{
if (attribute.GetAttributeRouteTemplate(AspNetMvcHelper.RouteTemplateAttributes) is { } templateParameter)
if (attribute.GetAttributeRouteTemplate() is { } templateParameter)
{
templates.Add(attribute.ApplicationSyntaxReference.GetSyntax().GetLocation(), templateParameter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@ public class ControllerOverridesActionWithRoute : BaseControllerWithActionWithRo
public sealed class ExtendedRouteAttribute() : RouteAttribute("[controller]/[action]");

[ExtendedRoute]
public class SomeController : ControllerBase // Noncompliant, FP the route attribute template is set in the base class of ExtendedRouteAttribute
public class SomeController : ControllerBase // Compliant - the route attribute template is set in the base class of ExtendedRouteAttribute
{
[HttpGet("foo")]
public string Foo() => "Hi"; // Secondary
public string Foo() => "Hi";
}

// https://github.com/SonarSource/sonar-dotnet/issues/9252
Expand Down
Loading