forked from DotNetAnalyzers/DocumentationAnalyzers
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement DOC103 (Use Unicode Characters)
Closes DotNetAnalyzers#1
- Loading branch information
Showing
8 changed files
with
374 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
DocumentationAnalyzers/DocumentationAnalyzers.CodeFixes/StyleRules/DOC103CodeFixProvider.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,72 @@ | ||
// 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.StyleRules | ||
{ | ||
using System.Collections.Immutable; | ||
using System.Composition; | ||
using System.Net; | ||
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; | ||
|
||
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(DOC103CodeFixProvider))] | ||
[Shared] | ||
internal class DOC103CodeFixProvider : CodeFixProvider | ||
{ | ||
private const string CS1570 = nameof(CS1570); | ||
|
||
public override ImmutableArray<string> FixableDiagnosticIds { get; } | ||
= ImmutableArray.Create(DOC103UseUnicodeCharacters.DiagnosticId, CS1570); | ||
|
||
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( | ||
StyleResources.DOC103CodeFix, | ||
token => GetTransformedDocumentAsync(context.Document, diagnostic, token), | ||
nameof(DOC103CodeFixProvider)), | ||
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); | ||
|
||
string newText = token.ValueText; | ||
if (newText == token.Text) | ||
{ | ||
// The entity is not recognized. Try decoding as an HTML entity. | ||
newText = WebUtility.HtmlDecode(token.Text); | ||
} | ||
|
||
if (newText == token.Text) | ||
{ | ||
// Unknown entity | ||
return document; | ||
} | ||
|
||
var newToken = SyntaxFactory.Token(token.LeadingTrivia, SyntaxKind.XmlTextLiteralToken, newText, newText, token.TrailingTrivia); | ||
|
||
return document.WithSyntaxRoot(root.ReplaceToken(token, newToken)); | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...ntationAnalyzers/DocumentationAnalyzers.Test.CSharp7/StyleRules/DOC103CSharp7UnitTests.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.StyleRules | ||
{ | ||
using DocumentationAnalyzers.Test.StyleRules; | ||
|
||
public class DOC103CSharp7UnitTests : DOC103UnitTests | ||
{ | ||
} | ||
} |
114 changes: 114 additions & 0 deletions
114
DocumentationAnalyzers/DocumentationAnalyzers.Test/StyleRules/DOC103UnitTests.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,114 @@ | ||
// 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.StyleRules | ||
{ | ||
using System.Threading.Tasks; | ||
using DocumentationAnalyzers.StyleRules; | ||
using Microsoft.CodeAnalysis.CSharp.Testing; | ||
using Microsoft.CodeAnalysis.Testing; | ||
using Microsoft.CodeAnalysis.Testing.Verifiers; | ||
using Xunit; | ||
using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier<DocumentationAnalyzers.StyleRules.DOC103UseUnicodeCharacters, DocumentationAnalyzers.StyleRules.DOC103CodeFixProvider, Microsoft.CodeAnalysis.Testing.Verifiers.XUnitVerifier>; | ||
|
||
public class DOC103UnitTests | ||
{ | ||
[Fact] | ||
public async Task TestApostropheReplacementAsync() | ||
{ | ||
var testCode = @" | ||
/// <summary> | ||
/// Don[|'|]t use <![CDATA[']]> this <element attr=""'"" attr2='''/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
var fixedCode = @" | ||
/// <summary> | ||
/// Don't use <![CDATA[']]> this <element attr=""'"" attr2='''/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
|
||
await Verify.VerifyCodeFixAsync(testCode, fixedCode); | ||
} | ||
|
||
[Fact] | ||
public async Task TestApostropheReplacementByNumberAsync() | ||
{ | ||
var testCode = @" | ||
/// <summary> | ||
/// Don[|'|]t use <![CDATA[']]> this <element attr=""'"" attr2='''/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
var fixedCode = @" | ||
/// <summary> | ||
/// Don't use <![CDATA[']]> this <element attr=""'"" attr2='''/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
|
||
await Verify.VerifyCodeFixAsync(testCode, fixedCode); | ||
} | ||
|
||
[Fact] | ||
public async Task TestQuoteReplacementAsync() | ||
{ | ||
var testCode = @" | ||
/// <summary> | ||
/// Don[|"|]t use <![CDATA["]]> this <element attr=""""" attr2='"'/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
var fixedCode = @" | ||
/// <summary> | ||
/// Don""t use <![CDATA["]]> this <element attr=""""" attr2='"'/>. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
|
||
await Verify.VerifyCodeFixAsync(testCode, fixedCode); | ||
} | ||
|
||
[Fact] | ||
public async Task TestHtmlEntityReplacementAsync() | ||
{ | ||
var testCode = @" | ||
/// <summary> | ||
/// From A→B. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
var fixedCode = @" | ||
/// <summary> | ||
/// From A→B. | ||
/// </summary> | ||
class TestClass | ||
{ | ||
} | ||
"; | ||
|
||
await new CSharpCodeFixTest<DOC103UseUnicodeCharacters, DOC103CodeFixProvider, XUnitVerifier> | ||
{ | ||
TestCode = testCode, | ||
ExpectedDiagnostics = { DiagnosticResult.CompilerWarning("CS1570").WithSpan(3, 11, 3, 11).WithMessage("XML comment has badly formed XML -- 'Reference to undefined entity 'rarr'.'") }, | ||
FixedCode = fixedCode, | ||
CompilerDiagnostics = CompilerDiagnostics.Warnings, | ||
}.RunAsync(); | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
DocumentationAnalyzers/DocumentationAnalyzers/StyleRules/DOC103UseUnicodeCharacters.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,67 @@ | ||
// 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.StyleRules | ||
{ | ||
using System.Collections.Immutable; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.CSharp.Syntax; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
|
||
/// <summary> | ||
/// Use Unicode characters <see text="""/>. | ||
/// </summary> | ||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
internal class DOC103UseUnicodeCharacters : DiagnosticAnalyzer | ||
{ | ||
/// <summary> | ||
/// The ID for diagnostics produced by the <see cref="DOC103UseUnicodeCharacters"/> analyzer. | ||
/// </summary> | ||
public const string DiagnosticId = "DOC103"; | ||
private const string HelpLink = "https://github.com/DotNetAnalyzers/DocumentationAnalyzers/blob/master/docs/DOC103.md"; | ||
|
||
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(StyleResources.DOC103Title), StyleResources.ResourceManager, typeof(StyleResources)); | ||
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(StyleResources.DOC103MessageFormat), StyleResources.ResourceManager, typeof(StyleResources)); | ||
private static readonly LocalizableString Description = new LocalizableResourceString(nameof(StyleResources.DOC103Description), StyleResources.ResourceManager, typeof(StyleResources)); | ||
|
||
private static readonly DiagnosticDescriptor Descriptor = | ||
new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.PortabilityRules, DiagnosticSeverity.Info, AnalyzerConstants.EnabledByDefault, Description, HelpLink); | ||
|
||
/// <inheritdoc/> | ||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } | ||
= ImmutableArray.Create(Descriptor); | ||
|
||
public override void Initialize(AnalysisContext context) | ||
{ | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.EnableConcurrentExecution(); | ||
|
||
context.RegisterSyntaxNodeAction(HandleXmlElementSyntax, SyntaxKind.XmlText); | ||
} | ||
|
||
private static void HandleXmlElementSyntax(SyntaxNodeAnalysisContext context) | ||
{ | ||
var xmlText = (XmlTextSyntax)context.Node; | ||
foreach (var token in xmlText.TextTokens) | ||
{ | ||
if (!token.IsKind(SyntaxKind.XmlEntityLiteralToken)) | ||
{ | ||
continue; | ||
} | ||
|
||
switch (token.ValueText) | ||
{ | ||
// Characters which are often XML-escaped unnecessarily | ||
case "'": | ||
case "\"": | ||
context.ReportDiagnostic(Diagnostic.Create(Descriptor, token.GetLocation())); | ||
break; | ||
|
||
default: | ||
continue; | ||
} | ||
} | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
DocumentationAnalyzers/DocumentationAnalyzers/StyleRules/StyleResources.Designer.cs
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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,61 @@ | ||
# DOC103 | ||
|
||
<table> | ||
<tr> | ||
<td>TypeName</td> | ||
<td>DOC103UseUnicodeCharacters</td> | ||
</tr> | ||
<tr> | ||
<td>CheckId</td> | ||
<td>DOC103</td> | ||
</tr> | ||
<tr> | ||
<td>Category</td> | ||
<td>Style Rules</td> | ||
</tr> | ||
</table> | ||
|
||
## Cause | ||
|
||
The documentation contains an unnecessary or unrecognized HTML character entity. | ||
|
||
## Rule description | ||
|
||
A violation of this rule occurs when documentation an unnecessarily-escaped character, making the documentation more | ||
difficult to read than necessary. The code fix for this diagnostic also helps correct HTML character entity references | ||
(e.g. `&rarr`), which are not supported by the XML documentation compiler. | ||
|
||
```csharp | ||
/// <summary> | ||
/// A city's graph from A→B. | ||
/// </summary> | ||
public class SomeType | ||
{ | ||
} | ||
``` | ||
|
||
## How to fix violations | ||
|
||
To fix a violation of this rule, replace the XML- or HTML-escape sequence with the intended character. | ||
|
||
```csharp | ||
/// <summary> | ||
/// A city's graph from A→B. | ||
/// </summary> | ||
public class SomeType | ||
{ | ||
} | ||
``` | ||
|
||
## How to suppress violations | ||
|
||
```csharp | ||
#pragma warning disable DOC103 // Use Unicode characters | ||
/// <summary> | ||
/// A city's graph from A→B. | ||
/// </summary> | ||
public class SomeType | ||
#pragma warning restore DOC103 // Use Unicode characters | ||
{ | ||
} | ||
``` |
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