88using Microsoft . CodeAnalysis ;
99using Microsoft . CodeAnalysis . CodeActions ;
1010using Microsoft . CodeAnalysis . CodeFixes ;
11- using Microsoft . CodeAnalysis . CSharp ;
1211using Microsoft . CodeAnalysis . CSharp . Syntax ;
1312using Roslynator . CodeFixes ;
1413using Roslynator . CSharp . Syntax ;
@@ -19,16 +18,7 @@ namespace Roslynator.CSharp.CodeFixes;
1918[ Shared ]
2019public sealed class XmlNodeCodeFixProvider : BaseCodeFixProvider
2120{
22- public override ImmutableArray < string > FixableDiagnosticIds
23- {
24- get
25- {
26- return ImmutableArray . Create (
27- DiagnosticIdentifiers . UnusedElementInDocumentationComment ,
28- DiagnosticIdentifiers . InvalidReferenceInDocumentationComment ,
29- DiagnosticIdentifiers . FixDocumentationCommentTag ) ;
30- }
31- }
21+ public override ImmutableArray < string > FixableDiagnosticIds => ImmutableArray . Create ( DiagnosticIdentifiers . FixDocumentationCommentTag ) ;
3222
3323 public override async Task RegisterCodeFixesAsync ( CodeFixContext context )
3424 {
@@ -38,148 +28,17 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
3828 return ;
3929
4030 Document document = context . Document ;
31+ Diagnostic diagnostic = context . Diagnostics [ 0 ] ;
32+ XmlElementInfo elementInfo = SyntaxInfo . XmlElementInfo ( xmlNode ) ;
4133
42- foreach ( Diagnostic diagnostic in context . Diagnostics )
43- {
44- switch ( diagnostic . Id )
45- {
46- case DiagnosticIdentifiers . UnusedElementInDocumentationComment :
47- case DiagnosticIdentifiers . InvalidReferenceInDocumentationComment :
48- {
49- XmlElementInfo elementInfo = SyntaxInfo . XmlElementInfo ( xmlNode ) ;
50-
51- string name = elementInfo . LocalName ;
52-
53- CodeAction codeAction = CodeAction . Create (
54- $ "Remove '{ name } ' element",
55- ct => RemoveUnusedElementInDocumentationCommentAsync ( document , elementInfo , ct ) ,
56- GetEquivalenceKey ( diagnostic , name ) ) ;
57-
58- context . RegisterCodeFix ( codeAction , diagnostic ) ;
59- break ;
60- }
61- case DiagnosticIdentifiers . FixDocumentationCommentTag :
62- {
63- XmlElementInfo elementInfo = SyntaxInfo . XmlElementInfo ( xmlNode ) ;
64-
65- CodeAction codeAction = CodeAction . Create (
66- ( elementInfo . GetTag ( ) == XmlTag . C )
67- ? "Rename tag to 'code'"
68- : "Rename tag to 'c'" ,
69- ct => FixDocumentationCommentTagAsync ( document , elementInfo , ct ) ,
70- GetEquivalenceKey ( diagnostic ) ) ;
71-
72- context . RegisterCodeFix ( codeAction , diagnostic ) ;
73- break ;
74- }
75- }
76- }
77- }
78-
79- private static Task < Document > RemoveUnusedElementInDocumentationCommentAsync (
80- Document document ,
81- in XmlElementInfo elementInfo ,
82- CancellationToken cancellationToken )
83- {
84- cancellationToken . ThrowIfCancellationRequested ( ) ;
85-
86- XmlNodeSyntax element = elementInfo . Element ;
87-
88- var documentationComment = ( DocumentationCommentTriviaSyntax ) element . Parent ;
89-
90- SyntaxList < XmlNodeSyntax > content = documentationComment . Content ;
91-
92- int count = content . Count ;
93- int index = content . IndexOf ( element ) ;
94-
95- if ( index == 0 )
96- {
97- if ( count == 2
98- && content [ 1 ] is XmlTextSyntax xmlText
99- && IsNewLine ( xmlText ) )
100- {
101- return document . RemoveSingleLineDocumentationComment ( documentationComment , cancellationToken ) ;
102- }
103-
104- if ( content [ index + 1 ] is XmlTextSyntax xmlText2
105- && IsXmlTextBetweenLines ( xmlText2 ) )
106- {
107- return document . RemoveNodesAsync ( new XmlNodeSyntax [ ] { element , xmlText2 } , SyntaxRefactorings . DefaultRemoveOptions , cancellationToken ) ;
108- }
109- }
110- else if ( index == 1 )
111- {
112- if ( count == 3
113- && content [ 0 ] is XmlTextSyntax xmlText
114- && IsWhitespace ( xmlText )
115- && content [ 2 ] is XmlTextSyntax xmlText2
116- && IsNewLine ( xmlText2 ) )
117- {
118- return document . RemoveSingleLineDocumentationComment ( documentationComment , cancellationToken ) ;
119- }
120-
121- if ( content [ 2 ] is XmlTextSyntax xmlText3
122- && IsXmlTextBetweenLines ( xmlText3 ) )
123- {
124- return document . RemoveNodesAsync ( new XmlNodeSyntax [ ] { element , xmlText3 } , SyntaxRefactorings . DefaultRemoveOptions , cancellationToken ) ;
125- }
126- }
127- else if ( content [ index - 1 ] is XmlTextSyntax xmlText
128- && IsXmlTextBetweenLines ( xmlText ) )
129- {
130- return document . RemoveNodesAsync ( new XmlNodeSyntax [ ] { xmlText , element } , SyntaxRefactorings . DefaultRemoveOptions , cancellationToken ) ;
131- }
132-
133- return document . RemoveNodeAsync ( element , cancellationToken ) ;
134-
135- static bool IsXmlTextBetweenLines ( XmlTextSyntax xmlText )
136- {
137- SyntaxTokenList tokens = xmlText . TextTokens ;
138-
139- SyntaxTokenList . Enumerator en = tokens . GetEnumerator ( ) ;
140-
141- if ( ! en . MoveNext ( ) )
142- return false ;
143-
144- if ( IsEmptyOrWhitespace ( en . Current )
145- && ! en . MoveNext ( ) )
146- {
147- return false ;
148- }
34+ CodeAction codeAction = CodeAction . Create (
35+ ( elementInfo . GetTag ( ) == XmlTag . C )
36+ ? "Rename tag to 'code'"
37+ : "Rename tag to 'c'" ,
38+ ct => FixDocumentationCommentTagAsync ( document , elementInfo , ct ) ,
39+ GetEquivalenceKey ( diagnostic ) ) ;
14940
150- if ( ! en . Current . IsKind ( SyntaxKind . XmlTextLiteralNewLineToken ) )
151- return false ;
152-
153- if ( en . MoveNext ( ) )
154- {
155- if ( ! IsEmptyOrWhitespace ( en . Current ) )
156- return false ;
157-
158- if ( en . MoveNext ( ) )
159- return false ;
160- }
161-
162- return true ;
163-
164- static bool IsEmptyOrWhitespace ( SyntaxToken token )
165- {
166- return token . IsKind ( SyntaxKind . XmlTextLiteralToken )
167- && StringUtility . IsEmptyOrWhitespace ( token . ValueText ) ;
168- }
169- }
170-
171- static bool IsWhitespace ( XmlTextSyntax xmlText )
172- {
173- string text = xmlText . TextTokens . SingleOrDefault ( shouldThrow : false ) . ValueText ;
174-
175- return text . Length > 0
176- && StringUtility . IsEmptyOrWhitespace ( text ) ;
177- }
178-
179- static bool IsNewLine ( XmlTextSyntax xmlText )
180- {
181- return xmlText . TextTokens . SingleOrDefault ( shouldThrow : false ) . IsKind ( SyntaxKind . XmlTextLiteralNewLineToken ) ;
182- }
41+ context . RegisterCodeFix ( codeAction , diagnostic ) ;
18342 }
18443
18544 private static Task < Document > FixDocumentationCommentTagAsync (
0 commit comments