using System; using System.Threading.Tasks; using JetBrains.Core; using JetBrains.Lifetimes; using JetBrains.ProjectModel; using JetBrains.ProjectModel.ProjectsHost; using JetBrains.Rd.Tasks; using JetBrains.RdBackend.Common.Features.ProjectModel.View; using JetBrains.Rider.Model; namespace JetBrains.EnvDTE.Host.Callback.Util { #pragma warning disable VSTHRD200 public static class EnvDteCallbackProviderExtensions { public static void SetWithProjectSync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func func) where TReq : ProjectItemRequest => endpoint.SetSync(req => { var project = GetProjectItemOrThrow(host, req); return func(req, project); }); public static void SetWithProjectAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func> func) where TReq : ProjectItemRequest => endpoint.SetAsync(async (lifetime, req) => { var project = GetProjectItemOrThrow(host, req); return await func(lifetime, req, project); }); public static void SetWithProjectItemAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func> func) where TReq : ProjectItemRequest => endpoint.SetAsync(async (lifetime, req) => { var projectItem = GetProjectItemOrThrow(host, req); return await func(lifetime, req, projectItem); }); public static void SetWithProjectFolderAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func> func) where TReq : ProjectItemRequest => endpoint.SetAsync(async (lifetime, req) => { var projectFolder = GetProjectItemOrThrow(host, req); return await func(lifetime, req, projectFolder); }); public static void SetWithProjectFileAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func> func) where TReq : ProjectItemRequest => endpoint.SetAsync(async (lifetime, req) => { var projectFile = GetProjectItemOrThrow(host, req); return await func(lifetime, req, projectFile); }); public static void SetWithProjectVoidAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func func) where TReq : ProjectItemRequest => endpoint.SetVoidAsync(async (lifetime, req) => { var project = GetProjectItemOrThrow(host, req); await func(lifetime, req, project); }); public static void SetWithProjectItemVoidAsync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func func) where TReq : ProjectItemRequest => endpoint.SetVoidAsync(async (lifetime, req) => { var projectItem = GetProjectItemOrThrow(host, req); await func(lifetime, req, projectItem); }); public static void SetWithProjectMarkSync( this IRdEndpoint endpoint, ProjectModelViewHost host, Func func) where TReq : ProjectItemRequest => endpoint.SetSync(req => { var projectMark = GetProjectMarkOrThrow(host, req); return func(req, projectMark); }); public static void SetWithSolutionMarkAsync( this IRdEndpoint endpoint, ISolution solution, Func> func) => endpoint.SetAsync(async (lifetime, req) => { var solutionMark = solution.GetSolutionMark(); if (solutionMark is null) throw new InvalidOperationException("Unable to get the solution mark."); return await func(lifetime, req, solutionMark); }); public static void SetWithSolutionMarkSync( this IRdEndpoint endpoint, ISolution solution, Func func) => endpoint.SetSync(req => { var solutionMark = solution.GetSolutionMark(); if (solutionMark is null) throw new InvalidOperationException("Unable to get the solution mark."); return func(req, solutionMark); }); private static TItem GetProjectItemOrThrow(ProjectModelViewHost host, TReq req) where TReq : ProjectItemRequest where TItem : class, IProjectItem { var projectItem = host.GetItemById(req.ProjectItemModel.Id); if (projectItem is null) throw new InvalidOperationException( $"{nameof(TItem)} not found for id: {req.ProjectItemModel.Id}." + " Project model probably changed, and id on the client side is outdated."); return projectItem; } private static IProjectMark GetProjectMarkOrThrow(ProjectModelViewHost host, TReq req) where TReq : ProjectItemRequest { var project = GetProjectItemOrThrow(host, req); var projectMark = project.GetProjectMark(); if (projectMark is null) throw new InvalidOperationException($"Project mark not found for project: {project.Name}."); return projectMark; } } #pragma warning restore VSTHRD200 }