@@ -40,6 +40,7 @@ public sealed class ScriptAnalyzer
4040 #region Private members
4141
4242 private IOutputWriter outputWriter ;
43+ private Dictionary < string , object > settings ;
4344#if ! CORECLR
4445 private CompositionContainer container ;
4546#endif // !CORECLR
@@ -87,13 +88,10 @@ public static ScriptAnalyzer Instance
8788#else
8889 [ ImportMany ]
8990 public IEnumerable < IScriptRule > ScriptRules { get ; private set ; }
90-
9191 [ ImportMany ]
9292 public IEnumerable < ITokenRule > TokenRules { get ; private set ; }
93-
9493 [ ImportMany ]
9594 public IEnumerable < ILogger > Loggers { get ; private set ; }
96-
9795 [ ImportMany ]
9896 public IEnumerable < IDSCResourceRule > DSCResourceRules { get ; private set ; }
9997 // Initializes via ImportMany
@@ -273,6 +271,135 @@ private bool AddProfileItem(
273271 return true ;
274272 }
275273
274+ private Dictionary < string , object > GetDictionaryFromHashTableAst (
275+ HashtableAst hashTableAst ,
276+ IOutputWriter writer ,
277+ string profile ,
278+ out bool hasError )
279+ {
280+ hasError = false ;
281+ var output = new Dictionary < string , object > ( StringComparer . OrdinalIgnoreCase ) ;
282+ foreach ( var kvp in hashTableAst . KeyValuePairs )
283+ {
284+ var keyAst = kvp . Item1 as StringConstantExpressionAst ;
285+ if ( keyAst == null )
286+ {
287+ // first item (the key) should be a string
288+ writer . WriteError (
289+ new ErrorRecord (
290+ new InvalidDataException (
291+ string . Format (
292+ CultureInfo . CurrentCulture ,
293+ Strings . WrongKeyFormat ,
294+ kvp . Item1 . Extent . StartLineNumber ,
295+ kvp . Item1 . Extent . StartColumnNumber ,
296+ profile ) ) ,
297+ Strings . ConfigurationKeyNotAString ,
298+ ErrorCategory . InvalidData ,
299+ profile ) ) ;
300+ hasError = true ;
301+ continue ;
302+ }
303+ var key = keyAst . Value ;
304+ // parse the item2 as array
305+ PipelineAst pipeAst = kvp . Item2 as PipelineAst ;
306+ List < string > rhsList = new List < string > ( ) ;
307+ if ( pipeAst != null )
308+ {
309+ ExpressionAst pureExp = pipeAst . GetPureExpression ( ) ;
310+ if ( pureExp is StringConstantExpressionAst )
311+ {
312+ rhsList . Add ( ( pureExp as StringConstantExpressionAst ) . Value ) ;
313+ }
314+ else if ( pureExp is HashtableAst )
315+ {
316+ output [ key ] = GetDictionaryFromHashTableAst (
317+ pureExp as HashtableAst ,
318+ writer ,
319+ profile ,
320+ out hasError ) ;
321+ continue ;
322+ }
323+ else
324+ {
325+ ArrayLiteralAst arrayLitAst = pureExp as ArrayLiteralAst ;
326+ if ( arrayLitAst == null && pureExp is ArrayExpressionAst )
327+ {
328+ ArrayExpressionAst arrayExp = pureExp as ArrayExpressionAst ;
329+ // Statements property is never null
330+ if ( arrayExp . SubExpression != null )
331+ {
332+ StatementAst stateAst = arrayExp . SubExpression . Statements . FirstOrDefault ( ) ;
333+ if ( stateAst != null && stateAst is PipelineAst )
334+ {
335+ CommandBaseAst cmdBaseAst = ( stateAst as PipelineAst ) . PipelineElements . FirstOrDefault ( ) ;
336+ if ( cmdBaseAst != null && cmdBaseAst is CommandExpressionAst )
337+ {
338+ CommandExpressionAst cmdExpAst = cmdBaseAst as CommandExpressionAst ;
339+ if ( cmdExpAst . Expression is StringConstantExpressionAst )
340+ {
341+ rhsList . Add ( ( cmdExpAst . Expression as StringConstantExpressionAst ) . Value ) ;
342+ }
343+ else
344+ {
345+ arrayLitAst = cmdExpAst . Expression as ArrayLiteralAst ;
346+ }
347+ }
348+ }
349+ }
350+ }
351+
352+ if ( arrayLitAst != null )
353+ {
354+ foreach ( var element in arrayLitAst . Elements )
355+ {
356+ // all the values in the array needs to be string
357+ if ( ! ( element is StringConstantExpressionAst ) )
358+ {
359+ outputWriter . WriteError (
360+ new ErrorRecord (
361+ new InvalidDataException (
362+ string . Format (
363+ CultureInfo . CurrentCulture ,
364+ Strings . WrongValueFormat ,
365+ element . Extent . StartLineNumber ,
366+ element . Extent . StartColumnNumber ,
367+ "" ) ) ,
368+ Strings . ConfigurationValueNotAString ,
369+ ErrorCategory . InvalidData ,
370+ null ) ) ;
371+ hasError = true ;
372+ continue ;
373+ }
374+
375+ rhsList . Add ( ( element as StringConstantExpressionAst ) . Value ) ;
376+ }
377+ }
378+ }
379+ }
380+
381+ if ( rhsList . Count == 0 )
382+ {
383+ writer . WriteError (
384+ new ErrorRecord (
385+ new InvalidDataException (
386+ string . Format (
387+ CultureInfo . CurrentCulture ,
388+ Strings . WrongValueFormat ,
389+ kvp . Item2 . Extent . StartLineNumber ,
390+ kvp . Item2 . Extent . StartColumnNumber ,
391+ profile ) ) ,
392+ Strings . ConfigurationValueWrongFormat ,
393+ ErrorCategory . InvalidData ,
394+ profile ) ) ;
395+ hasError = true ;
396+ continue ;
397+ }
398+ output [ key ] = rhsList ;
399+ }
400+ return output ;
401+ }
402+
276403 private bool ParseProfileHashtable ( Hashtable profile , PathIntrinsics path , IOutputWriter writer ,
277404 List < string > severityList , List < string > includeRuleList , List < string > excludeRuleList )
278405 {
@@ -319,7 +446,6 @@ private bool ParseProfileHashtable(Hashtable profile, PathIntrinsics path, IOutp
319446 }
320447
321448 // if we get here then everything is good
322-
323449 List < string > values = new List < string > ( ) ;
324450
325451 if ( value is string )
@@ -390,91 +516,31 @@ private bool ParseProfileString(string profile, PathIntrinsics path, IOutputWrit
390516 else
391517 {
392518 HashtableAst hashTableAst = hashTableAsts . First ( ) as HashtableAst ;
393-
394- foreach ( var kvp in hashTableAst . KeyValuePairs )
519+ settings = GetDictionaryFromHashTableAst (
520+ hashTableAst ,
521+ writer ,
522+ profile ,
523+ out hasError ) ;
524+ foreach ( var key in settings . Keys )
395525 {
396- if ( ! ( kvp . Item1 is StringConstantExpressionAst ) )
526+ var rhsList = settings [ key ] as List < string > ;
527+ if ( rhsList == null )
397528 {
398- // first item (the key) should be a string
399- writer . WriteError ( new ErrorRecord ( new InvalidDataException ( string . Format ( CultureInfo . CurrentCulture , Strings . WrongKeyFormat , kvp . Item1 . Extent . StartLineNumber , kvp . Item1 . Extent . StartColumnNumber , profile ) ) ,
400- Strings . ConfigurationKeyNotAString , ErrorCategory . InvalidData , profile ) ) ;
401- hasError = true ;
402529 continue ;
403530 }
404-
405- // parse the item2 as array
406- PipelineAst pipeAst = kvp . Item2 as PipelineAst ;
407- List < string > rhsList = new List < string > ( ) ;
408- if ( pipeAst != null )
531+ if ( ! AddProfileItem ( key , rhsList , severityList , includeRuleList , excludeRuleList ) )
409532 {
410- ExpressionAst pureExp = pipeAst . GetPureExpression ( ) ;
411- if ( pureExp is StringConstantExpressionAst )
412- {
413- rhsList . Add ( ( pureExp as StringConstantExpressionAst ) . Value ) ;
414- }
415- else
416- {
417- ArrayLiteralAst arrayLitAst = pureExp as ArrayLiteralAst ;
418- if ( arrayLitAst == null && pureExp is ArrayExpressionAst )
419- {
420- ArrayExpressionAst arrayExp = pureExp as ArrayExpressionAst ;
421- // Statements property is never null
422- if ( arrayExp . SubExpression != null )
423- {
424- StatementAst stateAst = arrayExp . SubExpression . Statements . FirstOrDefault ( ) ;
425- if ( stateAst != null && stateAst is PipelineAst )
426- {
427- CommandBaseAst cmdBaseAst = ( stateAst as PipelineAst ) . PipelineElements . FirstOrDefault ( ) ;
428- if ( cmdBaseAst != null && cmdBaseAst is CommandExpressionAst )
429- {
430- CommandExpressionAst cmdExpAst = cmdBaseAst as CommandExpressionAst ;
431- if ( cmdExpAst . Expression is StringConstantExpressionAst )
432- {
433- rhsList . Add ( ( cmdExpAst . Expression as StringConstantExpressionAst ) . Value ) ;
434- }
435- else
436- {
437- arrayLitAst = cmdExpAst . Expression as ArrayLiteralAst ;
438- }
439- }
440- }
441- }
442- }
443-
444- if ( arrayLitAst != null )
445- {
446- foreach ( var element in arrayLitAst . Elements )
447- {
448- // all the values in the array needs to be string
449- if ( ! ( element is StringConstantExpressionAst ) )
450- {
451- writer . WriteError ( new ErrorRecord ( new InvalidDataException ( string . Format ( CultureInfo . CurrentCulture , Strings . WrongValueFormat , element . Extent . StartLineNumber , element . Extent . StartColumnNumber , profile ) ) ,
452- Strings . ConfigurationValueNotAString , ErrorCategory . InvalidData , profile ) ) ;
453- hasError = true ;
454- continue ;
455- }
456-
457- rhsList . Add ( ( element as StringConstantExpressionAst ) . Value ) ;
458- }
459- }
460- }
461- }
462-
463- if ( rhsList . Count == 0 )
464- {
465- writer . WriteError ( new ErrorRecord ( new InvalidDataException ( string . Format ( CultureInfo . CurrentCulture , Strings . WrongValueFormat , kvp . Item2 . Extent . StartLineNumber , kvp . Item2 . Extent . StartColumnNumber , profile ) ) ,
466- Strings . ConfigurationValueWrongFormat , ErrorCategory . InvalidData , profile ) ) ;
467- hasError = true ;
468- continue ;
469- }
470-
471- string key = ( kvp . Item1 as StringConstantExpressionAst ) . Value . ToLower ( ) ;
472-
473- if ( ! AddProfileItem ( key , rhsList , severityList , includeRuleList , excludeRuleList ) )
474- {
475- writer . WriteError ( new ErrorRecord (
476- new InvalidDataException ( string . Format ( CultureInfo . CurrentCulture , Strings . WrongKey , key , kvp . Item1 . Extent . StartLineNumber , kvp . Item1 . Extent . StartColumnNumber , profile ) ) ,
477- Strings . WrongConfigurationKey , ErrorCategory . InvalidData , profile ) ) ;
533+ writer . WriteError (
534+ new ErrorRecord (
535+ new InvalidDataException (
536+ string . Format (
537+ CultureInfo . CurrentCulture ,
538+ Strings . WrongKey ,
539+ key ,
540+ profile ) ) ,
541+ Strings . WrongConfigurationKey ,
542+ ErrorCategory . InvalidData ,
543+ profile ) ) ;
478544 hasError = true ;
479545 }
480546 }
@@ -517,7 +583,6 @@ private void Initialize(
517583 // But for Core CLR we need to load it explicitly
518584 this . Loggers = GetInterfaceImplementationsFromAssembly < ILogger > ( ) ;
519585#endif
520-
521586 #region Initializes Rules
522587
523588 var includeRuleList = new List < string > ( ) ;
@@ -1887,7 +1952,7 @@ public IEnumerable<DiagnosticRecord> AnalyzeSyntaxTree(
18871952 }
18881953 }
18891954 }
1890-
1955+
18911956 #endregion
18921957
18931958 // Need to reverse the concurrentbag to ensure that results are sorted in the increasing order of line numbers
0 commit comments