-
Notifications
You must be signed in to change notification settings - Fork 470
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
Implement Use 'StartsWith' instead of 'IndexOf' analyzer #6295
Conversation
...osoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.Fixer.cs
Outdated
Show resolved
Hide resolved
...osoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.Fixer.cs
Outdated
Show resolved
Hide resolved
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #6295 +/- ##
========================================
Coverage 96.08% 96.09%
========================================
Files 1357 1362 +5
Lines 315287 316086 +799
Branches 10184 10209 +25
========================================
+ Hits 302951 303740 +789
- Misses 9904 9909 +5
- Partials 2432 2437 +5 |
@Youssef1313 thanks a lot for submitting the PR. You may expect a slow response from me as I am currently off. May others get a chance to comment too. |
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
...osoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.Fixer.cs
Outdated
Show resolved
Hide resolved
...rosoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZeroTests.cs
Show resolved
Hide resolved
|
||
namespace Microsoft.NetCore.Analyzers.Performance.UnitTests | ||
{ | ||
public class UseStartsWithInsteadOfIndexOfComparisonWithZeroTests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tarekgh What about IndexOf(char, StringComparison)
? There is no char overload in StartsWith
that accepts StringComparison. Should we not report? Or use StartsWith(string, StringComparison)
? Or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good question. If it will not be complicated to implement, we can use StartsWith(ReadOnlySpan, ReadOnlySpan, StringComparison). In general, I see the IndexOf
overloads that takes string is higher priority as these used in main scenario. We can support the char
overloads later if we need to.
CC @stephentoub if has input here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stephentoub What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Youssef1313 how complex would it be if implement IndexOf(char, StringComparison)
as I suggested above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found dotnet/roslyn#61432, but it doesn't seem like the comment there applies in the test project in this repo (I don't see we reference Newtonsoft.Json in test project - maybe another dependency does and we get it as a transitive dependency?).
@sharwell Can you help please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tarekgh One more question is IndexOf(Char)
. There is StartsWith(Char)
, but it is newer and might not be available (e.g, in .NET Standard 2.0 IndexOf(Char)
exists but StartsWith(Char)
doesn't). In this case (only if StartsWith(Char)
doesn't exist) should we replace IndexOf('a')
with StartsWith('a'.ToString())
/StartsWith("a")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the whole point of this analyzer is the performance.
for s.IndexOf(c) == 0
you can convert it to
s.length > 0 && s[0] == c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense.
I started looking into IndexOf(char, StringComparison)
and there is one thing.
we can use StartsWith(ReadOnlySpan, ReadOnlySpan, StringComparison)
Here, we need to change the char
to a ReadOnlySpan<char>
The ReadOnlySpan<T>(T)
ctor is only available in .NET 7, the other way is to use stackalloc char[1] { ch }
. Is that okay? What about VB? I'm also not sure about ReadOnlySpan
(ref struct
s in general) support in VB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to use stackalloc char[1] { ch }. Is that okay?
Yes, this should be Ok. You just convert the IndexOf call too string.AsSpan().StartsWith(stackalloc char[1] { chr }, stringComparison);
What about VB? I'm also not sure about ReadOnlySpan (ref structs in general) support in VB.
Considering it is rare to find the pattern IndexOf(char, StringComparison) == 0
in VB. I think for this case we either exclude this rule from there or we can go with the fixer that allocates the string from the character. I mean use StartsWith(char.ToString(), StringComparison)
.
@tarekgh I handled For VB, if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Youssef1313 thanks a lot for getting this ready.
@buyaa-n could you please have a look? The changes LGTM. You may merge it after reviewing too. Thanks!
@Youssef1313 could you please fix the merge conflicts? @jeffhandley is there anyone who can look and merge this one? The changes look good to me. |
src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
Outdated
Show resolved
Hide resolved
...osoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.Fixer.cs
Outdated
Show resolved
Hide resolved
...osoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.Fixer.cs
Show resolved
Hide resolved
"""; | ||
|
||
await VerifyCodeFixVBAsync(testCode, fixedCode, ReferenceAssemblies.NetStandard.NetStandard20); | ||
await VerifyCodeFixVBAsync(testCode, fixedCode, ReferenceAssemblies.NetStandard.NetStandard21); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add tests for the cases that should not be flagged?
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left few comments, overall LGTM, thank you!
@buyaa-n Thanks for the review! I addressed your feedback. Can you take another look? Thanks! |
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
...e/Microsoft.NetCore.Analyzers/Performance/UseStartsWithInsteadOfIndexOfComparisonWithZero.cs
Outdated
Show resolved
Hide resolved
Looks great, thank you! |
Thanks @buyaa-n for the quick review! I opened the docs PR: dotnet/docs#33114 |
Fixes dotnet/runtime#78608
cc @stephentoub @tarekgh @mavasani