| File: Workspace\Workspace_Registration.cs | Web Access |
| Project: src\roslyn\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. using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.Text; using static Microsoft.CodeAnalysis.WorkspaceEventMap; namespace Microsoft.CodeAnalysis; /* This is the static API on Workspace that lets you associate text containers with workspace instances */ public abstract partial class Workspace { private static readonly ConditionalWeakTable<SourceTextContainer, WorkspaceRegistration> s_bufferToWorkspaceRegistrationMap = new(); /// <summary> /// Gets the workspace associated with the specific text container. /// </summary> public static bool TryGetWorkspace(SourceTextContainer textContainer, [NotNullWhen(true)] out Workspace? workspace) { if (textContainer == null) { throw new ArgumentNullException(nameof(textContainer)); } var registration = GetWorkspaceRegistration(textContainer); workspace = registration.Workspace; return workspace != null; } /// <summary> /// Register a correspondence between a text container and a workspace. /// </summary> protected void RegisterText(SourceTextContainer textContainer) { if (textContainer == null) { throw new ArgumentNullException(nameof(textContainer)); } var registration = GetWorkspaceRegistration(textContainer); registration.SetWorkspace(this); // Require main thread on the callback as WorkspaceRegistration.RaiseEvents invokes Workspace.WorkspaceChanges which is publicly exposed // and the event handlers may have main thread dependencies. Potential cleanup here with relation to // https://github.com/dotnet/roslyn/issues/32551 var handlerAndOptions = new WorkspaceEventHandlerAndOptions(args => registration.RaiseEvents(), WorkspaceEventOptions.RequiresMainThreadOptions); var handlerSet = EventHandlerSet.Create(handlerAndOptions); this.ScheduleTask(EventArgs.Empty, handlerSet); } /// <summary> /// Unregister a correspondence between a text container and a workspace. /// </summary> protected void UnregisterText(SourceTextContainer textContainer) { if (textContainer == null) { throw new ArgumentNullException(nameof(textContainer)); } var registration = GetWorkspaceRegistration(textContainer); if (registration.Workspace == this) { registration.SetWorkspaceAndRaiseEvents(null); } } /// <summary> /// Returns a <see cref="WorkspaceRegistration" /> for a given text container. /// </summary> public static WorkspaceRegistration GetWorkspaceRegistration(SourceTextContainer textContainer) { if (textContainer == null) { throw new ArgumentNullException(nameof(textContainer)); } return s_bufferToWorkspaceRegistrationMap.GetValue(textContainer, static _ => new WorkspaceRegistration()); } }