Skip to content

Commit 13e1547

Browse files
committed
Make inspection listener base and parse tree inspection base generic
1 parent fbdcf00 commit 13e1547

35 files changed

+286
-272
lines changed

Rubberduck.CodeAnalysis/Inspections/Abstract/ParseTreeInspectionBase.cs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,32 @@
1212

1313
namespace Rubberduck.Inspections.Abstract
1414
{
15-
public abstract class ParseTreeInspectionBase : InspectionBase, IParseTreeInspection
15+
public abstract class ParseTreeInspectionBase<TContext> : InspectionBase, IParseTreeInspection
16+
where TContext : ParserRuleContext
1617
{
1718
protected ParseTreeInspectionBase(IDeclarationFinderProvider declarationFinderProvider)
1819
: base(declarationFinderProvider)
1920
{}
2021

21-
public abstract IInspectionListener Listener { get; }
22-
protected abstract string ResultDescription(QualifiedContext<ParserRuleContext> context);
22+
public IInspectionListener Listener => ContextListener;
2323

24-
protected virtual bool IsResultContext(QualifiedContext<ParserRuleContext> context) => true;
24+
protected abstract IInspectionListener<TContext> ContextListener { get; }
25+
26+
protected abstract string ResultDescription(QualifiedContext<TContext> context);
27+
28+
protected virtual bool IsResultContext(QualifiedContext<TContext> context) => true;
2529

2630
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
2731
{
28-
return DoGetInspectionResults(Listener.Contexts());
32+
return DoGetInspectionResults(ContextListener.Contexts());
2933
}
3034

3135
protected override IEnumerable<IInspectionResult> DoGetInspectionResults(QualifiedModuleName module)
3236
{
33-
return DoGetInspectionResults(Listener.Contexts(module));
37+
return DoGetInspectionResults(ContextListener.Contexts(module));
3438
}
3539

36-
private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<QualifiedContext<ParserRuleContext>> contexts)
40+
private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<QualifiedContext<TContext>> contexts)
3741
{
3842
var objectionableContexts = contexts
3943
.Where(IsResultContext);
@@ -43,7 +47,7 @@ private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<Qualif
4347
.ToList();
4448
}
4549

46-
protected virtual IInspectionResult InspectionResult(QualifiedContext<ParserRuleContext> context)
50+
protected virtual IInspectionResult InspectionResult(QualifiedContext<TContext> context)
4751
{
4852
return new QualifiedContextInspectionResult(
4953
this,
@@ -52,32 +56,35 @@ protected virtual IInspectionResult InspectionResult(QualifiedContext<ParserRule
5256
DisabledQuickFixes(context));
5357
}
5458

55-
protected virtual ICollection<string> DisabledQuickFixes(QualifiedContext<ParserRuleContext> context) => new List<string>();
59+
protected virtual ICollection<string> DisabledQuickFixes(QualifiedContext<TContext> context) => new List<string>();
5660
public virtual CodeKind TargetKindOfCode => CodeKind.CodePaneCode;
5761
}
5862

5963

60-
public abstract class ParseTreeInspectionBase<T> : InspectionBase, IParseTreeInspection
64+
public abstract class ParseTreeInspectionBase<TContext, TProperties> : InspectionBase, IParseTreeInspection
65+
where TContext : ParserRuleContext
6166
{
6267
protected ParseTreeInspectionBase(IDeclarationFinderProvider declarationFinderProvider)
6368
: base(declarationFinderProvider)
6469
{}
6570

66-
public abstract IInspectionListener Listener { get; }
67-
protected abstract string ResultDescription(QualifiedContext<ParserRuleContext> context, T properties);
68-
protected abstract (bool isResult, T properties) IsResultContextWithAdditionalProperties(QualifiedContext<ParserRuleContext> context);
71+
public IInspectionListener Listener => ContextListener;
72+
73+
protected abstract IInspectionListener<TContext> ContextListener { get; }
74+
protected abstract string ResultDescription(QualifiedContext<TContext> context, TProperties properties);
75+
protected abstract (bool isResult, TProperties properties) IsResultContextWithAdditionalProperties(QualifiedContext<TContext> context);
6976

7077
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
7178
{
72-
return DoGetInspectionResults(Listener.Contexts());
79+
return DoGetInspectionResults(ContextListener.Contexts());
7380
}
7481

7582
protected override IEnumerable<IInspectionResult> DoGetInspectionResults(QualifiedModuleName module)
7683
{
77-
return DoGetInspectionResults(Listener.Contexts(module));
84+
return DoGetInspectionResults(ContextListener.Contexts(module));
7885
}
7986

80-
private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<QualifiedContext<ParserRuleContext>> contexts)
87+
private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<QualifiedContext<TContext>> contexts)
8188
{
8289
var objectionableContexts = contexts
8390
.Select(ContextsWithResultProperties)
@@ -89,49 +96,50 @@ private IEnumerable<IInspectionResult> DoGetInspectionResults(IEnumerable<Qualif
8996
.ToList();
9097
}
9198

92-
private (QualifiedContext<ParserRuleContext> context, T properties)? ContextsWithResultProperties(QualifiedContext<ParserRuleContext> context)
99+
private (QualifiedContext<TContext> context, TProperties properties)? ContextsWithResultProperties(QualifiedContext<TContext> context)
93100
{
94101
var (isResult, properties) = IsResultContextWithAdditionalProperties(context);
95102
return isResult
96103
? (context, properties)
97-
: ((QualifiedContext<ParserRuleContext> context, T properties)?) null;
104+
: ((QualifiedContext<TContext> context, TProperties properties)?) null;
98105
}
99106

100-
protected virtual IInspectionResult InspectionResult(QualifiedContext<ParserRuleContext> context, T properties)
107+
protected virtual IInspectionResult InspectionResult(QualifiedContext<TContext> context, TProperties properties)
101108
{
102-
return new QualifiedContextInspectionResult<T>(
109+
return new QualifiedContextInspectionResult<TProperties>(
103110
this,
104111
ResultDescription(context, properties),
105112
context,
106113
properties,
107114
DisabledQuickFixes(context, properties));
108115
}
109116

110-
protected virtual ICollection<string> DisabledQuickFixes(QualifiedContext<ParserRuleContext> context, T properties) => new List<string>();
117+
protected virtual ICollection<string> DisabledQuickFixes(QualifiedContext<TContext> context, TProperties properties) => new List<string>();
111118
public virtual CodeKind TargetKindOfCode => CodeKind.CodePaneCode;
112119
}
113120

114-
public class InspectionListenerBase : VBAParserBaseListener, IInspectionListener
121+
public class InspectionListenerBase<TContext> : VBAParserBaseListener, IInspectionListener<TContext>
122+
where TContext : ParserRuleContext
115123
{
116-
private readonly IDictionary<QualifiedModuleName, List<QualifiedContext<ParserRuleContext>>> _contexts;
124+
private readonly IDictionary<QualifiedModuleName, List<QualifiedContext<TContext>>> _contexts;
117125

118126
public InspectionListenerBase()
119127
{
120-
_contexts = new Dictionary<QualifiedModuleName, List<QualifiedContext<ParserRuleContext>>>();
128+
_contexts = new Dictionary<QualifiedModuleName, List<QualifiedContext<TContext>>>();
121129
}
122130

123131
public QualifiedModuleName CurrentModuleName { get; set; }
124132

125-
public IReadOnlyList<QualifiedContext<ParserRuleContext>> Contexts()
133+
public IReadOnlyList<QualifiedContext<TContext>> Contexts()
126134
{
127135
return _contexts.AllValues().ToList();
128136
}
129137

130-
public IReadOnlyList<QualifiedContext<ParserRuleContext>> Contexts(QualifiedModuleName module)
138+
public IReadOnlyList<QualifiedContext<TContext>> Contexts(QualifiedModuleName module)
131139
{
132140
return _contexts.TryGetValue(module, out var contexts)
133141
? contexts
134-
: new List<QualifiedContext<ParserRuleContext>>();
142+
: new List<QualifiedContext<TContext>>();
135143
}
136144

137145
public virtual void ClearContexts()
@@ -144,17 +152,17 @@ public virtual void ClearContexts(QualifiedModuleName module)
144152
_contexts.Remove(module);
145153
}
146154

147-
protected void SaveContext(ParserRuleContext context)
155+
protected void SaveContext(TContext context)
148156
{
149157
var module = CurrentModuleName;
150-
var qualifiedContext = new QualifiedContext<ParserRuleContext>(module, context);
158+
var qualifiedContext = new QualifiedContext<TContext>(module, context);
151159
if (_contexts.TryGetValue(module, out var contexts))
152160
{
153161
contexts.Add(qualifiedContext);
154162
}
155163
else
156164
{
157-
_contexts.Add(module, new List<QualifiedContext<ParserRuleContext>>{qualifiedContext});
165+
_contexts.Add(module, new List<QualifiedContext<TContext>>{qualifiedContext});
158166
}
159167
}
160168
}

Rubberduck.CodeAnalysis/Inspections/Concrete/BooleanAssignedInIfElseInspection.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Linq;
2-
using Antlr4.Runtime;
32
using Rubberduck.Inspections.Abstract;
43
using Rubberduck.Parsing;
54
using Rubberduck.Parsing.Grammar;
@@ -37,18 +36,19 @@ namespace Rubberduck.Inspections.Concrete
3736
/// End Sub
3837
/// ]]>
3938
/// </example>
40-
public sealed class BooleanAssignedInIfElseInspection : ParseTreeInspectionBase
39+
public sealed class BooleanAssignedInIfElseInspection : ParseTreeInspectionBase<VBAParser.IfStmtContext>
4140
{
4241
public BooleanAssignedInIfElseInspection(IDeclarationFinderProvider declarationFinderProvider)
4342
: base(declarationFinderProvider)
44-
{}
43+
{
44+
ContextListener = new BooleanAssignedInIfElseListener();
45+
}
4546

46-
public override IInspectionListener Listener { get; } =
47-
new BooleanAssignedInIfElseListener();
47+
protected override IInspectionListener<VBAParser.IfStmtContext> ContextListener { get; }
4848

49-
protected override string ResultDescription(QualifiedContext<ParserRuleContext> context)
49+
protected override string ResultDescription(QualifiedContext<VBAParser.IfStmtContext> context)
5050
{
51-
var literalText = ((VBAParser.IfStmtContext) context.Context)
51+
var literalText = context.Context
5252
.block()
5353
.GetDescendent<VBAParser.LetStmtContext>()
5454
.lExpression()
@@ -59,7 +59,7 @@ protected override string ResultDescription(QualifiedContext<ParserRuleContext>
5959
literalText);
6060
}
6161

62-
public class BooleanAssignedInIfElseListener : InspectionListenerBase
62+
public class BooleanAssignedInIfElseListener : InspectionListenerBase<VBAParser.IfStmtContext>
6363
{
6464
public override void ExitIfStmt(VBAParser.IfStmtContext context)
6565
{

Rubberduck.CodeAnalysis/Inspections/Concrete/DefTypeStatementInspection.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Rubberduck.Resources.Inspections;
55
using Rubberduck.Parsing.Inspections.Abstract;
66
using Rubberduck.Parsing.Grammar;
7-
using Antlr4.Runtime;
87
using Rubberduck.Parsing;
98
using Antlr4.Runtime.Misc;
109

@@ -27,16 +26,17 @@ namespace Rubberduck.Inspections.Concrete
2726
/// End Sub
2827
/// ]]>
2928
/// </example>
30-
public sealed class DefTypeStatementInspection : ParseTreeInspectionBase
29+
public sealed class DefTypeStatementInspection : ParseTreeInspectionBase<VBAParser.DefTypeContext>
3130
{
3231
public DefTypeStatementInspection(IDeclarationFinderProvider declarationFinderProvider)
3332
: base(declarationFinderProvider)
3433
{
35-
Listener = new DefTypeStatementInspectionListener();
34+
ContextListener = new DefTypeStatementInspectionListener();
3635
}
3736

38-
public override IInspectionListener Listener { get; }
39-
protected override string ResultDescription(QualifiedContext<ParserRuleContext> context)
37+
protected override IInspectionListener<VBAParser.DefTypeContext> ContextListener { get; }
38+
39+
protected override string ResultDescription(QualifiedContext<VBAParser.DefTypeContext> context)
4040
{
4141
var typeName = GetTypeOfDefType(context.Context.start.Text);
4242
var defStmtText = context.Context.start.Text;
@@ -68,7 +68,7 @@ private string GetTypeOfDefType(string defType)
6868
{ "DefVar", "Variant" }
6969
};
7070

71-
public class DefTypeStatementInspectionListener : InspectionListenerBase
71+
public class DefTypeStatementInspectionListener : InspectionListenerBase<VBAParser.DefTypeContext>
7272
{
7373
public override void ExitDefType([NotNull] VBAParser.DefTypeContext context)
7474
{

Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyBlockInspectionListenerBase.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
namespace Rubberduck.Inspections.Concrete
99
{
10-
public class EmptyBlockInspectionListenerBase : InspectionListenerBase
10+
public class EmptyBlockInspectionListenerBase<TContext> : InspectionListenerBase<TContext>
11+
where TContext : ParserRuleContext
1112
{
12-
public void InspectBlockForExecutableStatements<T>(VBAParser.BlockContext block, T context) where T : ParserRuleContext
13+
public void InspectBlockForExecutableStatements<T>(VBAParser.BlockContext block, T context) where T : TContext
1314
{
1415
if (!BlockContainsExecutableStatements(block))
1516
{
@@ -61,7 +62,7 @@ child is VBAParser.CommentOrAnnotationContext ||
6162
return false;
6263
}
6364

64-
public void InspectBlockForExecutableStatements<T>(VBAParser.UnterminatedBlockContext block, T context) where T : ParserRuleContext
65+
public void InspectBlockForExecutableStatements<T>(VBAParser.UnterminatedBlockContext block, T context) where T : TContext
6566
{
6667
if (!BlockContainsExecutableStatements(block))
6768
{

Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyCaseBlockInspection.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Rubberduck.Parsing.Inspections.Abstract;
66
using Rubberduck.Resources.Inspections;
77
using Rubberduck.Parsing.VBA;
8-
using Antlr4.Runtime;
98
using Rubberduck.Resources.Experimentals;
109
using Rubberduck.Parsing;
1110

@@ -41,21 +40,22 @@ namespace Rubberduck.Inspections.Concrete
4140
/// ]]>
4241
/// </example>
4342
[Experimental(nameof(ExperimentalNames.EmptyBlockInspections))]
44-
internal class EmptyCaseBlockInspection : ParseTreeInspectionBase
43+
internal sealed class EmptyCaseBlockInspection : ParseTreeInspectionBase<VBAParser.CaseClauseContext>
4544
{
4645
public EmptyCaseBlockInspection(IDeclarationFinderProvider declarationFinderProvider)
4746
: base(declarationFinderProvider)
48-
{}
47+
{
48+
ContextListener = new EmptyCaseBlockListener();
49+
}
4950

50-
public override IInspectionListener Listener { get; } =
51-
new EmptyCaseBlockListener();
51+
protected override IInspectionListener<VBAParser.CaseClauseContext> ContextListener { get; }
5252

53-
protected override string ResultDescription(QualifiedContext<ParserRuleContext> context)
53+
protected override string ResultDescription(QualifiedContext<VBAParser.CaseClauseContext> context)
5454
{
5555
return InspectionResults.EmptyCaseBlockInspection;
5656
}
5757

58-
public class EmptyCaseBlockListener : EmptyBlockInspectionListenerBase
58+
public class EmptyCaseBlockListener : EmptyBlockInspectionListenerBase<VBAParser.CaseClauseContext>
5959
{
6060
public override void EnterCaseClause([NotNull] VBAParser.CaseClauseContext context)
6161
{

Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyDoWhileBlockInspection.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Rubberduck.Parsing.Inspections.Abstract;
66
using Rubberduck.Resources.Inspections;
77
using Rubberduck.Parsing.VBA;
8-
using Antlr4.Runtime;
98
using Rubberduck.Resources.Experimentals;
109
using Rubberduck.Parsing;
1110

@@ -36,20 +35,22 @@ namespace Rubberduck.Inspections.Concrete
3635
/// ]]>
3736
/// </example>
3837
[Experimental(nameof(ExperimentalNames.EmptyBlockInspections))]
39-
internal class EmptyDoWhileBlockInspection : ParseTreeInspectionBase
38+
internal sealed class EmptyDoWhileBlockInspection : ParseTreeInspectionBase<VBAParser.DoLoopStmtContext>
4039
{
4140
public EmptyDoWhileBlockInspection(IDeclarationFinderProvider declarationFinderProvider)
4241
: base(declarationFinderProvider)
43-
{}
42+
{
43+
ContextListener = new EmptyDoWhileBlockListener();
44+
}
4445

45-
protected override string ResultDescription(QualifiedContext<ParserRuleContext> context)
46+
protected override IInspectionListener<VBAParser.DoLoopStmtContext> ContextListener { get; }
47+
48+
protected override string ResultDescription(QualifiedContext<VBAParser.DoLoopStmtContext> context)
4649
{
4750
return InspectionResults.EmptyDoWhileBlockInspection;
4851
}
4952

50-
public override IInspectionListener Listener { get; } = new EmptyDoWhileBlockListener();
51-
52-
public class EmptyDoWhileBlockListener : EmptyBlockInspectionListenerBase
53+
public class EmptyDoWhileBlockListener : EmptyBlockInspectionListenerBase<VBAParser.DoLoopStmtContext>
5354
{
5455
public override void EnterDoLoopStmt([NotNull] VBAParser.DoLoopStmtContext context)
5556
{

Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyElseBlockInspection.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using Rubberduck.Parsing.Inspections.Abstract;
66
using Rubberduck.Resources.Inspections;
77
using Rubberduck.Parsing.VBA;
8-
using Antlr4.Runtime;
98
using Rubberduck.Resources.Experimentals;
109
using Rubberduck.Parsing;
1110

@@ -38,21 +37,22 @@ namespace Rubberduck.Inspections.Concrete
3837
/// ]]>
3938
/// </example>
4039
[Experimental(nameof(ExperimentalNames.EmptyBlockInspections))]
41-
internal class EmptyElseBlockInspection : ParseTreeInspectionBase
40+
internal sealed class EmptyElseBlockInspection : ParseTreeInspectionBase<VBAParser.ElseBlockContext>
4241
{
4342
public EmptyElseBlockInspection(IDeclarationFinderProvider declarationFinderProvider)
4443
: base(declarationFinderProvider)
45-
{}
44+
{
45+
ContextListener = new EmptyElseBlockListener();
46+
}
47+
48+
protected override IInspectionListener<VBAParser.ElseBlockContext> ContextListener { get; }
4649

47-
protected override string ResultDescription(QualifiedContext<ParserRuleContext> context)
50+
protected override string ResultDescription(QualifiedContext<VBAParser.ElseBlockContext> context)
4851
{
4952
return InspectionResults.EmptyElseBlockInspection;
5053
}
5154

52-
public override IInspectionListener Listener { get; }
53-
= new EmptyElseBlockListener();
54-
55-
public class EmptyElseBlockListener : EmptyBlockInspectionListenerBase
55+
public class EmptyElseBlockListener : EmptyBlockInspectionListenerBase<VBAParser.ElseBlockContext>
5656
{
5757
public override void EnterElseBlock([NotNull] VBAParser.ElseBlockContext context)
5858
{

0 commit comments

Comments
 (0)