22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5- using System . Collections . Generic ;
5+ #nullable enable
6+
67using System . ComponentModel . Composition ;
78using System . Diagnostics . CodeAnalysis ;
8- using System . Linq ;
9- using System . Threading ;
10- using Microsoft . CodeAnalysis . CSharp ;
11- using Microsoft . CodeAnalysis . CSharp . Extensions ;
129using Microsoft . CodeAnalysis . CSharp . Syntax ;
1310using Microsoft . CodeAnalysis . Editor . Host ;
1411using Microsoft . CodeAnalysis . Editor . Implementation . DocumentationComments ;
15- using Microsoft . CodeAnalysis . Shared . Extensions ;
1612using Microsoft . VisualStudio . Commanding ;
1713using Microsoft . VisualStudio . Language . Intellisense . AsyncCompletion ;
1814using Microsoft . VisualStudio . Text . Operations ;
@@ -39,249 +35,5 @@ public DocumentationCommentCommandHandler(
3935 }
4036
4137 protected override string ExteriorTriviaText => "///" ;
42-
43- protected override MemberDeclarationSyntax GetContainingMember (
44- SyntaxTree syntaxTree , int position , CancellationToken cancellationToken )
45- {
46- return syntaxTree . GetRoot ( cancellationToken ) . FindToken ( position ) . GetAncestor < MemberDeclarationSyntax > ( ) ;
47- }
48-
49- protected override bool SupportsDocumentationComments ( MemberDeclarationSyntax member )
50- {
51- if ( member == null )
52- {
53- return false ;
54- }
55-
56- switch ( member . Kind ( ) )
57- {
58- case SyntaxKind . ClassDeclaration :
59- case SyntaxKind . InterfaceDeclaration :
60- case SyntaxKind . StructDeclaration :
61- case SyntaxKind . DelegateDeclaration :
62- case SyntaxKind . EnumDeclaration :
63- case SyntaxKind . EnumMemberDeclaration :
64- case SyntaxKind . FieldDeclaration :
65- case SyntaxKind . MethodDeclaration :
66- case SyntaxKind . ConstructorDeclaration :
67- case SyntaxKind . DestructorDeclaration :
68- case SyntaxKind . PropertyDeclaration :
69- case SyntaxKind . IndexerDeclaration :
70- case SyntaxKind . EventDeclaration :
71- case SyntaxKind . EventFieldDeclaration :
72- case SyntaxKind . OperatorDeclaration :
73- case SyntaxKind . ConversionOperatorDeclaration :
74- return true ;
75-
76- default :
77- return false ;
78- }
79- }
80-
81- protected override bool HasDocumentationComment ( MemberDeclarationSyntax member )
82- => member . GetFirstToken ( ) . LeadingTrivia . Any ( SyntaxKind . SingleLineDocumentationCommentTrivia , SyntaxKind . MultiLineDocumentationCommentTrivia ) ;
83-
84- protected override int GetPrecedingDocumentationCommentCount ( MemberDeclarationSyntax member )
85- {
86- var firstToken = member . GetFirstToken ( ) ;
87-
88- var count = firstToken . LeadingTrivia . Count ( t => t . IsDocComment ( ) ) ;
89-
90- var previousToken = firstToken . GetPreviousToken ( ) ;
91- if ( previousToken . Kind ( ) != SyntaxKind . None )
92- {
93- count += previousToken . TrailingTrivia . Count ( t => t . IsDocComment ( ) ) ;
94- }
95-
96- return count ;
97- }
98-
99- protected override bool IsMemberDeclaration ( MemberDeclarationSyntax member )
100- => true ;
101-
102- protected override List < string > GetDocumentationCommentStubLines ( MemberDeclarationSyntax member )
103- {
104- var list = new List < string >
105- {
106- "/// <summary>" ,
107- "/// " ,
108- "/// </summary>"
109- } ;
110-
111- var typeParameterList = member . GetTypeParameterList ( ) ;
112- if ( typeParameterList != null )
113- {
114- foreach ( var typeParam in typeParameterList . Parameters )
115- {
116- list . Add ( "/// <typeparam name=\" " + typeParam . Identifier . ValueText + "\" ></typeparam>" ) ;
117- }
118- }
119-
120- var parameterList = member . GetParameterList ( ) ;
121- if ( parameterList != null )
122- {
123- foreach ( var param in parameterList . Parameters )
124- {
125- list . Add ( "/// <param name=\" " + param . Identifier . ValueText + "\" ></param>" ) ;
126- }
127- }
128-
129- if ( member . IsKind ( SyntaxKind . MethodDeclaration ) ||
130- member . IsKind ( SyntaxKind . IndexerDeclaration ) ||
131- member . IsKind ( SyntaxKind . DelegateDeclaration ) ||
132- member . IsKind ( SyntaxKind . OperatorDeclaration ) )
133- {
134- var returnType = member . GetMemberType ( ) ;
135- if ( returnType != null &&
136- ! ( returnType . IsKind ( SyntaxKind . PredefinedType , out PredefinedTypeSyntax predefinedType ) && predefinedType . Keyword . IsKindOrHasMatchingText ( SyntaxKind . VoidKeyword ) ) )
137- {
138- list . Add ( "/// <returns></returns>" ) ;
139- }
140- }
141-
142- return list ;
143- }
144-
145- protected override SyntaxToken GetTokenToRight (
146- SyntaxTree syntaxTree , int position , CancellationToken cancellationToken )
147- {
148- if ( position >= syntaxTree . GetText ( cancellationToken ) . Length )
149- {
150- return default ;
151- }
152-
153- return syntaxTree . GetRoot ( cancellationToken ) . FindTokenOnRightOfPosition (
154- position , includeDirectives : true , includeDocumentationComments : true ) ;
155- }
156-
157- protected override SyntaxToken GetTokenToLeft (
158- SyntaxTree syntaxTree , int position , CancellationToken cancellationToken )
159- {
160- if ( position < 1 )
161- {
162- return default ;
163- }
164-
165- return syntaxTree . GetRoot ( cancellationToken ) . FindTokenOnLeftOfPosition (
166- position - 1 , includeDirectives : true , includeDocumentationComments : true , includeSkipped : true ) ;
167- }
168-
169- protected override bool IsDocCommentNewLine ( SyntaxToken token )
170- => token . RawKind == ( int ) SyntaxKind . XmlTextLiteralNewLineToken ;
171-
172- protected override bool IsEndOfLineTrivia ( SyntaxTrivia trivia )
173- => trivia . RawKind == ( int ) SyntaxKind . EndOfLineTrivia ;
174-
175- protected override bool IsSingleExteriorTrivia ( DocumentationCommentTriviaSyntax documentationComment , bool allowWhitespace = false )
176- {
177- if ( documentationComment == null )
178- {
179- return false ;
180- }
181-
182- if ( IsMultilineDocComment ( documentationComment ) )
183- {
184- return false ;
185- }
186-
187- if ( documentationComment . Content . Count != 1 )
188- {
189- return false ;
190- }
191-
192- if ( ! ( documentationComment . Content [ 0 ] is XmlTextSyntax xmlText ) )
193- {
194- return false ;
195- }
196-
197- var textTokens = xmlText . TextTokens ;
198- if ( ! textTokens . Any ( ) )
199- {
200- return false ;
201- }
202-
203- if ( ! allowWhitespace && textTokens . Count != 1 )
204- {
205- return false ;
206- }
207-
208- if ( textTokens . Any ( t => ! string . IsNullOrWhiteSpace ( t . ToString ( ) ) ) )
209- {
210- return false ;
211- }
212-
213- var lastTextToken = textTokens . Last ( ) ;
214- var firstTextToken = textTokens . First ( ) ;
215-
216- return lastTextToken . Kind ( ) == SyntaxKind . XmlTextLiteralNewLineToken
217- && firstTextToken . LeadingTrivia . Count == 1
218- && firstTextToken . LeadingTrivia . ElementAt ( 0 ) . Kind ( ) == SyntaxKind . DocumentationCommentExteriorTrivia
219- && firstTextToken . LeadingTrivia . ElementAt ( 0 ) . ToString ( ) == ExteriorTriviaText
220- && lastTextToken . TrailingTrivia . Count == 0 ;
221- }
222-
223- private static IList < SyntaxToken > GetTextTokensFollowingExteriorTrivia ( XmlTextSyntax xmlText )
224- {
225- var result = new List < SyntaxToken > ( ) ;
226-
227- var tokenList = xmlText . TextTokens ;
228- foreach ( var token in tokenList . Reverse ( ) )
229- {
230- result . Add ( token ) ;
231-
232- if ( token . LeadingTrivia . Any ( SyntaxKind . DocumentationCommentExteriorTrivia ) )
233- {
234- break ;
235- }
236- }
237-
238- result . Reverse ( ) ;
239-
240- return result ;
241- }
242-
243- protected override bool EndsWithSingleExteriorTrivia ( DocumentationCommentTriviaSyntax documentationComment )
244- {
245- if ( documentationComment == null )
246- {
247- return false ;
248- }
249-
250- if ( IsMultilineDocComment ( documentationComment ) )
251- {
252- return false ;
253- }
254-
255- if ( ! ( documentationComment . Content . LastOrDefault ( ) is XmlTextSyntax xmlText ) )
256- {
257- return false ;
258- }
259-
260- var textTokens = GetTextTokensFollowingExteriorTrivia ( xmlText ) ;
261-
262- if ( textTokens . Any ( t => ! string . IsNullOrWhiteSpace ( t . ToString ( ) ) ) )
263- {
264- return false ;
265- }
266-
267- var lastTextToken = textTokens . LastOrDefault ( ) ;
268- var firstTextToken = textTokens . FirstOrDefault ( ) ;
269-
270- return lastTextToken . Kind ( ) == SyntaxKind . XmlTextLiteralNewLineToken
271- && firstTextToken . LeadingTrivia . Count == 1
272- && firstTextToken . LeadingTrivia . ElementAt ( 0 ) . Kind ( ) == SyntaxKind . DocumentationCommentExteriorTrivia
273- && firstTextToken . LeadingTrivia . ElementAt ( 0 ) . ToString ( ) == ExteriorTriviaText
274- && lastTextToken . TrailingTrivia . Count == 0 ;
275- }
276-
277- protected override bool IsMultilineDocComment ( DocumentationCommentTriviaSyntax documentationComment )
278- => documentationComment . IsMultilineDocComment ( ) ;
279-
280- protected override bool AddIndent
281- {
282- get { return true ; }
283- }
284-
285- internal override bool HasSkippedTrailingTrivia ( SyntaxToken token ) => token . TrailingTrivia . Any ( t => t . Kind ( ) == SyntaxKind . SkippedTokensTrivia ) ;
28638 }
28739}
0 commit comments