Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snippet refactoring 2 #74767

Merged
merged 3 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets;
internal abstract class AbstractCSharpMainMethodSnippetProvider
: AbstractMainMethodSnippetProvider<MethodDeclarationSyntax, StatementSyntax, TypeSyntax>
{
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal abstract class AbstractCSharpTypeSnippetProvider<TTypeDeclarationSyntax
{
protected abstract ISet<SyntaxKind> ValidModifiers { get; }

protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken)
protected override bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken)
{
var syntaxContext = (CSharpSyntaxContext)context.SyntaxContext;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ 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;

// Console.WriteLine snippet is legal after an arrow token of a void-returning lambda, e.g.
// 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<TextChange> GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
/// </summary>
public async Task<ImmutableArray<SnippetData>> GetSnippetsAsync(SnippetContext context, CancellationToken cancellationToken)
public ImmutableArray<SnippetData> GetSnippets(SnippetContext context, CancellationToken cancellationToken)
{
using var _ = ArrayBuilder<SnippetData>.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));
}

Expand Down
3 changes: 1 addition & 2 deletions src/Features/Core/Portable/Snippets/ISnippetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Snippets.SnippetProviders;

Expand All @@ -15,7 +14,7 @@ internal interface ISnippetService : ILanguageService
/// <summary>
/// Retrieves all possible types of snippets for a particular position
/// </summary>
Task<ImmutableArray<SnippetData>> GetSnippetsAsync(SnippetContext context, CancellationToken cancellationToken);
ImmutableArray<SnippetData> GetSnippets(SnippetContext context, CancellationToken cancellationToken);

/// <summary>
/// Gets the corresponding provider from a snippet identifier.
Expand Down
5 changes: 5 additions & 0 deletions src/Features/Core/Portable/Snippets/SnippetContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ internal SnippetContext(SyntaxContext syntaxContext)
/// </summary>
public int Position => SyntaxContext.Position;

/// <summary>
/// The semantic model of the document.
/// </summary>
public SemanticModel SemanticModel => SyntaxContext.SemanticModel;

internal SyntaxContext SyntaxContext { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ internal abstract class AbstractInlineStatementSnippetProvider<TStatementSyntax>
/// </summary>
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<ISyntaxFactsService>();
Expand All @@ -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<TextChange> GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal abstract class AbstractSnippetProvider<TSnippetSyntax> : ISnippetProvid
/// Implemented by each SnippetProvider to determine if that particular position is a valid
/// location for the snippet to be inserted.
/// </summary>
protected abstract bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken);
protected abstract bool IsValidSnippetLocationCore(SnippetContext context, CancellationToken cancellationToken);

/// <summary>
/// Generates the new snippet's TextChanges that are being inserted into the document.
Expand All @@ -50,16 +50,16 @@ internal abstract class AbstractSnippetProvider<TSnippetSyntax> : ISnippetProvid
/// </summary>
protected abstract ImmutableArray<SnippetPlaceholder> GetPlaceHolderLocationsList(TSnippetSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken);

public ValueTask<bool> IsValidSnippetLocationAsync(in SnippetContext context, CancellationToken cancellationToken)
public bool IsValidSnippetLocation(SnippetContext context, CancellationToken cancellationToken)
{
var syntaxFacts = context.Document.GetRequiredLanguageService<ISyntaxFactsService>();
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);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders;
internal abstract class AbstractStatementSnippetProvider<TStatementSyntax> : AbstractSingleChangeSnippetProvider<TStatementSyntax>
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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal interface ISnippetProvider
/// <summary>
/// Determines if a snippet can exist at a particular location.
/// </summary>
ValueTask<bool> IsValidSnippetLocationAsync(in SnippetContext context, CancellationToken cancellationToken);
bool IsValidSnippetLocation(SnippetContext context, CancellationToken cancellationToken);
sharwell marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Gets the Snippet change from the corresponding snippet provider.
Expand Down
Loading