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

Avoid Task allocations in common document extensions

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