Skip to content

Commit 7ab99e1

Browse files
authored
Merge pull request #225 from WiseTechGlobal/MNJ/WI00764889/WTG1001_Exclude_NonVoid_Partial_Method
Cover WTG1001 on edge cases
2 parents 3091f12 + 273aa78 commit 7ab99e1

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<diagnostics severity="Hidden">
33
<languageVersion>9.0</languageVersion>
4+
<suppressId>CS8799</suppressId>
45
<diagnostic id="WTG1001" message="Our convention is to omit the 'private' modifier where it is already the default.">
5-
<location>Test0.cs: (15,3-10)</location>
6+
<location>Test0.cs: (9,3-10)</location>
7+
</diagnostic>
8+
<diagnostic id="WTG1001" message="Our convention is to omit the 'private' modifier where it is already the default.">
9+
<location>Test0.cs: (19,3-10)</location>
10+
</diagnostic>
11+
<diagnostic id="WTG1001" message="Our convention is to omit the 'private' modifier where it is already the default.">
12+
<location>Test0.cs: (25,3-10)</location>
613
</diagnostic>
714
<diagnostic id="WTG1006" message="Our convention is to omit the 'internal' modifier on types where it is already the default." >
8-
<location>Test0.cs: (20,2-10)</location>
15+
<location>Test0.cs: (30,2-10)</location>
916
</diagnostic>
1017
</diagnostics>

src/WTG.Analyzers.Test/TestData/VisibilityAnalyzer/Partial/Result.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ namespace ns
33
partial class Foo
44
{
55
private partial int Bar();
6+
public partial void FooBar();
7+
private partial int FooBarBaz(out int value);
8+
9+
partial void Qux();
10+
private partial void Quux(out int value);
611
}
712

813
partial class Foo
914
{
1015
private partial int Bar() { return default; }
16+
public partial void FooBar() { }
17+
private partial int FooBarBaz(out int value) => throw null;
18+
19+
partial void Qux() { }
20+
private partial void Quux(out int value) { value = default; }
1121
}
1222

1323
class Outer

src/WTG.Analyzers.Test/TestData/VisibilityAnalyzer/Partial/Source.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@ namespace ns
33
partial class Foo
44
{
55
private partial int Bar();
6+
public partial void FooBar();
7+
private partial int FooBarBaz(out int value);
8+
9+
private partial void Qux();
10+
private partial void Quux(out int value);
611
}
712

813
partial class Foo
914
{
1015
private partial int Bar() { return default; }
16+
public partial void FooBar() { }
17+
private partial int FooBarBaz(out int value) => throw null;
18+
19+
private partial void Qux() { }
20+
private partial void Quux(out int value) { value = default; }
1121
}
1222

1323
class Outer

src/WTG.Analyzers/Analyzers/Visibility/VisibilityAnalyzer.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Collections.Immutable;
2+
using System.Linq;
23
using Microsoft.CodeAnalysis;
34
using Microsoft.CodeAnalysis.CSharp;
5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
46
using Microsoft.CodeAnalysis.Diagnostics;
57
using WTG.Analyzers.Utils;
68

@@ -32,7 +34,8 @@ static void Analyze(SyntaxNodeAnalysisContext context, FileDetailCache cache)
3234
return;
3335
}
3436

35-
var list = ModifierExtractionVisitor.Instance.Visit(context.Node);
37+
var currentNode = context.Node;
38+
var list = ModifierExtractionVisitor.Instance.Visit(currentNode);
3639
var privateToken = default(SyntaxToken);
3740

3841
foreach (var modifier in list)
@@ -47,11 +50,10 @@ static void Analyze(SyntaxNodeAnalysisContext context, FileDetailCache cache)
4750

4851
case SyntaxKind.ProtectedKeyword:
4952
case SyntaxKind.PublicKeyword:
50-
case SyntaxKind.PartialKeyword when (context.Node.IsKind(SyntaxKind.MethodDeclaration)):
53+
case SyntaxKind.PartialKeyword when (PartialMethodRequiresAccessibilityModifier(currentNode)):
5154
return;
52-
5355
case SyntaxKind.InternalKeyword:
54-
if (IsTopLevel(context.Node))
56+
if (IsTopLevel(currentNode))
5557
{
5658
context.ReportDiagnostic(Rules.CreateDoNotUseTheInternalKeywordForTopLevelTypesDiagnostic(modifier.GetLocation()));
5759
}
@@ -65,6 +67,31 @@ static void Analyze(SyntaxNodeAnalysisContext context, FileDetailCache cache)
6567
}
6668
}
6769

70+
static bool PartialMethodRequiresAccessibilityModifier(SyntaxNode node)
71+
{
72+
if (!node.IsKind(SyntaxKind.MethodDeclaration))
73+
{
74+
return false;
75+
}
76+
77+
var methodNode = (MethodDeclarationSyntax)node;
78+
if (methodNode.ReturnType.IsKind(SyntaxKind.PredefinedType))
79+
{
80+
var returnType = (PredefinedTypeSyntax)methodNode.ReturnType;
81+
if (!returnType.Keyword.IsKind(SyntaxKind.VoidKeyword))
82+
{
83+
return true;
84+
}
85+
}
86+
87+
if (methodNode.ParameterList?.Parameters.Any(static p => p.Modifiers.Any(SyntaxKind.OutKeyword)) == true)
88+
{
89+
return true;
90+
}
91+
92+
return false;
93+
}
94+
6895
static bool IsTopLevel(SyntaxNode node)
6996
{
7097
var parentKind = node.Parent?.Kind() ?? SyntaxKind.None;

0 commit comments

Comments
 (0)