Skip to content

Commit eba683f

Browse files
Merge pull request #82 from marinasundstrom/feature/precise-source-locations
Report more precise source locations #78
2 parents a5c44c7 + 09ef602 commit eba683f

File tree

9 files changed

+68
-25
lines changed

9 files changed

+68
-25
lines changed

CheckedExceptions.Tests/AnazylerConfigTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void TestMethod2()
4343
""";
4444

4545
var expected = Verifier.Informational("IOException")
46-
.WithSpan(7, 9, 7, 35);
46+
.WithSpan(7, 17, 7, 35);
4747

4848
await Verifier.VerifyAnalyzerAsync2(test, expected);
4949
}
@@ -71,7 +71,7 @@ public void TestMethod2()
7171
""";
7272

7373
var expected2 = Verifier.Informational("IOException")
74-
.WithSpan(9, 13, 9, 39);
74+
.WithSpan(9, 21, 9, 39);
7575

7676
await Verifier.VerifyAnalyzerAsync2(test, expected2);
7777
}

CheckedExceptions.Tests/AwaitTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public async Task Run()
9090
""";
9191

9292
var expected = Verifier.MightBeThrown("InvalidOperationException")
93-
.WithSpan(14, 15, 14, 35);
93+
.WithSpan(14, 20, 14, 35);
9494

9595
await Verifier.VerifyAnalyzerAsync(test, expected);
9696
}

CheckedExceptions.Tests/BugFixes/Bugfix19_CatchBlockSilencesExceptionInCatchClauses.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ public void Foo()
3535
""";
3636

3737
var expected1 = Verifier.MightBeThrown("IOException")
38-
.WithSpan(10, 13, 10, 33); // Position of Console.Write("Foo");
38+
.WithSpan(10, 21, 10, 33); // Position of Console.Write("Foo");
3939

4040
var expected2 = Verifier.MightBeThrown("IOException")
41-
.WithSpan(14, 13, 14, 41); // Position of Console.WriteLine(e.Message);
41+
.WithSpan(14, 21, 14, 41); // Position of Console.WriteLine(e.Message);
4242

4343
await Verifier.VerifyAnalyzerAsync(test, [expected1, expected2]);
4444
}
@@ -72,7 +72,7 @@ public void Foo()
7272
""";
7373

7474
var expected = Verifier.MightBeThrown("IOException")
75-
.WithSpan(15, 13, 15, 41); // Position of Console.WriteLine(e.Message);
75+
.WithSpan(15, 21, 15, 41); // Position of Console.WriteLine(e.Message);
7676

7777
await Verifier.VerifyAnalyzerAsync(test, [expected]);
7878
}

CheckedExceptions.Tests/DictionaryTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void TestMethod2()
2929
""";
3030

3131
var expected = Verifier.MightBeThrown("ArgumentException")
32-
.WithSpan(10, 9, 10, 28);
32+
.WithSpan(10, 14, 10, 28);
3333

3434
await Verifier.VerifyAnalyzerAsync(test, expected);
3535
}

CheckedExceptions.Tests/ExtensionMethods.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public void MethodThatThrows()
2727
""";
2828

2929
var expected1 = Verifier.MightBeThrown("ArgumentNullException")
30-
.WithSpan(11, 17, 11, 30);
30+
.WithSpan(11, 23, 11, 30);
3131

3232
var expected2 = Verifier.MightBeThrown("InvalidOperationException")
33-
.WithSpan(11, 17, 11, 30);
33+
.WithSpan(11, 23, 11, 30);
3434

3535
await Verifier.VerifyAnalyzerAsync(test, expected1, expected2);
3636
}
@@ -57,7 +57,7 @@ public void MethodThatThrows()
5757
""";
5858

5959
var expected = Verifier.MightBeThrown("InvalidOperationException")
60-
.WithSpan(12, 17, 12, 30);
60+
.WithSpan(12, 23, 12, 30);
6161

6262
await Verifier.VerifyAnalyzerAsync(test, expected);
6363
}
@@ -84,7 +84,7 @@ public void MethodThatThrows()
8484
""";
8585

8686
var expected = Verifier.MightBeThrown("InvalidOperationException")
87-
.WithSpan(12, 17, 12, 30);
87+
.WithSpan(12, 23, 12, 30);
8888

8989
await Verifier.VerifyAnalyzerAsync(test, expected);
9090
}
@@ -111,7 +111,7 @@ public void MethodThatThrows()
111111
""";
112112

113113
var expected = Verifier.MightBeThrown("InvalidOperationException")
114-
.WithSpan(12, 17, 12, 30);
114+
.WithSpan(12, 23, 12, 30);
115115

116116
await Verifier.VerifyAnalyzerAsync(test, expected);
117117
}

CheckedExceptions.Tests/MemberAccessAndIdentifierNameTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Foo()
3131
""";
3232

3333
var expected = Verifier.MightBeThrown("ArgumentNullException")
34-
.WithSpan(15, 9, 15, 19);
34+
.WithSpan(15, 14, 15, 19);
3535

3636
await Verifier.VerifyAnalyzerAsync(test, expected);
3737
}
@@ -89,7 +89,7 @@ public void Foo()
8989
""";
9090

9191
var expected = Verifier.MightBeThrown("ArgumentNullException")
92-
.WithSpan(15, 9, 15, 19);
92+
.WithSpan(15, 14, 15, 19);
9393

9494
await Verifier.VerifyAnalyzerAsync(test, [expected]);
9595
}

CheckedExceptions.Tests/XmlDocTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ public void TestMethod1()
5757
""";
5858

5959
var expected1 = Verifier.MightBeThrown("ArgumentNullException")
60-
.WithSpan(7, 9, 7, 24);
60+
.WithSpan(7, 13, 7, 24);
6161

6262
var expected2 = Verifier.MightBeThrown("FormatException")
63-
.WithSpan(7, 9, 7, 24);
63+
.WithSpan(7, 13, 7, 24);
6464

6565
var expected3 = Verifier.MightBeThrown("OverflowException")
66-
.WithSpan(7, 9, 7, 24);
66+
.WithSpan(7, 13, 7, 24);
6767

6868
await Verifier.VerifyAnalyzerAsync(test, expected1, expected2, expected3);
6969
}
@@ -87,10 +87,10 @@ public void TestMethod1()
8787
""";
8888

8989
var expected2 = Verifier.MightBeThrown("FormatException")
90-
.WithSpan(8, 9, 8, 24);
90+
.WithSpan(8, 13, 8, 24);
9191

9292
var expected3 = Verifier.MightBeThrown("OverflowException")
93-
.WithSpan(8, 9, 8, 24);
93+
.WithSpan(8, 13, 8, 24);
9494

9595
await Verifier.VerifyAnalyzerAsync(test, [expected2, expected3]);
9696
}
@@ -139,7 +139,7 @@ public void TestMethod1()
139139
""";
140140

141141
var expected = Verifier.MightBeThrown("ArgumentOutOfRangeException")
142-
.WithSpan(11, 9, 11, 29);
142+
.WithSpan(11, 23, 11, 29);
143143

144144
await Verifier.VerifyAnalyzerAsync(test, [expected]);
145145
}

CheckedExceptions/CheckedExceptionsAnalyzer.Shared.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.CSharp.Syntax;
3+
using Microsoft.CodeAnalysis.Text;
34

45
namespace Sundstrom.CheckedExceptions;
56

@@ -123,4 +124,46 @@ private IEnumerable<INamedTypeSymbol> GetExceptionTypes(AttributeSyntax attribut
123124
{
124125
return node.Ancestors().OfType<CatchClauseSyntax>().FirstOrDefault();
125126
}
127+
128+
private static Location GetSignificantLocation(SyntaxNode expression)
129+
{
130+
if (expression is InvocationExpressionSyntax)
131+
return GetSignificantInvocationLocation(expression);
132+
133+
var node = GetSignificantNodeCore(expression);
134+
return node.GetLocation();
135+
}
136+
137+
private static SyntaxNode GetSignificantNodeCore(SyntaxNode expression)
138+
{
139+
if (expression is InvocationExpressionSyntax ie)
140+
{
141+
return GetSignificantNodeCore(ie.Expression);
142+
}
143+
144+
if (expression is MemberAccessExpressionSyntax mae)
145+
{
146+
return mae.Name;
147+
}
148+
149+
return expression;
150+
}
151+
152+
private static Location GetSignificantInvocationLocation(SyntaxNode expression)
153+
{
154+
if (expression is InvocationExpressionSyntax invocation)
155+
{
156+
// Get the name part (e.g., bar in foo.bar(s))
157+
var nameNode = GetSignificantNodeCore(invocation.Expression);
158+
159+
// Compute the span from name start to the full invocation end
160+
var start = nameNode.SpanStart;
161+
var end = invocation.Span.End;
162+
163+
var span = TextSpan.FromBounds(start, end);
164+
return Location.Create(invocation.SyntaxTree, span);
165+
}
166+
167+
return expression.GetLocation();
168+
}
126169
}

CheckedExceptions/CheckedExceptionsAnalyzer.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ private void AnalyzeExceptionsInTryBlock(SyntaxNodeAnalysisContext context, TryS
351351
if (ShouldIgnore(throwStatement, mode))
352352
{
353353
// Report as THROW002 (Info level)
354-
var diagnostic = Diagnostic.Create(RuleIgnoredException, throwStatement.GetLocation(), exceptionType.Name);
354+
var diagnostic = Diagnostic.Create(RuleIgnoredException, GetSignificantLocation(throwStatement), exceptionType.Name);
355355
context.ReportDiagnostic(diagnostic);
356356
continue;
357357
}
@@ -368,7 +368,7 @@ private void AnalyzeExceptionsInTryBlock(SyntaxNodeAnalysisContext context, TryS
368368
// Report diagnostic for unhandled exception
369369
var diagnostic = Diagnostic.Create(
370370
RuleUnhandledException,
371-
throwStatement.GetLocation(),
371+
GetSignificantLocation(throwStatement),
372372
exceptionType.Name,
373373
THROW001Verbs.MightBe);
374374

@@ -1195,7 +1195,7 @@ private void AnalyzeExceptionThrowingNode(
11951195
if (ShouldIgnore(node, mode))
11961196
{
11971197
// Report as THROW002 (Info level)
1198-
var diagnostic = Diagnostic.Create(RuleIgnoredException, node.GetLocation(), exceptionType.Name);
1198+
var diagnostic = Diagnostic.Create(RuleIgnoredException, GetSignificantLocation(node), exceptionType.Name);
11991199
context.ReportDiagnostic(diagnostic);
12001200
return;
12011201
}
@@ -1204,7 +1204,7 @@ private void AnalyzeExceptionThrowingNode(
12041204
// Check for general exceptions
12051205
if (IsGeneralException(exceptionType))
12061206
{
1207-
context.ReportDiagnostic(Diagnostic.Create(RuleGeneralThrow, node.GetLocation()));
1207+
context.ReportDiagnostic(Diagnostic.Create(RuleGeneralThrow, GetSignificantLocation(node)));
12081208
}
12091209

12101210
// Check if the exception is declared via [Throws]
@@ -1223,7 +1223,7 @@ private void AnalyzeExceptionThrowingNode(
12231223

12241224
var verb = isThrowingConstruct ? THROW001Verbs.Is : THROW001Verbs.MightBe;
12251225

1226-
var diagnostic = Diagnostic.Create(RuleUnhandledException, node.GetLocation(), properties, exceptionType.Name, verb);
1226+
var diagnostic = Diagnostic.Create(RuleUnhandledException, GetSignificantLocation(node), properties, exceptionType.Name, verb);
12271227
context.ReportDiagnostic(diagnostic);
12281228
}
12291229
}

0 commit comments

Comments
 (0)