Exemplo n.º 1
0
        public void ProjectConfigurationFileChanged(ProjectConfigurationFileChangeEventArgs args)
        {
            if (args is null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            _projectSnapshotManagerDispatcher.AssertDispatcherThread();

            switch (args.Kind)
            {
            case RazorFileChangeKind.Changed:
            {
                var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                if (!args.TryDeserialize(out var projectRazorJson))
                {
                    if (!_configurationToProjectMap.TryGetValue(configurationFilePath, out var associatedProjectFilePath))
                    {
                        // Could not resolve an associated project file, noop.
                        _logger.LogWarning("Failed to deserialize configuration file after change for an unknown project. Configuration file path: '{0}'", configurationFilePath);
                        return;
                    }
                    else
                    {
                        _logger.LogWarning("Failed to deserialize configuration file after change for project '{0}': '{1}'", associatedProjectFilePath, configurationFilePath);
                    }

                    // We found the last associated project file for the configuration file. Reset the project since we can't
                    // accurately determine its configurations.

                    EnqueueUpdateProject(associatedProjectFilePath, projectRazorJson: null);
                    return;
                }

                var projectFilePath = _filePathNormalizer.Normalize(projectRazorJson.FilePath);
                _logger.LogInformation("Project configuration file changed for project '{0}': '{1}'", projectFilePath, configurationFilePath);

                EnqueueUpdateProject(projectFilePath, projectRazorJson);
                break;
            }

            case RazorFileChangeKind.Added:
            {
                var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                if (!args.TryDeserialize(out var projectRazorJson))
                {
                    // Given that this is the first time we're seeing this configuration file if we can't deserialize it
                    // then we have to noop.
                    _logger.LogWarning("Failed to deserialize configuration file on configuration added event. Configuration file path: '{0}'", configurationFilePath);
                    return;
                }

                var projectFilePath = _filePathNormalizer.Normalize(projectRazorJson.FilePath);
                _configurationToProjectMap[configurationFilePath] = projectFilePath;
                _projectService.AddProject(projectFilePath);

                _logger.LogInformation("Project configuration file added for project '{0}': '{1}'", projectFilePath, configurationFilePath);
                EnqueueUpdateProject(projectFilePath, projectRazorJson);
                break;
            }

            case RazorFileChangeKind.Removed:
            {
                var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                if (!_configurationToProjectMap.TryGetValue(configurationFilePath, out var projectFilePath))
                {
                    // Failed to deserialize the initial project configuration file on add so we can't remove the configuration file because it doesn't exist in the list.
                    _logger.LogWarning("Failed to resolve associated project on configuration removed event. Configuration file path: '{0}'", configurationFilePath);
                    return;
                }

                _configurationToProjectMap.Remove(configurationFilePath);

                _logger.LogInformation("Project configuration file removed for project '{0}': '{1}'", projectFilePath, configurationFilePath);

                EnqueueUpdateProject(projectFilePath, projectRazorJson: null);
                break;
            }
            }

            void UpdateProject(string projectFilePath, ProjectRazorJson?projectRazorJson)
            {
                if (projectFilePath is null)
                {
                    throw new ArgumentNullException(nameof(projectFilePath));
                }

                if (projectRazorJson is null)
                {
                    ResetProject(projectFilePath);
                    return;
                }

                var projectWorkspaceState = projectRazorJson.ProjectWorkspaceState ?? ProjectWorkspaceState.Default;
                var documents             = projectRazorJson.Documents ?? Array.Empty <DocumentSnapshotHandle>();

                _projectService.UpdateProject(
                    projectRazorJson.FilePath,
                    projectRazorJson.Configuration,
                    projectRazorJson.RootNamespace,
                    projectWorkspaceState,
                    documents);
            }

            async Task UpdateAfterDelayAsync(string projectFilePath)
            {
                await Task.Delay(EnqueueDelay).ConfigureAwait(true);

                var delayedProjectInfo = ProjectInfoMap[projectFilePath];

                UpdateProject(projectFilePath, delayedProjectInfo.ProjectRazorJson);
            }

            void EnqueueUpdateProject(string projectFilePath, ProjectRazorJson?projectRazorJson)
            {
                projectFilePath = _filePathNormalizer.Normalize(projectFilePath);
                if (!ProjectInfoMap.ContainsKey(projectFilePath))
                {
                    ProjectInfoMap[projectFilePath] = new DelayedProjectInfo();
                }

                var delayedProjectInfo = ProjectInfoMap[projectFilePath];

                delayedProjectInfo.ProjectRazorJson = projectRazorJson;

                if (delayedProjectInfo.ProjectUpdateTask is null || delayedProjectInfo.ProjectUpdateTask.IsCompleted)
                {
                    delayedProjectInfo.ProjectUpdateTask = UpdateAfterDelayAsync(projectFilePath);
                }
            }

            void ResetProject(string projectFilePath)
            {
                _projectService.UpdateProject(
                    projectFilePath,
                    configuration: null,
                    rootNamespace: null,
                    ProjectWorkspaceState.Default,
                    Array.Empty <DocumentSnapshotHandle>());
            }
        }
Exemplo n.º 2
0
        public void ProjectConfigurationFileChanged(ProjectConfigurationFileChangeEventArgs args)
        {
            if (args is null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            _foregroundDispatcher.AssertForegroundThread();

            switch (args.Kind)
            {
            case RazorFileChangeKind.Changed:
            {
                if (!args.TryDeserialize(out var handle))
                {
                    var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                    if (!_configurationToProjectMap.TryGetValue(configurationFilePath, out var projectFilePath))
                    {
                        // Could not resolve an associated project file, noop.
                        return;
                    }

                    // We found the last associated project file for the configuration file. Reset the project since we can't
                    // accurately determine its configurations.
                    EnqueueUpdateProject(projectFilePath, snapshotHandle: null);
                    return;
                }


                EnqueueUpdateProject(handle.FilePath, handle);
                break;
            }

            case RazorFileChangeKind.Added:
            {
                if (!args.TryDeserialize(out var handle))
                {
                    // Given that this is the first time we're seeing this configuration file if we can't deserialize it
                    // then we have to noop.
                    return;
                }

                var projectFilePath       = _filePathNormalizer.Normalize(handle.FilePath);
                var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                _configurationToProjectMap[configurationFilePath] = projectFilePath;
                _projectService.AddProject(projectFilePath);

                EnqueueUpdateProject(projectFilePath, handle);
                break;
            }

            case RazorFileChangeKind.Removed:
            {
                var configurationFilePath = _filePathNormalizer.Normalize(args.ConfigurationFilePath);
                if (!_configurationToProjectMap.TryGetValue(configurationFilePath, out var projectFilePath))
                {
                    // Failed to deserialize the initial handle on add so we can't remove the configuration file because it doesn't exist in the list.
                    return;
                }

                _configurationToProjectMap.Remove(configurationFilePath);

                EnqueueUpdateProject(projectFilePath, snapshotHandle: null);
                break;
            }
            }

            void UpdateProject(string projectFilePath, FullProjectSnapshotHandle handle)
            {
                if (projectFilePath is null)
                {
                    throw new ArgumentNullException(nameof(projectFilePath));
                }

                if (handle is null)
                {
                    ResetProject(projectFilePath);
                    return;
                }

                var projectWorkspaceState = handle.ProjectWorkspaceState ?? ProjectWorkspaceState.Default;
                var documents             = handle.Documents ?? Array.Empty <DocumentSnapshotHandle>();

                _projectService.UpdateProject(
                    handle.FilePath,
                    handle.Configuration,
                    handle.RootNamespace,
                    projectWorkspaceState,
                    documents);
            }

            async Task UpdateAfterDelayAsync(string projectFilePath)
            {
                await Task.Delay(EnqueueDelay).ConfigureAwait(true);

                var delayedProjectInfo = _projectInfoMap[projectFilePath];

                UpdateProject(projectFilePath, delayedProjectInfo.FullProjectSnapshotHandle);
            }

            void EnqueueUpdateProject(string projectFilePath, FullProjectSnapshotHandle snapshotHandle)
            {
                if (!_projectInfoMap.ContainsKey(projectFilePath))
                {
                    _projectInfoMap[projectFilePath] = new DelayedProjectInfo();
                }

                var delayedProjectInfo = _projectInfoMap[projectFilePath];

                delayedProjectInfo.FullProjectSnapshotHandle = snapshotHandle;

                if (delayedProjectInfo.ProjectUpdateTask is null || delayedProjectInfo.ProjectUpdateTask.IsCompleted)
                {
                    delayedProjectInfo.ProjectUpdateTask = UpdateAfterDelayAsync(projectFilePath);
                }
            }

            void ResetProject(string projectFilePath)
            {
                _projectService.UpdateProject(
                    projectFilePath,
                    configuration: null,
                    rootNamespace: null,
                    ProjectWorkspaceState.Default,
                    Array.Empty <DocumentSnapshotHandle>());
            }
        }