/
ImplicitActiveSheetReferenceInspection.cs
66 lines (62 loc) · 2.68 KB
/
ImplicitActiveSheetReferenceInspection.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System.Linq;
using Rubberduck.CodeAnalysis.Inspections.Abstract;
using Rubberduck.CodeAnalysis.Inspections.Attributes;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.DeclarationCaching;
using Rubberduck.Resources.Inspections;
namespace Rubberduck.CodeAnalysis.Inspections.Concrete
{
/// <summary>
/// Locates unqualified Worksheet.Range/Cells/Columns/Rows member calls inside worksheet modules.
/// </summary>
/// <reference name="Excel" />
/// <why>
/// Implicit references to the active worksheet rarely mean to be working with *whatever worksheet is currently active*.
/// By explicitly qualifying these member calls with a specific Worksheet object, the assumptions are removed, the code
/// is more robust, and will be less likely to throw run-time error 1004 or produce unexpected results
/// when the active sheet isn't the expected one.
/// </why>
/// <example hasResult="true">
/// <module name="MyModule" type="Standard Module">
/// <![CDATA[
/// Private Sub Example()
/// Dim foo As Range
/// Set foo = Sheet1.Range(Cells(1, 1), Cells(1, 10)) ' Worksheet.Cells implicitly from ActiveSheet; error 1004 if that isn't Sheet1.
/// End Sub
/// ]]>
/// </module>
/// </example>
/// <example hasResult="false">
/// <module name="MyModule" type="Standard Module">
/// <![CDATA[
/// Private Sub Example()
/// Dim foo As Range
/// With Sheet1
/// Set foo = .Range(.Cells(1, 1), .Cells(1, 10)) ' all member calls are made against the With block object
/// End With
/// End Sub
/// ]]>
/// </module>
/// </example>
[RequiredLibrary("Excel")]
internal sealed class ImplicitActiveSheetReferenceInspection : ImplicitSheetReferenceInspectionBase
{
public ImplicitActiveSheetReferenceInspection(IDeclarationFinderProvider declarationFinderProvider)
: base(declarationFinderProvider)
{}
protected override string[] GlobalObjectClassNames => new[] { "Global", "_Global", };
protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder)
{
var result = !(Declaration.GetModuleParent(reference.ParentNonScoping) is DocumentModuleDeclaration document)
|| !document.SupertypeNames.Contains("Worksheet");
return result;
}
protected override string ResultDescription(IdentifierReference reference)
{
return string.Format(
InspectionResults.ImplicitActiveSheetReferenceInspection,
reference.Declaration.IdentifierName);
}
}
}