/
ImplicitActiveWorkbookReferenceInspection.cs
67 lines (63 loc) · 2.85 KB
/
ImplicitActiveWorkbookReferenceInspection.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
67
using System.Collections.Generic;
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 Workbook.Worksheets/Sheets/Names member calls that implicitly refer to ActiveWorkbook.
/// </summary>
/// <reference name="Excel" />
/// <why>
/// Implicit references to the active workbook rarely mean to be working with *whatever workbook is currently active*.
/// By explicitly qualifying these member calls with a specific Workbook 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 workbook isn't the expected one.
/// </why>
/// <example hasResult="true">
/// <module name="MyModule" type="Standard Module">
/// <![CDATA[
/// Private Sub Example()
/// Dim summarySheet As Worksheet
/// Set summarySheet = Worksheets("Summary") ' unqualified Worksheets is implicitly querying the active workbook's Worksheets collection.
/// End Sub
/// ]]>
/// </module>
/// </example>
/// <example hasResult="false">
/// <module name="MyModule" type="Standard Module">
/// <![CDATA[
/// Private Sub Example(ByVal book As Workbook)
/// Dim summarySheet As Worksheet
/// Set summarySheet = book.Worksheets("Summary")
/// End Sub
/// ]]>
/// </module>
/// </example>
[RequiredLibrary("Excel")]
internal sealed class ImplicitActiveWorkbookReferenceInspection : ImplicitWorkbookReferenceInspectionBase
{
public ImplicitActiveWorkbookReferenceInspection(IDeclarationFinderProvider declarationFinderProvider)
: base(declarationFinderProvider)
{}
private static readonly List<string> _alwaysActiveWorkbookReferenceParents = new List<string>
{
"_Application", "Application"
};
protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder)
{
return !(Declaration.GetModuleParent(reference.ParentNonScoping) is DocumentModuleDeclaration document)
|| !document.SupertypeNames.Contains("Workbook")
|| _alwaysActiveWorkbookReferenceParents.Contains(reference.Declaration.ParentDeclaration.IdentifierName);
}
protected override string ResultDescription(IdentifierReference reference)
{
var referenceText = reference.Context.GetText();
return string.Format(InspectionResults.ImplicitActiveWorkbookReferenceInspection, referenceText);
}
}
}