diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index 954a85488b311..9e6a532dd26f2 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -30,7 +30,7 @@ internal abstract class AbstractCSharpAutoPropertySnippetProvider : AbstractProp protected virtual AccessorDeclarationSyntax? GenerateSetAccessorDeclaration(CSharpSyntaxContext syntaxContext, SyntaxGenerator generator, CancellationToken cancellationToken) => (AccessorDeclarationSyntax)generator.SetAccessorDeclaration(); - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { return context.SyntaxContext.SyntaxTree.IsMemberDeclarationContext(context.Position, (CSharpSyntaxContext)context.SyntaxContext, SyntaxKindSet.AllMemberModifiers, SyntaxKindSet.ClassInterfaceStructRecordTypeDeclarations, canBePartial: true, cancellationToken); diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs index aa84a9a5061c8..cc9cce7497814 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs @@ -15,9 +15,9 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; internal abstract class AbstractCSharpMainMethodSnippetProvider : AbstractMainMethodSnippetProvider { - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { - var semanticModel = context.SyntaxContext.SemanticModel; + var semanticModel = context.SemanticModel; var syntaxContext = (CSharpSyntaxContext)context.SyntaxContext; if (!syntaxContext.IsMemberDeclarationContext( diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 6569ef7bdd066..af4945b17c570 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -27,7 +27,7 @@ internal abstract class AbstractCSharpTypeSnippetProvider ValidModifiers { get; } - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = (CSharpSyntaxContext)context.SyntaxContext; diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs index cf175e08e78a8..0a91a98893177 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs @@ -21,11 +21,12 @@ internal sealed class CSharpConsoleSnippetProvider() : AbstractConsoleSnippetPro ArgumentListSyntax, LambdaExpressionSyntax> { - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = context.SyntaxContext; + var semanticModel = context.SemanticModel; - var consoleSymbol = GetConsoleSymbolFromMetaDataName(syntaxContext.SemanticModel.Compilation); + var consoleSymbol = GetConsoleSymbolFromMetaDataName(semanticModel.Compilation); if (consoleSymbol is null) return false; @@ -33,7 +34,6 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel // Action a = () => Console.WriteLine("Action called"); if (syntaxContext.TargetToken is { RawKind: (int)SyntaxKind.EqualsGreaterThanToken, Parent: LambdaExpressionSyntax lambda }) { - var semanticModel = syntaxContext.SemanticModel; var lambdaSymbol = semanticModel.GetSymbolInfo(lambda, cancellationToken).Symbol; // Given that we are in a partially written lambda state compiler might not always infer return type correctly. diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs index 1e7ab1e7817bc..f885a980d0a48 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs @@ -36,7 +36,7 @@ internal sealed class CSharpConstructorSnippetProvider() : AbstractConstructorSn SyntaxKind.StaticKeyword, }; - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = (CSharpSyntaxContext)context.SyntaxContext; diff --git a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs index 4fdf90a78525c..a720e79571b8d 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs @@ -24,7 +24,7 @@ internal sealed class CSharpElseSnippetProvider() : AbstractElseSnippetProvider< public override string Description => FeaturesResources.else_statement; - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = context.SyntaxContext; var token = syntaxContext.TargetToken; @@ -51,7 +51,7 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel } } - return isAfterIfStatement && base.IsValidSnippetLocation(in context, cancellationToken); + return isAfterIfStatement && base.IsValidSnippetLocationCore(context, cancellationToken); } protected override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs index 1ff99c4351f6d..32c64990213fc 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs @@ -34,7 +34,7 @@ internal sealed class CSharpForEachLoopSnippetProvider() : AbstractForEachLoopSn public override string Description => FeaturesResources.foreach_loop; - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = context.SyntaxContext; var token = syntaxContext.TargetToken; @@ -48,7 +48,7 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel return true; } - return base.IsValidSnippetLocation(in context, cancellationToken); + return base.IsValidSnippetLocationCore(context, cancellationToken); } protected override ForEachStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) diff --git a/src/Features/Core/Portable/Completion/Providers/Snippets/AbstractSnippetCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/Snippets/AbstractSnippetCompletionProvider.cs index d22d15178c26a..ecc4b1fedba12 100644 --- a/src/Features/Core/Portable/Completion/Providers/Snippets/AbstractSnippetCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/Snippets/AbstractSnippetCompletionProvider.cs @@ -82,7 +82,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) var syntaxContext = await context.GetSyntaxContextWithExistingSpeculativeModelAsync(document, cancellationToken).ConfigureAwait(false); var snippetContext = new SnippetContext(syntaxContext); - var snippets = await service.GetSnippetsAsync(snippetContext, cancellationToken).ConfigureAwait(false); + var snippets = service.GetSnippets(snippetContext, cancellationToken); foreach (var snippetData in snippets) { diff --git a/src/Features/Core/Portable/Snippets/AbstractSnippetService.cs b/src/Features/Core/Portable/Snippets/AbstractSnippetService.cs index 24010eb1adeec..8ee61c89eb4bc 100644 --- a/src/Features/Core/Portable/Snippets/AbstractSnippetService.cs +++ b/src/Features/Core/Portable/Snippets/AbstractSnippetService.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -37,12 +36,12 @@ public ISnippetProvider GetSnippetProvider(string snippetIdentifier) /// Iterates through all providers and determines if the snippet /// can be added to the Completion list at the corresponding position. /// - public async Task> GetSnippetsAsync(SnippetContext context, CancellationToken cancellationToken) + public ImmutableArray GetSnippets(SnippetContext context, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); foreach (var provider in GetSnippetProviders(context.Document)) { - if (await provider.IsValidSnippetLocationAsync(in context, cancellationToken).ConfigureAwait(false)) + if (provider.IsValidSnippetLocation(context, cancellationToken)) arrayBuilder.Add(new(provider.Identifier, provider.Description, provider.AdditionalFilterTexts)); } diff --git a/src/Features/Core/Portable/Snippets/ISnippetService.cs b/src/Features/Core/Portable/Snippets/ISnippetService.cs index b8e45d4bc0812..53f0f1aba624a 100644 --- a/src/Features/Core/Portable/Snippets/ISnippetService.cs +++ b/src/Features/Core/Portable/Snippets/ISnippetService.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using System.Threading; -using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -15,7 +14,7 @@ internal interface ISnippetService : ILanguageService /// /// Retrieves all possible types of snippets for a particular position /// - Task> GetSnippetsAsync(SnippetContext context, CancellationToken cancellationToken); + ImmutableArray GetSnippets(SnippetContext context, CancellationToken cancellationToken); /// /// Gets the corresponding provider from a snippet identifier. diff --git a/src/Features/Core/Portable/Snippets/SnippetContext.cs b/src/Features/Core/Portable/Snippets/SnippetContext.cs index 58d6437794bfe..034a4e0e10fef 100644 --- a/src/Features/Core/Portable/Snippets/SnippetContext.cs +++ b/src/Features/Core/Portable/Snippets/SnippetContext.cs @@ -28,5 +28,10 @@ internal SnippetContext(SyntaxContext syntaxContext) /// public int Position => SyntaxContext.Position; + /// + /// The semantic model of the document. + /// + public SemanticModel SemanticModel => SyntaxContext.SemanticModel; + internal SyntaxContext SyntaxContext { get; } } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs index ac60dc0569394..f29734df6fd92 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs @@ -39,10 +39,10 @@ internal abstract class AbstractInlineStatementSnippetProvider /// protected bool ConstructedFromInlineExpression { get; private set; } - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) { var syntaxContext = context.SyntaxContext; - var semanticModel = syntaxContext.SemanticModel; + var semanticModel = context.SemanticModel; var targetToken = syntaxContext.TargetToken; var syntaxFacts = context.Document.GetRequiredLanguageService(); @@ -51,7 +51,7 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel return IsValidAccessingType(type, semanticModel.Compilation); } - return base.IsValidSnippetLocation(in context, cancellationToken); + return base.IsValidSnippetLocationCore(context, cancellationToken); } protected sealed override async Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index 85b01302fe601..7dd77c9c9d2a7 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -33,7 +33,7 @@ internal abstract class AbstractSnippetProvider : ISnippetProvid /// Implemented by each SnippetProvider to determine if that particular position is a valid /// location for the snippet to be inserted. /// - protected abstract bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken); + protected abstract bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken); /// /// Generates the new snippet's TextChanges that are being inserted into the document. @@ -50,16 +50,16 @@ internal abstract class AbstractSnippetProvider : ISnippetProvid /// protected abstract ImmutableArray GetPlaceHolderLocationsList(TSnippetSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken); - public ValueTask IsValidSnippetLocationAsync(in SnippetContext context, CancellationToken cancellationToken) + public bool IsValidSnippetLocation(SnippetContext context, CancellationToken cancellationToken) { var syntaxFacts = context.Document.GetRequiredLanguageService(); var syntaxTree = context.SyntaxContext.SyntaxTree; if (syntaxFacts.IsInNonUserCode(syntaxTree, context.Position, cancellationToken)) { - return ValueTaskFactory.FromResult(false); + return false; } - return ValueTaskFactory.FromResult(IsValidSnippetLocation(in context, cancellationToken)); + return IsValidSnippetLocationCore(context, cancellationToken); } /// diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs index 16b98b988c8e9..2cc624a4e736f 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs @@ -9,6 +9,6 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; internal abstract class AbstractStatementSnippetProvider : AbstractSingleChangeSnippetProvider where TStatementSyntax : SyntaxNode { - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken) => context.SyntaxContext.IsStatementContext || context.SyntaxContext.IsGlobalStatementContext; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/ISnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/ISnippetProvider.cs index 5c6d298db3e7b..56052399364ae 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/ISnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/ISnippetProvider.cs @@ -28,7 +28,7 @@ internal interface ISnippetProvider /// /// Determines if a snippet can exist at a particular location. /// - ValueTask IsValidSnippetLocationAsync(in SnippetContext context, CancellationToken cancellationToken); + bool IsValidSnippetLocation(SnippetContext context, CancellationToken cancellationToken); /// /// Gets the Snippet change from the corresponding snippet provider.