20
20
#endif
21
21
using System . Globalization ;
22
22
using System . Management . Automation ;
23
+ using System . Text ;
23
24
24
25
namespace Microsoft . Windows . PowerShell . ScriptAnalyzer . BuiltinRules
25
26
{
26
27
/// <summary>
27
28
/// ProvideCommentHelp: Analyzes ast to check that cmdlets have help.
28
29
/// </summary>
29
30
#if ! CORECLR
30
- [ Export ( typeof ( IScriptRule ) ) ]
31
+ [ Export ( typeof ( IScriptRule ) ) ]
31
32
#endif
32
33
public class ProvideCommentHelp : SkipTypeDefinition , IScriptRule
33
34
{
@@ -39,7 +40,8 @@ public class ProvideCommentHelp : SkipTypeDefinition, IScriptRule
39
40
/// <param name="ast">The script's ast</param>
40
41
/// <param name="fileName">The name of the script</param>
41
42
/// <returns>A List of diagnostic results of this rule</returns>
42
- public IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName ) {
43
+ public IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName )
44
+ {
43
45
if ( ast == null ) throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
44
46
45
47
DiagnosticRecords . Clear ( ) ;
@@ -67,13 +69,18 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
67
69
{
68
70
if ( funcAst . GetHelpContent ( ) == null )
69
71
{
72
+ // todo create auto correction
73
+ // todo add option to add help for non exported members
74
+ // todo add option to set help location
70
75
DiagnosticRecords . Add (
71
76
new DiagnosticRecord (
72
77
string . Format ( CultureInfo . CurrentCulture , Strings . ProvideCommentHelpError , funcAst . Name ) ,
73
78
Helper . Instance . GetScriptExtentForFunctionName ( funcAst ) ,
74
79
GetName ( ) ,
75
80
DiagnosticSeverity . Information ,
76
- fileName ) ) ;
81
+ fileName ,
82
+ null ,
83
+ GetCorrection ( funcAst ) . ToList ( ) ) ) ;
77
84
}
78
85
}
79
86
@@ -102,7 +109,8 @@ public string GetCommonName()
102
109
/// GetDescription: Retrieves the description of this rule.
103
110
/// </summary>
104
111
/// <returns>The description of this rule</returns>
105
- public string GetDescription ( ) {
112
+ public string GetDescription ( )
113
+ {
106
114
return string . Format ( CultureInfo . CurrentCulture , Strings . ProvideCommentHelpDescription ) ;
107
115
}
108
116
@@ -130,6 +138,122 @@ public string GetSourceName()
130
138
{
131
139
return string . Format ( CultureInfo . CurrentCulture , Strings . SourceName ) ;
132
140
}
141
+
142
+ private IEnumerable < CorrectionExtent > GetCorrection ( FunctionDefinitionAst funcDefnAst )
143
+ {
144
+ var helpBuilder = new CommentHelpBuilder ( ) ;
145
+
146
+ // todo replace with an extension version
147
+ var paramAsts = ( funcDefnAst . Parameters ?? funcDefnAst . Body . ParamBlock ? . Parameters )
148
+ ?? Enumerable . Empty < ParameterAst > ( ) ;
149
+ foreach ( var paramAst in paramAsts )
150
+ {
151
+ helpBuilder . AddParameter ( paramAst . Name . VariablePath . UserPath ) ;
152
+ }
153
+
154
+ var correctionExtents = new List < CorrectionExtent > ( ) ;
155
+ yield return new CorrectionExtent (
156
+ funcDefnAst . Extent . StartLineNumber ,
157
+ funcDefnAst . Extent . StartLineNumber ,
158
+ funcDefnAst . Extent . StartColumnNumber ,
159
+ funcDefnAst . Extent . StartColumnNumber ,
160
+ helpBuilder . GetCommentHelp ( ) ,
161
+ funcDefnAst . Extent . File ) ;
162
+ }
163
+
164
+ private class CommentHelpBuilder
165
+ {
166
+ private CommentHelpNode synopsis ;
167
+ private CommentHelpNode description ;
168
+ private List < CommentHelpNode > parameters ;
169
+ private CommentHelpNode example ;
170
+ private CommentHelpNode notes ;
171
+
172
+ public CommentHelpBuilder ( )
173
+ {
174
+ synopsis = new CommentHelpNode ( "Synopsis" , "Short description" ) ;
175
+ description = new CommentHelpNode ( "Description" , "Long description" ) ;
176
+ example = new CommentHelpNode ( "Example" , "An example" ) ;
177
+ parameters = new List < CommentHelpNode > ( ) ;
178
+ notes = new CommentHelpNode ( "Notes" , "General notes" ) ;
179
+ }
180
+
181
+ public void AddParameter ( string paramName )
182
+ {
183
+ parameters . Add ( new ParameterHelpNode ( paramName , "Parameter description" ) ) ;
184
+ }
185
+
186
+ // todo add option for comment type
187
+ public string GetCommentHelp ( )
188
+ {
189
+ var sb = new StringBuilder ( ) ;
190
+ sb . AppendLine ( "<#" ) ;
191
+ sb . AppendLine ( this . ToString ( ) ) ;
192
+ sb . Append ( "#>" ) ;
193
+ return sb . ToString ( ) ;
194
+ }
195
+
196
+ public override string ToString ( )
197
+ {
198
+ var sb = new StringBuilder ( ) ;
199
+ sb . AppendLine ( synopsis . ToString ( ) ) . AppendLine ( ) ;
200
+ sb . AppendLine ( description . ToString ( ) ) . AppendLine ( ) ;
201
+ foreach ( var parameter in parameters )
202
+ {
203
+ sb . AppendLine ( parameter . ToString ( ) ) . AppendLine ( ) ;
204
+ }
205
+
206
+ sb . AppendLine ( example . ToString ( ) ) . AppendLine ( ) ;
207
+ sb . Append ( notes . ToString ( ) ) ;
208
+ return sb . ToString ( ) ;
209
+ }
210
+ private class CommentHelpNode
211
+ {
212
+ public CommentHelpNode ( string nodeName , string description )
213
+ {
214
+ Name = nodeName ;
215
+ Description = description ;
216
+ }
217
+
218
+ public string Name { get ; }
219
+ public string Description { get ; set ; }
220
+
221
+ public override string ToString ( )
222
+ {
223
+ var sb = new StringBuilder ( ) ;
224
+ sb . Append ( "." ) . AppendLine ( Name . ToUpper ( ) ) ;
225
+ if ( ! String . IsNullOrWhiteSpace ( Description ) )
226
+ {
227
+ sb . Append ( Description ) ;
228
+ }
229
+
230
+ return sb . ToString ( ) ;
231
+ }
232
+ }
233
+
234
+ private class ParameterHelpNode : CommentHelpNode
235
+ {
236
+ public ParameterHelpNode ( string parameterName , string parameterDescription )
237
+ : base ( "Parameter" , parameterDescription )
238
+ {
239
+ ParameterName = parameterName ;
240
+ }
241
+
242
+ public string ParameterName { get ; }
243
+
244
+ public override string ToString ( )
245
+ {
246
+ var sb = new StringBuilder ( ) ;
247
+ sb . Append ( "." ) . Append ( Name . ToUpper ( ) ) . Append ( " " ) . AppendLine ( ParameterName ) ;
248
+ if ( ! String . IsNullOrWhiteSpace ( Description ) )
249
+ {
250
+ sb . Append ( Description ) ;
251
+ }
252
+
253
+ return sb . ToString ( ) ;
254
+ }
255
+ }
256
+ }
133
257
}
134
258
}
135
259
0 commit comments