Skip to content

Commit 3ba0ece

Browse files
Merge pull request #79 from marinasundstrom/feature/implicit-object-creation
Handle implicit object creation expressions #76
2 parents ce679c2 + f2ba304 commit 3ba0ece

File tree

4 files changed

+97
-0
lines changed

4 files changed

+97
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.Testing;
3+
4+
namespace Sundstrom.CheckedExceptions.Tests;
5+
6+
using Verifier = CSharpAnalyzerVerifier<CheckedExceptionsAnalyzer, DefaultVerifier>;
7+
8+
partial class CheckedExceptionsAnalyzerTests
9+
{
10+
[Fact]
11+
public async Task ThrowingConstructor_WithThrowsAttribute_ShouldReportDiagnostics_WhenCallerDoesNotHandleOrDeclare()
12+
{
13+
var test = /* lang=c#-test */ """
14+
using System;
15+
16+
public class ThrowingObject
17+
{
18+
[Throws(typeof(InvalidOperationException))]
19+
public ThrowingObject()
20+
{
21+
throw new InvalidOperationException();
22+
}
23+
}
24+
25+
public class TestClass
26+
{
27+
public void ExplicitNew()
28+
{
29+
ThrowingObject obj = new ThrowingObject(); // ❗ Expect diagnostic
30+
}
31+
32+
public void TargetTypedNew()
33+
{
34+
ThrowingObject obj = new(); // ❗ Expect diagnostic
35+
}
36+
}
37+
""";
38+
39+
var expected1 = Verifier.MightBeThrown("InvalidOperationException")
40+
.WithSpan(16, 30, 16, 50); // new ThrowingObject()
41+
42+
var expected2 = Verifier.MightBeThrown("InvalidOperationException")
43+
.WithSpan(21, 30, 21, 35); // new()
44+
45+
await Verifier.VerifyAnalyzerAsync(test, expected1, expected2);
46+
}
47+
}

CheckedExceptions/CheckedExceptionsAnalyzer.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public override void Initialize(AnalysisContext context)
113113
// Register additional actions for method calls, object creations, etc.
114114
context.RegisterSyntaxNodeAction(AnalyzeMethodCall, SyntaxKind.InvocationExpression);
115115
context.RegisterSyntaxNodeAction(AnalyzeObjectCreation, SyntaxKind.ObjectCreationExpression);
116+
context.RegisterSyntaxNodeAction(AnalyzeImplicitObjectCreation, SyntaxKind.ImplicitObjectCreationExpression);
116117
context.RegisterSyntaxNodeAction(AnalyzeIdentifier, SyntaxKind.IdentifierName);
117118
context.RegisterSyntaxNodeAction(AnalyzeMemberAccess, SyntaxKind.SimpleMemberAccessExpression);
118119
context.RegisterSyntaxNodeAction(AnalyzeAwait, SyntaxKind.AwaitExpression);
@@ -810,6 +811,23 @@ private void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context)
810811
AnalyzeMemberExceptions(context, objectCreation, constructorSymbol, settings);
811812
}
812813

814+
815+
/// <summary>
816+
/// Analyzes implicit object creation expressions to determine if exceptions are handled or declared.
817+
/// </summary>
818+
private void AnalyzeImplicitObjectCreation(SyntaxNodeAnalysisContext context)
819+
{
820+
var settings = GetAnalyzerSettings(context.Options);
821+
822+
var objectCreation = (ImplicitObjectCreationExpressionSyntax)context.Node;
823+
824+
var constructorSymbol = context.SemanticModel.GetSymbolInfo(objectCreation).Symbol as IMethodSymbol;
825+
if (constructorSymbol is null)
826+
return;
827+
828+
AnalyzeMemberExceptions(context, objectCreation, constructorSymbol, settings);
829+
}
830+
813831
/// <summary>
814832
/// Analyzes member access expressions (e.g., property accessors) for exception handling.
815833
/// </summary>

Test/Cases/Constructors/Constructors.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,21 @@ public void ProcessData2()
4848
Console.WriteLine("Handled exception: " + ex.Message);
4949
}
5050
}
51+
52+
public void ProcessData3()
53+
{
54+
DataFetcher3 fetcher = new();
55+
}
56+
57+
public void ProcessData4()
58+
{
59+
try
60+
{
61+
DataFetcher3 fetcher = new();
62+
}
63+
catch (Exception ex)
64+
{
65+
Console.WriteLine("Handled exception: " + ex.Message);
66+
}
67+
}
5168
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Test.Cases.Constructors;
2+
3+
public class ImplicitObjectCreationTest
4+
{
5+
[Throws(typeof(InvalidOperationException))]
6+
public ImplicitObjectCreationTest()
7+
{
8+
throw new InvalidOperationException("Constructor exception.");
9+
}
10+
11+
public static void Test()
12+
{
13+
ImplicitObjectCreationTest foo = new();
14+
}
15+
}

0 commit comments

Comments
 (0)