diff --git a/src/CodeStyle/Core/CodeFixes/LanguageServices/SemanticModelWorkspaceService/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs b/src/CodeStyle/Core/CodeFixes/LanguageServices/SemanticModelWorkspaceService/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs index c598ebc13f64a..eb6fa32d58975 100644 --- a/src/CodeStyle/Core/CodeFixes/LanguageServices/SemanticModelWorkspaceService/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs +++ b/src/CodeStyle/Core/CodeFixes/LanguageServices/SemanticModelWorkspaceService/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs @@ -17,7 +17,7 @@ public SemanticModelReuseWorkspaceService(Workspace _) { } - public Task ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) + public ValueTask ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) { // TODO: port the GetSemanticModelForNodeAsync implementation from Workspaces layer, // which currently relies on a bunch of internal APIs. diff --git a/src/EditorFeatures/TestUtilities/ChangeSignature/AddedParameterOrExistingIndex.cs b/src/EditorFeatures/TestUtilities/ChangeSignature/AddedParameterOrExistingIndex.cs index c4a70ce2b208d..a54e40efeebf1 100644 --- a/src/EditorFeatures/TestUtilities/ChangeSignature/AddedParameterOrExistingIndex.cs +++ b/src/EditorFeatures/TestUtilities/ChangeSignature/AddedParameterOrExistingIndex.cs @@ -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 { diff --git a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs index cf79bdf6d20cb..d2270ee55eaa6 100644 --- a/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs +++ b/src/VisualStudio/Core/Def/Implementation/AbstractEditorFactory.cs @@ -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); diff --git a/src/VisualStudio/Core/Def/Implementation/ChangeSignature/AddParameterDialogViewModel.cs b/src/VisualStudio/Core/Def/Implementation/ChangeSignature/AddParameterDialogViewModel.cs index 43635dbd02c16..70a5c03791bb0 100644 --- a/src/VisualStudio/Core/Def/Implementation/ChangeSignature/AddParameterDialogViewModel.cs +++ b/src/VisualStudio/Core/Def/Implementation/ChangeSignature/AddParameterDialogViewModel.cs @@ -27,7 +27,7 @@ internal class AddParameterDialogViewModel : AbstractNotifyPropertyChanged public AddParameterDialogViewModel(Document document, int positionForTypeBinding) { _notificationService = document.Project.Solution.Workspace.Services.GetService(); - _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; diff --git a/src/Workspaces/Core/Portable/ExternalAccess/Pythia/Api/PythiaDocumentExtensions.cs b/src/Workspaces/Core/Portable/ExternalAccess/Pythia/Api/PythiaDocumentExtensions.cs index c096460e25ec5..677c6648a082f 100644 --- a/src/Workspaces/Core/Portable/ExternalAccess/Pythia/Api/PythiaDocumentExtensions.cs +++ b/src/Workspaces/Core/Portable/ExternalAccess/Pythia/Api/PythiaDocumentExtensions.cs @@ -11,6 +11,6 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api internal static class PythiaDocumentExtensions { public static Task GetSemanticModelForNodeAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken) - => DocumentExtensions.ReuseExistingSpeculativeModelAsync(document, node, cancellationToken); + => DocumentExtensions.ReuseExistingSpeculativeModelAsync(document, node, cancellationToken).AsTask(); } } diff --git a/src/Workspaces/Core/Portable/SemanticModelReuse/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs b/src/Workspaces/Core/Portable/SemanticModelReuse/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs index c81912250541b..fe5ea8ca4250e 100644 --- a/src/Workspaces/Core/Portable/SemanticModelReuse/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs +++ b/src/Workspaces/Core/Portable/SemanticModelReuse/SemanticModelWorkspaceServiceFactory.SemanticModelWorkspaceService.cs @@ -90,7 +90,7 @@ public SemanticModelReuseWorkspaceService(Workspace workspace) }; } - public async Task ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) + public async ValueTask ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken) { var reuseService = document.GetRequiredLanguageService(); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs index 7fc6063e78325..7cfe442bab5b6 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs @@ -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(this Document document) where TLanguageService : class, ILanguageService => document.Project.GetRequiredLanguageService(); - public static async Task GetRequiredSemanticModelAsync(this Document document, CancellationToken cancellationToken) + public static async ValueTask 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 GetRequiredSyntaxTreeAsync(this Document document, CancellationToken cancellationToken) + public static async ValueTask 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 GetRequiredSyntaxRootAsync(this Document document, CancellationToken cancellationToken) + public static async ValueTask 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) /// /// As a speculative semantic model may be returned, location based information provided by it may be innacurate. /// - public static Task ReuseExistingSpeculativeModelAsync(this Document document, int position, CancellationToken cancellationToken) + public static ValueTask ReuseExistingSpeculativeModelAsync(this Document document, int position, CancellationToken cancellationToken) => ReuseExistingSpeculativeModelAsync(document, new TextSpan(position, 0), cancellationToken); /// @@ -93,7 +101,7 @@ public static Task ReuseExistingSpeculativeModelAsync(this Docume /// /// As a speculative semantic model may be returned, location based information provided by it may be innacurate. /// - public static async Task ReuseExistingSpeculativeModelAsync(this Document document, TextSpan span, CancellationToken cancellationToken) + public static async ValueTask ReuseExistingSpeculativeModelAsync(this Document document, TextSpan span, CancellationToken cancellationToken) { Contract.ThrowIfFalse(document.SupportsSemanticModel); @@ -118,7 +126,7 @@ public static async Task ReuseExistingSpeculativeModelAsync(this /// /// As a speculative semantic model may be returned, location based information provided by it may be innacurate. /// - public static Task ReuseExistingSpeculativeModelAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken) + public static ValueTask ReuseExistingSpeculativeModelAsync(this Document document, SyntaxNode? node, CancellationToken cancellationToken) { if (node == null) return document.GetRequiredSemanticModelAsync(cancellationToken); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceServices/SemanticModelReuse/ISemanticModelReuseWorkspaceService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceServices/SemanticModelReuse/ISemanticModelReuseWorkspaceService.cs index 2565078829672..95448a2708af2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceServices/SemanticModelReuse/ISemanticModelReuseWorkspaceService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceServices/SemanticModelReuse/ISemanticModelReuseWorkspaceService.cs @@ -18,6 +18,6 @@ internal interface ISemanticModelReuseWorkspaceService : IWorkspaceService /// /// Don't call this directly. use (or an overload). /// - Task ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); + ValueTask ReuseExistingSpeculativeModelAsync(Document document, SyntaxNode node, CancellationToken cancellationToken); } }