File: Workspace\AdhocWorkspace.cs
Web Access
Project: ..\..\..\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// 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.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Text;
 
namespace Microsoft.CodeAnalysis
{
    /// <summary>
    /// A workspace that allows full manipulation of projects and documents,
    /// but does not persist changes.
    /// </summary>
    public sealed class AdhocWorkspace : Workspace
    {
        public AdhocWorkspace(HostServices host, string workspaceKind = WorkspaceKind.Custom)
            : base(host, workspaceKind)
        {
        }
 
        public AdhocWorkspace()
            : this(Host.Mef.MefHostServices.DefaultHost)
        {
        }
 
        public override bool CanApplyChange(ApplyChangesKind feature)
        {
            // all kinds supported.
            return true;
        }
 
        /// <summary>
        /// Returns true, signifiying that you can call the open and close document APIs to add the document into the open document list.
        /// </summary>
        public override bool CanOpenDocuments => true;
 
        /// <summary>
        /// Clears all projects and documents from the workspace.
        /// </summary>
        public new void ClearSolution()
            => base.ClearSolution();
 
        /// <summary>
        /// Adds an entire solution to the workspace, replacing any existing solution.
        /// </summary>
        public Solution AddSolution(SolutionInfo solutionInfo)
        {
            if (solutionInfo == null)
            {
                throw new ArgumentNullException(nameof(solutionInfo));
            }
 
            this.OnSolutionAdded(solutionInfo);
 
            this.UpdateReferencesAfterAdd();
 
            return this.CurrentSolution;
        }
 
        /// <summary>
        /// Adds a project to the workspace. All previous projects remain intact.
        /// </summary>
        public Project AddProject(string name, string language)
        {
            var info = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), name, name, language);
            return this.AddProject(info);
        }
 
        /// <summary>
        /// Adds a project to the workspace. All previous projects remain intact.
        /// </summary>
        public Project AddProject(ProjectInfo projectInfo)
        {
            if (projectInfo == null)
            {
                throw new ArgumentNullException(nameof(projectInfo));
            }
 
            this.OnProjectAdded(projectInfo);
 
            this.UpdateReferencesAfterAdd();
 
            return this.CurrentSolution.GetProject(projectInfo.Id);
        }
 
        /// <summary>
        /// Adds multiple projects to the workspace at once. All existing projects remain intact.
        /// </summary>
        /// <param name="projectInfos"></param>
        public void AddProjects(IEnumerable<ProjectInfo> projectInfos)
        {
            if (projectInfos == null)
            {
                throw new ArgumentNullException(nameof(projectInfos));
            }
 
            foreach (var info in projectInfos)
            {
                this.OnProjectAdded(info);
            }
 
            this.UpdateReferencesAfterAdd();
        }
 
        /// <summary>
        /// Adds a document to the workspace.
        /// </summary>
        public Document AddDocument(ProjectId projectId, string name, SourceText text)
        {
            if (projectId == null)
            {
                throw new ArgumentNullException(nameof(projectId));
            }
 
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
 
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }
 
            var id = DocumentId.CreateNewId(projectId);
            var loader = TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create()));
 
            return AddDocument(DocumentInfo.Create(id, name, loader: loader));
        }
 
        /// <summary>
        /// Adds a document to the workspace.
        /// </summary>
        public Document AddDocument(DocumentInfo documentInfo)
        {
            if (documentInfo == null)
            {
                throw new ArgumentNullException(nameof(documentInfo));
            }
 
            this.OnDocumentAdded(documentInfo);
 
            return this.CurrentSolution.GetDocument(documentInfo.Id);
        }
 
        /// <summary>
        /// Puts the specified document into the open state.
        /// </summary>
        public override void OpenDocument(DocumentId documentId, bool activate = true)
        {
            var doc = this.CurrentSolution.GetDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                this.OnDocumentOpened(documentId, text.Container, activate);
            }
        }
 
        /// <summary>
        /// Puts the specified document into the closed state.
        /// </summary>
        public override void CloseDocument(DocumentId documentId)
        {
            var doc = this.CurrentSolution.GetDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                var version = doc.GetTextVersionSynchronously(CancellationToken.None);
                var loader = TextLoader.From(TextAndVersion.Create(text, version, doc.FilePath));
                this.OnDocumentClosed(documentId, loader);
            }
        }
 
        /// <summary>
        /// Puts the specified additional document into the open state.
        /// </summary>
        public override void OpenAdditionalDocument(DocumentId documentId, bool activate = true)
        {
            var doc = this.CurrentSolution.GetAdditionalDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                this.OnAdditionalDocumentOpened(documentId, text.Container, activate);
            }
        }
 
        /// <summary>
        /// Puts the specified additional document into the closed state
        /// </summary>
        public override void CloseAdditionalDocument(DocumentId documentId)
        {
            var doc = this.CurrentSolution.GetAdditionalDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                var version = doc.GetTextVersionSynchronously(CancellationToken.None);
                var loader = TextLoader.From(TextAndVersion.Create(text, version, doc.FilePath));
                this.OnAdditionalDocumentClosed(documentId, loader);
            }
        }
 
        /// <summary>
        /// Puts the specified analyzer config document into the open state.
        /// </summary>
        public override void OpenAnalyzerConfigDocument(DocumentId documentId, bool activate = true)
        {
            var doc = this.CurrentSolution.GetAnalyzerConfigDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                this.OnAnalyzerConfigDocumentOpened(documentId, text.Container, activate);
            }
        }
 
        /// <summary>
        /// Puts the specified analyzer config document into the closed state
        /// </summary>
        public override void CloseAnalyzerConfigDocument(DocumentId documentId)
        {
            var doc = this.CurrentSolution.GetAnalyzerConfigDocument(documentId);
            if (doc != null)
            {
                var text = doc.GetTextSynchronously(CancellationToken.None);
                var version = doc.GetTextVersionSynchronously(CancellationToken.None);
                var loader = TextLoader.From(TextAndVersion.Create(text, version, doc.FilePath));
                this.OnAnalyzerConfigDocumentClosed(documentId, loader);
            }
        }
    }
}