1+ using  System . Collections . Generic ; 
12using  System . Linq ; 
23using  Rubberduck . CodeAnalysis . Inspections . Abstract ; 
34using  Rubberduck . CodeAnalysis . Inspections . Extensions ; 
@@ -14,32 +15,92 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
1415    /// </summary> 
1516    /// <why> 
1617    /// Unused procedures are dead code that should probably be removed. Note, a procedure may be effectively "not used" in code, but attached to some 
17-     /// Shape object in the host document: in such cases the inspection result should be ignored. An event handler procedure that isn't being 
18-     /// resolved as such, may also wrongly trigger this inspection. 
18+     /// Shape object in the host document: in such cases the inspection result should be ignored. 
1919    /// </why> 
2020    /// <remarks> 
2121    /// Not all unused procedures can/should be removed: ignore any inspection results for  
2222    /// event handler procedures and interface members that Rubberduck isn't recognizing as such. 
23+     /// Public procedures of Standard Modules are not flagged by this inspection regardless of 
24+     /// the presence or absence of user code references. 
2325    /// </remarks> 
2426    /// <example hasResult="true"> 
25-     /// <module name="MyModule " type="Standard Module"> 
27+     /// <module name="Module1 " type="Standard Module"> 
2628    /// <![CDATA[ 
2729    /// Option Explicit 
2830    ///  
29-     /// Public Sub DoSomething() 
30-     ///     ' macro is attached to a worksheet Shape. 
31+     /// Private Sub DoSomething() 
3132    /// End Sub 
3233    /// ]]> 
3334    /// </module> 
3435    /// </example> 
3536    /// <example hasResult="false"> 
36-     /// <module name="MyModule " type="Standard Module"> 
37+     /// <module name="Module1 " type="Standard Module"> 
3738    /// <![CDATA[ 
3839    /// Option Explicit 
39-     /// 
40+     ///   
4041    /// '@Ignore ProcedureNotUsed 
42+     /// Private Sub DoSomething() 
43+     /// End Sub 
44+     /// ]]> 
45+     /// </module> 
46+     /// </example> 
47+     /// <example hasResult="false"> 
48+     /// <module name="Macros" type="Standard Module"> 
49+     /// <![CDATA[ 
50+     /// Option Explicit 
51+     ///  
52+     /// Public Sub DoSomething() 
53+     ///     'a public procedure in a standard module may be a macro  
54+     ///     'attached to a worksheet Shape or invoked by means other than user code. 
55+     /// End Sub 
56+     /// ]]> 
57+     /// </module> 
58+     /// </example> 
59+     /// <example hasResult="true"> 
60+     /// <module name="Class1" type="Class Module"> 
61+     /// <![CDATA[ 
62+     /// Option Explicit 
63+     ///  
64+     /// Public Sub DoSomething() 
65+     /// End Sub 
66+     ///  
67+     /// Public Sub DoSomethingElse() 
68+     /// End Sub 
69+     /// ]]> 
70+     /// </module> 
71+     /// <module name="Module1" type="Standard Module"> 
72+     /// <![CDATA[ 
73+     /// Option Explicit 
74+     ///  
75+     /// Public Sub ReferenceOneClass1Procedure() 
76+     ///     Dim target As Class1 
77+     ///     Set target = new Class1 
78+     ///     target.DoSomething 
79+     /// End Sub 
80+     /// ]]> 
81+     /// </module> 
82+     /// </example> 
83+     /// <example hasResult="false"> 
84+     /// <module name="Class1" type="Class Module"> 
85+     /// <![CDATA[ 
86+     /// Option Explicit 
87+     ///  
4188    /// Public Sub DoSomething() 
42-     ///     ' macro is attached to a worksheet Shape. 
89+     /// End Sub 
90+     ///  
91+     /// Public Sub DoSomethingElse() 
92+     /// End Sub 
93+     /// ]]> 
94+     /// </module> 
95+     /// <module name="Module1" type="Standard Module"> 
96+     /// <![CDATA[ 
97+     /// Option Explicit 
98+     ///  
99+     /// Public Sub ReferenceAllClass1Procedures() 
100+     ///     Dim target As Class1 
101+     ///     Set target = new Class1 
102+     ///     target.DoSomething 
103+     ///     target.DoSomethingElse 
43104    /// End Sub 
44105    /// ]]> 
45106    /// </module> 
@@ -78,8 +139,7 @@ public ProcedureNotUsedInspection(IDeclarationFinderProvider declarationFinderPr
78139        protected  override  bool  IsResultDeclaration ( Declaration  declaration ,  DeclarationFinder  finder ) 
79140        { 
80141            return  ! declaration . References 
81-                        . Any ( reference =>  ! reference . IsAssignment  
82-                                          &&  ! reference . ParentScoping . Equals ( declaration ) )  // recursive calls don't count 
142+                        . Any ( reference =>  ! reference . ParentScoping . Equals ( declaration ) )  // ignore recursive/self-referential calls 
83143                   &&  ! finder . FindEventHandlers ( ) . Contains ( declaration ) 
84144                   &&  ! IsPublicModuleMember ( declaration ) 
85145                   &&  ! IsClassLifeCycleHandler ( declaration ) 
0 commit comments