1
+ using System . Collections . Generic ;
2
+ using System . Diagnostics ;
3
+ using Antlr4 . Runtime ;
4
+ using Antlr4 . Runtime . Tree ;
5
+ using Rubberduck . Parsing . Grammar ;
6
+ using Rubberduck . Parsing . VBA ;
7
+
8
+ namespace Rubberduck . Inspections . Abstract
9
+ {
10
+ public abstract class EmptyBlockInspectionBase < TContext > : ParseTreeInspectionBase < TContext >
11
+ where TContext : ParserRuleContext
12
+ {
13
+ protected EmptyBlockInspectionBase ( IDeclarationFinderProvider declarationFinderProvider )
14
+ : base ( declarationFinderProvider )
15
+ { }
16
+
17
+ protected class EmptyBlockInspectionListenerBase : InspectionListenerBase < TContext >
18
+ {
19
+ public void InspectBlockForExecutableStatements < T > ( VBAParser . BlockContext block , T context ) where T : TContext
20
+ {
21
+ if ( ! BlockContainsExecutableStatements ( block ) )
22
+ {
23
+ SaveContext ( context ) ;
24
+ }
25
+ }
26
+
27
+ private bool BlockContainsExecutableStatements ( VBAParser . BlockContext block )
28
+ {
29
+ return block ? . children != null && ContainsExecutableStatements ( block . children ) ;
30
+ }
31
+
32
+ private bool ContainsExecutableStatements ( IList < IParseTree > blockChildren )
33
+ {
34
+ foreach ( var child in blockChildren )
35
+ {
36
+ if ( child is VBAParser . BlockStmtContext blockStmt )
37
+ {
38
+ var mainBlockStmt = blockStmt . mainBlockStmt ( ) ;
39
+
40
+ if ( mainBlockStmt == null )
41
+ {
42
+ continue ; //We have a lone line label, which is not executable.
43
+ }
44
+
45
+ Debug . Assert ( mainBlockStmt . ChildCount == 1 ) ;
46
+
47
+ // exclude variables and consts because they are not executable statements
48
+ if ( mainBlockStmt . GetChild ( 0 ) is VBAParser . VariableStmtContext ||
49
+ mainBlockStmt . GetChild ( 0 ) is VBAParser . ConstStmtContext )
50
+ {
51
+ continue ;
52
+ }
53
+
54
+ return true ;
55
+ }
56
+
57
+ if ( child is VBAParser . RemCommentContext ||
58
+ child is VBAParser . CommentContext ||
59
+ child is VBAParser . CommentOrAnnotationContext ||
60
+ child is VBAParser . EndOfStatementContext )
61
+ {
62
+ continue ;
63
+ }
64
+
65
+ return true ;
66
+ }
67
+
68
+ return false ;
69
+ }
70
+
71
+ public void InspectBlockForExecutableStatements < T > ( VBAParser . UnterminatedBlockContext block , T context ) where T : TContext
72
+ {
73
+ if ( ! BlockContainsExecutableStatements ( block ) )
74
+ {
75
+ SaveContext ( context ) ;
76
+ }
77
+ }
78
+
79
+ private bool BlockContainsExecutableStatements ( VBAParser . UnterminatedBlockContext block )
80
+ {
81
+ return block ? . children != null && ContainsExecutableStatements ( block . children ) ;
82
+ }
83
+ }
84
+ }
85
+ }
0 commit comments