public BinaryUnityFileCache(Lifetime lifetime, ISolution solution, IPersistentIndexManager persistentIndexManager, IShellLocks locks, ChangeManager changeManager) : base(lifetime, persistentIndexManager, BinaryFileCacheItem.Marshaller) { myGroupingEvent = solution.Locks.GroupingEvents.CreateEvent(lifetime, "UnityRefresherOnSaveEvent", TimeSpan.FromMilliseconds(500), Rgc.Guarded, () => { var changedFiles = new JetHashSet <IPsiSourceFile>(myChangedFiles); myChangedFiles.Clear(); if (changedFiles.Count > 0) { locks.ExecuteWithWriteLock(() => changeManager.ExecuteAfterChange(() => { var builder = new PsiModuleChangeBuilder(); foreach (var file in changedFiles) { if (file.IsValid()) { builder.AddFileChange(file, PsiModuleChange.ChangeType.Modified); } } changeManager.OnProviderChanged(solution, builder.Result, SimpleTaskExecutor.Instance); })); } }); myChangedFiles = new JetHashSet <IPsiSourceFile>(); }
public UnityCacheUpdater(Lifetime lifetime, ISolution solution, UnityYamlSupport unityYamlSupport, IShellLocks locks, ChangeManager changeManager, UnityExternalFilesModuleFactory factory) { var module = factory.PsiModule; if (module != null) { unityYamlSupport.IsUnityYamlParsingEnabled.Change.Advise_NoAcknowledgement(lifetime, (handler) => { if (handler.HasNew && handler.HasOld && handler.New == handler.Old) { return; } locks.ExecuteOrQueueReadLockEx(lifetime, "YamlParsingStateChange", () => { var psiSourceFiles = module.SourceFiles.ToList(); if (psiSourceFiles.Any()) { locks.ExecuteWithWriteLock(() => changeManager.ExecuteAfterChange(() => { var changeBuilder = new PsiModuleChangeBuilder(); foreach (var sourceFile in psiSourceFiles) { if (sourceFile.IsValid()) { changeBuilder.AddFileChange(sourceFile, PsiModuleChange.ChangeType.Modified); } } changeManager.OnProviderChanged(solution, changeBuilder.Result, SimpleTaskExecutor.Instance); })); } }); }); } }
/// <summary>Called when the associated data file changed: added/removed assemblies or includes.</summary> /// <param name="dataDiff">The difference between the old and new data.</param> private void OnFileDataChanged([NotNull] T4DeclaredAssembliesDiff dataDiff) { ShellLocks.AssertWriteAccessAllowed(); if (!AssemblyReferenceManager.ProcessDiff(dataDiff)) { return; } var changeBuilder = new PsiModuleChangeBuilder(); changeBuilder.AddModuleChange(this, PsiModuleChange.ChangeType.Modified); // TODO: get rid of this queuing? ShellLocks.ExecuteOrQueueEx( "T4PsiModuleChange", () => ChangeManager.ExecuteAfterChange( () => ShellLocks.ExecuteWithWriteLock( () => { if (!IsValid()) { return; } ChangeManager.OnProviderChanged( ChangeProvider, changeBuilder.Result, SimpleTaskExecutor.Instance ); }) ) ); }
private void NotifyModuleChange() { var changeBuilder = new PsiModuleChangeBuilder(); changeBuilder.AddModuleChange(this, PsiModuleChange.ChangeType.Modified); // TODO: get rid of this queuing? ShellLocks.ExecuteOrQueueEx( "T4PsiModuleChange", () => ChangeManager.ExecuteAfterChange( () => ShellLocks.ExecuteWithWriteLock( () => ChangeManager.OnProviderChanged( ChangeProvider, changeBuilder.Result, SimpleTaskExecutor.Instance ) ) ) ); }
/// <summary> /// Called when the associated data file changed: added/removed assemblies or includes. /// </summary> /// <param name="dataDiff">The difference between the old and new data.</param> private void OnDataFileChanged([NotNull] T4FileDataDiff dataDiff) { _shellLocks.AssertWriteAccessAllowed(); bool hasFileChanges = ResolveMacros(dataDiff.AddedMacros); bool hasChanges = hasFileChanges; ITextTemplatingComponents components = _t4Environment.Components.CanBeNull; using (components.With(TryGetVsHierarchy(), _projectFile.Location)) { // removes the assembly references from the old assembly directives foreach (string removedAssembly in dataDiff.RemovedAssemblies) { string assembly = removedAssembly; if (components != null) { assembly = components.Host.ResolveAssemblyReference(assembly); } IAssemblyCookie cookie; if (!_assemblyReferences.TryGetValue(assembly, out cookie)) { continue; } _assemblyReferences.Remove(assembly); hasChanges = true; cookie.Dispose(); } // adds assembly references from the new assembly directives foreach (string addedAssembly in dataDiff.AddedAssemblies) { string assembly = addedAssembly; if (components != null) { assembly = components.Host.ResolveAssemblyReference(assembly); } if (assembly == null) { continue; } if (_assemblyReferences.ContainsKey(assembly)) { continue; } IAssemblyCookie cookie = TryAddReference(assembly); if (cookie != null) { hasChanges = true; } } } if (!hasChanges) { return; } // tells the world the module has changed var changeBuilder = new PsiModuleChangeBuilder(); changeBuilder.AddModuleChange(this, PsiModuleChange.ChangeType.Modified); if (hasFileChanges) { GetPsiServices().MarkAsDirty(SourceFile); } _shellLocks.ExecuteOrQueue("T4PsiModuleChange", () => _changeManager.ExecuteAfterChange( () => _shellLocks.ExecuteWithWriteLock( () => _changeManager.OnProviderChanged(this, changeBuilder.Result, SimpleTaskExecutor.Instance)) ) ); }
/// <summary> /// Called when the associated data file changed: added/removed assemblies or includes. /// </summary> /// <param name="dataDiff">The difference between the old and new data.</param> private void OnDataFileChanged([NotNull] T4FileDataDiff dataDiff) { _shellLocks.AssertWriteAccessAllowed(); bool hasFileChanges = ResolveMacros(dataDiff.AddedMacros); bool hasChanges = hasFileChanges; IDictionary <string, string> resolvedMacros = GetResolvedMacros(); // removes the assembly references from the old assembly directives foreach (string removedAssembly in dataDiff.RemovedAssemblies) { string assembly = VsBuildMacroHelper.ResolveMacros(removedAssembly, resolvedMacros); IAssemblyCookie cookie; if (!_assemblyReferences.TryGetValue(assembly, out cookie)) { continue; } _assemblyReferences.Remove(assembly); hasChanges = true; cookie.Dispose(); } // adds assembly references from the new assembly directives foreach (string addedAssembly in dataDiff.AddedAssemblies) { string assembly = VsBuildMacroHelper.ResolveMacros(addedAssembly, resolvedMacros); if (_assemblyReferences.ContainsKey(assembly)) { continue; } IAssemblyCookie cookie = TryAddReference(assembly); if (cookie != null) { hasChanges = true; } } if (!hasChanges) { return; } // tells the world the module has changed var changeBuilder = new PsiModuleChangeBuilder(); changeBuilder.AddModuleChange(this, ModifiedChangeType); if (hasFileChanges) { GetPsiServices().MarkAsDirty(_sourceFile); } _shellLocks.ExecuteOrQueue("T4PsiModuleChange", () => _changeManager.ExecuteAfterChange( () => _shellLocks.ExecuteWithWriteLock( () => _changeManager.OnProviderChanged(this, changeBuilder.Result, SimpleTaskExecutor.Instance)) ) ); }