EnvDTE.Host/Callback/Util/EnvDteCallbackProviderExtensions.cs (129 lines of code) (raw):
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<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<TReq, IProject, TRes> func) where TReq : ProjectItemRequest =>
endpoint.SetSync(req =>
{
var project = GetProjectItemOrThrow<TReq, IProject>(host, req);
return func(req, project);
});
public static void SetWithProjectAsync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProject, Task<TRes>> func) where TReq : ProjectItemRequest =>
endpoint.SetAsync(async (lifetime, req) =>
{
var project = GetProjectItemOrThrow<TReq, IProject>(host, req);
return await func(lifetime, req, project);
});
public static void SetWithProjectItemAsync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProjectItem, Task<TRes>> func) where TReq : ProjectItemRequest =>
endpoint.SetAsync(async (lifetime, req) =>
{
var projectItem = GetProjectItemOrThrow<TReq, IProjectItem>(host, req);
return await func(lifetime, req, projectItem);
});
public static void SetWithProjectFolderAsync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProjectFolder, Task<TRes>> func) where TReq : ProjectItemRequest =>
endpoint.SetAsync(async (lifetime, req) =>
{
var projectFolder = GetProjectItemOrThrow<TReq, IProjectFolder>(host, req);
return await func(lifetime, req, projectFolder);
});
public static void SetWithProjectFileAsync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProjectFile, Task<TRes>> func) where TReq : ProjectItemRequest =>
endpoint.SetAsync(async (lifetime, req) =>
{
var projectFile = GetProjectItemOrThrow<TReq, IProjectFile>(host, req);
return await func(lifetime, req, projectFile);
});
public static void SetWithProjectVoidAsync<TReq>(
this IRdEndpoint<TReq, Unit> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProject, Task> func) where TReq : ProjectItemRequest =>
endpoint.SetVoidAsync(async (lifetime, req) =>
{
var project = GetProjectItemOrThrow<TReq, IProject>(host, req);
await func(lifetime, req, project);
});
public static void SetWithProjectItemVoidAsync<TReq>(
this IRdEndpoint<TReq, Unit> endpoint,
ProjectModelViewHost host,
Func<Lifetime, TReq, IProjectItem, Task> func) where TReq : ProjectItemRequest =>
endpoint.SetVoidAsync(async (lifetime, req) =>
{
var projectItem = GetProjectItemOrThrow<TReq, IProjectItem>(host, req);
await func(lifetime, req, projectItem);
});
public static void SetWithProjectMarkSync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ProjectModelViewHost host,
Func<TReq, IProjectMark, TRes> func) where TReq : ProjectItemRequest =>
endpoint.SetSync(req =>
{
var projectMark = GetProjectMarkOrThrow(host, req);
return func(req, projectMark);
});
public static void SetWithSolutionMarkAsync<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ISolution solution,
Func<Lifetime, TReq, ISolutionMark, Task<TRes>> 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<TReq, TRes>(
this IRdEndpoint<TReq, TRes> endpoint,
ISolution solution,
Func<TReq, ISolutionMark, TRes> 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<TReq, TItem>(ProjectModelViewHost host, TReq req)
where TReq : ProjectItemRequest where TItem : class, IProjectItem
{
var projectItem = host.GetItemById<TItem>(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<TReq>(ProjectModelViewHost host, TReq req)
where TReq : ProjectItemRequest
{
var project = GetProjectItemOrThrow<TReq, IProject>(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
}