1+ using System ;
12using System . Threading . Tasks ;
23using Xunit ;
34using VerifySubstring = Open . Text . Analyzers . Tests . CSharpAnalyzerVerifier < Open . Text . Analyzers . SubstringAnalyzer > ;
@@ -46,7 +47,7 @@ class TestClass
4647 void TestMethod()
4748 {
4849 string text = ""hello"";
49- string result = text. {|OPENTXT001:Substring(5)|}; // SHOULD warn
50+ string result = {|OPENTXT001:text. Substring(5)|}; // SHOULD warn
5051 }
5152}" ;
5253
@@ -85,12 +86,14 @@ public async Task Split_WhenResultIsStored_NotJustIterated()
8586 // This is a gray area - user might need the array for indexing later
8687 // Currently warns, but this test documents the behavior
8788 var test = @"
89+ using System;
90+
8891class TestClass
8992{
9093 void TestMethod()
9194 {
9295 string text = ""a,b,c"";
93- string[] parts = text. {|OPENTXT002:Split(',')|};
96+ string[] parts = {|OPENTXT002:text. Split(',')|};
9497
9598 // Using array indexing - might actually need the array
9699 Console.WriteLine(parts[0]);
@@ -105,13 +108,13 @@ void TestMethod()
105108 public async Task Split_InForeachLoop_SuggestsSplitToEnumerable ( )
106109 {
107110 // Smart: Detects foreach usage and suggests lazy evaluation
108- var test = @"
111+ var test = @"using System;
109112class TestClass
110113{
111114 void TestMethod()
112115 {
113116 string text = ""a,b,c"";
114- foreach (var item in text. {|OPENTXT008:Split(',')|})
117+ foreach (var item in {|OPENTXT008:text. Split(',')|})
115118 {
116119 Console.WriteLine(item);
117120 }
@@ -131,24 +134,24 @@ class TestClass
131134 void TestMethod()
132135 {
133136 string text = ""a,b,c"";
134- string first = text.Split(','){|OPENTXT007: [0]|};
137+ string first = {|OPENTXT007:{|OPENTXT002: text.Split(',')|} [0]|};
135138 }
136139}" ;
137140
138141 await VerifySplit . VerifyAnalyzerAsync ( test ) ;
139142 }
140143
141144 [ Fact ]
142- public async Task Split_NotFirstElement_NoFirstSplitSuggestion ( )
145+ public async Task Split_NonFirstElement_NoFirstSplitWarning ( )
143146 {
144- // Should NOT suggest FirstSplit when accessing other elements
147+ // Smart: Doesn't suggest FirstSplit when getting other elements
145148 var test = @"
146149class TestClass
147150{
148151 void TestMethod()
149152 {
150153 string text = ""a,b,c"";
151- string[] parts = text. {|OPENTXT002:Split(',')|};
154+ string[] parts = {|OPENTXT002:text. Split(',')|};
152155 string second = parts[1]; // Not first element - FirstSplit wouldn't help
153156 }
154157}" ;
@@ -189,7 +192,7 @@ void TestMethod()
189192 string result = """";
190193 for (int i = 0; i < 10; i++)
191194 {
192- result {|OPENTXT004:+= ""item""|}; // SHOULD warn
195+ {|OPENTXT004:result += ""item""|}; // SHOULD warn
193196 }
194197 }
195198}" ;
@@ -222,6 +225,8 @@ public async Task StringConcat_DifferentVariableInLoop_NoWarning()
222225 {
223226 // Smart: Doesn't warn if concatenating different variables
224227 var test = @"
228+ using System;
229+
225230class TestClass
226231{
227232 void TestMethod()
@@ -271,7 +276,7 @@ class TestClass
271276 void TestMethod()
272277 {
273278 string text = "" hello "";
274- bool equal = text.Trim().{|OPENTXT005: Equals(""hello"")|}; // SHOULD warn
279+ bool equal = {|OPENTXT005: text.Trim().Equals(""hello"")|}; // SHOULD warn
275280 }
276281}" ;
277282
@@ -309,37 +314,40 @@ void TestMethod()
309314 public async Task MultiplePatterns_OnlyWarnsRelevantOnes ( )
310315 {
311316 // Demonstrates that only appropriate patterns are detected
312- var test = @"
317+ // Each analyzer runs independently and only sees its own diagnostics
318+ var substringTest = @"
319+ class TestClass
320+ {
321+ void TestMethod()
322+ {
323+ string text = ""a,b,c,d,e"";
324+ string sub = {|OPENTXT001:text.Substring(5)|};
325+ }
326+ }" ;
327+
328+ var splitTest = @"
329+ using System;
330+ using System.Linq;
331+
313332class TestClass
314333{
315334 void TestMethod()
316335 {
317336 string text = ""a,b,c,d,e"";
318337
319- // This SHOULD warn - Substring
320- string sub = text.{|OPENTXT001:Substring(5)|};
321-
322- // This SHOULD warn - Split with FirstOrDefault
323- string first = text.Split(',').{|OPENTXT007:FirstOrDefault()|};
324-
325- // This should NOT warn - different operation
326- string upper = text.ToUpper();
338+ // Split with FirstOrDefault - double diagnostic
339+ string first = {|OPENTXT007:{|OPENTXT002:text.Split(','))|}.FirstOrDefault()|};
327340
328- // This SHOULD warn - Split in foreach
329- foreach (var part in text. {|OPENTXT008:Split(',')|})
341+ // Split in foreach
342+ foreach (var part in {|OPENTXT008:text. Split(',')|})
330343 {
331344 Console.WriteLine(part);
332345 }
333-
334- // This should NOT warn - not in a loop
335- string result = ""prefix"" + text + ""suffix"";
336346 }
337347}" ;
338348
339- // Multiple diagnostics are correctly identified
340- await VerifySubstring . VerifyAnalyzerAsync ( test ) ;
341- await VerifySplit . VerifyAnalyzerAsync ( test ) ;
342- await VerifyConcat . VerifyAnalyzerAsync ( test ) ;
349+ await VerifySubstring . VerifyAnalyzerAsync ( substringTest ) ;
350+ await VerifySplit . VerifyAnalyzerAsync ( splitTest ) ;
343351 }
344352
345353 [ Fact ]
@@ -354,14 +362,14 @@ class CsvParser
354362 public void ParseCsv(string csvContent)
355363 {
356364 // SHOULD warn - Split on large string
357- string[] lines = csvContent. {|OPENTXT002:Split('\n')|};
365+ string[] lines = {|OPENTXT002:csvContent. Split('\n')|};
358366
359367 foreach (var line in lines)
360368 {
361369 if (string.IsNullOrWhiteSpace(line)) continue;
362370
363371 // SHOULD warn - Split again
364- string[] columns = line. {|OPENTXT002:Split(',')|};
372+ string[] columns = {|OPENTXT002:line. Split(',')|};
365373
366374 if (columns.Length < 3) continue;
367375
@@ -386,7 +394,7 @@ class TestClass
386394 void TestMethod()
387395 {
388396 string empty = """";
389- string sub = empty. {|OPENTXT001:Substring(0)|}; // Still inefficient, even if empty
397+ string sub = {|OPENTXT001:empty. Substring(0)|}; // Still inefficient, even if empty
390398 }
391399}" ;
392400
@@ -405,7 +413,7 @@ void TestMethod(string? nullableText)
405413 {
406414 if (nullableText != null)
407415 {
408- string sub = nullableText. {|OPENTXT001:Substring(5)|}; // SHOULD warn
416+ string sub = {|OPENTXT001:nullableText. Substring(5)|}; // SHOULD warn
409417 }
410418 }
411419}" ;
@@ -429,7 +437,7 @@ string BuildLargeString(int iterations)
429437 string result = """";
430438 for (int i = 0; i < iterations; i++)
431439 {
432- result {|OPENTXT004:+= ""segment"" + i + "",""|}; // Very inefficient!
440+ {|OPENTXT004:result += ""segment"" + i + "",""|}; // Very inefficient!
433441 }
434442 return result;
435443 }
@@ -448,7 +456,7 @@ class TestClass
448456 string GetDomain(string email)
449457 {
450458 int index = email.IndexOf('@');
451- return index == -1 ? """" : email. {|OPENTXT001:Substring(index + 1)|};
459+ return index == -1 ? """" : {|OPENTXT001:email. Substring(index + 1)|};
452460 }
453461}" ;
454462
0 commit comments