Skip to content

Commit 4ed08e6

Browse files
author
Kapil Borle
committed
Add logic to detect alignment violation in hashtable
1 parent e89d5cb commit 4ed08e6

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

Rules/AlignAssignmentStatement.cs

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
2323
/// <summary>
2424
/// A class to walk an AST to check if consecutive assignment statements are aligned.
2525
/// </summary>
26-
#if !CORECLR
26+
#if !CORECLR
2727
[Export(typeof(IScriptRule))]
2828
#endif
2929
class AlignAssignmentStatement : ConfigurableRule
@@ -32,10 +32,10 @@ class AlignAssignmentStatement : ConfigurableRule
3232
private List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>> violationFinders
3333
= new List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>>();
3434

35-
[ConfigurableRuleProperty(defaultValue:true)]
35+
[ConfigurableRuleProperty(defaultValue: true)]
3636
public bool CheckHashtable { get; set; }
3737

38-
[ConfigurableRuleProperty(defaultValue:true)]
38+
[ConfigurableRuleProperty(defaultValue: true)]
3939
public bool CheckDSCConfiguration { get; set; }
4040

4141
public override void ConfigureRule(IDictionary<string, object> paramValueMap)
@@ -54,7 +54,7 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
5454

5555
private IEnumerable<DiagnosticRecord> FindDSCConfigurationViolations(TokenOperations arg)
5656
{
57-
throw new NotImplementedException();
57+
yield break;
5858
}
5959

6060
private IEnumerable<DiagnosticRecord> FindHashtableViolations(TokenOperations tokenOps)
@@ -90,23 +90,52 @@ private IEnumerable<DiagnosticRecord> FindHashtableViolations(TokenOperations to
9090
}
9191

9292
var nodeTuples = GetExtents(tokenOps, hashtableAst);
93-
if (nodeTuples == null)
93+
if (nodeTuples == null
94+
|| !nodeTuples.All(t => t.Item1.StartLineNumber == t.Item2.EndLineNumber))
9495
{
9596
continue;
9697
}
98+
99+
var widestKeyExtent = nodeTuples
100+
.Select(t => t.Item1)
101+
.Aggregate((t1, tAggregate) => {
102+
return TokenOperations.GetExtentWidth(tAggregate) > TokenOperations.GetExtentWidth(t1)
103+
? tAggregate
104+
: t1;
105+
});
106+
var expectedStartColumn = widestKeyExtent.EndColumnNumber + 1;
107+
foreach (var extentTuple in nodeTuples)
108+
{
109+
if (extentTuple.Item2.StartColumnNumber != expectedStartColumn)
110+
{
111+
yield return new DiagnosticRecord(
112+
GetError(),
113+
extentTuple.Item2,
114+
GetName(),
115+
GetDiagnosticSeverity(),
116+
extentTuple.Item1.File,
117+
null,
118+
null);
119+
}
120+
}
97121
}
98122
}
99123

124+
private string GetError()
125+
{
126+
return String.Format(CultureInfo.CurrentCulture, Strings.AlignAssignmentStatementError);
127+
}
128+
100129
private static IList<Tuple<IScriptExtent, IScriptExtent>> GetExtents(
101130
TokenOperations tokenOps,
102131
HashtableAst hashtableAst)
103132
{
104133
var nodeTuples = new List<Tuple<IScriptExtent, IScriptExtent>>();
105134
foreach (var kvp in hashtableAst.KeyValuePairs)
106135
{
107-
var keyStartPos = kvp.Item1.Extent.StartScriptPosition;
136+
var keyStartOffset = kvp.Item1.Extent.StartOffset;
108137
var keyTokenNode = tokenOps.GetTokenNodes(
109-
token => token.Extent.StartScriptPosition == keyStartPos).FirstOrDefault();
138+
token => token.Extent.StartOffset == keyStartOffset).FirstOrDefault();
110139
if (keyTokenNode == null
111140
|| keyTokenNode.Next == null
112141
|| keyTokenNode.Next.Value.Kind != TokenKind.Equals)
@@ -115,8 +144,8 @@ private static IList<Tuple<IScriptExtent, IScriptExtent>> GetExtents(
115144
}
116145

117146
nodeTuples.Add(new Tuple<IScriptExtent, IScriptExtent>(
118-
keyTokenNode.Next.Value.Extent,
119-
kvp.Item1.Extent));
147+
kvp.Item1.Extent,
148+
keyTokenNode.Next.Value.Extent));
120149
}
121150

122151
return nodeTuples;
@@ -155,10 +184,14 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
155184
// only handles one line assignments
156185
// if the rule encounters assignment statements that are multi-line, the rule will ignore that block
157186

158-
159-
160-
// your code goes here
161-
yield break;
187+
var tokenOps = new TokenOperations(Helper.Instance.Tokens, ast);
188+
foreach (var violationFinder in violationFinders)
189+
{
190+
foreach (var diagnosticRecord in violationFinder(tokenOps))
191+
{
192+
yield return diagnosticRecord;
193+
}
194+
}
162195
}
163196

164197
/// <summary>

0 commit comments

Comments
 (0)