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

New constant expected analyzer #5766

Merged
merged 32 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1f4234a
Add ConstantExpectedAnalyzer
wzchua Feb 25, 2022
f39fc60
Fix floating point string culture issue
wzchua Feb 25, 2022
74d9533
Update tests
wzchua Feb 25, 2022
d13a77e
Fix typos
wzchua Feb 25, 2022
8b3d43e
Rework test cases
wzchua Feb 25, 2022
d4fe364
run pack command
wzchua Feb 25, 2022
5f8922f
Reorganize and combine some rules.
wzchua Feb 25, 2022
7b883e0
Apply suggestions from code review
wzchua Feb 25, 2022
f784732
Merge branch 'main' into new-analyzer/constant-expected
wzchua May 28, 2022
d12e2fb
Apply suggestion from feedback
wzchua May 29, 2022
9d4c1a3
Merge branch 'main' into new-analyzer/constant-expected
wzchua Jul 16, 2022
db80589
Apply suggestions from code review
wzchua Jul 16, 2022
68e6e28
Apply suggestions from code review
wzchua Jul 16, 2022
52f5e3f
rebuild
wzchua Jul 16, 2022
f991607
Use const variable for Min Max literal
wzchua Jul 16, 2022
eab469f
Drop nint nuint support from ConstantExpected
wzchua Jul 16, 2022
5e1b4c3
Add early exit if symbol for attribute is not found
wzchua Jul 16, 2022
e7ac792
Add check for enums
wzchua Jul 23, 2022
1196110
Merge branch 'main' into new-analyzer/constant-expected
wzchua Aug 27, 2022
65de245
Fix RS1032
wzchua Aug 27, 2022
04ad5b1
Fix IDE0200: Lambda expression can be removed
wzchua Aug 27, 2022
011d9eb
Rework attribute symbol matching
wzchua Aug 27, 2022
ec3f1ae
Update diagnostic Ids
wzchua Aug 27, 2022
59fdd58
Update test to use ReferenceAssemblies.Net70
wzchua Aug 27, 2022
865974c
Add performance tests
wzchua Aug 27, 2022
c87ee13
Apply suggestions from code review
buyaa-n Sep 13, 2022
5f07e36
Update localized messages
buyaa-n Sep 13, 2022
7c8b93b
Merge branch 'main' into new-analyzer/constant-expected
wzchua Nov 12, 2022
266fba8
Run pack
wzchua Nov 12, 2022
86dbee4
Merge branch 'main' into new-analyzer/constant-expected
buyaa-n Nov 16, 2022
774008b
Apply suggestions from code review
buyaa-n Nov 16, 2022
ca89072
Fix generated file
buyaa-n Nov 16, 2022
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
@@ -0,0 +1,64 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

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);
}
wzchua marked this conversation as resolved.
Show resolved Hide resolved

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 attributeNode) => GetArgumentLocation(attributeNode, _constantExpectedMaxIdentifier);

public override Location? GetMinLocation(SyntaxNode attributeNode) => GetArgumentLocation(attributeNode, _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));
return targetArg?.GetLocation();
}
}
}
}
;
7 changes: 7 additions & 0 deletions src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
; Please do not edit this file manually, it should only be updated through code fix application.

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
CA1856 | Performance | Error | ConstantExpectedAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1856)
CA1857 | Performance | Warning | ConstantExpectedAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857)
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,42 @@
<data name="UsesPreviewTypeParameterMessage" xml:space="preserve">
<value>'{0}' uses the preview type '{1}' and needs to opt into preview features. See {2} for more information.</value>
</data>
<data name="ConstantExpectedApplicationTitle" xml:space="preserve">
<value>Incorrect usage of ConstantExpected attribute</value>
</data>
<data name="ConstantExpectedApplicationDescription" xml:space="preserve">
<value>ConstantExpected attribute is not applied correctly on the parameter.</value>
</data>
<data name="ConstantExpectedUsageTitle" xml:space="preserve">
<value>A constant is expected for the parameter</value>
</data>
<data name="ConstantExpectedUsageDescription" xml:space="preserve">
<value>The parameter expects a constant for optimal performance.</value>
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
</data>
<data name="ConstantExpectedNotSupportedMessage" xml:space="preserve">
<value>The '{0}' type is not supported for ConstantExpected attribute</value>
</data>
<data name="ConstantExpectedIncompatibleConstantTypeMessage" xml:space="preserve">
<value>The '{0}' value is not compatible with parameter type of '{1}'</value>
</data>
<data name="ConstantExpectedInvalidBoundsMessage" xml:space="preserve">
<value>The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'</value>
</data>
<data name="ConstantExpectedInvertedRangeMessage" xml:space="preserve">
<value>The Min and Max values are inverted</value>
</data>
<data name="ConstantExpectedOutOfBoundsMessage" xml:space="preserve">
<value>The constant does not fit within the value bounds of '{0}' to '{1}'</value>
</data>
<data name="ConstantExpectedInvalidMessage" xml:space="preserve">
<value>The constant is not of the same '{0}' type as the parameter</value>
wzchua marked this conversation as resolved.
Show resolved Hide resolved
</data>
<data name="ConstantExpectedNotConstantMessage" xml:space="preserve">
<value>The argument should be a constant for optimal performance</value>
</data>
<data name="ConstantExpectedAttributExpectedMessage" xml:space="preserve">
<value>The ConstantExpected attribute is required for the parameter due to the parent method annotation</value>
</data>
<data name="SpecifyCultureForToLowerAndToUpperTitle" xml:space="preserve">
<value>Specify a culture or use an invariant version</value>
</data>
Expand Down
Loading