2222namespace Microsoft . Windows . PowerShell . ScriptAnalyzer . BuiltinRules
2323{
2424 /// <summary>
25- /// ProvideVerboseMessage: Analyzes the ast to check that Write-Verbose is called at least once in every cmdlet or script.
25+ /// ProvideVerboseMessage: Analyzes the ast to check that Write-Verbose is called for DSC Resources
2626 /// </summary>
27- [ Export ( typeof ( IScriptRule ) ) ]
28- public class ProvideVerboseMessage : SkipNamedBlock , IScriptRule
27+ [ Export ( typeof ( IDSCResourceRule ) ) ]
28+ public class UseVerboseMessageInDSCResource : SkipNamedBlock , IDSCResourceRule
2929 {
3030 /// <summary>
31- /// AnalyzeScript : Analyzes the ast to check that Write-Verbose is called at least once in every cmdlet or script.
31+ /// AnalyzeDSCResource : Analyzes the ast to check that Write-Verbose is called for DSC Resources
3232 /// <param name="ast">The script's ast</param>
3333 /// <param name="fileName">The script's file name</param>
3434 /// </summary>
35- public IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName )
35+ public IEnumerable < DiagnosticRecord > AnalyzeDSCResource ( Ast ast , string fileName )
3636 {
37- if ( ast == null ) throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
38-
39- ClearList ( ) ;
40- this . AddNames ( new List < string > ( ) { "Configuration" , "Workflow" } ) ;
41- DiagnosticRecords . Clear ( ) ;
42-
43- this . fileName = fileName ;
44- //We only check that advanced functions should have Write-Verbose
45- ast . Visit ( this ) ;
46-
47- return DiagnosticRecords ;
48- }
49-
50- /// <summary>
51- /// Visit function and checks that it has write verbose
52- /// </summary>
53- /// <param name="funcAst"></param>
54- /// <returns></returns>
55- public override AstVisitAction VisitFunctionDefinition ( FunctionDefinitionAst funcAst )
56- {
57- if ( funcAst == null )
37+ if ( ast == null )
5838 {
59- return AstVisitAction . SkipChildren ;
60- }
39+ throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
40+ }
41+
42+ IEnumerable < Ast > functionDefinitionAsts = Helper . Instance . DscResourceFunctions ( ast ) ;
6143
62- //Write-Verbose is not required for non-advanced functions
63- if ( funcAst . Body == null || funcAst . Body . ParamBlock == null
64- || funcAst . Body . ParamBlock . Attributes == null ||
65- funcAst . Body . ParamBlock . Parameters == null ||
66- ! funcAst . Body . ParamBlock . Attributes . Any ( attr => attr . TypeName . GetReflectionType ( ) == typeof ( CmdletBindingAttribute ) ) )
44+ foreach ( FunctionDefinitionAst functionDefinitionAst in functionDefinitionAsts )
6745 {
68- return AstVisitAction . Continue ;
69- }
46+ var commandAsts = functionDefinitionAst . Body . FindAll ( testAst => testAst is CommandAst , false ) ;
47+ bool hasVerbose = false ;
7048
71- var commandAsts = funcAst . Body . FindAll ( testAst => testAst is CommandAst , false ) ;
72- bool hasVerbose = false ;
49+ if ( null != commandAsts )
50+ {
51+ foreach ( CommandAst commandAst in commandAsts )
52+ {
53+ hasVerbose |= String . Equals ( commandAst . GetCommandName ( ) , "Write-Verbose" , StringComparison . OrdinalIgnoreCase ) ;
54+ }
55+ }
7356
74- if ( commandAsts != null )
75- {
76- foreach ( CommandAst commandAst in commandAsts )
57+ if ( ! hasVerbose )
7758 {
78- hasVerbose |= String . Equals ( commandAst . GetCommandName ( ) , "Write-Verbose" , StringComparison . OrdinalIgnoreCase ) ;
59+ yield return new DiagnosticRecord ( string . Format ( CultureInfo . CurrentCulture , Strings . UseVerboseMessageInDSCResourceErrorFunction , functionDefinitionAst . Name ) ,
60+ functionDefinitionAst . Extent , GetName ( ) , DiagnosticSeverity . Information , fileName ) ;
7961 }
80- }
8162
82- if ( ! hasVerbose )
83- {
84- DiagnosticRecords . Add ( new DiagnosticRecord ( string . Format ( CultureInfo . CurrentCulture , Strings . ProvideVerboseMessageErrorFunction , funcAst . Name ) ,
85- funcAst . Extent , GetName ( ) , DiagnosticSeverity . Information , fileName ) ) ;
8663 }
87-
88- return AstVisitAction . Continue ;
64+ }
65+
66+ /// <summary>
67+ /// AnalyzeDSCClass: This function returns nothing in the case of dsc class.
68+ /// </summary>
69+ /// <param name="ast"></param>
70+ /// <param name="fileName"></param>
71+ /// <returns></returns>
72+ public IEnumerable < DiagnosticRecord > AnalyzeDSCClass ( Ast ast , string fileName )
73+ {
74+ return Enumerable . Empty < DiagnosticRecord > ( ) ;
8975 }
9076
9177 /// <summary>
9278 /// Method: Retrieves the name of this rule.
9379 /// </summary>
9480 public string GetName ( )
9581 {
96- return string . Format ( CultureInfo . CurrentCulture , Strings . NameSpaceFormat , GetSourceName ( ) , Strings . ProvideVerboseMessageName ) ;
82+ return string . Format ( CultureInfo . CurrentCulture , Strings . NameSpaceFormat , GetSourceName ( ) , Strings . UseVerboseMessageInDSCResourceName ) ;
9783 }
9884
9985 /// <summary>
@@ -102,7 +88,7 @@ public string GetName()
10288 /// <returns>The common name of this rule</returns>
10389 public string GetCommonName ( )
10490 {
105- return string . Format ( CultureInfo . CurrentCulture , Strings . ProvideVerboseMessageCommonName ) ;
91+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseVerboseMessageInDSCResourceCommonName ) ;
10692 }
10793
10894 /// <summary>
@@ -111,7 +97,7 @@ public string GetCommonName()
11197 /// <returns>The description of this rule</returns>
11298 public string GetDescription ( )
11399 {
114- return string . Format ( CultureInfo . CurrentCulture , Strings . ProvideVerboseMessageDescription ) ;
100+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseVerboseMessageInDSCResourceDescription ) ;
115101 }
116102
117103 /// <summary>
@@ -136,7 +122,7 @@ public RuleSeverity GetSeverity()
136122 /// </summary>
137123 public string GetSourceName ( )
138124 {
139- return string . Format ( CultureInfo . CurrentCulture , Strings . SourceName ) ;
125+ return string . Format ( CultureInfo . CurrentCulture , Strings . DSCSourceName ) ;
140126 }
141127 }
142- }
128+ }
0 commit comments