diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationNameCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationNameCompletionProvider.cs index 49bca936189e5..b4275f66224d0 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationNameCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/DeclarationNameCompletionProvider.cs @@ -53,14 +53,13 @@ public override async Task ProvideCompletionsAsync(CompletionContext completionC var position = completionContext.Position; var document = completionContext.Document; var cancellationToken = completionContext.CancellationToken; - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); if (!completionContext.CompletionOptions.ShowNameSuggestions) { return; } - var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); + var context = (CSharpSyntaxContext)await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); if (context.IsInNonUserCode) { return; @@ -69,7 +68,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext completionC // Do not show name suggestions for unbound "async" identifier. // Most likely user is writing an async method, so name suggestion will just interfere him if (context.TargetToken.IsKindOrHasMatchingText(SyntaxKind.AsyncKeyword) && - semanticModel.GetSymbolInfo(context.TargetToken).GetAnySymbol() is null) + context.SemanticModel.GetSymbolInfo(context.TargetToken).GetAnySymbol() is null) { return; } @@ -85,7 +84,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext completionC AddNamesFromExistingOverloads(context, partialSemanticModel, result, cancellationToken); } - var baseNames = GetBaseNames(semanticModel, nameInfo); + var baseNames = GetBaseNames(context.SemanticModel, nameInfo); if (baseNames != default) { await GetRecommendedNamesAsync(baseNames, nameInfo, context, document, result, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs index 35cd8755be451..e40458a90feeb 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/EnumAndCompletionListTagCompletionProvider.cs @@ -69,8 +69,8 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) if (tree.IsInNonUserCode(position, cancellationToken)) return; - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); - var syntaxContext = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); + var syntaxContext = await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); + var semanticModel = syntaxContext.SemanticModel; if (syntaxContext.IsInTaskLikeTypeContext) return; diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/OperatorsAndIndexer/UnnamedSymbolCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/OperatorsAndIndexer/UnnamedSymbolCompletionProvider.cs index 31206cffa7622..fe3c85da6775d 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/OperatorsAndIndexer/UnnamedSymbolCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/OperatorsAndIndexer/UnnamedSymbolCompletionProvider.cs @@ -111,11 +111,11 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) return; var recommender = document.GetRequiredLanguageService(); - - var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var syntaxContext = await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); + var semanticModel = syntaxContext.SemanticModel; var options = context.CompletionOptions.ToRecommendationServiceOptions(); - var recommendedSymbols = recommender.GetRecommendedSymbolsAtPosition(document, semanticModel, position, options, cancellationToken); + var recommendedSymbols = recommender.GetRecommendedSymbolsInContext(syntaxContext, options, cancellationToken); AddUnnamedSymbols(context, position, semanticModel, recommendedSymbols.UnnamedSymbols, cancellationToken); } diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/SnippetCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/SnippetCompletionProvider.cs index c7f4aa577c010..2487f578a9f89 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/SnippetCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/SnippetCompletionProvider.cs @@ -65,7 +65,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) context.AddItems(await document.GetUnionItemsFromDocumentAndLinkedDocumentsAsync( UnionCompletionItemComparer.Instance, - d => GetSnippetsForDocumentAsync(d, position, cancellationToken)).ConfigureAwait(false)); + d => GetSnippetsForDocumentAsync(d, context, cancellationToken)).ConfigureAwait(false)); } } catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, ErrorSeverity.General)) @@ -75,8 +75,9 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) } private static async Task> GetSnippetsForDocumentAsync( - Document document, int position, CancellationToken cancellationToken) + Document document, CompletionContext completionContext, CancellationToken cancellationToken) { + var position = completionContext.Position; var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); var semanticFacts = document.GetRequiredLanguageService(); @@ -93,8 +94,9 @@ private static async Task> GetSnippetsForDocument return ImmutableArray.Empty; } - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); - var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); + var context = await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); + var semanticModel = context.SemanticModel; + if (context.IsInTaskLikeTypeContext) return ImmutableArray.Empty; diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/SpeculativeTCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/SpeculativeTCompletionProvider.cs index 6683678142149..3a4c0bccc7421 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/SpeculativeTCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/SpeculativeTCompletionProvider.cs @@ -17,6 +17,7 @@ using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers { @@ -43,11 +44,10 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) try { var document = context.Document; - var position = context.Position; var cancellationToken = context.CancellationToken; var showSpeculativeT = await document.IsValidContextForDocumentOrLinkedDocumentsAsync( - (doc, ct) => ShouldShowSpeculativeTCompletionItemAsync(doc, position, ct), + (doc, ct) => ShouldShowSpeculativeTCompletionItemAsync(doc, context, ct), cancellationToken).ConfigureAwait(false); if (showSpeculativeT) @@ -63,8 +63,9 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) } } - private static async Task ShouldShowSpeculativeTCompletionItemAsync(Document document, int position, CancellationToken cancellationToken) + private static async Task ShouldShowSpeculativeTCompletionItemAsync(Document document, CompletionContext completionContext, CancellationToken cancellationToken) { + var position = completionContext.Position; var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) @@ -75,10 +76,8 @@ private static async Task ShouldShowSpeculativeTCompletionItemAsync(Docume // We could be in the middle of a ref/generic/tuple type, instead of a simple T case. // If we managed to walk out and get a different SpanStart, we treat it as a simple $$T case. - var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(token.Parent, cancellationToken).ConfigureAwait(false); + var context = await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); - var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); if (context.IsInTaskLikeTypeContext) return false; @@ -87,7 +86,7 @@ private static async Task ShouldShowSpeculativeTCompletionItemAsync(Docume { var oldSpanStart = spanStart; - spanStart = WalkOutOfGenericType(syntaxTree, spanStart, semanticModel, cancellationToken); + spanStart = WalkOutOfGenericType(syntaxTree, spanStart, context.SemanticModel, cancellationToken); spanStart = WalkOutOfTupleType(syntaxTree, spanStart, cancellationToken); spanStart = WalkOutOfRefType(syntaxTree, spanStart, cancellationToken); diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/TupleNameCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/TupleNameCompletionProvider.cs index 74049eb26f8b2..ddf523d620b1a 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/TupleNameCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/TupleNameCompletionProvider.cs @@ -18,6 +18,7 @@ using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers { @@ -41,12 +42,12 @@ public override async Task ProvideCompletionsAsync(CompletionContext completionC try { var document = completionContext.Document; - var position = completionContext.Position; var cancellationToken = completionContext.CancellationToken; - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); + var context = await completionContext.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false) as CSharpSyntaxContext; + Contract.ThrowIfNull(context); - var context = CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); + var semanticModel = context.SemanticModel; var index = GetElementIndex(context); if (index == null) diff --git a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs index 238c8ca820e82..899e5425f85a0 100644 --- a/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs +++ b/src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs @@ -24,6 +24,7 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Recommendations; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; using Microsoft.CodeAnalysis.Simplification; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -916,7 +917,9 @@ private async Task GenerateInferredCallsiteExpressionAsync( var recommender = document.GetRequiredLanguageService(); var options = RecommendationServiceOptions.From(document.Project); - var recommendations = recommender.GetRecommendedSymbolsAtPosition(document, semanticModel, position, options, cancellationToken).NamedSymbols; + + var context = document.GetRequiredLanguageService().CreateContext(document, semanticModel, position, cancellationToken); + var recommendations = recommender.GetRecommendedSymbolsInContext(context, options, cancellationToken).NamedSymbols; var sourceSymbols = recommendations.Where(r => r.IsNonImplicitAndFromSource()); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractAwaitCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractAwaitCompletionProvider.cs index b80cd734385f5..e72f3b6b18ee5 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractAwaitCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractAwaitCompletionProvider.cs @@ -88,8 +88,7 @@ public sealed override async Task ProvideCompletionsAsync(CompletionContext cont if (syntaxFacts.IsInNonUserCode(syntaxTree, position, cancellationToken)) return; - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); - var syntaxContext = document.GetRequiredLanguageService().CreateContext(document, semanticModel, position, cancellationToken); + var syntaxContext = await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); var isAwaitKeywordContext = IsAwaitKeywordContext(syntaxContext); var dotAwaitContext = GetDotAwaitKeywordContext(syntaxContext, cancellationToken); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractKeywordCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractKeywordCompletionProvider.cs index df0f01226be69..7caf809dfa7c3 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractKeywordCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractKeywordCompletionProvider.cs @@ -36,15 +36,14 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) { context.AddItems(await context.Document.GetUnionItemsFromDocumentAndLinkedDocumentsAsync( s_comparer, - d => RecommendCompletionItemsAsync(d, context.Position, cancellationToken)).ConfigureAwait(false)); + d => RecommendCompletionItemsAsync(d, context, cancellationToken)).ConfigureAwait(false)); } } - private async Task> RecommendCompletionItemsAsync(Document document, int position, CancellationToken cancellationToken) + private async Task> RecommendCompletionItemsAsync(Document document, CompletionContext context, CancellationToken cancellationToken) { - var syntaxContextService = document.GetRequiredLanguageService(); - var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); - var syntaxContext = (TContext)syntaxContextService.CreateContext(document, semanticModel, position, cancellationToken); + var position = context.Position; + var syntaxContext = (TContext)await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); var keywords = await RecommendKeywordsAsync(document, position, syntaxContext, cancellationToken).ConfigureAwait(false); return keywords.SelectAsArray(k => CreateItem(k, syntaxContext, cancellationToken)); } diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractPreprocessorCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractPreprocessorCompletionProvider.cs index c1e64e5635016..f039c9496605a 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractPreprocessorCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractPreprocessorCompletionProvider.cs @@ -20,11 +20,8 @@ public sealed override async Task ProvideCompletionsAsync(CompletionContext cont var cancellationToken = context.CancellationToken; var originatingDocument = context.Document; var position = context.Position; - - var semanticModel = await originatingDocument.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); - var service = originatingDocument.GetRequiredLanguageService(); var solution = originatingDocument.Project.Solution; - var syntaxContext = service.CreateContext(originatingDocument, semanticModel, position, cancellationToken); + var syntaxContext = await context.GetSyntaxContextWithExistingSpeculativeModelAsync(originatingDocument, cancellationToken).ConfigureAwait(false); if (!syntaxContext.IsPreProcessorExpressionContext) return; diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs index f70eaaae6409d..a030f435b8f13 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractRecommendationServiceBasedCompletionProvider.cs @@ -34,7 +34,7 @@ internal abstract class AbstractRecommendationServiceBasedCompletionProvider(); - var recommendedSymbols = recommender.GetRecommendedSymbolsAtPosition(context.Document, context.SemanticModel, position, recommendationOptions, cancellationToken); + var recommendedSymbols = recommender.GetRecommendedSymbolsInContext(context, recommendationOptions, cancellationToken); if (context.IsInTaskLikeTypeContext) { diff --git a/src/Features/Core/Portable/Completion/SharedSyntaxContextsWithSpeculativeModel.cs b/src/Features/Core/Portable/Completion/SharedSyntaxContextsWithSpeculativeModel.cs index 888efbd984271..011b60958d0ed 100644 --- a/src/Features/Core/Portable/Completion/SharedSyntaxContextsWithSpeculativeModel.cs +++ b/src/Features/Core/Portable/Completion/SharedSyntaxContextsWithSpeculativeModel.cs @@ -35,16 +35,16 @@ public Task GetSyntaxContextAsync(Document document, Cancellation if (_document.Id != document.Id && !_lazyRelatedDocumentIds.Value.Contains(document.Id)) throw new ArgumentException("Don't support getting SyntaxContext for document unrelated to the original document"); - lazyContext = GetLazySyntaxContextWithSpeculativeModel(document); + lazyContext = GetLazySyntaxContextWithSpeculativeModel(document, this); } return lazyContext.GetValueAsync(cancellationToken); // Extract a local function to avoid creating a closure for code path of cache hit. - AsyncLazy GetLazySyntaxContextWithSpeculativeModel(Document document) + static AsyncLazy GetLazySyntaxContextWithSpeculativeModel(Document document, SharedSyntaxContextsWithSpeculativeModel self) { - return _cache.GetOrAdd(document, d => AsyncLazy.Create(cancellationToken - => CompletionHelper.CreateSyntaxContextWithExistingSpeculativeModelAsync(d, _position, cancellationToken), cacheResult: true)); + return self._cache.GetOrAdd(document, d => AsyncLazy.Create(cancellationToken + => CompletionHelper.CreateSyntaxContextWithExistingSpeculativeModelAsync(d, self._position, cancellationToken), cacheResult: true)); } } } diff --git a/src/VisualStudio/VisualBasic/Impl/Snippets/SnippetCompletionProvider.vb b/src/VisualStudio/VisualBasic/Impl/Snippets/SnippetCompletionProvider.vb index 685882e3d63db..53916c54a9c40 100644 --- a/src/VisualStudio/VisualBasic/Impl/Snippets/SnippetCompletionProvider.vb +++ b/src/VisualStudio/VisualBasic/Impl/Snippets/SnippetCompletionProvider.vb @@ -89,8 +89,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Snippets Return End If - Dim semanticModel = Await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(False) - Dim syntaxContext = VisualBasicSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken) + Dim syntaxContext = Await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(False) If syntaxContext.IsInTaskLikeTypeContext Then Return End If diff --git a/src/Workspaces/CSharp/Portable/Recommendations/CSharpRecommendationService.cs b/src/Workspaces/CSharp/Portable/Recommendations/CSharpRecommendationService.cs index 031295d9d0434..7c493ae409783 100644 --- a/src/Workspaces/CSharp/Portable/Recommendations/CSharpRecommendationService.cs +++ b/src/Workspaces/CSharp/Portable/Recommendations/CSharpRecommendationService.cs @@ -20,9 +20,6 @@ public CSharpRecommendationService() { } - protected override CSharpSyntaxContext CreateContext(Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken) - => CSharpSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken); - protected override AbstractRecommendationServiceRunner CreateRunner(CSharpSyntaxContext context, bool filterOutOfScopeLocals, CancellationToken cancellationToken) => new CSharpRecommendationServiceRunner(context, filterOutOfScopeLocals, cancellationToken); } diff --git a/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs b/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs index 8dea60dbbf689..29afdff7ab0f8 100644 --- a/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs +++ b/src/Workspaces/Core/Portable/Recommendations/AbstractRecommendationService.cs @@ -17,16 +17,13 @@ namespace Microsoft.CodeAnalysis.Recommendations internal abstract partial class AbstractRecommendationService : IRecommendationService where TSyntaxContext : SyntaxContext { - protected abstract TSyntaxContext CreateContext( - Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken); - protected abstract AbstractRecommendationServiceRunner CreateRunner( TSyntaxContext context, bool filterOutOfScopeLocals, CancellationToken cancellationToken); - public RecommendedSymbols GetRecommendedSymbolsAtPosition(Document document, SemanticModel semanticModel, int position, RecommendationServiceOptions options, CancellationToken cancellationToken) + public RecommendedSymbols GetRecommendedSymbolsInContext(SyntaxContext syntaxContext, RecommendationServiceOptions options, CancellationToken cancellationToken) { - var context = CreateContext(document, semanticModel, position, cancellationToken); - var result = CreateRunner(context, options.FilterOutOfScopeLocals, cancellationToken).GetRecommendedSymbols(); + var semanticModel = syntaxContext.SemanticModel; + var result = CreateRunner((TSyntaxContext)syntaxContext, options.FilterOutOfScopeLocals, cancellationToken).GetRecommendedSymbols(); var namedSymbols = result.NamedSymbols; var unnamedSymbols = result.UnnamedSymbols; @@ -34,7 +31,7 @@ public RecommendedSymbols GetRecommendedSymbolsAtPosition(Document document, Sem namedSymbols = namedSymbols.FilterToVisibleAndBrowsableSymbols(options.HideAdvancedMembers, semanticModel.Compilation); unnamedSymbols = unnamedSymbols.FilterToVisibleAndBrowsableSymbols(options.HideAdvancedMembers, semanticModel.Compilation); - var shouldIncludeSymbolContext = new ShouldIncludeSymbolContext(context, cancellationToken); + var shouldIncludeSymbolContext = new ShouldIncludeSymbolContext(syntaxContext, cancellationToken); namedSymbols = namedSymbols.WhereAsArray(shouldIncludeSymbolContext.ShouldIncludeSymbol); unnamedSymbols = unnamedSymbols.WhereAsArray(shouldIncludeSymbolContext.ShouldIncludeSymbol); diff --git a/src/Workspaces/Core/Portable/Recommendations/IRecommendationService.cs b/src/Workspaces/Core/Portable/Recommendations/IRecommendationService.cs index 3f98c0059c492..9227fe209690c 100644 --- a/src/Workspaces/Core/Portable/Recommendations/IRecommendationService.cs +++ b/src/Workspaces/Core/Portable/Recommendations/IRecommendationService.cs @@ -5,15 +5,14 @@ using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; namespace Microsoft.CodeAnalysis.Recommendations { internal interface IRecommendationService : ILanguageService { - RecommendedSymbols GetRecommendedSymbolsAtPosition( - Document document, - SemanticModel semanticModel, - int position, + RecommendedSymbols GetRecommendedSymbolsInContext( + SyntaxContext syntaxContext, RecommendationServiceOptions options, CancellationToken cancellationToken); } diff --git a/src/Workspaces/Core/Portable/Recommendations/Recommender.cs b/src/Workspaces/Core/Portable/Recommendations/Recommender.cs index 63c8a351e2c27..153534b40fec3 100644 --- a/src/Workspaces/Core/Portable/Recommendations/Recommender.cs +++ b/src/Workspaces/Core/Portable/Recommendations/Recommender.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; namespace Microsoft.CodeAnalysis.Recommendations { @@ -25,8 +26,10 @@ public static IEnumerable GetRecommendedSymbolsAtPosition( var solution = workspace.CurrentSolution; options ??= solution.Options; var document = solution.GetRequiredDocument(semanticModel.SyntaxTree); + var context = document.GetRequiredLanguageService().CreateContext(document, semanticModel, position, cancellationToken); + var languageRecommender = document.GetRequiredLanguageService(); - return languageRecommender.GetRecommendedSymbolsAtPosition(document, semanticModel, position, RecommendationServiceOptions.From(options, document.Project.Language), cancellationToken).NamedSymbols; + return languageRecommender.GetRecommendedSymbolsInContext(context, RecommendationServiceOptions.From(options, document.Project.Language), cancellationToken).NamedSymbols; } [Obsolete("Use GetRecommendedSymbolsAtPositionAsync(Document, ...)")] @@ -49,8 +52,9 @@ public static async Task> GetRecommendedSymbolsAtPositio var solution = document.Project.Solution; var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); options ??= solution.Options; + var context = document.GetRequiredLanguageService().CreateContext(document, semanticModel, position, cancellationToken); var languageRecommender = document.GetRequiredLanguageService(); - return languageRecommender.GetRecommendedSymbolsAtPosition(document, semanticModel, position, RecommendationServiceOptions.From(options, document.Project.Language), cancellationToken).NamedSymbols; + return languageRecommender.GetRecommendedSymbolsInContext(context, RecommendationServiceOptions.From(options, document.Project.Language), cancellationToken).NamedSymbols; } } } diff --git a/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb b/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb index 4e8f0c5ebc35b..e1caff2aef8c8 100644 --- a/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb +++ b/src/Workspaces/VisualBasic/Portable/Recommendations/VisualBasicRecommendationService.vb @@ -18,10 +18,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Recommendations Public Sub New() End Sub - Protected Overrides Function CreateContext(document As Document, semanticModel As SemanticModel, position As Integer, cancellationToken As CancellationToken) As VisualBasicSyntaxContext - Return VisualBasicSyntaxContext.CreateContext(document, semanticModel, position, cancellationToken) - End Function - Protected Overrides Function CreateRunner(context As VisualBasicSyntaxContext, filterOutOfScopeLocals As Boolean, cancellationToken As CancellationToken) As AbstractRecommendationServiceRunner Return New VisualBasicRecommendationServiceRunner(context, filterOutOfScopeLocals, cancellationToken) End Function