-
Notifications
You must be signed in to change notification settings - Fork 295
/
EmptyMethodInspection.cs
89 lines (80 loc) · 3.03 KB
/
EmptyMethodInspection.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using Rubberduck.Inspections.Abstract;
using Rubberduck.Inspections.Results;
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Resources.Inspections;
using Rubberduck.Parsing.VBA;
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Common;
using Rubberduck.Inspections.Inspections.Extensions;
using Rubberduck.Parsing.VBA.DeclarationCaching;
using Rubberduck.Parsing.VBA.Extensions;
using Rubberduck.VBEditor;
namespace Rubberduck.Inspections.Concrete
{
/// <summary>
/// Identifies empty module member blocks.
/// </summary>
/// <why>
/// Methods containing no executable statements are misleading as they appear to be doing something which they actually don't.
/// This might be the result of delaying the actual implementation for a later stage of development, and then forgetting all about that.
/// </why>
/// <example hasResults="true">
/// <![CDATA[
/// Sub Foo()
/// ' ...
/// End Sub
/// ]]>
/// </example>
/// <example hasResults="false">
/// <![CDATA[
/// Sub Foo()
/// MsgBox "?"
/// End Sub
/// ]]>
/// </example>
internal class EmptyMethodInspection : InspectionBase
{
public EmptyMethodInspection(RubberduckParserState state)
: base(state) { }
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
{
var finder = State.DeclarationFinder;
var userInterfaces = UserInterfaces(finder);
var emptyMethods = EmptyNonInterfaceMethods(finder, userInterfaces);
return emptyMethods.Select(Result);
}
private static ICollection<QualifiedModuleName> UserInterfaces(DeclarationFinder finder)
{
return finder
.FindAllUserInterfaces()
.Select(decl => decl.QualifiedModuleName)
.ToHashSet();
}
private static IEnumerable<Declaration> EmptyNonInterfaceMethods(DeclarationFinder finder, ICollection<QualifiedModuleName> userInterfaces)
{
return finder
.UserDeclarations(DeclarationType.Member)
.Where(member => !userInterfaces.Contains(member.QualifiedModuleName)
&& member is ModuleBodyElementDeclaration moduleBodyElement
&& !moduleBodyElement.Block.ContainsExecutableStatements());
}
private IInspectionResult Result(Declaration member)
{
return new DeclarationInspectionResult(
this,
ResultDescription(member),
member);
}
private static string ResultDescription(Declaration member)
{
var identifierName = member.IdentifierName;
var declarationType = member.DeclarationType.ToLocalizedString();
return string.Format(
InspectionResults.EmptyMethodInspection,
declarationType,
identifierName);
}
}
}