@@ -23,43 +23,90 @@ namespace Microsoft.Windows.Powershell.ScriptAnalyzer.BuiltinRules
23
23
/// AvoidUsingWriteHost: Check that Write-Host or Console.Write are not used
24
24
/// </summary>
25
25
[ Export ( typeof ( IScriptRule ) ) ]
26
- public class AvoidUsingWriteHost : IScriptRule
26
+ public class AvoidUsingWriteHost : AstVisitor , IScriptRule
27
27
{
28
+ List < DiagnosticRecord > records ;
29
+ string fileName ;
30
+
28
31
/// <summary>
29
32
/// AnalyzeScript: check that Write-Host or Console.Write are not used.
30
33
/// </summary>
31
34
public IEnumerable < DiagnosticRecord > AnalyzeScript ( Ast ast , string fileName )
32
35
{
33
36
if ( ast == null ) throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
34
37
35
- // Finds all CommandAsts.
36
- IEnumerable < Ast > commandAsts = ast . FindAll ( testAst => testAst is CommandAst , true ) ;
38
+ records = new List < DiagnosticRecord > ( ) ;
39
+ this . fileName = fileName ;
40
+
41
+ ast . Visit ( this ) ;
42
+
43
+ return records ;
44
+ }
45
+
46
+
47
+ /// <summary>
48
+ /// Visit function and skips any function that starts with show
49
+ /// </summary>
50
+ /// <param name="funcAst"></param>
51
+ /// <returns></returns>
52
+ public override AstVisitAction VisitFunctionDefinition ( FunctionDefinitionAst funcAst )
53
+ {
54
+ if ( funcAst == null || funcAst . Name == null )
55
+ {
56
+ return AstVisitAction . SkipChildren ;
57
+ }
58
+
59
+ if ( funcAst . Name . StartsWith ( "show" , StringComparison . OrdinalIgnoreCase ) )
60
+ {
61
+ return AstVisitAction . SkipChildren ;
62
+ }
63
+
64
+ return AstVisitAction . Continue ;
65
+ }
66
+
67
+ /// <summary>
68
+ /// Checks that write-host command is not used
69
+ /// </summary>
70
+ /// <param name="cmdAst"></param>
71
+ /// <returns></returns>
72
+ public override AstVisitAction VisitCommand ( CommandAst cmdAst )
73
+ {
74
+ if ( cmdAst == null )
75
+ {
76
+ return AstVisitAction . SkipChildren ;
77
+ }
37
78
38
- // Iterrates all CommandAsts and check the command name.
39
- foreach ( CommandAst cmdAst in commandAsts )
79
+ if ( cmdAst . GetCommandName ( ) != null && String . Equals ( cmdAst . GetCommandName ( ) , "write-host" , StringComparison . OrdinalIgnoreCase ) )
40
80
{
41
- if ( cmdAst . GetCommandName ( ) != null && String . Equals ( cmdAst . GetCommandName ( ) , "write-host" , StringComparison . OrdinalIgnoreCase ) )
42
- {
43
- yield return new DiagnosticRecord ( String . Format ( CultureInfo . CurrentCulture , Strings . AvoidUsingWriteHostError , System . IO . Path . GetFileName ( fileName ) ) ,
44
- cmdAst . Extent , GetName ( ) , DiagnosticSeverity . Warning , fileName ) ;
45
- }
81
+ records . Add ( new DiagnosticRecord ( String . Format ( CultureInfo . CurrentCulture , Strings . AvoidUsingWriteHostError , System . IO . Path . GetFileName ( fileName ) ) ,
82
+ cmdAst . Extent , GetName ( ) , DiagnosticSeverity . Warning , fileName ) ) ;
46
83
}
47
84
48
- // Finds all InvokeMemberExpressionAst
49
- IEnumerable < Ast > invokeAsts = ast . FindAll ( testAst => testAst is InvokeMemberExpressionAst , true ) ;
85
+ return AstVisitAction . Continue ;
86
+ }
50
87
51
- foreach ( InvokeMemberExpressionAst invokeAst in invokeAsts )
88
+ public override AstVisitAction VisitInvokeMemberExpression ( InvokeMemberExpressionAst imeAst )
89
+ {
90
+ if ( imeAst == null )
52
91
{
53
- TypeExpressionAst typeAst = invokeAst . Expression as TypeExpressionAst ;
54
- if ( typeAst == null || typeAst . TypeName == null || typeAst . TypeName . FullName == null ) continue ;
55
-
56
- if ( typeAst . TypeName . FullName . EndsWith ( "console" , StringComparison . OrdinalIgnoreCase )
57
- && ! String . IsNullOrWhiteSpace ( invokeAst . Member . Extent . Text ) && invokeAst . Member . Extent . Text . StartsWith ( "Write" , StringComparison . OrdinalIgnoreCase ) )
58
- {
59
- yield return new DiagnosticRecord ( String . Format ( CultureInfo . CurrentCulture , Strings . AvoidUsingConsoleWriteError , System . IO . Path . GetFileName ( fileName ) , invokeAst . Member . Extent . Text ) ,
60
- invokeAst . Extent , GetName ( ) , DiagnosticSeverity . Warning , fileName ) ;
61
- }
92
+ return AstVisitAction . SkipChildren ;
62
93
}
94
+
95
+ TypeExpressionAst typeAst = imeAst . Expression as TypeExpressionAst ;
96
+
97
+ if ( typeAst == null || typeAst . TypeName == null || typeAst . TypeName . FullName == null )
98
+ {
99
+ return AstVisitAction . SkipChildren ;
100
+ }
101
+
102
+ if ( typeAst . TypeName . FullName . EndsWith ( "console" , StringComparison . OrdinalIgnoreCase )
103
+ && ! String . IsNullOrWhiteSpace ( imeAst . Member . Extent . Text ) && imeAst . Member . Extent . Text . StartsWith ( "Write" , StringComparison . OrdinalIgnoreCase ) )
104
+ {
105
+ records . Add ( new DiagnosticRecord ( String . Format ( CultureInfo . CurrentCulture , Strings . AvoidUsingConsoleWriteError , System . IO . Path . GetFileName ( fileName ) , imeAst . Member . Extent . Text ) ,
106
+ imeAst . Extent , GetName ( ) , DiagnosticSeverity . Warning , fileName ) ) ;
107
+ }
108
+
109
+ return AstVisitAction . Continue ;
63
110
}
64
111
65
112
/// <summary>
0 commit comments