Skip to content

Commit 2a966c1

Browse files
authored
Merge pull request #2187 from vweijsters/fix-included-documentation
Updates to handle included documentation
2 parents 1f6c929 + db1a2b4 commit 2a966c1

43 files changed

Lines changed: 3682 additions & 519 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/DocumentationRules/SA1609SA1610CodeFixProvider.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,15 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
4444
{
4545
foreach (var diagnostic in context.Diagnostics)
4646
{
47-
context.RegisterCodeFix(
48-
CodeAction.Create(
49-
DocumentationResources.SA1609SA1610CodeFix,
50-
cancellationToken => this.GetTransformedDocumentAsync(context.Document, diagnostic, cancellationToken),
51-
nameof(SA1609SA1610CodeFixProvider)),
52-
diagnostic);
47+
if (!diagnostic.Properties.ContainsKey(PropertyDocumentationBase.NoCodeFixKey))
48+
{
49+
context.RegisterCodeFix(
50+
CodeAction.Create(
51+
DocumentationResources.SA1609SA1610CodeFix,
52+
cancellationToken => this.GetTransformedDocumentAsync(context.Document, diagnostic, cancellationToken),
53+
nameof(SA1609SA1610CodeFixProvider)),
54+
diagnostic);
55+
}
5356
}
5457

5558
return SpecializedTasks.CompletedTask;

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/DocumentationRules/SA1617CodeFixProvider.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,15 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
3939
{
4040
foreach (Diagnostic diagnostic in context.Diagnostics)
4141
{
42-
context.RegisterCodeFix(
43-
CodeAction.Create(
44-
DocumentationResources.SA1617CodeFix,
45-
cancellationToken => GetTransformedDocumentAsync(context.Document, diagnostic, cancellationToken),
46-
nameof(SA1617CodeFixProvider)),
47-
diagnostic);
42+
if (!diagnostic.Properties.ContainsKey(SA1617VoidReturnValueMustNotBeDocumented.NoCodeFixKey))
43+
{
44+
context.RegisterCodeFix(
45+
CodeAction.Create(
46+
DocumentationResources.SA1617CodeFix,
47+
cancellationToken => GetTransformedDocumentAsync(context.Document, diagnostic, cancellationToken),
48+
nameof(SA1617CodeFixProvider)),
49+
diagnostic);
50+
}
4851
}
4952

5053
return SpecializedTasks.CompletedTask;

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/DocumentationRules/SA1642SA1643CodeFixProvider.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
5050

5151
foreach (var diagnostic in context.Diagnostics)
5252
{
53-
var node = root.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
53+
if (diagnostic.Properties.ContainsKey(StandardTextDiagnosticBase.NoCodeFixKey))
54+
{
55+
continue;
56+
}
5457

58+
var node = root.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
5559
var xmlElementSyntax = node as XmlElementSyntax;
5660

5761
if (xmlElementSyntax != null)

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/DocumentationRules/SA1651CodeFixProvider.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
4444
{
4545
foreach (var diagnostic in context.Diagnostics)
4646
{
47+
if (diagnostic.Properties.ContainsKey(SA1651DoNotUsePlaceholderElements.NoCodeFixKey))
48+
{
49+
// skip diagnostics that should not offer a code fix.
50+
continue;
51+
}
52+
4753
var documentRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
4854
SyntaxNode syntax = documentRoot.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
4955
if (syntax == null)

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1605UnitTests.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace StyleCop.Analyzers.Test.DocumentationRules
66
using System.Collections.Generic;
77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Helpers;
10+
using Microsoft.CodeAnalysis;
911
using Microsoft.CodeAnalysis.Diagnostics;
1012
using StyleCop.Analyzers.DocumentationRules;
1113
using TestHelper;
@@ -207,6 +209,104 @@ public void Test() { }
207209
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
208210
}
209211

212+
[Fact]
213+
public async Task TestIncludedDocumentationWithoutSummaryAsync()
214+
{
215+
var testCode = @"
216+
/// <include file='ClassWithoutSummary.xml' path='/ClassName/*'/>
217+
public partial class ClassName
218+
{
219+
///
220+
public void Test() { }
221+
}";
222+
var expected = this.CSharpDiagnostic().WithLocation(3, 22);
223+
224+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
225+
}
226+
227+
[Fact]
228+
public async Task TestIncludedDocumentationWithInheritdocAsync()
229+
{
230+
var testCode = @"
231+
/// <include file='ClassWithInheritdoc.xml' path='/ClassName/*'/>
232+
public partial class ClassName
233+
{
234+
///
235+
public void Test() { }
236+
}";
237+
238+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
239+
}
240+
241+
[Fact]
242+
public async Task TestIncludedDocumentationWithSummaryAsync()
243+
{
244+
var testCode = @"
245+
/// <include file='ClassWithSummary.xml' path='/ClassName/*'/>
246+
public partial class ClassName
247+
{
248+
///
249+
public void Test() { }
250+
}";
251+
252+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
253+
}
254+
255+
[Fact]
256+
public async Task TestIncludedDocumentationWithContentAsync()
257+
{
258+
var testCode = @"
259+
/// <include file='ClassWithContent.xml' path='/ClassName/*'/>
260+
public partial class ClassName
261+
{
262+
///
263+
public void Test() { }
264+
}";
265+
266+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
267+
}
268+
269+
/// <inheritdoc/>
270+
protected override Project ApplyCompilationOptions(Project project)
271+
{
272+
var resolver = new TestXmlReferenceResolver();
273+
274+
string contentWithoutSummary = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
275+
<ClassName>
276+
</ClassName>
277+
";
278+
resolver.XmlReferences.Add("ClassWithoutSummary.xml", contentWithoutSummary);
279+
280+
string contentWithInheritdoc = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
281+
<ClassName>
282+
<inheritdoc/>
283+
</ClassName>
284+
";
285+
resolver.XmlReferences.Add("ClassWithInheritdoc.xml", contentWithInheritdoc);
286+
287+
string contentWithSummary = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
288+
<ClassName>
289+
<summary>
290+
Foo
291+
</summary>
292+
</ClassName>
293+
";
294+
resolver.XmlReferences.Add("ClassWithSummary.xml", contentWithSummary);
295+
296+
string contentWithContent = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
297+
<ClassName>
298+
<content>
299+
Foo
300+
</content>
301+
</ClassName>
302+
";
303+
resolver.XmlReferences.Add("ClassWithContent.xml", contentWithContent);
304+
305+
project = base.ApplyCompilationOptions(project);
306+
project = project.WithCompilationOptions(project.CompilationOptions.WithXmlReferenceResolver(resolver));
307+
return project;
308+
}
309+
210310
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
211311
{
212312
yield return new SA1605PartialElementDocumentationMustHaveSummary();

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1607UnitTests.cs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace StyleCop.Analyzers.Test.DocumentationRules
66
using System.Collections.Generic;
77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Helpers;
10+
using Microsoft.CodeAnalysis;
911
using Microsoft.CodeAnalysis.Diagnostics;
1012
using StyleCop.Analyzers.DocumentationRules;
1113
using TestHelper;
@@ -290,6 +292,175 @@ public void Test() { }
290292
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
291293
}
292294

295+
[Fact]
296+
public async Task TestIncludedDocumentationWithoutSummaryOrContentAsync()
297+
{
298+
var testCode = @"
299+
/// <summary>
300+
/// Foo
301+
/// </summary>
302+
public partial class ClassName
303+
{
304+
/// <include file='MethodWithoutSummaryOrContent.xml' path='/ClassName/Test/*'/>
305+
partial void Test();
306+
}";
307+
308+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
309+
}
310+
311+
[Fact]
312+
public async Task TestIncludedDocumentationWithEmptySummaryAsync()
313+
{
314+
var testCode = @"
315+
/// <summary>
316+
/// Foo
317+
/// </summary>
318+
public partial class ClassName
319+
{
320+
/// <include file='MethodWithEmptySummary.xml' path='/ClassName/Test/*'/>
321+
partial void Test();
322+
}";
323+
var expected = this.CSharpDiagnostic().WithLocation(8, 18);
324+
325+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
326+
}
327+
328+
[Fact]
329+
public async Task TestIncludedDocumentationWithEmptyContentAsync()
330+
{
331+
var testCode = @"
332+
/// <summary>
333+
/// Foo
334+
/// </summary>
335+
public partial class ClassName
336+
{
337+
/// <include file='MethodWithEmptyContent.xml' path='/ClassName/Test/*'/>
338+
partial void Test();
339+
}";
340+
var expected = this.CSharpDiagnostic().WithLocation(8, 18);
341+
342+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
343+
}
344+
345+
[Fact]
346+
public async Task TestIncludedDocumentationWithInheritdocAsync()
347+
{
348+
var testCode = @"
349+
/// <summary>
350+
/// Foo
351+
/// </summary>
352+
public partial class ClassName
353+
{
354+
/// <include file='MethodWithInheritdoc.xml' path='/ClassName/Test/*'/>
355+
partial void Test();
356+
}";
357+
358+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
359+
}
360+
361+
[Fact]
362+
public async Task TestIncludedDocumentationWithSummaryAsync()
363+
{
364+
var testCode = @"
365+
/// <summary>
366+
/// Foo
367+
/// </summary>
368+
public partial class ClassName
369+
{
370+
/// <include file='MethodWithSummary.xml' path='/ClassName/Test/*'/>
371+
partial void Test();
372+
}";
373+
374+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
375+
}
376+
377+
[Fact]
378+
public async Task TestIncludedDocumentationWithContentAsync()
379+
{
380+
var testCode = @"
381+
/// <summary>
382+
/// Foo
383+
/// </summary>
384+
public partial class ClassName
385+
{
386+
/// <include file='MethodWithContent.xml' path='/ClassName/Test/*'/>
387+
partial void Test();
388+
}";
389+
390+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
391+
}
392+
393+
/// <inheritdoc/>
394+
protected override Project ApplyCompilationOptions(Project project)
395+
{
396+
var resolver = new TestXmlReferenceResolver();
397+
398+
string contentWithoutSummaryOrContent = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
399+
<ClassName>
400+
<Test>
401+
</Test>
402+
</ClassName>
403+
";
404+
resolver.XmlReferences.Add("MethodWithoutSummaryOrContent.xml", contentWithoutSummaryOrContent);
405+
406+
string contentWithEmptySummary = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
407+
<ClassName>
408+
<Test>
409+
<summary>
410+
411+
</summary>
412+
</Test>
413+
</ClassName>
414+
";
415+
resolver.XmlReferences.Add("MethodWithEmptySummary.xml", contentWithEmptySummary);
416+
417+
string contentWithEmptyContent = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
418+
<ClassName>
419+
<Test>
420+
<content>
421+
422+
</content>
423+
</Test>
424+
</ClassName>
425+
";
426+
resolver.XmlReferences.Add("MethodWithEmptyContent.xml", contentWithEmptyContent);
427+
428+
string contentWithInheritdoc = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
429+
<ClassName>
430+
<Test>
431+
<inheritdoc/>
432+
</Test>
433+
</ClassName>
434+
";
435+
resolver.XmlReferences.Add("MethodWithInheritdoc.xml", contentWithInheritdoc);
436+
437+
string contentWithSummary = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
438+
<ClassName>
439+
<Test>
440+
<summary>
441+
Foo
442+
</summary>
443+
</Test>
444+
</ClassName>
445+
";
446+
resolver.XmlReferences.Add("MethodWithSummary.xml", contentWithSummary);
447+
448+
string contentWithContent = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
449+
<ClassName>
450+
<Test>
451+
<content>
452+
Foo
453+
</content>
454+
</Test>
455+
</ClassName>
456+
";
457+
resolver.XmlReferences.Add("MethodWithContent.xml", contentWithContent);
458+
459+
project = base.ApplyCompilationOptions(project);
460+
project = project.WithCompilationOptions(project.CompilationOptions.WithXmlReferenceResolver(resolver));
461+
return project;
462+
}
463+
293464
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
294465
{
295466
yield return new SA1607PartialElementDocumentationMustHaveSummaryText();

0 commit comments

Comments
 (0)