@@ -23,7 +23,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
23
23
/// <summary>
24
24
/// A class to walk an AST to check if consecutive assignment statements are aligned.
25
25
/// </summary>
26
- #if ! CORECLR
26
+ #if ! CORECLR
27
27
[ Export ( typeof ( IScriptRule ) ) ]
28
28
#endif
29
29
class AlignAssignmentStatement : ConfigurableRule
@@ -32,10 +32,10 @@ class AlignAssignmentStatement : ConfigurableRule
32
32
private List < Func < TokenOperations , IEnumerable < DiagnosticRecord > > > violationFinders
33
33
= new List < Func < TokenOperations , IEnumerable < DiagnosticRecord > > > ( ) ;
34
34
35
- [ ConfigurableRuleProperty ( defaultValue : true ) ]
35
+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
36
36
public bool CheckHashtable { get ; set ; }
37
37
38
- [ ConfigurableRuleProperty ( defaultValue : true ) ]
38
+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
39
39
public bool CheckDSCConfiguration { get ; set ; }
40
40
41
41
public override void ConfigureRule ( IDictionary < string , object > paramValueMap )
@@ -54,7 +54,7 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
54
54
55
55
private IEnumerable < DiagnosticRecord > FindDSCConfigurationViolations ( TokenOperations arg )
56
56
{
57
- throw new NotImplementedException ( ) ;
57
+ yield break ;
58
58
}
59
59
60
60
private IEnumerable < DiagnosticRecord > FindHashtableViolations ( TokenOperations tokenOps )
@@ -90,23 +90,52 @@ private IEnumerable<DiagnosticRecord> FindHashtableViolations(TokenOperations to
90
90
}
91
91
92
92
var nodeTuples = GetExtents ( tokenOps , hashtableAst ) ;
93
- if ( nodeTuples == null )
93
+ if ( nodeTuples == null
94
+ || ! nodeTuples . All ( t => t . Item1 . StartLineNumber == t . Item2 . EndLineNumber ) )
94
95
{
95
96
continue ;
96
97
}
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
+ }
97
121
}
98
122
}
99
123
124
+ private string GetError ( )
125
+ {
126
+ return String . Format ( CultureInfo . CurrentCulture , Strings . AlignAssignmentStatementError ) ;
127
+ }
128
+
100
129
private static IList < Tuple < IScriptExtent , IScriptExtent > > GetExtents (
101
130
TokenOperations tokenOps ,
102
131
HashtableAst hashtableAst )
103
132
{
104
133
var nodeTuples = new List < Tuple < IScriptExtent , IScriptExtent > > ( ) ;
105
134
foreach ( var kvp in hashtableAst . KeyValuePairs )
106
135
{
107
- var keyStartPos = kvp . Item1 . Extent . StartScriptPosition ;
136
+ var keyStartOffset = kvp . Item1 . Extent . StartOffset ;
108
137
var keyTokenNode = tokenOps . GetTokenNodes (
109
- token => token . Extent . StartScriptPosition == keyStartPos ) . FirstOrDefault ( ) ;
138
+ token => token . Extent . StartOffset == keyStartOffset ) . FirstOrDefault ( ) ;
110
139
if ( keyTokenNode == null
111
140
|| keyTokenNode . Next == null
112
141
|| keyTokenNode . Next . Value . Kind != TokenKind . Equals )
@@ -115,8 +144,8 @@ private static IList<Tuple<IScriptExtent, IScriptExtent>> GetExtents(
115
144
}
116
145
117
146
nodeTuples . Add ( new Tuple < IScriptExtent , IScriptExtent > (
118
- keyTokenNode . Next . Value . Extent ,
119
- kvp . Item1 . Extent ) ) ;
147
+ kvp . Item1 . Extent ,
148
+ keyTokenNode . Next . Value . Extent ) ) ;
120
149
}
121
150
122
151
return nodeTuples ;
@@ -155,10 +184,14 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
155
184
// only handles one line assignments
156
185
// if the rule encounters assignment statements that are multi-line, the rule will ignore that block
157
186
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
+ }
162
195
}
163
196
164
197
/// <summary>
0 commit comments