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

Prefer readonlyspan properties to array fields #5548

Open
wants to merge 25 commits into
base: main
Choose a base branch
from

Conversation

NewellClark
Copy link
Contributor

@NewellClark NewellClark commented Sep 29, 2021

Fix dotnet/runtime#33780.
I've found and fixed all violations in dotnet/runtime (already merged) and dotnet/roslyn (PR).

I've gone ahead and implemented a fixer, however because of this issue the fixer will not show up in visual studio. The testing framework is still able to run the fixer, however, so I was able to test it.

Edit: I've implemented it as a SymbolStart/SymbolEnd analyzer as requested, so it will work normally.

@NewellClark NewellClark requested a review from a team as a code owner September 29, 2021 16:44
Copy link
Contributor

@buyaa-n buyaa-n left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @NewellClark, left some suggestions/questions overall looks it is quite close to get merged.

src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md Outdated Show resolved Hide resolved
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis.Text;
using Resx = Microsoft.NetCore.Analyzers.MicrosoftNetCoreAnalyzersResources;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: normally we do a static import

};
return test.RunAsync();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall test coverage looks great, only suggestions: please add a test with a comment

// reference to the array field) and then remove the first argument from the argument list.
if (invocationSyntax.ArgumentList.Arguments.Count == invocation.Arguments.Length)
{
var newArgumentList = invocationSyntax.ArgumentList.WithArguments(invocationSyntax.ArgumentList.Arguments.RemoveAt(0));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the arguments doesn't match the parameters order?

@mavasani
Copy link
Contributor

I've gone ahead and implemented a fixer, however because of this issue the fixer will not show up in visual studio.

@NewellClark I believe this analyzer should be written to only operate on private fields and should be written as a SymbolStart/SymbolEnd analyzer, not CompilationEnd analyzer. Once you make that change, the code fix will start working in the IDE and be available to users.

var field = (IFieldSymbol)context.Symbol;
if (field.IsStatic && field.IsReadOnly && field.Type is IArrayTypeSymbol arrayType && cache.IsSupportedArrayElementType(arrayType.ElementType))
{
cache.AddCandidate(field);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only private fields should be candidates.

Copy link
Contributor

@mavasani mavasani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be written as a SymbolStart/SymbolEnd analyzer.

@mavasani
Copy link
Contributor

Ping @NewellClark - are you able to do the rewrite as a SymbolStart/End analyzer?

@stephentoub
Copy link
Member

@NewellClark, are you still working on this, or should it be closed?

@buyaa-n
Copy link
Contributor

buyaa-n commented May 8, 2023

@NewellClark are you still planning to work on this?

@NewellClark
Copy link
Contributor Author

The school year just ended for me, so I will be working on this ASAP. Sorry for the delay.

@NewellClark
Copy link
Contributor Author

@mavasani I will convert the analyzer to use a symbol start/end analyzer.

@NewellClark NewellClark force-pushed the prefer-readonlyspan-properties-to-array-fields branch from 7818fd2 to 5ad4dd9 Compare May 12, 2023 18:17
@NewellClark
Copy link
Contributor Author

I've modified the analyzer to use SymbolStart/SymbolEnd as requested.

I'd like to take a moment to apologize for taking so long to get this done. When I became swamped with school work this past year, I should have indicated that I wouldn't be able to work on it so somebody else could have picked it up. For that, I apologize, and I will make sure it doesn't happen going forward.

I am interested in contributing to this repository in the future, and I will ensure to finish assignments I pick up quickly.

@stephentoub
Copy link
Member

No need to apologize! We appreciate your efforts. And school absolutely takes priority.

@NewellClark
Copy link
Contributor Author

NewellClark commented May 31, 2023

Oh dear, looks like I forgot to do something. I remember there was some command I'm supposed to run on the command line before submitting, and I can't remember what it is and I'm unable to find it. All I remember is that when I forget to run it, all the CI tests fail.

Edit: I found it. I forgot to run MSBUILD.

After this goes through, I'm submitting an issue to add the msbuild /t:pack /v:m instruction to a salient place in contributor documentation, because it took me over an hour to find these instructions (I had to create a dummy branch and pull request to get them to show up in the pull-request comment box).
@codecov
Copy link

codecov bot commented Jun 1, 2023

Codecov Report

Merging #5548 (1af039e) into main (2b6ab8d) will increase coverage by 0.00%.
The diff coverage is 96.51%.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #5548    +/-   ##
========================================
  Coverage   96.40%   96.40%            
========================================
  Files        1379     1383     +4     
  Lines      322253   322971   +718     
  Branches    10460    10494    +34     
========================================
+ Hits       310657   311356   +699     
- Misses       9103     9112     +9     
- Partials     2493     2503    +10     

@buyaa-n buyaa-n requested a review from mavasani June 28, 2023 20:41
@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 29, 2023

@NewellClark found a false positive while testing in runtime repo, I believe it should no flag below case:

public class Tests
{
    private static readonly byte[] s_protocolMismatch13 = new byte[] { (byte)TlsContentType.Alert, 3, 4, 0, 2, 2, 70 };
    private static readonly byte[] s_protocolMismatch12 = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, 70 };
	
    private static byte[] CreateProtocolVersionAlert(SslProtocols version) =>
        version switch
        {
            SslProtocols.Tls13 => s_protocolMismatch13,
            SslProtocols.Tls12 => s_protocolMismatch12,
            _ => Array.Empty<byte>(),
        };
}

Comment on lines 51 to 56
private void OnSymbolStart(SymbolStartAnalysisContext context)
{
// Bail if we're missing required symbols.
if (!RequiredSymbols.TryGetRequiredSymbols(context.Compilation, out RequiredSymbols? symbols))
return;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part should go to the CompilationStartAction as it will not be different for each Symbol.

Suggested change
private void OnSymbolStart(SymbolStartAnalysisContext context)
{
// Bail if we're missing required symbols.
if (!RequiredSymbols.TryGetRequiredSymbols(context.Compilation, out RequiredSymbols? symbols))
return;
private void OnSymbolStart(SymbolStartAnalysisContext context, RequiredSymbols symbols)
{

i.e public override void Initialize(AnalysisContext context) would look like this:

        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
            context.EnableConcurrentExecution();
            context.RegisterCompilationStartAction(context =>
            {
                //  Bail if we're missing required symbols.
                if (!RequiredSymbols.TryGetRequiredSymbols(context.Compilation, out RequiredSymbols? symbols))
                    return;

                context.RegisterSymbolStartAction(context => OnSymbolStart(context, symbols), SymbolKind.NamedType);
            });
        }

@alrz
Copy link
Member

alrz commented Mar 6, 2024

Was about to file an issue for this. Is there anything that is blocking this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Prefer static ReadOnlySpan<byte> properties over static readonly byte[] fields
7 participants