提交 4646331d 编写于 作者: S Sam Harwell

Avoid Task allocations in common document extensions

上级 6344c7ae
......@@ -17,7 +17,7 @@ public SemanticModelReuseWorkspaceService(Workspace _)
{
}
public Task<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
public ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
{
// TODO: port the GetSemanticModelForNodeAsync implementation from Workspaces layer,
// which currently relies on a bunch of internal APIs.
......
......@@ -61,7 +61,7 @@ public override string ToString()
internal AddedParameter GetAddedParameter(Document document)
{
var semanticModel = document.GetRequiredSemanticModelAsync(CancellationToken.None).Result;
var semanticModel = document.GetRequiredSemanticModelAsync(CancellationToken.None).AsTask().Result;
var type = document.Project.Language switch
{
......
......@@ -321,7 +321,7 @@ private void FormatDocumentCreatedFromTemplate(IVsHierarchy hierarchy, uint item
// Organize using directives
addedDocument = ThreadHelper.JoinableTaskFactory.Run(() => OrganizeUsingsCreatedFromTemplateAsync(addedDocument, cancellationToken));
rootToFormat = ThreadHelper.JoinableTaskFactory.Run(() => addedDocument.GetRequiredSyntaxRootAsync(cancellationToken));
rootToFormat = ThreadHelper.JoinableTaskFactory.Run(() => addedDocument.GetRequiredSyntaxRootAsync(cancellationToken).AsTask());
// Format document
var unformattedText = addedDocument.GetTextSynchronously(cancellationToken);
......
......@@ -27,7 +27,7 @@ internal class AddParameterDialogViewModel : AbstractNotifyPropertyChanged
public AddParameterDialogViewModel(Document document, int positionForTypeBinding)
{
_notificationService = document.Project.Solution.Workspace.Services.GetService<INotificationService>();
_semanticModel = document.GetRequiredSemanticModelAsync(CancellationToken.None).WaitAndGetResult_CanCallOnBackground(CancellationToken.None);
_semanticModel = document.GetRequiredSemanticModelAsync(CancellationToken.None).AsTask().WaitAndGetResult_CanCallOnBackground(CancellationToken.None);
TypeIsEmptyImage = Visibility.Visible;
TypeBindsImage = Visibility.Collapsed;
......
......@@ -11,6 +11,6 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api
internal static class PythiaDocumentExtensions
{
public static Task<SemanticModel> GetSemanticModelForNodeAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken)
=> DocumentExtensions.ReuseExistingSpeculativeModelAsync(document, node, cancellationToken);
=> DocumentExtensions.ReuseExistingSpeculativeModelAsync(document, node, cancellationToken).AsTask();
}
}
......@@ -90,7 +90,7 @@ public SemanticModelReuseWorkspaceService(Workspace workspace)
};
}
public async Task<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
public async ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
{
var reuseService = document.GetRequiredLanguageService<ISemanticModelReuseLanguageService>();
......
......@@ -9,7 +9,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.GeneratedCodeRecognition;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.SemanticModelReuse;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -30,15 +29,21 @@ internal static partial class DocumentExtensions
public static TLanguageService GetRequiredLanguageService<TLanguageService>(this Document document) where TLanguageService : class, ILanguageService
=> document.Project.GetRequiredLanguageService<TLanguageService>();
public static async Task<SemanticModel> GetRequiredSemanticModelAsync(this Document document, CancellationToken cancellationToken)
public static async ValueTask<SemanticModel> GetRequiredSemanticModelAsync(this Document document, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
if (document.TryGetSemanticModel(out var semanticModel))
return semanticModel;
semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
return semanticModel ?? throw new InvalidOperationException(string.Format(WorkspaceExtensionsResources.SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0, document.Name));
}
public static async Task<SyntaxTree> GetRequiredSyntaxTreeAsync(this Document document, CancellationToken cancellationToken)
public static async ValueTask<SyntaxTree> GetRequiredSyntaxTreeAsync(this Document document, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
if (document.TryGetSyntaxTree(out var syntaxTree))
return syntaxTree;
syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
return syntaxTree ?? throw new InvalidOperationException(string.Format(WorkspaceExtensionsResources.SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0, document.Name));
}
......@@ -50,9 +55,12 @@ public static SyntaxTree GetRequiredSyntaxTreeSynchronously(this Document docume
}
#endif
public static async Task<SyntaxNode> GetRequiredSyntaxRootAsync(this Document document, CancellationToken cancellationToken)
public static async ValueTask<SyntaxNode> GetRequiredSyntaxRootAsync(this Document document, CancellationToken cancellationToken)
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
if (document.TryGetSyntaxRoot(out var root))
return root;
root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
return root ?? throw new InvalidOperationException(string.Format(WorkspaceExtensionsResources.SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0, document.Name));
}
......@@ -76,7 +84,7 @@ public static bool IsOpen(this TextDocument document)
/// <para/>
/// As a speculative semantic model may be returned, location based information provided by it may be innacurate.
/// </summary>
public static Task<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, int position, CancellationToken cancellationToken)
public static ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, int position, CancellationToken cancellationToken)
=> ReuseExistingSpeculativeModelAsync(document, new TextSpan(position, 0), cancellationToken);
/// <summary>
......@@ -93,7 +101,7 @@ public static Task<SemanticModel> ReuseExistingSpeculativeModelAsync(this Docume
/// <para/>
/// As a speculative semantic model may be returned, location based information provided by it may be innacurate.
/// </summary>
public static async Task<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, TextSpan span, CancellationToken cancellationToken)
public static async ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, TextSpan span, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(document.SupportsSemanticModel);
......@@ -118,7 +126,7 @@ public static async Task<SemanticModel> ReuseExistingSpeculativeModelAsync(this
/// <para/>
/// As a speculative semantic model may be returned, location based information provided by it may be innacurate.
/// </summary>
public static Task<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken)
public static ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken)
{
if (node == null)
return document.GetRequiredSemanticModelAsync(cancellationToken);
......
......@@ -18,6 +18,6 @@ internal interface ISemanticModelReuseWorkspaceService : IWorkspaceService
/// <summary>
/// Don't call this directly. use <see cref="DocumentExtensions.ReuseExistingSpeculativeModelAsync(Document, SyntaxNode, CancellationToken)"/> (or an overload).
/// </summary>
Task<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken);
ValueTask<SemanticModel> ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册