2020#endif
2121using System . Globalization ;
2222using System . Management . Automation ;
23+ using System . Text ;
2324
2425namespace Microsoft . Windows . PowerShell . ScriptAnalyzer . BuiltinRules
2526{
2627 /// <summary>
2728 /// ProvideCommentHelp: Analyzes ast to check that cmdlets have help.
2829 /// </summary>
2930#if ! CORECLR
30- [ Export ( typeof ( IScriptRule ) ) ]
31+ [ Export ( typeof ( IScriptRule ) ) ]
3132#endif
3233 public class ProvideCommentHelp : SkipTypeDefinition , IScriptRule
3334 {
@@ -39,7 +40,8 @@ public class ProvideCommentHelp : SkipTypeDefinition, IScriptRule
3940 /// <param name="ast">The script's ast</param>
4041 /// <param name="fileName">The name of the script</param>
4142 /// <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+ {
4345 if ( ast == null ) throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
4446
4547 DiagnosticRecords . Clear ( ) ;
@@ -67,13 +69,18 @@ public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst fun
6769 {
6870 if ( funcAst . GetHelpContent ( ) == null )
6971 {
72+ // todo create auto correction
73+ // todo add option to add help for non exported members
74+ // todo add option to set help location
7075 DiagnosticRecords . Add (
7176 new DiagnosticRecord (
7277 string . Format ( CultureInfo . CurrentCulture , Strings . ProvideCommentHelpError , funcAst . Name ) ,
7378 Helper . Instance . GetScriptExtentForFunctionName ( funcAst ) ,
7479 GetName ( ) ,
7580 DiagnosticSeverity . Information ,
76- fileName ) ) ;
81+ fileName ,
82+ null ,
83+ GetCorrection ( funcAst ) . ToList ( ) ) ) ;
7784 }
7885 }
7986
@@ -102,7 +109,8 @@ public string GetCommonName()
102109 /// GetDescription: Retrieves the description of this rule.
103110 /// </summary>
104111 /// <returns>The description of this rule</returns>
105- public string GetDescription ( ) {
112+ public string GetDescription ( )
113+ {
106114 return string . Format ( CultureInfo . CurrentCulture , Strings . ProvideCommentHelpDescription ) ;
107115 }
108116
@@ -130,6 +138,122 @@ public string GetSourceName()
130138 {
131139 return string . Format ( CultureInfo . CurrentCulture , Strings . SourceName ) ;
132140 }
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+ }
133257 }
134258}
135259
0 commit comments