Skip to content

Commit 09d2e08

Browse files
committed
Adding support for catch clause variables
1 parent 559efdf commit 09d2e08

5 files changed

Lines changed: 72 additions & 1 deletion

File tree

src/EditorFeatures/CSharpTest/Diagnostics/NamingStyles/NamingStylesTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,39 @@ void M()
298298
options: options.LocalNamesAreCamelCase);
299299
}
300300

301+
[Fact, Trait(Traits.Feature, Traits.Features.NamingStyle)]
302+
public async Task TestCamelCaseLocals_CatchVariable()
303+
{
304+
await TestInRegularAndScriptAsync(
305+
@"using System;
306+
class C
307+
{
308+
void M()
309+
{
310+
try
311+
{
312+
}
313+
catch (Exception [|Exception|])
314+
{
315+
}
316+
}
317+
}",
318+
@"using System;
319+
class C
320+
{
321+
void M()
322+
{
323+
try
324+
{
325+
}
326+
catch (Exception exception)
327+
{
328+
}
329+
}
330+
}",
331+
options: options.LocalNamesAreCamelCase);
332+
}
333+
301334
[Fact, Trait(Traits.Feature, Traits.Features.NamingStyle)]
302335
public async Task TestCamelCaseLocals_Deconstruction1()
303336
{

src/EditorFeatures/VisualBasicTest/Diagnostics/NamingStyles/NamingStylesTests.vb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,28 @@ end module",
246246
options:=options.LocalNamesAreCamelCase)
247247
End Function
248248

249+
<Fact, Trait(Traits.Feature, Traits.Features.NamingStyle)>
250+
Public Async Function TestCamelCaseLocals_CatchVariable() As Task
251+
Await TestInRegularAndScriptAsync(
252+
"imports System
253+
module C
254+
sub M()
255+
try
256+
catch [|Exception|] as Exception
257+
end try
258+
end sub
259+
end module",
260+
"imports System
261+
module C
262+
sub M()
263+
try
264+
catch exception as Exception
265+
end try
266+
end sub
267+
end module",
268+
options:=options.LocalNamesAreCamelCase)
269+
End Function
270+
249271
<Fact(Skip:="Implicit declarations cannot be found by syntax. Requires https://github.com/dotnet/roslyn/issues/14061")>
250272
<Trait(Traits.Feature, Traits.Features.NamingStyle)>
251273
Public Async Function TestCamelCaseLocals_ImplicitlyDeclaredLocal() As Task

src/Features/CSharp/Portable/Diagnostics/Analyzers/CSharpNamingStyleDiagnosticAnalyzer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ internal sealed class CSharpNamingStyleDiagnosticAnalyzer : NamingStyleDiagnosti
1313
ImmutableArray.Create(
1414
SyntaxKind.VariableDeclarator,
1515
SyntaxKind.ForEachStatement,
16+
SyntaxKind.CatchDeclaration,
1617
SyntaxKind.SingleVariableDesignation);
1718
}
1819
}

src/Features/Core/Portable/CodeFixes/NamingStyle/AbstractNamingStyleCodeFixProvider.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
using Microsoft.CodeAnalysis.CodeActions;
1212
using Microsoft.CodeAnalysis.CodeActions.WorkspaceServices;
1313
using Microsoft.CodeAnalysis.Diagnostics;
14+
using Microsoft.CodeAnalysis.LanguageServices;
1415
using Microsoft.CodeAnalysis.NamingStyles;
1516
using Microsoft.CodeAnalysis.Rename;
17+
using Microsoft.CodeAnalysis.Shared.Extensions;
1618
using Roslyn.Utilities;
1719

1820
namespace Microsoft.CodeAnalysis.CodeFixes.NamingStyles
@@ -37,6 +39,17 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
3739

3840
var root = await document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
3941
var node = root.FindNode(span);
42+
43+
if (document.GetLanguageService<ISyntaxFactsService>().IsIdentifierName(node))
44+
{
45+
// The location we get from the analyzer only contains the identifier token and when we get its containing node,
46+
// it is usually the right one (such as a variable declarator, designation or a foreach statement)
47+
// because there is no other node in between. But there is one case in a VB catch clause where the token
48+
// is wrapped in an identifier name. So if what we found is an identifier, take the parent node instead.
49+
// Note that this is the correct thing to do because GetDeclaredSymbol never works on identifier names.
50+
node = node.Parent;
51+
}
52+
4053
var model = await document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
4154
var symbol = model.GetDeclaredSymbol(node, context.CancellationToken);
4255

src/Features/VisualBasic/Portable/Diagnostics/Analyzers/VisualBasicNamingStyleDiagnosticAnalyzer.vb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Diagnostics.Analyzers
1010
Inherits NamingStyleDiagnosticAnalyzerBase(Of SyntaxKind)
1111

1212
Protected Overrides ReadOnly Property SupportedSyntaxKinds As ImmutableArray(Of SyntaxKind) =
13-
ImmutableArray.Create(SyntaxKind.ModifiedIdentifier)
13+
ImmutableArray.Create(
14+
SyntaxKind.ModifiedIdentifier,
15+
SyntaxKind.CatchStatement)
1416
End Class
1517
End Namespace

0 commit comments

Comments
 (0)