Skip to content

Commit d7e60d8

Browse files
Merge pull request #7 from MattFromRVA/SA1514_Change
Fix SA1514: Do not report when documenting types declared in the global namespace
2 parents aa6c944 + 6ca6fef commit d7e60d8

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1514UnitTests.cs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,5 +1151,199 @@ public enum TestEnum
11511151

11521152
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
11531153
}
1154+
1155+
[Fact]
1156+
[WorkItem(3849, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3849")]
1157+
public async Task TestClassInGlobalNamespaceAsync()
1158+
{
1159+
var testCode = @"
1160+
/// <summary>
1161+
/// X.
1162+
/// </summary>
1163+
public class TestClass
1164+
{
1165+
}
1166+
";
1167+
1168+
var expected = DiagnosticResult.EmptyDiagnosticResults;
1169+
1170+
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
1171+
}
1172+
1173+
[Fact]
1174+
public async Task TestClassInGlobalNamespaceWithoutNewlineAsync()
1175+
{
1176+
var testCode = @"/// <summary>
1177+
/// X.
1178+
/// </summary>
1179+
public class TestClass
1180+
{
1181+
}
1182+
";
1183+
1184+
var expected = DiagnosticResult.EmptyDiagnosticResults;
1185+
1186+
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
1187+
}
1188+
1189+
[Fact]
1190+
public async Task TestClassInNamespaceAsync()
1191+
{
1192+
var testCode = @"
1193+
namespace TestNamespace
1194+
{
1195+
/// <summary>
1196+
/// X.
1197+
/// </summary>
1198+
public class TestClass
1199+
{
1200+
}
1201+
}
1202+
";
1203+
1204+
var expected = DiagnosticResult.EmptyDiagnosticResults;
1205+
1206+
await VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
1207+
}
1208+
1209+
[Fact]
1210+
public async Task TestClassInNamespaceWithCommentAsync()
1211+
{
1212+
var testCode = @"
1213+
namespace TestNamespace
1214+
{
1215+
// Normal comment
1216+
{|#0:///|} <summary>
1217+
/// X.
1218+
/// </summary>
1219+
public class TestClass
1220+
{
1221+
}
1222+
}
1223+
";
1224+
1225+
var fixedCode = @"
1226+
namespace TestNamespace
1227+
{
1228+
// Normal comment
1229+
1230+
/// <summary>
1231+
/// X.
1232+
/// </summary>
1233+
public class TestClass
1234+
{
1235+
}
1236+
}
1237+
";
1238+
1239+
var expected = new[]
1240+
{
1241+
Diagnostic().WithLocation(0).WithArguments(" not", "preceded"),
1242+
};
1243+
1244+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1245+
}
1246+
1247+
[Fact]
1248+
public async Task TestClassInGlobalNamespaceWithCommentAsync()
1249+
{
1250+
var testCode = @"
1251+
// Normal comment
1252+
{|#0:///|} <summary>
1253+
/// X.
1254+
/// </summary>
1255+
public class TestClass
1256+
{
1257+
}
1258+
";
1259+
1260+
var fixedCode = @"
1261+
// Normal comment
1262+
1263+
/// <summary>
1264+
/// X.
1265+
/// </summary>
1266+
public class TestClass
1267+
{
1268+
}
1269+
";
1270+
1271+
var expected = new[]
1272+
{
1273+
Diagnostic().WithLocation(0).WithArguments(" not", "preceded"),
1274+
};
1275+
1276+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1277+
}
1278+
1279+
[Fact]
1280+
public async Task TestClassInGlobalNamespaceWithPreprocessorDirectiveAsync()
1281+
{
1282+
var testCode = @"
1283+
#if DEBUG
1284+
#endif
1285+
{|#0:///|} <summary>
1286+
/// X.
1287+
/// </summary>
1288+
public class TestClass
1289+
{
1290+
}
1291+
";
1292+
1293+
var fixedCode = @"
1294+
#if DEBUG
1295+
#endif
1296+
1297+
/// <summary>
1298+
/// X.
1299+
/// </summary>
1300+
public class TestClass
1301+
{
1302+
}
1303+
";
1304+
1305+
var expected = new[]
1306+
{
1307+
Diagnostic().WithLocation(0).WithArguments(" not", "preceded"),
1308+
};
1309+
1310+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1311+
}
1312+
1313+
[Fact]
1314+
public async Task TestClassInGlobalNamespaceWithMultilineCommentAsync()
1315+
{
1316+
var testCode = @"
1317+
/* Normal
1318+
* multiline
1319+
* comment */
1320+
{|#0:///|} <summary>
1321+
/// X.
1322+
/// </summary>
1323+
public class TestClass
1324+
{
1325+
}
1326+
";
1327+
1328+
var fixedCode = @"
1329+
/* Normal
1330+
* multiline
1331+
* comment */
1332+
1333+
/// <summary>
1334+
/// X.
1335+
/// </summary>
1336+
public class TestClass
1337+
{
1338+
}
1339+
";
1340+
1341+
var expected = new[]
1342+
{
1343+
Diagnostic().WithLocation(0).WithArguments(" not", "preceded"),
1344+
};
1345+
1346+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1347+
}
11541348
}
11551349
}

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1514ElementDocumentationHeaderMustBePrecededByBlankLine.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ private static void HandleDeclaration(SyntaxNodeAnalysisContext context)
170170
// no leading blank line necessary at start of scope.
171171
return;
172172
}
173+
174+
// Logic to handle global namespace case
175+
if (prevToken.IsKind(SyntaxKind.None))
176+
{
177+
// Node is the first element in the global namespace
178+
return;
179+
}
173180
}
174181

175182
context.ReportDiagnostic(Diagnostic.Create(Descriptor, GetDiagnosticLocation(documentationHeader)));

0 commit comments

Comments
 (0)