Skip to content

Conversation

@NehanPathan
Copy link
Contributor

Related Issue: [Lucene.NET #1211](apache/lucenenet#1211)


Summary:
This PR adds the analyzers and codefixes for the following LuceneDev rules:

  • LuceneDev6001 – String overloads of StartsWith/EndsWith/IndexOf/LastIndexOf must specify StringComparison.

    • Split into:

      • LuceneDev6001_1: Missing StringComparison → Error
      • LuceneDev6001_2: Invalid StringComparison → Warning
  • LuceneDev6002 – Span overloads of StartsWith/EndsWith/IndexOf/LastIndexOf should not specify StringComparison.Ordinal and only allow Ordinal or OrdinalIgnoreCase.

    • Split into:

      • LuceneDev6002_1: Redundant Ordinal → Warning
      • LuceneDev6002_2: Invalid comparison → Error
  • LuceneDev6003 – Single-character string arguments should use the char overload instead of a string → Info

Changes included:

  • Added analyzers and codefix providers for 6001, 6002, and 6003.
  • Updated and added unit tests to cover good/bad cases.
  • Sample files updated to include both correct and incorrect usage patterns.
  • Adjusted diagnostic IDs to _1 and _2 for clarity and control.

Copy link
Contributor

@NightOwl888 NightOwl888 left a comment

Choose a reason for hiding this comment

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

This isn't a full review, but I noticed a number of things that should be fixed.

Inconsistent StringComparison Behavior

image

Both of these IndexOf() calls are identical, being called using StringComparison.CurrentCulture. However, we are getting an error only in the first case and in the latter case we are getting a warning. We should always get an error when choosing anything other than StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase because this is a Java to .NET translation bug.

Invalid error on Char overload

image

The char overload is always StringComparison.Ordinal and it is better optimized than using a string. There is no IndexOf(char, StringComparison) overload, but the code fix is prompting to change the code to call one.

Prompt to change case comparison

image

It doesn't make much sense to prompt the user to change from case sensitive to case insensitive or vice versa. The code fix should be smart enough to suggest the same case comparison that is already selected. For example, if the value is StringComparison.CurrentCulture there should be a prompt to change to StringComparison.Ordinal. If the value is StringComparison.CurrentCultureIgnoreCase the prompt should be for StringComparison.OrdinalIgnoreCase.

Similarly, if there is no StringComparison passed to a string, we should not assume that StringComparison.OrdinalIgnoreCase was the intention.

No prompt to optimize single-character string to char on ReadOnlySpan

On string, we get a CA1866 diagnostic to change from "H" to 'H' (string to char) for performance reasons.

image

However, on ReadOnlySpan<char> we are not getting a prompt even though the char overload exists for IndexOf() and LastIndexOf(). So, this is a gap that the Microsoft analyzers don't cover that we should.

NOTE: I was wrong about the Microsoft analyzers not detecting escaped single-char strings. We should copy their implementation and modify it to work with spans. We can rely on CA1865-CA1867 for strings, but as I mentioned before, we should elevate the importance to warning in the Lucene.NET codebase.

image

Note that StartsWith() and EndsWith() do not have a char overload on spans even though they exist on string. So, it is not sensible to have analyzers suggest to switch to char in these cases.

image

Lucene.Net.CodeAnalysis.Dev.Sample is not set up to show diagnostics

It looks like you have some code that is commented out that is supposed to fire the diagnostics, but the idea here is that we have them shown by default (I think - @paulirwin correct me if I am wrong). It is more or less a demo showing the diagnostics in IDEs that are not Visual Studio (in VS we have the VSIX project that launches the test instance of Visual Studio with the analyzers loaded).

Also, it isn't clear what is going on with the sample for LuceneDev6003, as it has none of the target methods (IndexOf, LastIndexOf, StartsWtih, or EndsWith) in it.

</PropertyGroup>

<ItemGroup Label="NuGet Package Reference Versions">
<PackageVersion Include="J2N" Version="2.1.0" />
Copy link
Contributor

Choose a reason for hiding this comment

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

J2N apparently isn't being used. Please remove it.

// instance through a field.

// 6001: Missing StringComparison argument
public static readonly DiagnosticDescriptor LuceneDev6001_MissingStringComparison =
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add a title, description, and message (which can be formatted with arguments) for each of these diagnostic IDs. This is the information that the user will see.

https://github.com/NehanPathan/lucenenet-codeanalysis-dev/blob/feature/lucene-dev600x-analyzers/src/Lucene.Net.CodeAnalysis.Dev/Resources.resx#L221

We put them in resource files so we can localize the strings later if we ever get around to it.

@NehanPathan
Copy link
Contributor Author

@NightOwl888
mostly fixed the issues and also improve after undertsanding edge cases

also the test that previously failed and comment out for discussion is resolved
And
regarding sample files i guess other analyzer sample file also contain only minimal and good example that's why in our also
->put only good examples and comment out the badexample code for reference

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.

2 participants