Skip to content

Commit 13ae992

Browse files
authored
Merge pull request #4695 from MDoerner/InvalidateInspectionResultsAfterParsing
Invalidate inspection results after parsing
2 parents e543769 + d372794 commit 13ae992

File tree

10 files changed

+269
-13
lines changed

10 files changed

+269
-13
lines changed

Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,5 +166,10 @@ public IEnumerable<IInspectionResult> GetInspectionResults(CancellationToken tok
166166
_logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms", GetType().Name, nameof(DoGetInspectionResults), _stopwatch.ElapsedMilliseconds);
167167
return result;
168168
}
169+
170+
public virtual bool ChangesInvalidateResult(IInspectionResult result, ICollection<QualifiedModuleName> modifiedModules)
171+
{
172+
return true;
173+
}
169174
}
170175
}

Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionResultBase.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.IO;
1+
using System.Collections.Generic;
2+
using System.IO;
23
using Antlr4.Runtime;
34
using Rubberduck.Common;
45
using Rubberduck.Parsing.Inspections;
@@ -39,6 +40,12 @@ protected InspectionResultBase(IInspection inspection,
3940
public Declaration Target { get; }
4041
public dynamic Properties { get; }
4142

43+
public virtual bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
44+
{
45+
return modifiedModules.Contains(QualifiedName)
46+
|| Inspection.ChangesInvalidateResult(this, modifiedModules);
47+
}
48+
4249
/// <summary>
4350
/// Gets the information needed to select the target instruction in the VBE.
4451
/// </summary>

Rubberduck.CodeAnalysis/Inspections/Results/DeclarationInspectionResult.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using Rubberduck.Inspections.Abstract;
1+
using System.Collections.Generic;
2+
using Rubberduck.Inspections.Abstract;
23
using Rubberduck.Parsing;
34
using Rubberduck.Parsing.Inspections.Abstract;
45
using Rubberduck.Parsing.Symbols;
56
using Rubberduck.VBEditor;
67

78
namespace Rubberduck.Inspections.Results
89
{
9-
internal class DeclarationInspectionResult : InspectionResultBase
10+
public class DeclarationInspectionResult : InspectionResultBase
1011
{
1112
public DeclarationInspectionResult(IInspection inspection, string description, Declaration target, QualifiedContext context = null, dynamic properties = null) :
1213
base(inspection,
@@ -31,5 +32,11 @@ public DeclarationInspectionResult(IInspection inspection, string description, D
3132
? target.QualifiedName
3233
: GetQualifiedMemberName(target.ParentDeclaration);
3334
}
35+
36+
public override bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
37+
{
38+
return modifiedModules.Contains(Target.QualifiedModuleName)
39+
|| base.ChangesInvalidateResult(modifiedModules);
40+
}
3441
}
3542
}
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Linq;
1+
using System.Collections.Generic;
2+
using System.Linq;
23
using Rubberduck.Inspections.Abstract;
34
using Rubberduck.Parsing;
45
using Rubberduck.Parsing.Inspections.Abstract;
@@ -8,24 +9,30 @@
89

910
namespace Rubberduck.Inspections.Results
1011
{
11-
internal class IdentifierReferenceInspectionResult : InspectionResultBase
12+
public class IdentifierReferenceInspectionResult : InspectionResultBase
1213
{
13-
public IdentifierReferenceInspectionResult(IInspection inspection, string description, RubberduckParserState state, IdentifierReference reference, dynamic properties = null) :
14+
public IdentifierReferenceInspectionResult(IInspection inspection, string description, IDeclarationFinderProvider declarationFinderProvider, IdentifierReference reference, dynamic properties = null) :
1415
base(inspection,
1516
description,
1617
reference.QualifiedModuleName,
1718
reference.Context,
1819
reference.Declaration,
1920
new QualifiedSelection(reference.QualifiedModuleName, reference.Context.GetSelection()),
20-
GetQualifiedMemberName(state, reference),
21+
GetQualifiedMemberName(declarationFinderProvider, reference),
2122
(object)properties)
2223
{
2324
}
2425

25-
private static QualifiedMemberName? GetQualifiedMemberName(RubberduckParserState state, IdentifierReference reference)
26+
private static QualifiedMemberName? GetQualifiedMemberName(IDeclarationFinderProvider declarationFinderProvider, IdentifierReference reference)
2627
{
27-
var members = state.DeclarationFinder.Members(reference.QualifiedModuleName);
28+
var members = declarationFinderProvider.DeclarationFinder.Members(reference.QualifiedModuleName);
2829
return members.SingleOrDefault(m => reference.Context.IsDescendentOf(m.Context))?.QualifiedName;
2930
}
31+
32+
public override bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
33+
{
34+
return modifiedModules.Contains(Target.QualifiedModuleName)
35+
|| base.ChangesInvalidateResult(modifiedModules);
36+
}
3037
}
3138
}

Rubberduck.CodeAnalysis/Inspections/Results/QualifiedContextInspectionResult.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Rubberduck.Inspections.Results
77
{
8-
internal class QualifiedContextInspectionResult : InspectionResultBase
8+
public class QualifiedContextInspectionResult : InspectionResultBase
99
{
1010
public QualifiedContextInspectionResult(IInspection inspection, string description, QualifiedContext context, dynamic properties = null) :
1111
base(inspection,
@@ -16,7 +16,6 @@ public QualifiedContextInspectionResult(IInspection inspection, string descripti
1616
new QualifiedSelection(context.ModuleName, context.Context.GetSelection()),
1717
context.MemberName,
1818
(object)properties)
19-
{
20-
}
19+
{}
2120
}
2221
}

Rubberduck.Core/UI/Inspections/AggregateInspectionResult.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using Antlr4.Runtime;
34
using Rubberduck.Parsing.Inspections.Abstract;
45
using Rubberduck.Parsing.Symbols;
@@ -29,6 +30,8 @@ public AggregateInspectionResult(IInspectionResult firstResult, int count)
2930

3031
public dynamic Properties => throw new InvalidOperationException();
3132

33+
public virtual bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules) => true;
34+
3235
public int CompareTo(IInspectionResult other)
3336
{
3437
if (other == this)

Rubberduck.Core/UI/Inspections/InspectionResultsViewModel.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
using Rubberduck.Parsing.Inspections.Abstract;
1515
using Rubberduck.Parsing.UIContext;
1616
using Rubberduck.Parsing.VBA;
17+
using Rubberduck.Parsing.VBA.Extensions;
1718
using Rubberduck.Settings;
1819
using Rubberduck.UI.Command;
19-
using Rubberduck.UI.Controls;
2020
using Rubberduck.UI.Settings;
21+
using Rubberduck.VBEditor;
2122

2223
namespace Rubberduck.UI.Inspections
2324
{
@@ -383,6 +384,12 @@ private void HandleStateChanged(object sender, ParserStateEventArgs e)
383384
{
384385
RefreshInspections(e.Token);
385386
}
387+
else
388+
{
389+
//Todo: Find a way to get the actually modified modules in here.
390+
var modifiedModules = _state.DeclarationFinder.AllModules.ToHashSet();
391+
InvalidateStaleInspectionResults(modifiedModules);
392+
}
386393
}
387394

388395
private async void RefreshInspections(CancellationToken token)
@@ -442,6 +449,18 @@ private async void RefreshInspections(CancellationToken token)
442449
LogManager.GetCurrentClassLogger().Trace("Inspections loaded in {0}ms", stopwatch.ElapsedMilliseconds);
443450
}
444451

452+
private void InvalidateStaleInspectionResults(ICollection<QualifiedModuleName> modifiedModules)
453+
{
454+
var staleResults = Results.Where(result => result.ChangesInvalidateResult(modifiedModules)).ToList();
455+
_uiDispatcher.Invoke(() =>
456+
{
457+
foreach (var staleResult in staleResults)
458+
{
459+
Results.Remove(staleResult);
460+
}
461+
});
462+
}
463+
445464
private void ExecuteQuickFixCommand(object parameter)
446465
{
447466
var quickFix = parameter as IQuickFix;

Rubberduck.Parsing/Inspections/Abstract/IInspection.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Threading;
4+
using Rubberduck.VBEditor;
45

56
namespace Rubberduck.Parsing.Inspections.Abstract
67
{
@@ -15,5 +16,10 @@ public interface IInspection : IInspectionModel, IComparable<IInspection>, IComp
1516
/// <param name="token"></param>
1617
/// <returns>Returns inspection results, if any.</returns>
1718
IEnumerable<IInspectionResult> GetInspectionResults(CancellationToken token);
19+
20+
/// <summary>
21+
/// Specifies whether an inspection result is deemed invalid after the specified modules have changed.
22+
/// </summary>
23+
bool ChangesInvalidateResult(IInspectionResult result, ICollection<QualifiedModuleName> modifiedModules);
1824
}
1925
}

Rubberduck.Parsing/Inspections/Abstract/IInspectionResult.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using Antlr4.Runtime;
34
using Rubberduck.Parsing.Symbols;
45
using Rubberduck.VBEditor;
@@ -14,5 +15,6 @@ public interface IInspectionResult : IComparable<IInspectionResult>, IComparable
1415
Declaration Target { get; }
1516
ParserRuleContext Context { get; }
1617
dynamic Properties { get; }
18+
bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules);
1719
}
1820
}

0 commit comments

Comments
 (0)