Beispiel #1
0
        public async Task ProjectLoaded_TriggersUpdate()
        {
            // Arrange
            await RunOnForegroundAsync(() => ProjectManager.ProjectAdded(Project1));

            var mre = new ManualResetEventSlim(initialState: false);
            var workspaceStateGenerator = new Mock <OmniSharpProjectWorkspaceStateGenerator>();

            workspaceStateGenerator.Setup(generator => generator.Update(It.IsAny <Project>(), It.IsAny <OmniSharpProjectSnapshot>()))
            .Callback <Project, OmniSharpProjectSnapshot>((_, __) => mre.Set());
            var refreshTrigger = CreateRefreshTrigger(workspaceStateGenerator.Object);
            var args           = new ProjectLoadedEventArgs(
                null,
                Project1Instance,
                EmptyDiagnostics,
                isReload: false,
                projectIdIsDefinedInSolution: false,
                sourceFiles: Enumerable.Empty <string>().ToImmutableArray());

            // Act
            refreshTrigger.ProjectLoaded(args);

            // Assert
            var result = mre.Wait(WaitDelay);

            Assert.True(result);
        }
Beispiel #2
0
        public void ProjectLoaded(ProjectLoadedEventArgs args)
        {
            try
            {
                var projectId           = GetProjectId(args);
                var sessionId           = GetSessionId(args);
                var targetFrameworks    = GetTargetFrameworks(args.ProjectInstance);
                var sdkVersion          = GetSdkVersion(args);
                var outputKind          = GetOutputKind(args);
                var projectCapabilities = GetProjectCapabilities(args.ProjectInstance);

                if (args.References == null)
                {
                    return;
                }

                var hashedReferences = GetHashedReferences(args);
                var(hashedFileExtensions, fileCounts) = GetUniqueHashedFileExtensionsAndCounts(args);

                _eventEmitter.ProjectInformation(projectId, sessionId, (int)outputKind, projectCapabilities, targetFrameworks, sdkVersion, hashedReferences, hashedFileExtensions, fileCounts);
            }
            catch (Exception ex)
            {
                _logger.LogError("Unexpected exception got thrown from project load listener: " + ex);
            }
        }
Beispiel #3
0
        // Internal for testing
        internal async Task ProjectLoadedAsync(ProjectLoadedEventArgs args)
        {
            var projectInstance = args.ProjectInstance;

            HandleDebug(projectInstance);

            if (!TryResolveConfigurationOutputPath(projectInstance, out var configPath))
            {
                return;
            }

            var projectFilePath = projectInstance.GetPropertyValue(MSBuildProjectFullPathPropertyName);

            if (string.IsNullOrEmpty(projectFilePath))
            {
                // This should never be true but we're being extra careful.
                return;
            }

            _projectConfigurationPublisher.SetPublishFilePath(projectFilePath, configPath);

            // Force project instance evaluation to ensure that all Razor specific targets have run.
            projectInstance = _projectInstanceEvaluator.Evaluate(projectInstance);

            await Task.Factory.StartNew(() => UpdateProjectState(projectInstance),
                                        CancellationToken.None, TaskCreationOptions.None, _foregroundDispatcher.ForegroundScheduler);
        }
 private void StudioEnvironment_ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     PrepareObjectModel();
     StartSelenium();
     Studio.RegisterPackageDefinition(new Models.Packaging.PackageDefinition()
     {
         Name = "Web action package", Extension = "iwp"
     });
 }
 public async void ProjectLoaded(ProjectLoadedEventArgs args)
 {
     try
     {
         await ProjectLoadedAsync(args);
     }
     catch (Exception ex)
     {
         _logger.LogError("Unexpected exception got thrown from the Razor plugin: " + ex);
     }
 }
#pragma warning disable VSTHRD100 // Avoid async void methods
        public async void ProjectLoaded(ProjectLoadedEventArgs args)
#pragma warning restore VSTHRD100 // Avoid async void methods
        {
            try
            {
                await ProjectLoadedAsync(args);
            }
            catch (Exception ex)
            {
                _logger.LogError("Unexpected exception got thrown from the Razor plugin: " + ex);
            }
        }
        public void ProjectLoaded(ProjectLoadedEventArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            // Project file was modified or impacted in a significant way.

            _ = _projectSnapshotManagerDispatcher.RunOnDispatcherThreadAsync(
                () => EnqueueUpdate(args.ProjectInstance.ProjectFileLocation.File),
                CancellationToken.None).ConfigureAwait(false);
        }
        public (ProjectFileInfo, ImmutableArray <MSBuildDiagnostic>, ProjectLoadedEventArgs) Reload(ProjectLoader loader)
        {
            var(projectInstance, diagnostics) = loader.BuildProject(FilePath);
            if (projectInstance == null)
            {
                return(null, diagnostics, null);
            }

            var data            = ProjectData.Create(projectInstance);
            var projectFileInfo = new ProjectFileInfo(Id, FilePath, data);
            var eventArgs       = new ProjectLoadedEventArgs(Id, projectInstance, diagnostics, isReload: true);

            return(projectFileInfo, diagnostics, eventArgs);
        }
Beispiel #9
0
        private static HashedString GetProjectId(ProjectLoadedEventArgs args)
        {
            if (args.ProjectIdIsDefinedInSolution)
            {
                //If we are getting a raw guid we should not hash it
                return(new HashedString(args.Id.Id.ToString()));
            }

            var projectFilePath = args.ProjectInstance.GetPropertyValue(MSBuildProjectFullPath);
            var content         = File.ReadAllText(projectFilePath);

            //create a hash from the filename and the content
            return(_referenceHashingAlgorithm.HashInput($"Filename: {Path.GetFileName(projectFilePath)}\n{content}"));
        }
Beispiel #10
0
        public void ProjectLoaded(ProjectLoadedEventArgs args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            // Project file was modified or impacted in a significant way.

            _ = Task.Factory.StartNew(
                () => EnqueueUpdate(args.ProjectInstance.ProjectFileLocation.File),
                CancellationToken.None,
                TaskCreationOptions.None,
                _foregroundDispatcher.ForegroundScheduler).ConfigureAwait(false);
        }
Beispiel #11
0
        public async Task ProjectLoadedAsync_AddsNewProjectWithDocument()
        {
            // Arrange
            var projectRootElement     = ProjectRootElement.Create("/project/project.csproj");
            var intermediateOutputPath = "/project/obj";

            projectRootElement.AddProperty(MSBuildProjectManager.IntermediateOutputPathPropertyName, intermediateOutputPath);
            var projectInstance       = new ProjectInstance(projectRootElement);
            var hostDocument          = new OmniSharpHostDocument("file.razor", "file.razor", FileKinds.Component);
            var projectConfiguration  = new ProjectConfiguration(CustomConfiguration, new[] { hostDocument }, "TestRootNamespace");
            var configurationProvider = new Mock <ProjectConfigurationProvider>(MockBehavior.Strict);

            configurationProvider.Setup(provider => provider.TryResolveConfiguration(It.IsAny <ProjectConfigurationProviderContext>(), out projectConfiguration))
            .Returns(true);
            var projectChangePublisher = new Mock <ProjectChangePublisher>(MockBehavior.Strict);

            projectChangePublisher.Setup(p => p.SetPublishFilePath(It.IsAny <string>(), It.IsAny <string>())).Verifiable();
            var msbuildProjectManager = new MSBuildProjectManager(
                new[] { configurationProvider.Object },
                CreateProjectInstanceEvaluator(),
                projectChangePublisher.Object,
                Dispatcher,
                LoggerFactory);
            var projectManager = CreateProjectSnapshotManager();

            msbuildProjectManager.Initialize(projectManager);
            var args = new ProjectLoadedEventArgs(
                ProjectId.CreateNewId(),
                projectInstance,
                diagnostics: Enumerable.Empty <MSBuildDiagnostic>().ToImmutableArray(),
                isReload: false,
                projectIdIsDefinedInSolution: false,
                sourceFiles: Enumerable.Empty <string>().ToImmutableArray());

            // Act
            await msbuildProjectManager.ProjectLoadedAsync(args);

            // Assert
            var project = await RunOnForegroundAsync(() => Assert.Single(projectManager.Projects));

            Assert.Equal(projectInstance.ProjectFileLocation.File, project.FilePath);
            Assert.Same(CustomConfiguration, project.Configuration);
            var document = project.GetDocument(hostDocument.FilePath);

            Assert.NotNull(document);
        }
        public void ProjectLoaded(ProjectLoadedEventArgs args)
        {
            try
            {
                HandleDebug(args.ProjectInstance);

                if (!TryResolveRazorConfigurationPath(args.ProjectInstance, out var configPath))
                {
                    return;
                }

                var projectFilePath = args.ProjectInstance.GetPropertyValue(MSBuildProjectFullPathPropertyName);
                if (string.IsNullOrEmpty(projectFilePath))
                {
                    // This should never be true but we're being extra careful.
                    return;
                }

                var projectConfiguration = new RazorProjectConfiguration()
                {
                    ProjectFilePath = projectFilePath,

                    // TODO: Work ;)
                };

                var serializedOutput = JsonConvert.SerializeObject(
                    projectConfiguration,
                    Formatting.Indented);

                try
                {
                    File.WriteAllText(configPath, serializedOutput);
                }
                catch (Exception)
                {
                    // TODO: Add retry.
                }
            }
            catch (Exception ex)
            {
                _logger.LogError("Unexpected exception got thrown from the Razor plugin: " + ex);
            }
        }
        public static (ProjectFileInfo, ImmutableArray <MSBuildDiagnostic>, ProjectLoadedEventArgs) Load(string filePath, ProjectLoader loader)
        {
            if (!File.Exists(filePath))
            {
                return(null, ImmutableArray <MSBuildDiagnostic> .Empty, null);
            }

            var(projectInstance, diagnostics) = loader.BuildProject(filePath);
            if (projectInstance == null)
            {
                return(null, diagnostics, null);
            }

            var id              = ProjectId.CreateNewId(debugName: filePath);
            var data            = ProjectData.Create(projectInstance);
            var projectFileInfo = new ProjectFileInfo(id, filePath, data);
            var eventArgs       = new ProjectLoadedEventArgs(id, projectInstance, diagnostics, isReload: false);

            return(projectFileInfo, diagnostics, eventArgs);
        }
Beispiel #14
0
        public void ProjectLoaded(ProjectLoadedEventArgs args)
        {
            try
            {
                var projectId        = GetProjectId(args);
                var targetFrameworks = GetTargetFrameworks(args.ProjectInstance);

                if (args.References == null)
                {
                    return;
                }

                var hashedReferences     = GetHashedReferences(args);
                var hashedFileExtensions = GetUniqueHashedFileExtensions(args);

                _eventEmitter.ProjectInformation(projectId, targetFrameworks, hashedReferences, hashedFileExtensions);
            }
            catch (Exception ex)
            {
                _logger.LogError("Unexpected exception got thrown from project load listener: " + ex);
            }
        }
Beispiel #15
0
        public async Task ProjectLoaded_BatchesUpdates()
        {
            // Arrange
            await RunOnForegroundAsync(() => ProjectManager.ProjectAdded(Project1));

            var mre = new ManualResetEventSlim(initialState: false);
            var workspaceStateGenerator = new Mock <OmniSharpProjectWorkspaceStateGenerator>(MockBehavior.Strict);

            workspaceStateGenerator.Setup(generator => generator.Update(It.IsAny <Project>(), It.IsAny <OmniSharpProjectSnapshot>()))
            .Callback <Project, OmniSharpProjectSnapshot>((_, __) =>
            {
                if (mre.IsSet)
                {
                    throw new XunitException("Should not have been called twice.");
                }

                mre.Set();
            });
            var refreshTrigger = CreateRefreshTrigger(workspaceStateGenerator.Object, enqueueDelay: 10);
            var args           = new ProjectLoadedEventArgs(
                null,
                (ProjectInstance)Project1Instance,
                Enumerable.Empty <MSBuildDiagnostic>().ToImmutableArray(),
                isReload: false,
                projectIdIsDefinedInSolution: false,
                sourceFiles: Enumerable.Empty <string>().ToImmutableArray());

            // Act
            refreshTrigger.ProjectLoaded(args);
            refreshTrigger.ProjectLoaded(args);
            refreshTrigger.ProjectLoaded(args);
            refreshTrigger.ProjectLoaded(args);

            // Assert
            var result = mre.Wait(WaitDelay);

            Assert.True(result);
        }
 public void ProjectLoaded(ProjectLoadedEventArgs args)
 {
     _ = ProjectLoadedAsync(args, CancellationToken.None);
 }
        public void ProjectLoaded(ProjectLoadedEventArgs loadedArgs)
        {
            if (loadedArgs == null)
            {
                throw new ArgumentNullException(nameof(loadedArgs));
            }

            var projectInstance = loadedArgs.ProjectInstance;
            var projectFilePath = projectInstance.GetPropertyValue(MSBuildProjectFullPathPropertyName);

            if (string.IsNullOrEmpty(projectFilePath))
            {
                // This should never be true but we're being extra careful.
                return;
            }

            var projectDirectory = projectInstance.GetPropertyValue(MSBuildProjectDirectoryPropertyName);

            if (string.IsNullOrEmpty(projectDirectory))
            {
                // This should never be true but we're beign extra careful.
                return;
            }

            if (_watcherMap.TryGetValue(projectDirectory, out var existingWatchers))
            {
                for (var i = 0; i < existingWatchers.Count; i++)
                {
                    existingWatchers[i].Dispose();
                }
            }

            var watchers = new List <FileSystemWatcher>(s_razorFileExtensions.Count);

            for (var i = 0; i < s_razorFileExtensions.Count; i++)
            {
                var documentWatcher = new FileSystemWatcher(projectDirectory, "*" + s_razorFileExtensions[i])
                {
                    NotifyFilter          = NotifyFilters.FileName | NotifyFilters.LastWrite | NotifyFilters.CreationTime,
                    IncludeSubdirectories = true,
                };

                documentWatcher.Created += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                documentWatcher.Deleted += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Removed);
                documentWatcher.Changed += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Changed);
                documentWatcher.Renamed += (sender, args) =>
                {
                    // Translate file renames into remove / add

                    if (s_razorFileExtensions.Any(extension => args.OldFullPath.EndsWith(extension, StringComparison.Ordinal)))
                    {
                        // Renaming from Razor file to something else.
                        FileSystemWatcher_RazorDocumentEvent(args.OldFullPath, projectInstance, RazorFileChangeKind.Removed);
                    }

                    if (s_razorFileExtensions.Any(extension => args.FullPath.EndsWith(extension, StringComparison.Ordinal)))
                    {
                        // Renaming into a Razor file. This typically occurs when users go from .cshtml => .razor
                        FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                    }
                };
                watchers.Add(documentWatcher);

                var documentOutputWatcher = new FileSystemWatcher(projectDirectory, "*" + s_razorFileExtensions[i] + ".g.cs")
                {
                    NotifyFilter          = NotifyFilters.FileName | NotifyFilters.LastWrite,
                    IncludeSubdirectories = true,
                };

                documentOutputWatcher.Created += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                documentOutputWatcher.Deleted += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Removed);
                documentOutputWatcher.Changed += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Changed);
                documentOutputWatcher.Renamed += (sender, args) =>
                {
                    // Translate file renames into remove / add

                    if (s_razorFileExtensions.Any(extension => args.OldFullPath.EndsWith(extension + ".g.cs", StringComparison.Ordinal)))
                    {
                        // Renaming from Razor background file to something else.
                        FileSystemWatcher_RazorDocumentOutputEvent(args.OldFullPath, projectInstance, RazorFileChangeKind.Removed);
                    }

                    if (s_razorFileExtensions.Any(extension => args.FullPath.EndsWith(extension + ".g.cs", StringComparison.Ordinal)))
                    {
                        // Renaming into a Razor generated file.
                        FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                    }
                };
                watchers.Add(documentOutputWatcher);

                documentWatcher.EnableRaisingEvents       = true;
                documentOutputWatcher.EnableRaisingEvents = true;
            }

            _watcherMap[projectDirectory] = watchers;
        }
Beispiel #18
0
        private static (IEnumerable <HashedString> Extensions, IEnumerable <int> Counts) GetUniqueHashedFileExtensionsAndCounts(ProjectLoadedEventArgs args)
        {
            var contentFiles = args.ProjectInstance
                               .GetItems(ItemNames.Content)
                               .Select(item => item.GetMetadataValue(MetadataNames.FullPath));
            var allFiles    = args.SourceFiles.Concat(contentFiles);
            var filesCounts = allFiles.GroupBy(file => Path.GetExtension(file)).ToDictionary(kvp => kvp.Key, kvp => kvp.Count());
            IEnumerable <string> fileExtensions = filesCounts.Select(kvp => kvp.Key);
            IEnumerable <int>    fileCounts     = filesCounts.Select(kvp => kvp.Value);

            return(fileExtensions.Select(_tfmAndFileHashingAlgorithm.HashInput), fileCounts);
        }
 /// <summary>
 /// Handles the ProjectLoaded event of the <see cref="ProjectManager"/> object.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="ProjectLoadedEventArgs"/> instance containing the event data.</param>
 private void ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     Enable();
 }
Beispiel #20
0
 private static HashedString GetSessionId(ProjectLoadedEventArgs args)
 {
     return(_tfmAndFileHashingAlgorithm.HashInput(args.SessionId.ToString()));
 }
 /// <summary>
 /// Handles the ProjectLoaded event of the <see cref="ProjectManager"/> class.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="ProjectLoadedEventArgs"/> instance containing the event data.</param>
 private void ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     _project = e.Project;
     LoadMaps(e.Project.MapPath);
 }
 /// <summary>
 /// Handles the ProjectLoaded event of the <see cref="ProjectManager"/> object.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="ProjectLoadedEventArgs"/> instance containing the event data.</param>
 private void ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     _projectName = e.Project.Name;
     Enable();
     BuildTreeView();
 }
Beispiel #23
0
 private static OutputKind GetOutputKind(ProjectLoadedEventArgs args)
 {
     return(PropertyConverter.ToOutputKind(args.ProjectInstance.GetPropertyValue(PropertyNames.OutputType)));
 }
 /// <summary>
 /// Handles the ProjectLoaded event of the <see cref="ProjectManager"/> class.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="ProjectLoadedEventArgs"/> instance containing the event data.</param>
 private void ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     _project = e.Project;
     LoadTerrainTiles(_project.TerrainPath);
 }
 public void ProjectLoaded(ProjectLoadedEventArgs _)
 {
 }
Beispiel #26
0
        private static IEnumerable <HashedString> GetUniqueHashedFileExtensions(ProjectLoadedEventArgs args)
        {
            IEnumerable <string> sourceFileExtensions = args.SourceFiles.Select(file => Path.GetExtension(file)).Distinct();

            return(sourceFileExtensions.Select(_tfmAndFileHashingAlgorithm.HashInput));
        }
Beispiel #27
0
        private static IEnumerable <HashedString> GetHashedReferences(ProjectLoadedEventArgs args)
        {
            var referenceNames = args.References.Select(reference => Path.GetFileNameWithoutExtension(reference).ToLower());

            return(referenceNames.Select(_referenceHashingAlgorithm.HashInput));
        }
Beispiel #28
0
 public void ProjectLoaded(ProjectLoadedEventArgs e)
 {
     _onLoaded(e);
 }
 public void ProjectLoaded(ProjectLoadedEventArgs e)
 {
     // We don't do anything on project load we're just using the IMSBuildEventSink to ensure we're instantiated.
 }
 /// <summary>
 /// Handles the ProjectLoaded event of the <see cref="ProjectManager"/> class.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="ProjectLoadedEventArgs"/> instance containing the event data.</param>
 private void ProjectLoaded(object sender, ProjectLoadedEventArgs e)
 {
     _project = e.Project;
     LoadTilesets(e.Project.TilesetPath);
 }
        public void ProjectLoaded(ProjectLoadedEventArgs loadedArgs)
        {
            if (loadedArgs == null)
            {
                throw new ArgumentNullException(nameof(loadedArgs));
            }

            var projectInstance = loadedArgs.ProjectInstance;
            var projectFilePath = projectInstance.GetPropertyValue(MSBuildProjectFullPathPropertyName);

            if (string.IsNullOrEmpty(projectFilePath))
            {
                // This should never be true but we're being extra careful.
                return;
            }

            var projectDirectory = projectInstance.GetPropertyValue(MSBuildProjectDirectoryPropertyName);

            if (string.IsNullOrEmpty(projectDirectory))
            {
                // This should never be true but we're beign extra careful.
                return;
            }

            if (_watcherMap.TryGetValue(projectDirectory, out var existingWatchers))
            {
                for (var i = 0; i < existingWatchers.Count; i++)
                {
                    existingWatchers[i].Dispose();
                }
            }

            var watchers = new List <FileSystemWatcher>(RazorFileExtensions.Count);

            for (var i = 0; i < RazorFileExtensions.Count; i++)
            {
                var documentWatcher = new FileSystemWatcher(projectDirectory, "*." + RazorFileExtensions[i])
                {
                    NotifyFilter          = NotifyFilters.FileName | NotifyFilters.LastWrite,
                    IncludeSubdirectories = true,
                };

                documentWatcher.Created += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                documentWatcher.Deleted += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Removed);
                documentWatcher.Changed += (sender, args) => FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Changed);
                documentWatcher.Renamed += (sender, args) =>
                {
                    // Translate file renames into remove->add
                    FileSystemWatcher_RazorDocumentEvent(args.OldFullPath, projectInstance, RazorFileChangeKind.Removed);
                    FileSystemWatcher_RazorDocumentEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                };
                watchers.Add(documentWatcher);

                var documentOutputWatcher = new FileSystemWatcher(projectDirectory, "*." + RazorFileExtensions[i] + ".g.cs")
                {
                    NotifyFilter          = NotifyFilters.FileName | NotifyFilters.LastWrite,
                    IncludeSubdirectories = true,
                };

                documentOutputWatcher.Created += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                documentOutputWatcher.Deleted += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Removed);
                documentOutputWatcher.Changed += (sender, args) => FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Changed);
                documentOutputWatcher.Renamed += (sender, args) =>
                {
                    // Translate file renames into remove->add
                    FileSystemWatcher_RazorDocumentOutputEvent(args.OldFullPath, projectInstance, RazorFileChangeKind.Removed);
                    FileSystemWatcher_RazorDocumentOutputEvent(args.FullPath, projectInstance, RazorFileChangeKind.Added);
                };
                watchers.Add(documentOutputWatcher);

                documentWatcher.EnableRaisingEvents       = true;
                documentOutputWatcher.EnableRaisingEvents = true;
            }

            _watcherMap[projectDirectory] = watchers;
        }