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

VisualStudio FileChangeWatcher doesn't correctly report changes for multiple projects #74716

Closed
svick opened this issue Aug 12, 2024 · 5 comments
Assignees
Milestone

Comments

@svick
Copy link
Contributor

svick commented Aug 12, 2024

Version Used: VS 17.10.5, Roslyn main (d939cd6)

We have noticed that in Visual Studio our incremental source generator is not regenerating its output when an additional file (that's watched by the incremental generator) is modified by an external action (i.e. the file is changed while not being opened in VS).

I was able to trace this to Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.FileChangeWatcher and specifically to the changes from #70936. Since that PR, it seems FileChangeWatcher is not reporting external changes to the correct project (files from multiple projects form a batch, and changes to these files are then all reported to the same sink, which corresponds to the first project in the batch), which is the cause of our source generator issue.

This can be seen by the following test (place it inside the Microsoft.VisualStudio..LanguageServices.UnitTests project):

Imports System.IO
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
Imports Roslyn.Test.Utilities
Imports IVsAsyncFileChangeEx2 = Microsoft.VisualStudio.Shell.IVsAsyncFileChangeEx2

Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim
    <UseExportProvider>
    Public Class FileChangeWatcherTests
        Implements IDisposable

        Private ReadOnly _tempPath As String

        Public Sub New()
            _tempPath = Path.Combine(TempRoot.Root, Path.GetRandomFileName())
            Directory.CreateDirectory(_tempPath)
        End Sub

        Private Sub Dispose() Implements IDisposable.Dispose
            Directory.Delete(_tempPath, recursive:=True)
        End Sub

        <WpfFact>
        Public Async Function WatchingMultipleContexts() As Task
            Using workspace = New EditorTestWorkspace()
                Dim fileChangeService = New MockVsFileChangeEx
                Dim fileChangeWatcher = New FileChangeWatcher(workspace.GetService(Of IAsynchronousOperationListenerProvider)(), Task.FromResult(Of IVsAsyncFileChangeEx2)(fileChangeService))

                Dim context1 = fileChangeWatcher.CreateContext()
                Dim context2 = fileChangeWatcher.CreateContext()

                Dim handler1Called As Boolean = False
                Dim handler2Called As Boolean = False

                AddHandler context1.FileChanged, Sub(sender, args) handler1Called = True
                AddHandler context2.FileChanged, Sub(sender, args) handler2Called = True

                Dim watchedFile1 = context1.EnqueueWatchingFile("file1.txt")
                Dim watchedFile2 = context2.EnqueueWatchingFile("file2.txt")

                Await workspace.GetService(Of AsynchronousOperationListenerProvider)().GetWaiter(FeatureAttribute.Workspace).ExpeditedWaitAsync()

                fileChangeService.FireUpdate("file2.txt")

                Assert.Equal("handler1Called=False, handler2Called=True", $"handler1Called={handler1Called}, handler2Called={handler2Called}")
            End Using
        End Function
    End Class
End Namespace

Expected: handler1Called=False, handler2Called=True
Actual: handler1Called=True, handler2Called=False

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Aug 12, 2024
@svick
Copy link
Contributor Author

svick commented Aug 12, 2024

cc: @ToddGrun, @jasonmalinowski

@svick svick added the Bug label Aug 12, 2024
@DoctorKrolic
Copy link
Contributor

Seems like a duplicate of #74395, which has already been fixed

@svick
Copy link
Contributor Author

svick commented Aug 12, 2024

@DoctorKrolic I believe that issue is about additional files that are open and edited inside VS. This issue is about additional files that are modified by something else.

Also, the test above fails on current main.

@Cosifne Cosifne removed the untriaged Issues and PRs which have not yet been triaged by a lead label Aug 12, 2024
@jasonmalinowski
Copy link
Member

@ToddGrun This might also be related to what you're looking at.

@jasonmalinowski
Copy link
Member

@ToddGrun fixed this in #75815.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants