@@ -28,14 +28,25 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
28
28
#endif
29
29
class AlignAssignmentStatement : ConfigurableRule
30
30
{
31
+ // We keep this switch even though the rule has only one switch (this) as of now, because we want
32
+ // to let the rule be expandable in the future to allow formatting assignments even
33
+ // in variable assignments. But for now we will stick to only one option.
34
+ /// <summary>
35
+ /// Check if key value pairs in a hashtable are aligned or not.
36
+ /// </summary>
37
+ /// <returns></returns>
38
+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
39
+ public bool CheckHashtable { get ; set ; }
40
+
31
41
private readonly char whitespaceChar = ' ' ;
32
42
33
43
private List < Func < TokenOperations , IEnumerable < DiagnosticRecord > > > violationFinders
34
44
= new List < Func < TokenOperations , IEnumerable < DiagnosticRecord > > > ( ) ;
35
45
36
- [ ConfigurableRuleProperty ( defaultValue : true ) ]
37
- public bool CheckHashtable { get ; set ; }
38
-
46
+ /// <summary>
47
+ /// Sets the configurable properties of this rule.
48
+ /// </summary>
49
+ /// <param name="paramValueMap">A dictionary that maps parameter name to it value. Must be non-null</param>
39
50
public override void ConfigureRule ( IDictionary < string , object > paramValueMap )
40
51
{
41
52
base . ConfigureRule ( paramValueMap ) ;
@@ -45,6 +56,92 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
45
56
}
46
57
}
47
58
59
+
60
+ /// <summary>
61
+ /// Analyzes the given ast to find if consecutive assignment statements are aligned.
62
+ /// </summary>
63
+ /// <param name="ast">AST to be analyzed. This should be non-null</param>
64
+ /// <param name="fileName">Name of file that corresponds to the input AST.</param>
65
+ /// <returns>A an enumerable type containing the violations</returns>
66
+ public override IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName )
67
+ {
68
+ if ( ast == null )
69
+ {
70
+ throw new ArgumentNullException ( "ast" ) ;
71
+ }
72
+ // only handles one line assignments
73
+ // if the rule encounters assignment statements that are multi-line, the rule will ignore that block
74
+
75
+ var tokenOps = new TokenOperations ( Helper . Instance . Tokens , ast ) ;
76
+ foreach ( var violationFinder in violationFinders )
77
+ {
78
+ foreach ( var diagnosticRecord in violationFinder ( tokenOps ) )
79
+ {
80
+ yield return diagnosticRecord ;
81
+ }
82
+ }
83
+ }
84
+
85
+ /// <summary>
86
+ /// Retrieves the common name of this rule.
87
+ /// </summary>
88
+ public override string GetCommonName ( )
89
+ {
90
+ return string . Format ( CultureInfo . CurrentCulture , Strings . AlignAssignmentStatementCommonName ) ;
91
+ }
92
+
93
+ /// <summary>
94
+ /// Retrieves the description of this rule.
95
+ /// </summary>
96
+ public override string GetDescription ( )
97
+ {
98
+ return string . Format ( CultureInfo . CurrentCulture , Strings . AlignAssignmentStatementDescription ) ;
99
+ }
100
+
101
+ /// <summary>
102
+ /// Retrieves the name of this rule.
103
+ /// </summary>
104
+ public override string GetName ( )
105
+ {
106
+ return string . Format (
107
+ CultureInfo . CurrentCulture ,
108
+ Strings . NameSpaceFormat ,
109
+ GetSourceName ( ) ,
110
+ Strings . AlignAssignmentStatementName ) ;
111
+ }
112
+
113
+ /// <summary>
114
+ /// Retrieves the severity of the rule: error, warning or information.
115
+ /// </summary>
116
+ public override RuleSeverity GetSeverity ( )
117
+ {
118
+ return RuleSeverity . Warning ;
119
+ }
120
+
121
+ /// <summary>
122
+ /// Gets the severity of the returned diagnostic record: error, warning, or information.
123
+ /// </summary>
124
+ /// <returns></returns>
125
+ public DiagnosticSeverity GetDiagnosticSeverity ( )
126
+ {
127
+ return DiagnosticSeverity . Warning ;
128
+ }
129
+
130
+ /// <summary>
131
+ /// Retrieves the name of the module/assembly the rule is from.
132
+ /// </summary>
133
+ public override string GetSourceName ( )
134
+ {
135
+ return string . Format ( CultureInfo . CurrentCulture , Strings . SourceName ) ;
136
+ }
137
+
138
+ /// <summary>
139
+ /// Retrieves the type of the rule, Builtin, Managed or Module.
140
+ /// </summary>
141
+ public override SourceType GetSourceType ( )
142
+ {
143
+ return SourceType . Builtin ;
144
+ }
48
145
private IEnumerable < DiagnosticRecord > FindHashtableViolations ( TokenOperations tokenOps )
49
146
{
50
147
var hashtableAsts = tokenOps . Ast . FindAll ( ast => ast is HashtableAst , true ) ;
@@ -54,19 +151,17 @@ private IEnumerable<DiagnosticRecord> FindHashtableViolations(TokenOperations to
54
151
}
55
152
56
153
// it is probably much easier have a hashtable writer that formats the hashtable and writes it
57
- // but it my make handling comments hard. So we need to use this approach.
154
+ // but it makes handling comments hard. So we need to use this approach.
58
155
59
- // check if each key is on a separate line
60
- // align only if each key=val pair is on a separate line
61
- // if each pair on a separate line
156
+ // This is how the algorithm actually works:
157
+ // if each key value pair are on a separate line
62
158
// find all the assignment operators
63
159
// if all the assignment operators are aligned (check the column number of each alignment operator)
64
160
// skip
65
161
// else
66
- // find the distance between the assignment operaters its left expression
162
+ // find the distance between the assignment operators and their corresponding LHS
67
163
// find the longest left expression
68
164
// make sure all the assignment operators are in the same column as that of the longest left hand.
69
- // else
70
165
71
166
var alignments = new List < int > ( ) ;
72
167
foreach ( var astItem in hashtableAsts )
@@ -173,91 +268,5 @@ private bool HasKeysOnSeparateLines(HashtableAst hashtableAst)
173
268
174
269
return true ;
175
270
}
176
-
177
- /// <summary>
178
- /// Analyzes the given ast to find if consecutive assignment statements are aligned.
179
- /// </summary>
180
- /// <param name="ast">AST to be analyzed. This should be non-null</param>
181
- /// <param name="fileName">Name of file that corresponds to the input AST.</param>
182
- /// <returns>A an enumerable type containing the violations</returns>
183
- public override IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName )
184
- {
185
- if ( ast == null )
186
- {
187
- throw new ArgumentNullException ( "ast" ) ;
188
- }
189
- // only handles one line assignments
190
- // if the rule encounters assignment statements that are multi-line, the rule will ignore that block
191
-
192
- var tokenOps = new TokenOperations ( Helper . Instance . Tokens , ast ) ;
193
- foreach ( var violationFinder in violationFinders )
194
- {
195
- foreach ( var diagnosticRecord in violationFinder ( tokenOps ) )
196
- {
197
- yield return diagnosticRecord ;
198
- }
199
- }
200
- }
201
-
202
- /// <summary>
203
- /// Retrieves the common name of this rule.
204
- /// </summary>
205
- public override string GetCommonName ( )
206
- {
207
- return string . Format ( CultureInfo . CurrentCulture , Strings . AlignAssignmentStatementCommonName ) ;
208
- }
209
-
210
- /// <summary>
211
- /// Retrieves the description of this rule.
212
- /// </summary>
213
- public override string GetDescription ( )
214
- {
215
- return string . Format ( CultureInfo . CurrentCulture , Strings . AlignAssignmentStatementDescription ) ;
216
- }
217
-
218
- /// <summary>
219
- /// Retrieves the name of this rule.
220
- /// </summary>
221
- public override string GetName ( )
222
- {
223
- return string . Format (
224
- CultureInfo . CurrentCulture ,
225
- Strings . NameSpaceFormat ,
226
- GetSourceName ( ) ,
227
- Strings . AlignAssignmentStatementName ) ;
228
- }
229
-
230
- /// <summary>
231
- /// Retrieves the severity of the rule: error, warning or information.
232
- /// </summary>
233
- public override RuleSeverity GetSeverity ( )
234
- {
235
- return RuleSeverity . Warning ;
236
- }
237
-
238
- /// <summary>
239
- /// Gets the severity of the returned diagnostic record: error, warning, or information.
240
- /// </summary>
241
- /// <returns></returns>
242
- public DiagnosticSeverity GetDiagnosticSeverity ( )
243
- {
244
- return DiagnosticSeverity . Warning ;
245
- }
246
-
247
- /// <summary>
248
- /// Retrieves the name of the module/assembly the rule is from.
249
- /// </summary>
250
- public override string GetSourceName ( )
251
- {
252
- return string . Format ( CultureInfo . CurrentCulture , Strings . SourceName ) ;
253
- }
254
-
255
- /// <summary>
256
- /// Retrieves the type of the rule, Builtin, Managed or Module.
257
- /// </summary>
258
- public override SourceType GetSourceType ( )
259
- {
260
- return SourceType . Builtin ;
261
- }
262
271
}
263
272
}
0 commit comments