Skip to content

Commit 17c7310

Browse files
author
Kapil Borle
committed
Add corrections to get comment help snippet
1 parent 950e5f2 commit 17c7310

File tree

1 file changed

+128
-4
lines changed

1 file changed

+128
-4
lines changed

Rules/ProvideCommentHelp.cs

Lines changed: 128 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
#endif
2121
using System.Globalization;
2222
using System.Management.Automation;
23+
using System.Text;
2324

2425
namespace 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

Comments
 (0)