Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalidate inspection results after parsing #4695

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,10 @@ public IEnumerable<IInspectionResult> GetInspectionResults(CancellationToken tok
_logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms", GetType().Name, nameof(DoGetInspectionResults), _stopwatch.ElapsedMilliseconds);
return result;
}

public virtual bool ChangesInvalidateResult(IInspectionResult result, ICollection<QualifiedModuleName> modifiedModules)
{
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using Antlr4.Runtime;
using Rubberduck.Common;
using Rubberduck.Parsing.Inspections;
Expand Down Expand Up @@ -39,6 +40,12 @@ public abstract class InspectionResultBase : IInspectionResult, INavigateSource,
public Declaration Target { get; }
public dynamic Properties { get; }

public virtual bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
{
return modifiedModules.Contains(QualifiedName)
|| Inspection.ChangesInvalidateResult(this, modifiedModules);
}

/// <summary>
/// Gets the information needed to select the target instruction in the VBE.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using Rubberduck.Inspections.Abstract;
using System.Collections.Generic;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Parsing.Symbols;
using Rubberduck.VBEditor;

namespace Rubberduck.Inspections.Results
{
internal class DeclarationInspectionResult : InspectionResultBase
public class DeclarationInspectionResult : InspectionResultBase
{
public DeclarationInspectionResult(IInspection inspection, string description, Declaration target, QualifiedContext context = null, dynamic properties = null) :
base(inspection,
Expand All @@ -31,5 +32,11 @@ internal class DeclarationInspectionResult : InspectionResultBase
? target.QualifiedName
: GetQualifiedMemberName(target.ParentDeclaration);
}

public override bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
{
return modifiedModules.Contains(Target.QualifiedModuleName)
|| base.ChangesInvalidateResult(modifiedModules);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Inspections.Abstract;
Expand All @@ -8,24 +9,30 @@

namespace Rubberduck.Inspections.Results
{
internal class IdentifierReferenceInspectionResult : InspectionResultBase
public class IdentifierReferenceInspectionResult : InspectionResultBase
{
public IdentifierReferenceInspectionResult(IInspection inspection, string description, RubberduckParserState state, IdentifierReference reference, dynamic properties = null) :
public IdentifierReferenceInspectionResult(IInspection inspection, string description, IDeclarationFinderProvider declarationFinderProvider, IdentifierReference reference, dynamic properties = null) :
base(inspection,
description,
reference.QualifiedModuleName,
reference.Context,
reference.Declaration,
new QualifiedSelection(reference.QualifiedModuleName, reference.Context.GetSelection()),
GetQualifiedMemberName(state, reference),
GetQualifiedMemberName(declarationFinderProvider, reference),
(object)properties)
{
}

private static QualifiedMemberName? GetQualifiedMemberName(RubberduckParserState state, IdentifierReference reference)
private static QualifiedMemberName? GetQualifiedMemberName(IDeclarationFinderProvider declarationFinderProvider, IdentifierReference reference)
{
var members = state.DeclarationFinder.Members(reference.QualifiedModuleName);
var members = declarationFinderProvider.DeclarationFinder.Members(reference.QualifiedModuleName);
return members.SingleOrDefault(m => reference.Context.IsDescendentOf(m.Context))?.QualifiedName;
}

public override bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
{
return modifiedModules.Contains(Target.QualifiedModuleName)
|| base.ChangesInvalidateResult(modifiedModules);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Rubberduck.Inspections.Results
{
internal class QualifiedContextInspectionResult : InspectionResultBase
public class QualifiedContextInspectionResult : InspectionResultBase
{
public QualifiedContextInspectionResult(IInspection inspection, string description, QualifiedContext context, dynamic properties = null) :
base(inspection,
Expand All @@ -16,7 +16,6 @@ internal class QualifiedContextInspectionResult : InspectionResultBase
new QualifiedSelection(context.ModuleName, context.Context.GetSelection()),
context.MemberName,
(object)properties)
{
}
{}
}
}
3 changes: 3 additions & 0 deletions Rubberduck.Core/UI/Inspections/AggregateInspectionResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Parsing.Symbols;
Expand Down Expand Up @@ -29,6 +30,8 @@ public AggregateInspectionResult(IInspectionResult firstResult, int count)

public dynamic Properties => throw new InvalidOperationException();

public virtual bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules) => true;

public int CompareTo(IInspectionResult other)
{
if (other == this)
Expand Down
21 changes: 20 additions & 1 deletion Rubberduck.Core/UI/Inspections/InspectionResultsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Parsing.UIContext;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.Extensions;
using Rubberduck.Settings;
using Rubberduck.UI.Command;
using Rubberduck.UI.Controls;
using Rubberduck.UI.Settings;
using Rubberduck.VBEditor;

namespace Rubberduck.UI.Inspections
{
Expand Down Expand Up @@ -383,6 +384,12 @@ private void HandleStateChanged(object sender, ParserStateEventArgs e)
{
RefreshInspections(e.Token);
}
else
{
//Todo: Find a way to get the actually modified modules in here.
var modifiedModules = _state.DeclarationFinder.AllModules.ToHashSet();
InvalidateStaleInspectionResults(modifiedModules);
}
}

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

private void InvalidateStaleInspectionResults(ICollection<QualifiedModuleName> modifiedModules)
{
var staleResults = Results.Where(result => result.ChangesInvalidateResult(modifiedModules)).ToList();
_uiDispatcher.Invoke(() =>
{
foreach (var staleResult in staleResults)
{
Results.Remove(staleResult);
}
});
}

private void ExecuteQuickFixCommand(object parameter)
{
var quickFix = parameter as IQuickFix;
Expand Down
6 changes: 6 additions & 0 deletions Rubberduck.Parsing/Inspections/Abstract/IInspection.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
using Rubberduck.VBEditor;

namespace Rubberduck.Parsing.Inspections.Abstract
{
Expand All @@ -15,5 +16,10 @@ public interface IInspection : IInspectionModel, IComparable<IInspection>, IComp
/// <param name="token"></param>
/// <returns>Returns inspection results, if any.</returns>
IEnumerable<IInspectionResult> GetInspectionResults(CancellationToken token);

/// <summary>
/// Specifies whether an inspection result is deemed invalid after the specified modules have changed.
/// </summary>
bool ChangesInvalidateResult(IInspectionResult result, ICollection<QualifiedModuleName> modifiedModules);
}
}
2 changes: 2 additions & 0 deletions Rubberduck.Parsing/Inspections/Abstract/IInspectionResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Rubberduck.Parsing.Symbols;
using Rubberduck.VBEditor;
Expand All @@ -14,5 +15,6 @@ public interface IInspectionResult : IComparable<IInspectionResult>, IComparable
Declaration Target { get; }
ParserRuleContext Context { get; }
dynamic Properties { get; }
bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules);
}
}