Backend/ReSharperPlugin/ForTea.ReSharperPlugin/Psi/Resolve/Macros/T4MacroResolutionCache.T4AfterMacroCacheBuiltFileInvalidator.cs (58 lines of code) (raw):
using System.Collections.Generic;
using JetBrains.Annotations;
using JetBrains.Application.ContentModel;
using JetBrains.Application.Parts;
using JetBrains.Application.Threading;
using JetBrains.Lifetimes;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Caches;
using JetBrains.ReSharper.Resources.Shell;
namespace JetBrains.ForTea.ReSharperPlugin.Psi.Resolve.Macros
{
[SolutionComponent(InstantiationEx.LegacyDefault)]
public sealed class T4AfterMacroCacheBuiltFileInvalidator
{
private Lifetime Lifetime { get; }
[NotNull] private List<IPsiSourceFile> FilesToInvalidate { get; set; } = new();
[NotNull] private IPsiServices Services { get; }
public T4AfterMacroCacheBuiltFileInvalidator(
Lifetime lifetime,
[NotNull] IPsiServices services,
[NotNull] IPsiCachesState state,
[NotNull] T4MacroResolutionCache cache)
{
Lifetime = lifetime;
Services = services;
services.Files.ObserveAfterCommit(lifetime, QueueAfterCommit);
state.IsInitialUpdateFinished.Change.Advise(lifetime, args =>
{
if (args.HasNew && args.New)
{
QueueAfterCommit();
}
});
cache.OnFileMarkedForInvalidation.Advise(lifetime, FilesToInvalidate.Add);
}
private void QueueAfterCommit()
{
if (ContentModelFork.IsCurrentlyForked)
return; // no forks support
Services.Locks.ExecuteOrQueue(Lifetime,
"T4 file invalidation caused by a change in macros in that file", () =>
{
AfterCommitSync(FilesToInvalidate);
FilesToInvalidate = new();
});
}
private void AfterCommitSync([NotNull] IEnumerable<IPsiSourceFile> filesToInvalidate)
{
using var cookie = WriteLockCookie.Create();
foreach (var file in filesToInvalidate)
{
Services.Caches.MarkAsDirty(file);
Services.Files.MarkAsDirty(file);
}
}
}
}