protected Task RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind kind, Solution oldSolution, Solution newSolution, ProjectId projectId = null, DocumentId documentId = null) { if (newSolution == null) { throw new ArgumentNullException("newSolution"); } if (oldSolution == newSolution) { return SpecializedTasks.EmptyTask; } if (projectId == null && documentId != null) { projectId = documentId.ProjectId; } var handlers = this.eventMap.GetEventHandlers<EventHandler<WorkspaceChangeEventArgs>>(WorkspaceChangeEventName); if (handlers.Length > 0) { return this.ScheduleTask(() => { var args = new WorkspaceChangeEventArgs(kind, oldSolution, newSolution, projectId, documentId); foreach (var handler in handlers) { handler(this, args); } }, "Workspace.WorkspaceChanged"); } else { return SpecializedTasks.EmptyTask; } }
protected Task RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind kind, Solution oldSolution, Solution newSolution, ProjectId projectId = null, DocumentId documentId = null) { if (newSolution == null) { throw new ArgumentNullException(nameof(newSolution)); } if (oldSolution == newSolution) { return SpecializedTasks.EmptyTask; } if (projectId == null && documentId != null) { projectId = documentId.ProjectId; } var ev = _eventMap.GetEventHandlers<EventHandler<WorkspaceChangeEventArgs>>(WorkspaceChangeEventName); if (ev.HasHandlers) { return this.ScheduleTask(() => { var args = new WorkspaceChangeEventArgs(kind, oldSolution, newSolution, projectId, documentId); ev.RaiseEvent(handler => handler(this, args)); }, "Workspace.WorkspaceChanged"); } else { return SpecializedTasks.EmptyTask; } }
public WorkspaceChangeEventArgs(WorkspaceChangeKind kind, Solution oldSolution, Solution newSolution, ProjectId projectId = null, DocumentId documentId = null) { this.Kind = kind; this.OldSolution = oldSolution; this.NewSolution = newSolution; this.ProjectId = projectId; this.DocumentId = documentId; }
public void WorkspaceChanged_SolutionEvents_EnqueuesUpdatesForProjectsInSolution(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); var e = new WorkspaceChangeEventArgs(kind, oldSolution: EmptySolution, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberOne.Id, p.workspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.workspaceProject.Id)); }
public static bool IsValid(this WorkspaceChangeKind kind) => kind >= WorkspaceChangeKind.SolutionChanged && kind <= WorkspaceChangeKind.AnalyzerConfigDocumentChanged;
public void WorkspaceChanged_SolutionEvents_ClearsExistingProjects_AddsProjectsInSolution(WorkspaceChangeKind kind) { // Arrange var trigger = new WorkspaceProjectSnapshotChangeTrigger(); var projectManager = new TestProjectSnapshotManager(new[] { trigger }, Workspace); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); trigger.Workspace_WorkspaceChanged(Workspace, e); e = new WorkspaceChangeEventArgs(kind, oldSolution: EmptySolution, newSolution: SolutionWithTwoProjects); // Act trigger.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( projectManager.Projects.OrderBy(p => p.UnderlyingProject.Name), p => Assert.Equal(ProjectNumberOne.Id, p.UnderlyingProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.UnderlyingProject.Id)); }
public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_AfterDelay(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => projectManager.ProjectAdded(HostProjectOne), CancellationToken.None).ConfigureAwait(false); var solution = SolutionWithTwoProjects.WithProjectAssemblyName(ProjectNumberOne.Id, "Changed"); var e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); var update = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(update.WorkspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(update.ProjectSnapshot.FilePath, HostProjectOne.FilePath); }
public async Task WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSolutionProjectUpdates(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue) { NotifyWorkspaceChangedEventComplete = new ManualResetEventSlim(initialState: false), }; var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); projectManager.ProjectAdded(HostProjectThree); }, CancellationToken.None).ConfigureAwait(false); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); detector.NotifyWorkspaceChangedEventComplete.Reset(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Reset(); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithOneProject, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberThree.Id, p.WorkspaceProject.Id), p => Assert.Null(p.WorkspaceProject), p => Assert.Equal(ProjectNumberOne.Id, p.WorkspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.WorkspaceProject.Id)); }
public async Task WorkspaceChanged_ProjectEvents_EnqueuesUpdatesForDependentProjects(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator, Dispatcher, WorkQueue) { NotifyWorkspaceChangedEventComplete = new ManualResetEventSlim(initialState: false), }; WorkQueueTestAccessor.BlockBackgroundWorkStart = new ManualResetEventSlim(initialState: false); var projectManager = new TestProjectSnapshotManager(Dispatcher, new[] { detector }, Workspace); await Dispatcher.RunOnDispatcherThreadAsync(() => { projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); projectManager.ProjectAdded(HostProjectThree); }, CancellationToken.None).ConfigureAwait(false); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); detector.NotifyWorkspaceChangedEventComplete.Reset(); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithOneProject, newSolution: SolutionWithDependentProject); var solution = SolutionWithDependentProject.WithProjectAssemblyName(ProjectNumberThree.Id, "Changed"); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithDependentProject, newSolution: solution, projectId: ProjectNumberThree.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); detector.NotifyWorkspaceChangedEventComplete.Wait(); // Assert Assert.Equal(3, WorkQueueTestAccessor.Work.Count); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberOne.FilePath); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberTwo.FilePath); Assert.Contains(WorkQueueTestAccessor.Work, u => u.Key == ProjectNumberThree.FilePath); WorkQueueTestAccessor.BlockBackgroundWorkStart.Set(); WorkQueueTestAccessor.NotifyBackgroundWorkCompleted.Wait(); Assert.Empty(WorkQueueTestAccessor.Work); }
public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProjectState_AfterDelay(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator) { EnqueueDelay = 1, BlockDelayedUpdateWorkEnqueue = new ManualResetEventSlim(initialState: false), }; var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); var solution = SolutionWithTwoProjects.WithProjectAssemblyName(ProjectNumberOne.Id, "Changed"); var e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Empty(workspaceStateGenerator.UpdateQueue); detector.BlockDelayedUpdateWorkEnqueue.Set(); await detector._deferredUpdates.Single().Value.Task; var(workspaceProject, projectSnapshot) = Assert.Single(workspaceStateGenerator.UpdateQueue); Assert.Equal(workspaceProject.Id, ProjectNumberOne.Id); Assert.Equal(projectSnapshot.FilePath, HostProjectOne.FilePath); }
public void WorkspaceChanged_SolutionEvents_EnqueuesStateClear_EnqueuesSolutionProjectUpdates(WorkspaceChangeKind kind) { // Arrange var workspaceStateGenerator = new TestProjectWorkspaceStateGenerator(); var detector = new WorkspaceProjectStateChangeDetector(workspaceStateGenerator); var projectManager = new TestProjectSnapshotManager(new[] { detector }, Workspace); projectManager.ProjectAdded(HostProjectOne); projectManager.ProjectAdded(HostProjectTwo); projectManager.ProjectAdded(HostProjectThree); // Initialize with a project. This will get removed. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithOneProject); detector.Workspace_WorkspaceChanged(Workspace, e); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithOneProject, newSolution: SolutionWithTwoProjects); // Act detector.Workspace_WorkspaceChanged(Workspace, e); // Assert Assert.Collection( workspaceStateGenerator.UpdateQueue, p => Assert.Equal(ProjectNumberThree.Id, p.workspaceProject.Id), p => Assert.Null(p.workspaceProject), p => Assert.Equal(ProjectNumberOne.Id, p.workspaceProject.Id), p => Assert.Equal(ProjectNumberTwo.Id, p.workspaceProject.Id)); }
public async Task WorkspaceChanged_ProjectChangeEvents_UpdatesProject_AfterDelay(WorkspaceChangeKind kind) { // Arrange var trigger = new WorkspaceProjectSnapshotChangeTrigger() { ProjectChangeDelay = 50, }; var projectManager = new TestProjectSnapshotManager(new[] { trigger }, Workspace); projectManager.HostProjectAdded(HostProjectOne); projectManager.HostProjectAdded(HostProjectTwo); // Initialize with some projects. var e = new WorkspaceChangeEventArgs(WorkspaceChangeKind.SolutionAdded, oldSolution: EmptySolution, newSolution: SolutionWithTwoProjects); trigger.Workspace_WorkspaceChanged(Workspace, e); var solution = SolutionWithTwoProjects.WithProjectAssemblyName(ProjectNumberOne.Id, "Changed"); e = new WorkspaceChangeEventArgs(kind, oldSolution: SolutionWithTwoProjects, newSolution: solution, projectId: ProjectNumberOne.Id); // Act trigger.Workspace_WorkspaceChanged(Workspace, e); // Assert // // The change hasn't come through yet. Assert.Equal("One", projectManager.Projects.Single().WorkspaceProject.AssemblyName); await trigger._deferredUpdates.Single().Value; Assert.Collection( projectManager.Projects.OrderBy(p => p.WorkspaceProject.Name), p => { Assert.Equal(ProjectNumberOne.Id, p.WorkspaceProject.Id); Assert.Equal("Changed", p.WorkspaceProject.AssemblyName); }, p => Assert.Equal(ProjectNumberTwo.Id, p.WorkspaceProject.Id)); }