3
3
using System . Linq ;
4
4
using System . Text . RegularExpressions ;
5
5
using Rubberduck . Inspections . Abstract ;
6
- using Rubberduck . Inspections . Results ;
7
6
using Rubberduck . Parsing . Inspections ;
8
7
using Rubberduck . Parsing . Inspections . Abstract ;
9
8
using Rubberduck . Parsing . Symbols ;
10
9
using Rubberduck . Parsing . VBA ;
10
+ using Rubberduck . Parsing . VBA . DeclarationCaching ;
11
11
using Rubberduck . Resources . Inspections ;
12
+ using Rubberduck . VBEditor ;
13
+ using Rubberduck . VBEditor . SafeComWrappers ;
12
14
13
15
namespace Rubberduck . Inspections . Inspections . Concrete
14
16
{
@@ -33,9 +35,69 @@ namespace Rubberduck.Inspections.Inspections.Concrete
33
35
/// ]]>
34
36
/// </example>
35
37
[ RequiredLibrary ( "Excel" ) ]
36
- public class ExcelUdfNameIsValidCellReferenceInspection : InspectionBase
38
+ public class ExcelUdfNameIsValidCellReferenceInspection : DeclarationInspectionBase
37
39
{
38
- public ExcelUdfNameIsValidCellReferenceInspection ( RubberduckParserState state ) : base ( state ) { }
40
+ public ExcelUdfNameIsValidCellReferenceInspection ( RubberduckParserState state )
41
+ : base ( state , new [ ] { DeclarationType . Function } , new [ ] { DeclarationType . PropertyGet , DeclarationType . LibraryFunction } )
42
+ { }
43
+
44
+ protected override IEnumerable < IInspectionResult > DoGetInspectionResults ( )
45
+ {
46
+ if ( ! State . DeclarationFinder . Projects . Any ( project => ! project . IsUserDefined
47
+ && project . IdentifierName == "Excel" ) )
48
+ {
49
+ return Enumerable . Empty < IInspectionResult > ( ) ;
50
+ }
51
+
52
+ return base . DoGetInspectionResults ( ) ;
53
+ }
54
+
55
+ protected override IEnumerable < IInspectionResult > DoGetInspectionResults ( QualifiedModuleName module )
56
+ {
57
+ if ( ! State . DeclarationFinder . Projects . Any ( project => ! project . IsUserDefined
58
+ && project . IdentifierName == "Excel" ) )
59
+ {
60
+ return Enumerable . Empty < IInspectionResult > ( ) ;
61
+ }
62
+
63
+ return base . DoGetInspectionResults ( module ) ;
64
+ }
65
+
66
+ protected override IEnumerable < IInspectionResult > DoGetInspectionResults ( QualifiedModuleName module , DeclarationFinder finder )
67
+ {
68
+ if ( module . ComponentType != ComponentType . StandardModule )
69
+ {
70
+ return Enumerable . Empty < IInspectionResult > ( ) ;
71
+ }
72
+
73
+ var proceduralModuleDeclaration = finder . Members ( module , DeclarationType . ProceduralModule )
74
+ . SingleOrDefault ( ) as ProceduralModuleDeclaration ;
75
+
76
+ if ( proceduralModuleDeclaration == null
77
+ || proceduralModuleDeclaration . IsPrivateModule )
78
+ {
79
+ return Enumerable . Empty < IInspectionResult > ( ) ;
80
+ }
81
+
82
+ return base . DoGetInspectionResults ( module , finder ) ;
83
+ }
84
+
85
+ protected override bool IsResultDeclaration ( Declaration declaration , DeclarationFinder finder )
86
+ {
87
+ if ( ! VisibleAsUdf . Contains ( declaration . Accessibility ) )
88
+ {
89
+ return false ;
90
+ }
91
+
92
+ var cellIdMatch = ValidCellIdRegex . Match ( declaration . IdentifierName ) ;
93
+ if ( ! cellIdMatch . Success )
94
+ {
95
+ return false ;
96
+ }
97
+
98
+ var row = Convert . ToUInt32 ( cellIdMatch . Groups [ "Row" ] . Value ) ;
99
+ return row > 0 && row <= MaximumExcelRows ;
100
+ }
39
101
40
102
private static readonly Regex ValidCellIdRegex =
41
103
new Regex ( @"^([a-z]|[a-z]{2}|[a-w][a-z]{2}|x([a-e][a-z]|f[a-d]))(?<Row>\d+)$" ,
@@ -45,25 +107,9 @@ public ExcelUdfNameIsValidCellReferenceInspection(RubberduckParserState state) :
45
107
46
108
private const uint MaximumExcelRows = 1048576 ;
47
109
48
- protected override IEnumerable < IInspectionResult > DoGetInspectionResults ( )
110
+ protected override string ResultDescription ( Declaration declaration )
49
111
{
50
- var excel = State . DeclarationFinder . Projects . SingleOrDefault ( item => ! item . IsUserDefined && item . IdentifierName == "Excel" ) ;
51
- if ( excel == null )
52
- {
53
- return Enumerable . Empty < IInspectionResult > ( ) ;
54
- }
55
-
56
- var candidates = UserDeclarations . OfType < FunctionDeclaration > ( ) . Where ( decl =>
57
- decl . ParentScopeDeclaration . DeclarationType == DeclarationType . ProceduralModule &&
58
- VisibleAsUdf . Contains ( decl . Accessibility ) ) ;
59
-
60
- return ( from function in candidates . Where ( decl => ValidCellIdRegex . IsMatch ( decl . IdentifierName ) )
61
- let row = Convert . ToUInt32 ( ValidCellIdRegex . Matches ( function . IdentifierName ) [ 0 ] . Groups [ "Row" ] . Value )
62
- where row > 0 && row <= MaximumExcelRows
63
- select new DeclarationInspectionResult ( this ,
64
- string . Format ( InspectionResults . ExcelUdfNameIsValidCellReferenceInspection , function . IdentifierName ) ,
65
- function ) )
66
- . Cast < IInspectionResult > ( ) . ToList ( ) ;
112
+ return string . Format ( InspectionResults . ExcelUdfNameIsValidCellReferenceInspection , declaration . IdentifierName ) ;
67
113
}
68
114
}
69
115
}
0 commit comments