-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from sharwell/inline-code
Implement element usage analyzers
- Loading branch information
Showing
18 changed files
with
1,219 additions
and
0 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
...ationAnalyzers/DocumentationAnalyzers.CodeFixes/PortabilityRules/DOC202CodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.PortabilityRules | ||
{ | ||
using System.Collections.Immutable; | ||
using System.Composition; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using DocumentationAnalyzers.Helpers; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(DOC202CodeFixProvider))] | ||
[Shared] | ||
internal class DOC202CodeFixProvider : CodeFixProvider | ||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds { get; } | ||
= ImmutableArray.Create(DOC202UseSectionElementsCorrectly.DiagnosticId); | ||
|
||
public override FixAllProvider GetFixAllProvider() | ||
=> CustomFixAllProviders.BatchFixer; | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
foreach (var diagnostic in context.Diagnostics) | ||
{ | ||
if (!FixableDiagnosticIds.Contains(diagnostic.Id)) | ||
{ | ||
continue; | ||
} | ||
|
||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
PortabilityResources.DOC202CodeFix, | ||
token => GetTransformedDocumentAsync(context.Document, diagnostic, token), | ||
nameof(DOC202CodeFixProvider)), | ||
diagnostic); | ||
} | ||
|
||
return SpecializedTasks.CompletedTask; | ||
} | ||
|
||
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) | ||
{ | ||
SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
SyntaxToken token = root.FindToken(diagnostic.Location.SourceSpan.Start, findInsideTrivia: true); | ||
|
||
var xmlNode = token.Parent.FirstAncestorOrSelf<XmlNodeSyntax>(); | ||
var oldStartToken = xmlNode.GetName().LocalName; | ||
|
||
string newIdentifier; | ||
switch (oldStartToken.ValueText) | ||
{ | ||
case XmlCommentHelper.ParamXmlTag: | ||
newIdentifier = XmlCommentHelper.ParamRefXmlTag; | ||
break; | ||
|
||
case XmlCommentHelper.TypeParamXmlTag: | ||
newIdentifier = XmlCommentHelper.TypeParamRefXmlTag; | ||
break; | ||
|
||
default: | ||
// Not handled | ||
return document; | ||
} | ||
|
||
var newStartToken = SyntaxFactory.Identifier(oldStartToken.LeadingTrivia, newIdentifier, oldStartToken.TrailingTrivia); | ||
var newXmlNode = xmlNode.ReplaceToken(oldStartToken, newStartToken); | ||
|
||
if (newXmlNode is XmlElementSyntax newXmlElement) | ||
{ | ||
var oldEndToken = newXmlElement.EndTag.Name.LocalName; | ||
var newEndToken = SyntaxFactory.Identifier(oldEndToken.LeadingTrivia, newIdentifier, oldEndToken.TrailingTrivia); | ||
newXmlNode = newXmlNode.ReplaceToken(oldEndToken, newEndToken); | ||
} | ||
|
||
return document.WithSyntaxRoot(root.ReplaceNode(xmlNode, newXmlNode)); | ||
} | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
...ationAnalyzers/DocumentationAnalyzers.CodeFixes/PortabilityRules/DOC203CodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.PortabilityRules | ||
{ | ||
using System.Collections.Immutable; | ||
using System.Composition; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using DocumentationAnalyzers.Helpers; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(DOC203CodeFixProvider))] | ||
[Shared] | ||
internal class DOC203CodeFixProvider : CodeFixProvider | ||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds { get; } | ||
= ImmutableArray.Create(DOC203UseBlockElementsCorrectly.DiagnosticId); | ||
|
||
public override FixAllProvider GetFixAllProvider() | ||
=> CustomFixAllProviders.BatchFixer; | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
foreach (var diagnostic in context.Diagnostics) | ||
{ | ||
if (!FixableDiagnosticIds.Contains(diagnostic.Id)) | ||
{ | ||
continue; | ||
} | ||
|
||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
PortabilityResources.DOC203CodeFix, | ||
token => GetTransformedDocumentAsync(context.Document, diagnostic, token), | ||
nameof(DOC203CodeFixProvider)), | ||
diagnostic); | ||
} | ||
|
||
return SpecializedTasks.CompletedTask; | ||
} | ||
|
||
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) | ||
{ | ||
SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
SyntaxToken token = root.FindToken(diagnostic.Location.SourceSpan.Start, findInsideTrivia: true); | ||
|
||
var xmlNode = token.Parent.FirstAncestorOrSelf<XmlNodeSyntax>(); | ||
var oldStartToken = xmlNode.GetName().LocalName; | ||
|
||
string newIdentifier; | ||
switch (oldStartToken.ValueText) | ||
{ | ||
case XmlCommentHelper.CodeXmlTag: | ||
newIdentifier = XmlCommentHelper.CXmlTag; | ||
break; | ||
|
||
default: | ||
// Not handled | ||
return document; | ||
} | ||
|
||
var newStartToken = SyntaxFactory.Identifier(oldStartToken.LeadingTrivia, newIdentifier, oldStartToken.TrailingTrivia); | ||
var newXmlNode = xmlNode.ReplaceToken(oldStartToken, newStartToken); | ||
|
||
if (newXmlNode is XmlElementSyntax newXmlElement) | ||
{ | ||
var oldEndToken = newXmlElement.EndTag.Name.LocalName; | ||
var newEndToken = SyntaxFactory.Identifier(oldEndToken.LeadingTrivia, newIdentifier, oldEndToken.TrailingTrivia); | ||
newXmlNode = newXmlNode.ReplaceToken(oldEndToken, newEndToken); | ||
} | ||
|
||
return document.WithSyntaxRoot(root.ReplaceNode(xmlNode, newXmlNode)); | ||
} | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
...ationAnalyzers/DocumentationAnalyzers.CodeFixes/PortabilityRules/DOC204CodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.PortabilityRules | ||
{ | ||
using System.Collections.Immutable; | ||
using System.Composition; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using DocumentationAnalyzers.Helpers; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(DOC204CodeFixProvider))] | ||
[Shared] | ||
internal class DOC204CodeFixProvider : CodeFixProvider | ||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds { get; } | ||
= ImmutableArray.Create(DOC204UseInlineElementsCorrectly.DiagnosticId); | ||
|
||
public override FixAllProvider GetFixAllProvider() | ||
=> CustomFixAllProviders.BatchFixer; | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
foreach (var diagnostic in context.Diagnostics) | ||
{ | ||
if (!FixableDiagnosticIds.Contains(diagnostic.Id)) | ||
{ | ||
continue; | ||
} | ||
|
||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
PortabilityResources.DOC204CodeFix, | ||
token => GetTransformedDocumentAsync(context.Document, diagnostic, token), | ||
nameof(DOC204CodeFixProvider)), | ||
diagnostic); | ||
} | ||
|
||
return SpecializedTasks.CompletedTask; | ||
} | ||
|
||
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) | ||
{ | ||
SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | ||
SyntaxToken token = root.FindToken(diagnostic.Location.SourceSpan.Start, findInsideTrivia: true); | ||
|
||
var xmlNode = token.Parent.FirstAncestorOrSelf<XmlNodeSyntax>(); | ||
var oldStartToken = xmlNode.GetName().LocalName; | ||
|
||
string newIdentifier; | ||
switch (oldStartToken.ValueText) | ||
{ | ||
case XmlCommentHelper.ParamRefXmlTag: | ||
newIdentifier = XmlCommentHelper.ParamXmlTag; | ||
break; | ||
|
||
case XmlCommentHelper.TypeParamRefXmlTag: | ||
newIdentifier = XmlCommentHelper.TypeParamXmlTag; | ||
break; | ||
|
||
default: | ||
// Not handled | ||
return document; | ||
} | ||
|
||
var newStartToken = SyntaxFactory.Identifier(oldStartToken.LeadingTrivia, newIdentifier, oldStartToken.TrailingTrivia); | ||
var newXmlNode = xmlNode.ReplaceToken(oldStartToken, newStartToken); | ||
|
||
if (newXmlNode is XmlElementSyntax newXmlElement) | ||
{ | ||
var oldEndToken = newXmlElement.EndTag.Name.LocalName; | ||
var newEndToken = SyntaxFactory.Identifier(oldEndToken.LeadingTrivia, newIdentifier, oldEndToken.TrailingTrivia); | ||
newXmlNode = newXmlNode.ReplaceToken(oldEndToken, newEndToken); | ||
} | ||
|
||
return document.WithSyntaxRoot(root.ReplaceNode(xmlNode, newXmlNode)); | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...nAnalyzers/DocumentationAnalyzers.Test.CSharp7/PortabilityRules/DOC202CSharp7UnitTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.Test.CSharp7.PortabilityRules | ||
{ | ||
using DocumentationAnalyzers.Test.PortabilityRules; | ||
|
||
public class DOC202CSharp7UnitTests : DOC202UnitTests | ||
{ | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...nAnalyzers/DocumentationAnalyzers.Test.CSharp7/PortabilityRules/DOC203CSharp7UnitTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.Test.CSharp7.PortabilityRules | ||
{ | ||
using DocumentationAnalyzers.Test.PortabilityRules; | ||
|
||
public class DOC203CSharp7UnitTests : DOC203UnitTests | ||
{ | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...nAnalyzers/DocumentationAnalyzers.Test.CSharp7/PortabilityRules/DOC204CSharp7UnitTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.Test.CSharp7.PortabilityRules | ||
{ | ||
using DocumentationAnalyzers.Test.PortabilityRules; | ||
|
||
public class DOC204CSharp7UnitTests : DOC204UnitTests | ||
{ | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
DocumentationAnalyzers/DocumentationAnalyzers.Test/PortabilityRules/DOC202UnitTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. | ||
// Licensed under the MIT license. See LICENSE in the project root for license information. | ||
|
||
namespace DocumentationAnalyzers.Test.PortabilityRules | ||
{ | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier<DocumentationAnalyzers.PortabilityRules.DOC202UseSectionElementsCorrectly, DocumentationAnalyzers.PortabilityRules.DOC202CodeFixProvider, Microsoft.CodeAnalysis.Testing.Verifiers.XUnitVerifier>; | ||
|
||
public class DOC202UnitTests | ||
{ | ||
[Fact] | ||
public async Task TestElementsUsedCorrectlyAsync() | ||
{ | ||
var testCode = @" | ||
class TestClass | ||
{ | ||
/// <summary> | ||
/// Pass in a value. | ||
/// </summary> | ||
/// <typeparam name=""T"">The type of value</typeparam> | ||
/// <param name=""value"">The value</param> | ||
void Method<T>(int value) | ||
{ | ||
} | ||
} | ||
"; | ||
|
||
await Verify.VerifyAnalyzerAsync(testCode); | ||
} | ||
|
||
[Fact] | ||
public async Task TestParamUsedAsParamRefAsync() | ||
{ | ||
var testCode = @" | ||
class TestClass | ||
{ | ||
/// <summary> | ||
/// Pass in a <$$param name=""value""/>. | ||
/// </summary> | ||
void Method(int value) | ||
{ | ||
} | ||
} | ||
"; | ||
var fixedCode = @" | ||
class TestClass | ||
{ | ||
/// <summary> | ||
/// Pass in a <paramref name=""value""/>. | ||
/// </summary> | ||
void Method(int value) | ||
{ | ||
} | ||
} | ||
"; | ||
|
||
await Verify.VerifyCodeFixAsync(testCode, fixedCode); | ||
} | ||
|
||
[Fact] | ||
public async Task TestTypeParamUsedAsTypeParamRefAsync() | ||
{ | ||
var testCode = @" | ||
class TestClass | ||
{ | ||
/// <summary> | ||
/// Pass in a <$$typeparam name=""T""/>. | ||
/// </summary> | ||
void Method<T>() | ||
{ | ||
} | ||
} | ||
"; | ||
var fixedCode = @" | ||
class TestClass | ||
{ | ||
/// <summary> | ||
/// Pass in a <typeparamref name=""T""/>. | ||
/// </summary> | ||
void Method<T>() | ||
{ | ||
} | ||
} | ||
"; | ||
|
||
await Verify.VerifyCodeFixAsync(testCode, fixedCode); | ||
} | ||
} | ||
} |
Oops, something went wrong.