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); })); } }); }); } }
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 object Execute(IChangeMap changeMap) { var change = changeMap.GetChange <ProjectModelChange>(mySolution); if (change == null) { return(null); } var projects = new JetHashSet <IProject>(); var unresolved = GetUnresolvedReferences(change); foreach (var reference in unresolved) { { myLogger.Warn($"Unresolved Unity reference: {reference.ReferenceTarget.AssemblyName}"); projects.Add(reference.GetProject()); } } foreach (var project in projects) { myChangeManager.ExecuteAfterChange(() => { Handle(project); }); } return(null); }
object IChangeProvider.Execute(IChangeMap changeMap) { var projectModelChange = changeMap.GetChange <ProjectModelChange>(mySolution); if (projectModelChange == null) { return(null); } // ReSharper hasn't necessarily processed all references when it adds the IProject // to the IViewableProjectsCollection. Keep an eye on reference changes, add the // project settings if/when the project becomes a unity project var projects = new JetHashSet <IProject>(); var changes = ReferencedAssembliesService.TryGetAssemblyReferenceChanges(projectModelChange, ProjectExtensions.UnityReferenceNames); foreach (var change in changes) { projects.Add(change.GetNewProject()); } foreach (var project in projects) { myChangeManager.ExecuteAfterChange(() => { if (project.IsUnityProject()) { Handle(project); } }); } return(null); }
/// <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 ); }) ) ); }
object IChangeProvider.Execute(IChangeMap changeMap) { var projectModelChange = changeMap.GetChange <ProjectModelChange>(mySolution); if (projectModelChange == null) { return(null); } var changes = ReferencedAssembliesService.TryGetAssemblyReferenceChanges(projectModelChange, ourUnityReferenceNameInfos, myLogger); var newUnityProjects = new List <KeyValuePair <IProject, Lifetime> >(); foreach (var change in changes) { if (change.IsAdded) { var project = change.GetNewProject(); if (HasUnityReferenceOrFlavour(project)) { Assertion.Assert(myAllProjectLifetimes.ContainsKey(project), "project is not added"); if (myAllProjectLifetimes.TryGetValue(project, out var projectLifetime)) { newUnityProjects.Add(JetKeyValuePair.Of(project, projectLifetime)); if (!myUnityProjects.Contains(project)) { myUnityProjects.Add(projectLifetime, project); } } } } } if (newUnityProjects.Count > 0) { myChangeManager.ExecuteAfterChange(() => { NotifyHasUnityReference(); NotifyOnUnityProjectAdded(newUnityProjects); }); } return(null); }
public T4FilePsiModule( Lifetime lifetime, [NotNull] IProjectFile projectFile, [NotNull] ChangeManager changeManager, [NotNull] IShellLocks shellLocks, [NotNull] IT4Environment t4Environment ) { Lifetime = lifetime; lifetime.AddDispose(this); ProjectFile = projectFile; Solution = ProjectFile.GetSolution(); PsiModules = Solution.GetComponent <IPsiModules>(); PsiServices = Solution.GetComponent <IPsiServices>(); ChangeManager = changeManager; ShellLocks = shellLocks; ChangeProvider = new FakeChangeProvider(); TargetFrameworkId = ProjectFile.SelectTargetFrameworkId(t4Environment); Project = ProjectFile.GetProject().NotNull(); var resolveContext = Project.IsMiscFilesProject() ? UniversalModuleReferenceContext.Instance : this.GetResolveContextEx(ProjectFile); AssemblyReferenceManager = new T4AssemblyReferenceManager( Solution.GetComponent <IAssemblyFactory>(), SourceFile, ProjectFile, resolveContext, shellLocks ); ProjectReferenceManager = new T4ProjectReferenceManager(ProjectFile, Solution); changeManager.RegisterChangeProvider(lifetime, ChangeProvider); changeManager.AddDependency(lifetime, PsiModules, ChangeProvider); var documentManager = Solution.GetComponent <DocumentManager>(); SourceFile = CreateSourceFile(ProjectFile, documentManager); Solution.GetComponent <T4DeclaredAssembliesManager>().FileDataChanged.Advise(lifetime, OnFileDataChanged); ChangeManager.ExecuteAfterChange(() => { AssemblyReferenceManager.AddBaseReferences(); NotifyModuleChange(); }); }
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 ) ) ) ); }
object IChangeProvider.Execute(IChangeMap changeMap) { var projectModelChange = changeMap.GetChange <ProjectModelChange>(mySolution); if (projectModelChange == null) { return(null); } var changes = ReferencedAssembliesService.TryGetAssemblyReferenceChanges(projectModelChange, ProjectExtensions.UnityReferenceNames, myLogger); var newUnityProjects = new JetHashSet <IProject>(); foreach (var change in changes) { if (change.IsAdded) { var project = change.GetNewProject(); if (project.IsUnityProject()) { newUnityProjects.Add(project); } } } myChangeManager.ExecuteAfterChange(() => { foreach (var project in newUnityProjects) { OnUnityProjectAdded(project); } }); return(null); }
/// <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)) ) ); }