Skip to content

Commit 2f88672

Browse files
author
Kapil Borle
committed
Add incremental edits to correction extent
1 parent 5988f3d commit 2f88672

1 file changed

Lines changed: 93 additions & 3 deletions

File tree

rules/UseSupportsShouldProcess.cs

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// THE SOFTWARE.
1010

1111
using System;
12+
using System.Linq;
1213
using System.Collections.Generic;
1314
#if !CORECLR
1415
using System.ComponentModel.Composition;
@@ -138,26 +139,55 @@ private List<CorrectionExtent> GetCorrections(
138139
var filePath = funcDefnAst.Extent.File;
139140
var correctionExtents = new List<CorrectionExtent>();
140141

141-
// replace whatif/confirm extent starting with the first character ending with the first character of
142+
// TODO Handle case where only one param is left after correction and there is a
143+
// comma left after the param.
144+
145+
var editableText = new EditableText(funcDefnAst.Extent.Text);
146+
// replace whatif/confirm extent starting with the last character of the previous parameter and ending with the last character of the whatif/confirm/parameter. This will take care of the trailing comma.
142147
// the next parameter
148+
// TODO Do not incrementally correct the text as it may lead to a situation in which a following
149+
// edits might try to modify edits that have already taken place.
150+
// A better approach is to gather all the edits and give them to the text edit class to handle.
143151
if (whatIfIndex != -1)
144152
{
145153
correctionExtents.Add(GetCorrectionExtent(whatIfIndex, parameterAsts));
154+
var shiftedCorrectionExtent = Normalize(funcDefnAst.Extent, correctionExtents.Last());
155+
editableText = editableText.ApplyEdit(shiftedCorrectionExtent);
146156
}
147157

148158
if (confirmIndex != -1)
149159
{
150160
correctionExtents.Add(GetCorrectionExtent(confirmIndex, parameterAsts));
161+
var shiftedCorrectionExtent = Normalize(funcDefnAst.Extent, correctionExtents.Last());
162+
editableText = editableText.ApplyEdit(shiftedCorrectionExtent);
151163
}
152164

153165
if (paramBlockAst != null)
154166
{
155-
167+
AttributeAst attributeAst;
168+
// check if it has cmdletbinding attribute
169+
if (TryGetCmdletBindingAttribute(paramBlockAst, out attributeAst))
170+
{
171+
if (!attributeAst.NamedArguments.Any(
172+
x => x.ArgumentName.Equals("supportsshouldprocess",
173+
StringComparison.OrdinalIgnoreCase)))
174+
{
175+
// add supportsshouldprocess to the attribute
176+
correctionExtents.Add(GetCorrectionExtent(attributeAst));
177+
}
178+
}
179+
else
180+
{
181+
// has no cmdletbinding attribute
182+
// add the attribute and supportsshouldprocess argument
183+
}
156184
}
157185
else
158186
{
159187
// function doesn't have param block
160-
// replace
188+
// remove the parameter list
189+
// and create an equivalent param block
190+
// add cmdletbinding attribute and add supportsshouldprocess to it.
161191
}
162192

163193
// This is how we handle multiple edits.
@@ -167,6 +197,66 @@ private List<CorrectionExtent> GetCorrections(
167197
return correctionExtents;
168198
}
169199

200+
// doesn't seem right. The arguments should be of same type.
201+
private CorrectionExtent Normalize(IScriptExtent referenceExtent, CorrectionExtent cextent)
202+
{
203+
// TODO Add ToRange extension methods for this conversion
204+
var refRange = new Range(
205+
referenceExtent.StartLineNumber,
206+
referenceExtent.StartColumnNumber,
207+
referenceExtent.EndLineNumber,
208+
referenceExtent.EndColumnNumber);
209+
210+
var range = new Range(
211+
cextent.StartLineNumber,
212+
cextent.StartColumnNumber,
213+
cextent.EndLineNumber,
214+
cextent.EndColumnNumber);
215+
216+
var shiftedRange = Range.Normalize(refRange, range);
217+
218+
// TODO Add a method to TextEdit class that takes in range and text
219+
// TODO Add a method to CorrectionExtent that takes in range and all other stuff
220+
return new CorrectionExtent(
221+
shiftedRange.Start.Line,
222+
shiftedRange.End.Line,
223+
shiftedRange.Start.Column,
224+
shiftedRange.End.Column,
225+
cextent.Text,
226+
cextent.File,
227+
cextent.Description);
228+
}
229+
private static bool TryGetCmdletBindingAttribute(
230+
ParamBlockAst paramBlockAst,
231+
out AttributeAst attributeAst)
232+
{
233+
attributeAst = paramBlockAst.Attributes.FirstOrDefault(attr =>
234+
{
235+
return attr.TypeName.Name.Equals("cmdletbinding", StringComparison.OrdinalIgnoreCase);
236+
});
237+
238+
return attributeAst != null;
239+
}
240+
241+
242+
private static CorrectionExtent GetCorrectionExtent(AttributeAst cmdletBindingAttributeAst)
243+
{
244+
// 1 for 1 based offset and 1 for the next position.
245+
var startColumnNumber = cmdletBindingAttributeAst.Extent.Text.IndexOf("(") + 2;
246+
var extent = cmdletBindingAttributeAst.Extent;
247+
var suffix = cmdletBindingAttributeAst.NamedArguments.Count > 0
248+
|| cmdletBindingAttributeAst.PositionalArguments.Count > 0
249+
? ", "
250+
: "";
251+
return new CorrectionExtent(
252+
extent.StartLineNumber,
253+
extent.StartLineNumber,
254+
startColumnNumber,
255+
startColumnNumber,
256+
"SupportsShouldProcess" + suffix,
257+
extent.File);
258+
}
259+
170260
private static CorrectionExtent GetCorrectionExtent(
171261
int paramIndex,
172262
ParameterAst[] parameterAsts)

0 commit comments

Comments
 (0)