File: Interactive\InteractiveWorkspace.cs
Web Access
Project: ..\..\..\src\EditorFeatures\Core\Microsoft.CodeAnalysis.EditorFeatures.csproj (Microsoft.CodeAnalysis.EditorFeatures)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;
using Roslyn.Utilities;
 
namespace Microsoft.CodeAnalysis.Interactive
{
    internal partial class InteractiveWorkspace : Workspace
    {
        private SourceTextContainer? _openTextContainer;
        private DocumentId? _openDocumentId;
 
        internal InteractiveWorkspace(HostServices hostServices, IGlobalOptionService globalOptions)
            : base(hostServices, WorkspaceKind.Interactive)
        {
            // register work coordinator for this workspace
            if (globalOptions.GetOption(SolutionCrawlerRegistrationService.EnableSolutionCrawler))
            {
                Services.GetRequiredService<ISolutionCrawlerRegistrationService>().Register(this);
            }
        }
 
        protected override void Dispose(bool finalize)
        {
            // workspace is going away. unregister this workspace from work coordinator
            Services.GetRequiredService<ISolutionCrawlerRegistrationService>().Unregister(this, blockingShutdown: true);
 
            base.Dispose(finalize);
        }
 
        public override bool CanOpenDocuments
            => true;
 
        public override bool CanApplyChange(ApplyChangesKind feature)
            => feature == ApplyChangesKind.ChangeDocument;
 
        public void OpenDocument(DocumentId documentId, SourceTextContainer textContainer)
        {
            _openTextContainer = textContainer;
            _openDocumentId = documentId;
            OnDocumentOpened(documentId, textContainer);
        }
 
        protected override void ApplyDocumentTextChanged(DocumentId document, SourceText newText)
        {
            if (_openDocumentId != document)
            {
                return;
            }
 
            Contract.ThrowIfNull(_openTextContainer);
 
            ITextSnapshot appliedText;
            using (var edit = _openTextContainer.GetTextBuffer().CreateEdit(EditOptions.DefaultMinimalChange, reiteratedVersionNumber: null, editTag: null))
            {
                var oldText = _openTextContainer.CurrentText;
                var changes = newText.GetTextChanges(oldText);
 
                foreach (var change in changes)
                {
                    edit.Replace(change.Span.Start, change.Span.Length, change.NewText);
                }
 
                appliedText = edit.Apply();
            }
 
            OnDocumentTextChanged(document, appliedText.AsText(), PreservationMode.PreserveIdentity);
        }
 
        /// <summary>
        /// Closes all open documents and empties the solution but keeps all solution-level analyzers.
        /// </summary>
        public void ResetSolution()
        {
            ClearOpenDocuments();
 
            var emptySolution = CreateSolution(SolutionId.CreateNewId("InteractiveSolution"));
            SetCurrentSolution(solution => emptySolution.WithAnalyzerReferences(solution.AnalyzerReferences), WorkspaceChangeKind.SolutionCleared);
        }
    }
}