Skip to content

Commit fab92c3

Browse files
committed
Renumber LuceneDev6xxx rules to contiguous IDs
Replace the underscore-suffixed IDs (6001_1, 6001_2, 6002_1, 6002_2) with contiguous numeric IDs matching the rest of the Lucene.NET analyzer taxonomy: 6001_1 -> 6001 Missing StringComparison on String overload 6001_2 -> 6002 Invalid StringComparison on String overload 6002_1 -> 6003 Redundant Ordinal on span overload 6002_2 -> 6004 Invalid StringComparison on span overload 6003 -> 6005 Single-character string literal Each analyzer class still bundles the two related diagnostics that share symbol resolution; files are named with the ID range (e.g., LuceneDev6001_6002_StringComparisonAnalyzer.cs) and the LuceneDev6005 analyzer stands alone. Update Descriptors, Resources.resx, AnalyzerReleases.Unshipped.md, DiagnosticCategoryAndIdRanges.txt, samples, editorconfig overrides, and tests to reference the new IDs. Tighten the 6005 summary doc to note that spans only have char overloads for IndexOf/LastIndexOf.
1 parent 1c82f19 commit fab92c3

20 files changed

Lines changed: 204 additions & 206 deletions

DiagnosticCategoryAndIdRanges.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Globalization:
1818
Mobility:
1919
Performance:
2020
Security:
21-
Usage: LuceneDev6000-LuceneDev6003
21+
Usage: LuceneDev6000-LuceneDev6005
2222
Naming:
2323
Interoperability:
2424
Maintainability:

src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6001_StringComparisonCodeFixProvider.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6001_6002_StringComparisonCodeFixProvider.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
namespace Lucene.Net.CodeAnalysis.Dev.CodeFixes.LuceneDev6xxx
2020
{
21-
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6001_StringComparisonCodeFixProvider)), Shared]
22-
public sealed class LuceneDev6001_StringComparisonCodeFixProvider : CodeFixProvider
21+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6001_6002_StringComparisonCodeFixProvider)), Shared]
22+
public sealed class LuceneDev6001_6002_StringComparisonCodeFixProvider : CodeFixProvider
2323
{
2424
private const string Ordinal = "Ordinal";
2525
private const string OrdinalIgnoreCase = "OrdinalIgnoreCase";
@@ -29,7 +29,7 @@ public sealed class LuceneDev6001_StringComparisonCodeFixProvider : CodeFixProvi
2929
public override ImmutableArray<string> FixableDiagnosticIds =>
3030
ImmutableArray.Create(
3131
Descriptors.LuceneDev6001_MissingStringComparison.Id,
32-
Descriptors.LuceneDev6001_InvalidStringComparison.Id);
32+
Descriptors.LuceneDev6002_InvalidStringComparison.Id);
3333

3434
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
3535

@@ -54,7 +54,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
5454
var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
5555
if (semanticModel == null) continue;
5656

57-
// Skip char literals and single-character string literals when safe (covered by 6003 instead).
57+
// Skip char literals and single-character string literals when safe (LuceneDev6005 handles conversion).
5858
var firstArgExpr = invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression;
5959
if (firstArgExpr is LiteralExpressionSyntax lit)
6060
{
@@ -81,7 +81,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
8181
// Case 1: Argument is missing. Only offer Ordinal as the safe, conservative default.
8282
RegisterFix(context, invocation, Ordinal, TitleOrdinal, diagnostic);
8383
}
84-
else if (diagnostic.Id == Descriptors.LuceneDev6001_InvalidStringComparison.Id)
84+
else if (diagnostic.Id == Descriptors.LuceneDev6002_InvalidStringComparison.Id)
8585
{
8686
// Case 2: Invalid argument is present. Determine the best replacement.
8787
if (TryDetermineReplacement(invocation, semanticModel, out string? targetComparison))

src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6002_SpanComparisonCodeFixProvider.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6003_6004_SpanComparisonCodeFixProvider.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030

3131
namespace Lucene.Net.CodeAnalysis.Dev.CodeFixes.LuceneDev6xxx
3232
{
33-
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6002_SpanComparisonCodeFixProvider)), Shared]
34-
public sealed class LuceneDev6002_SpanComparisonCodeFixProvider : CodeFixProvider
33+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6003_6004_SpanComparisonCodeFixProvider)), Shared]
34+
public sealed class LuceneDev6003_6004_SpanComparisonCodeFixProvider : CodeFixProvider
3535
{
3636
private const string TitleRemoveOrdinal = "Remove redundant StringComparison.Ordinal";
3737
private const string TitleOptimizeToDefaultOrdinal = "Optimize to default Ordinal comparison (remove argument)";
@@ -47,8 +47,8 @@ public sealed class LuceneDev6002_SpanComparisonCodeFixProvider : CodeFixProvide
4747

4848
public override ImmutableArray<string> FixableDiagnosticIds =>
4949
ImmutableArray.Create(
50-
Descriptors.LuceneDev6002_RedundantOrdinal.Id,
51-
Descriptors.LuceneDev6002_InvalidComparison.Id);
50+
Descriptors.LuceneDev6003_RedundantOrdinal.Id,
51+
Descriptors.LuceneDev6004_InvalidComparison.Id);
5252

5353
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
5454

@@ -64,7 +64,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
6464
if (invocation == null)
6565
return;
6666

67-
// Skip char literals and single-character string literals when safe (covered by 6003 instead).
67+
// Skip char literals and single-character string literals when safe (LuceneDev6005 handles conversion).
6868
var firstArgExpr = invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression;
6969
if (firstArgExpr is LiteralExpressionSyntax lit)
7070
{
@@ -89,7 +89,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
8989
}
9090
switch (diagnostic.Id)
9191
{
92-
case var id when id == Descriptors.LuceneDev6002_RedundantOrdinal.Id:
92+
case var id when id == Descriptors.LuceneDev6003_RedundantOrdinal.Id:
9393
context.RegisterCodeFix(
9494
CodeAction.Create(
9595
title: TitleRemoveOrdinal,
@@ -98,7 +98,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
9898
diagnostic);
9999
break;
100100

101-
case var id when id == Descriptors.LuceneDev6002_InvalidComparison.Id:
101+
case var id when id == Descriptors.LuceneDev6004_InvalidComparison.Id:
102102
var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
103103
if (semanticModel == null)
104104
return;

src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6003_SingleCharStringCodeFixProvider.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.CodeFixes/LuceneDev6xxx/LuceneDev6005_SingleCharStringCodeFixProvider.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@
3131

3232
namespace Lucene.Net.CodeAnalysis.Dev.LuceneDev6xxx
3333
{
34-
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6003_SingleCharStringCodeFixProvider))]
34+
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(LuceneDev6005_SingleCharStringCodeFixProvider))]
3535
[Shared]
36-
public sealed class LuceneDev6003_SingleCharStringCodeFixProvider : CodeFixProvider
36+
public sealed class LuceneDev6005_SingleCharStringCodeFixProvider : CodeFixProvider
3737
{
3838
public override ImmutableArray<string> FixableDiagnosticIds
39-
=> ImmutableArray.Create(Descriptors.LuceneDev6003_SingleCharStringAnalyzer.Id);
39+
=> ImmutableArray.Create(Descriptors.LuceneDev6005_SingleCharString.Id);
4040

4141
public override FixAllProvider GetFixAllProvider()
4242
=> WellKnownFixAllProviders.BatchFixer;
@@ -60,7 +60,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
6060
CodeAction.Create(
6161
"Use char literal",
6262
c => ReplaceWithCharLiteralAsync(context.Document, literal, c),
63-
nameof(LuceneDev6003_SingleCharStringCodeFixProvider)),
63+
nameof(LuceneDev6005_SingleCharStringCodeFixProvider)),
6464
diagnostic);
6565
}
6666
}

src/Lucene.Net.CodeAnalysis.Dev.Sample/.editorconfig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
# so contributors can see the diagnostics live in their IDE. Downgrade Error-severity
33
# rules to Warning here so the project still compiles.
44
[*.cs]
5-
dotnet_diagnostic.LuceneDev6001_1.severity = warning
6-
dotnet_diagnostic.LuceneDev6001_2.severity = warning
7-
dotnet_diagnostic.LuceneDev6002_2.severity = warning
5+
dotnet_diagnostic.LuceneDev6001.severity = warning
6+
dotnet_diagnostic.LuceneDev6002.severity = warning
7+
dotnet_diagnostic.LuceneDev6004.severity = warning

src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6001_StringComparisonSample.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6001_6002_StringComparisonSample.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@
2121

2222
namespace Lucene.Net.CodeAnalysis.Dev.Sample;
2323

24-
public class LuceneDev6001_StringComparisonSample
24+
public class LuceneDev6001_6002_StringComparisonSample
2525
{
2626
public void MyMethod()
2727
{
2828
string text = "Hello World";
2929

30-
// Missing StringComparison argument: triggers LuceneDev6001_1 (Error).
30+
// Missing StringComparison argument: triggers LuceneDev6001 (Error).
3131
int index1 = text.IndexOf("Hello");
3232
bool starts1 = text.StartsWith("Hello");
3333
bool ends1 = text.EndsWith("World");
3434
int lastIndex1 = text.LastIndexOf("World");
3535

36-
// Invalid StringComparison value: triggers LuceneDev6001_2 (Error).
36+
// Invalid StringComparison value: triggers LuceneDev6002 (Error).
3737
int index2 = text.IndexOf("Hello", StringComparison.CurrentCulture);
3838
bool starts2 = text.StartsWith("hello", StringComparison.CurrentCultureIgnoreCase);
3939
bool ends2 = text.EndsWith("World", StringComparison.InvariantCulture);

src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6002_SpanComparisonSample.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6003_6004_SpanComparisonSample.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@
2121

2222
namespace Lucene.Net.CodeAnalysis.Dev.Sample.LuceneDev6xxx;
2323

24-
public class LuceneDev6002_SpanComparisonSample
24+
public class LuceneDev6003_6004_SpanComparisonSample
2525
{
2626
public void MyMethod()
2727
{
2828
ReadOnlySpan<char> span = "Hello World".AsSpan();
2929

30-
// Redundant StringComparison.Ordinal on span: triggers LuceneDev6002_1 (Warning).
30+
// Redundant StringComparison.Ordinal on span: triggers LuceneDev6003 (Warning).
3131
int index1 = span.IndexOf("Hello".AsSpan(), StringComparison.Ordinal);
3232
int lastIndex1 = span.LastIndexOf("World".AsSpan(), StringComparison.Ordinal);
3333
bool starts1 = span.StartsWith("Hello".AsSpan(), StringComparison.Ordinal);
3434
bool ends1 = span.EndsWith("World".AsSpan(), StringComparison.Ordinal);
3535

36-
// Invalid comparison on span: triggers LuceneDev6002_2 (Error).
36+
// Invalid comparison on span: triggers LuceneDev6004 (Error).
3737
int index2 = span.IndexOf("Hello".AsSpan(), StringComparison.CurrentCulture);
3838
int lastIndex2 = span.LastIndexOf("World".AsSpan(), StringComparison.CurrentCultureIgnoreCase);
3939
bool starts2 = span.StartsWith("Hello".AsSpan(), StringComparison.InvariantCulture);

src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6003_SingleCharStringSample.cs renamed to src/Lucene.Net.CodeAnalysis.Dev.Sample/LuceneDev6xxx/LuceneDev6005_SingleCharStringSample.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
namespace Lucene.Net.CodeAnalysis.Dev.Sample.LuceneDev6xxx;
2323

24-
public class LuceneDev6003_SingleCharStringSample
24+
public class LuceneDev6005_SingleCharStringSample
2525
{
2626
public void MyMethod()
2727
{

src/Lucene.Net.CodeAnalysis.Dev/AnalyzerReleases.Unshipped.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Rule ID | Category | Severity | Notes
55
LuceneDev1007 | Design | Warning | Generic Dictionary<TKey, TValue> indexer should not be used to retrieve values because it may throw KeyNotFoundException (value type value)
66
LuceneDev1008 | Design | Warning | Generic Dictionary<TKey, TValue> indexer should not be used to retrieve values because it may throw KeyNotFoundException (reference type value)
77
LuceneDev6000 | Usage | Info | IDictionary indexer may be used to retrieve values, but must be checked for null before using the value
8-
LuceneDev6001_1 | Usage | Error | Missing StringComparison argument in String overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; must use Ordinal/OrdinalIgnoreCase
9-
LuceneDev6001_2 | Usage | Error | Invalid StringComparison value in String overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; only Ordinal/OrdinalIgnoreCase allowed
10-
LuceneDev6002_1 | Usage | Warning | Redundant StringComparison.Ordinal argument in Span overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; should be removed
11-
LuceneDev6002_2 | Usage | Error | Invalid StringComparison value in Span overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; only Ordinal or OrdinalIgnoreCase allowed
12-
LuceneDev6003 | Usage | Info | Single-character string arguments should use the char overload of StartsWith/EndsWith/IndexOf/LastIndexOf instead of a string
8+
LuceneDev6001 | Usage | Error | Missing StringComparison argument in String overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; must use Ordinal/OrdinalIgnoreCase
9+
LuceneDev6002 | Usage | Error | Invalid StringComparison value in String overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; only Ordinal/OrdinalIgnoreCase allowed
10+
LuceneDev6003 | Usage | Warning | Redundant StringComparison.Ordinal argument in Span overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; should be removed
11+
LuceneDev6004 | Usage | Error | Invalid StringComparison value in Span overloads of StartsWith/EndsWith/IndexOf/LastIndexOf; only Ordinal or OrdinalIgnoreCase allowed
12+
LuceneDev6005 | Usage | Info | Single-character string arguments should use the char overload of StartsWith/EndsWith/IndexOf/LastIndexOf instead of a string

src/Lucene.Net.CodeAnalysis.Dev/LuceneDev6xxx/LuceneDev6001_StringComparisonAnalyzer.cs renamed to src/Lucene.Net.CodeAnalysis.Dev/LuceneDev6xxx/LuceneDev6001_6002_StringComparisonAnalyzer.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727
namespace Lucene.Net.CodeAnalysis.Dev.LuceneDev6xxx
2828
{
2929
[DiagnosticAnalyzer(LanguageNames.CSharp)]
30-
public sealed class LuceneDev6001_StringComparisonAnalyzer : DiagnosticAnalyzer
30+
public sealed class LuceneDev6001_6002_StringComparisonAnalyzer : DiagnosticAnalyzer
3131
{
3232
private static readonly ImmutableHashSet<string> TargetMethodNames =
3333
ImmutableHashSet.Create("StartsWith", "EndsWith", "IndexOf", "LastIndexOf");
3434

3535
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
3636
=> ImmutableArray.Create(
3737
Descriptors.LuceneDev6001_MissingStringComparison,
38-
Descriptors.LuceneDev6001_InvalidStringComparison);
38+
Descriptors.LuceneDev6002_InvalidStringComparison);
3939

4040
public override void Initialize(AnalysisContext context)
4141
{
@@ -82,10 +82,10 @@ private static void AnalyzeInvocation(SyntaxNodeAnalysisContext ctx)
8282

8383
if (!hasStringComparisonArgForLiteral)
8484
{
85-
// safe to convert to char (6003), so skip 6001 reporting
85+
// Safe to convert to char (LuceneDev6005 handles it); skip 6001/6002 here.
8686
return;
8787
}
88-
// else: has StringComparison -> do not skip; let 6001/6002 validate or codefix handle it
88+
// Has StringComparison -> do not skip; 6001/6002 validation continues.
8989
}
9090
}
9191

@@ -134,7 +134,7 @@ static bool HasStringComparisonParameter(IMethodSymbol? m, INamedTypeSymbol scTy
134134
if (!isValidValue)
135135
{
136136
var diag = Diagnostic.Create(
137-
Descriptors.LuceneDev6001_InvalidStringComparison,
137+
Descriptors.LuceneDev6002_InvalidStringComparison,
138138
invalidArgLocation ?? memberAccess.Name.GetLocation(),
139139
methodName,
140140
comparisonValueName ?? "non-ordinal comparison");
@@ -174,7 +174,7 @@ static bool HasStringComparisonParameter(IMethodSymbol? m, INamedTypeSymbol scTy
174174
if (!isValidValue)
175175
{
176176
var diag = Diagnostic.Create(
177-
Descriptors.LuceneDev6001_InvalidStringComparison,
177+
Descriptors.LuceneDev6002_InvalidStringComparison,
178178
invalidArgLocation ?? memberAccess.Name.GetLocation(),
179179
methodName,
180180
comparisonValueName ?? "non-ordinal comparison");

0 commit comments

Comments
 (0)