From 59c11ce29228c209ac40887e20d257c7166d54e3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:18:36 -0700 Subject: [PATCH 01/29] in progress --- .../CSharpDoWhileLoopStatementProvider.cs | 12 +++---- ...AbstractConditionalBlockSnippetProvider.cs | 10 +++--- .../AbstractConsoleSnippetProvider.cs | 35 ++++++++----------- .../AbstractConstructorSnippetProvider.cs | 13 +++---- .../AbstractElseSnippetProvider.cs | 7 ++-- .../AbstractForEachLoopSnippetProvider.cs | 11 +++--- .../AbstractForLoopSnippetProvider.cs | 7 ++-- .../AbstractIfSnippetProvider.cs | 12 ++++--- .../AbstractInlineStatementSnippetProvider.cs | 9 ++--- .../AbstractLockSnippetProvider.cs | 7 ++-- .../AbstractMainMethodSnippetProvider.cs | 9 ++--- .../AbstractPropertySnippetProvider.cs | 9 ++--- .../AbstractSingleChangeSnippetProvider.cs | 3 +- .../AbstractSnippetProvider.cs | 15 ++++---- .../AbstractStatementSnippetProvider.cs | 3 +- .../AbstractTypeSnippetProvider.cs | 9 ++--- .../AbstractWhileLoopSnippetProvider.cs | 11 +++--- 17 files changed, 94 insertions(+), 88 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs index eecd8f6549786..d0c9d825e11bb 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs @@ -20,24 +20,22 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpDoWhileLoopStatementProvider() : AbstractConditionalBlockSnippetProvider +internal sealed class CSharpDoWhileLoopStatementProvider() + : AbstractConditionalBlockSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.Do; public override string Description => CSharpFeaturesResources.do_while_loop; - protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) + protected override DoStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) { return SyntaxFactory.DoStatement( SyntaxFactory.Block(), (ExpressionSyntax)(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression())); } - protected override SyntaxNode GetCondition(SyntaxNode node) - { - var doStatement = (DoStatementSyntax)node; - return doStatement.Condition; - } + protected override ExpressionSyntax GetCondition(DoStatementSyntax node) + => node.Condition; protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => static node => node is DoStatementSyntax; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs index a5b5f1851712f..194ec386a7e28 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs @@ -11,14 +11,16 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; /// /// Base class for "if" and "while" snippet providers /// -internal abstract class AbstractConditionalBlockSnippetProvider : AbstractInlineStatementSnippetProvider +internal abstract class AbstractConditionalBlockSnippetProvider : AbstractInlineStatementSnippetProvider + where TStatementSyntax : SyntaxNode + where TExpressionSyntax : SyntaxNode { - protected abstract SyntaxNode GetCondition(SyntaxNode node); + protected abstract TExpressionSyntax GetCondition(TStatementSyntax node); - protected override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) + protected sealed override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) => type.SpecialType == SpecialType.System_Boolean; - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { if (ConstructedFromInlineExpression) return []; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs index 75cd79d46d593..a9c09c2e437f2 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs @@ -18,31 +18,30 @@ namespace Microsoft.CodeAnalysis.Snippets; -internal abstract class AbstractConsoleSnippetProvider : AbstractStatementSnippetProvider +internal abstract class AbstractConsoleSnippetProvider : AbstractStatementSnippetProvider + where TExpressionStatementSyntax : SyntaxNode { - public override string Identifier => CommonSnippetIdentifiers.ConsoleWriteLine; + public sealed override string Identifier => CommonSnippetIdentifiers.ConsoleWriteLine; - public override string Description => FeaturesResources.console_writeline; + public sealed override string Description => FeaturesResources.console_writeline; - public override ImmutableArray AdditionalFilterTexts { get; } = ["WriteLine"]; + public sealed override ImmutableArray AdditionalFilterTexts { get; } = ["WriteLine"]; - protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) + protected sealed override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) { var consoleSymbol = GetConsoleSymbolFromMetaDataName(context.SyntaxContext.SemanticModel.Compilation); if (consoleSymbol is null) - { return false; - } return base.IsValidSnippetLocation(in context, cancellationToken); } - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) { return syntaxFacts.IsExpressionStatement; } - protected override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) + protected sealed override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); @@ -57,7 +56,7 @@ protected override Task GenerateSnippetTextChangeAsync(Document docu /// Tries to get the location after the open parentheses in the argument list. /// If it can't, then we default to the end of the snippet's span. /// - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) + protected sealed override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) { var invocationExpression = caretTarget.DescendantNodes().Where(syntaxFacts.IsInvocationExpression).FirstOrDefault(); if (invocationExpression is null) @@ -75,7 +74,7 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, S return openParenToken.Span.End; } - protected override async Task AnnotateNodesToReformatAsync(Document document, + protected sealed override async Task AnnotateNodesToReformatAsync(Document document, SyntaxAnnotation findSnippetAnnotation, SyntaxAnnotation cursorAnnotation, int position, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); @@ -89,10 +88,8 @@ protected override async Task AnnotateNodesToReformatAsync(Document return root.ReplaceNode(snippetExpressionNode, reformatSnippetNode); } - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) - { - return []; - } + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TExpressionStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + => []; private static SyntaxToken? GetOpenParenToken(SyntaxNode node, ISyntaxFacts syntaxFacts) { @@ -116,22 +113,18 @@ protected override ImmutableArray GetPlaceHolderLocationsLis private static INamedTypeSymbol? GetConsoleSymbolFromMetaDataName(Compilation compilation) => compilation.GetBestTypeByMetadataName(typeof(Console).FullName!); - protected override SyntaxNode? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected sealed override TExpressionStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) { var closestNode = root.FindNode(TextSpan.FromBounds(position, position)); - var nearestExpressionStatement = closestNode.FirstAncestorOrSelf(isCorrectContainer); + var nearestExpressionStatement = closestNode.FirstAncestorOrSelf(isCorrectContainer); if (nearestExpressionStatement is null) - { return null; - } // Checking to see if that expression statement that we found is // starting at the same position as the position we inserted // the Console WriteLine expression statement. if (nearestExpressionStatement.SpanStart != position) - { return null; - } return nearestExpressionStatement; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs index 6758953a6981c..2a7f0e7e1e991 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs @@ -9,16 +9,17 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractConstructorSnippetProvider : AbstractSingleChangeSnippetProvider +internal abstract class AbstractConstructorSnippetProvider : AbstractSingleChangeSnippetProvider + where TConstructorDeclarationSyntax : SyntaxNode { - public override string Identifier => CommonSnippetIdentifiers.Constructor; + public sealed override string Identifier => CommonSnippetIdentifiers.Constructor; - public override string Description => FeaturesResources.constructor; + public sealed override string Description => FeaturesResources.constructor; - public override ImmutableArray AdditionalFilterTexts { get; } = ["constructor"]; + public sealed override ImmutableArray AdditionalFilterTexts { get; } = ["constructor"]; - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsConstructorDeclaration; + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsConstructorDeclaration; - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TConstructorDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs index 011cd47ec0bc6..0a7ca9902fece 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs @@ -9,10 +9,11 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractElseSnippetProvider : AbstractStatementSnippetProvider +internal abstract class AbstractElseSnippetProvider : AbstractStatementSnippetProvider + where TElseClauseSyntax : SyntaxNode { - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsElseClause; + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsElseClause; - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TElseClauseSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs index a8543986818f7..4af760b508e32 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs @@ -9,13 +9,12 @@ namespace Microsoft.CodeAnalysis.Snippets; -internal abstract class AbstractForEachLoopSnippetProvider : AbstractInlineStatementSnippetProvider +internal abstract class AbstractForEachLoopSnippetProvider : AbstractInlineStatementSnippetProvider + where TStatementSyntax : SyntaxNode { - protected override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) + protected sealed override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) => type.CanBeEnumerated() || type.CanBeAsynchronouslyEnumerated(compilation); - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsForEachStatement; - } + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + => syntaxFacts.IsForEachStatement; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs index 88444b5140578..b8d8e53224d60 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs @@ -9,9 +9,10 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractForLoopSnippetProvider : AbstractInlineStatementSnippetProvider +internal abstract class AbstractForLoopSnippetProvider : AbstractInlineStatementSnippetProvider + where TStatementSyntax : SyntaxNode { - protected override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) + protected sealed override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) { if (IsSuitableIntegerType(type)) { @@ -25,7 +26,7 @@ protected override bool IsValidAccessingType(ITypeSymbol type, Compilation compi return hasLengthProperty ^ hasCountProperty; } - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsForStatement; protected static bool IsSuitableIntegerType(ITypeSymbol type) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs index 8e4fe49334e36..9e43789c3ecc5 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs @@ -11,12 +11,14 @@ namespace Microsoft.CodeAnalysis.Snippets; -internal abstract class AbstractIfSnippetProvider : AbstractConditionalBlockSnippetProvider +internal abstract class AbstractIfSnippetProvider : AbstractConditionalBlockSnippetProvider + where TIfStatementSyntax : SyntaxNode + where TExpressionSyntax : SyntaxNode { - public override ImmutableArray AdditionalFilterTexts { get; } = ["statement"]; + public sealed override ImmutableArray AdditionalFilterTexts { get; } = ["statement"]; - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsIfStatement; + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsIfStatement; - protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) - => generator.IfStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); + protected sealed override TIfStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) + => (TIfStatementSyntax)generator.IfStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs index 128990253988b..56e0f398a7e56 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs @@ -18,7 +18,8 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; /// Base class for snippets, that can be both executed as normal statement snippets /// or constructed from a member access expression when accessing members of a specific type /// -internal abstract class AbstractInlineStatementSnippetProvider : AbstractStatementSnippetProvider +internal abstract class AbstractInlineStatementSnippetProvider : AbstractStatementSnippetProvider + where TStatementSyntax : SyntaxNode { /// /// Tells if accessing type of a member access expression is valid for that snippet @@ -31,7 +32,7 @@ internal abstract class AbstractInlineStatementSnippetProvider : AbstractStateme /// Generate statement node /// /// Information about inline expression or if snippet is executed in normal statement context - protected abstract SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo); + protected abstract TStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo); /// /// Tells whether the original snippet was constructed from member access expression. @@ -69,10 +70,10 @@ protected sealed override async Task GenerateSnippetTextChangeAsync( return new TextChange(TextSpan.FromBounds(inlineExpressionInfo?.Node.SpanStart ?? position, position), statement.ToFullString()); } - protected sealed override SyntaxNode? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected sealed override TStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) { var closestNode = root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true); - return closestNode.FirstAncestorOrSelf(isCorrectContainer); + return closestNode.FirstAncestorOrSelf(isCorrectContainer); } private static bool TryGetInlineExpressionInfo(SyntaxToken targetToken, ISyntaxFactsService syntaxFacts, SemanticModel semanticModel, [NotNullWhen(true)] out InlineExpressionInfo? expressionInfo, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs index d8797403a6f18..184287875e307 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs @@ -12,15 +12,16 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractLockSnippetProvider : AbstractStatementSnippetProvider +internal abstract class AbstractLockSnippetProvider : AbstractStatementSnippetProvider + where TLockStatementSyntax : SyntaxNode { - protected override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) + protected sealed override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var statement = generator.LockStatement(generator.ThisExpression(), SpecializedCollections.EmptyEnumerable()); return Task.FromResult(new TextChange(TextSpan.FromBounds(position, position), statement.NormalizeWhitespace().ToFullString())); } - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsLockStatement; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs index 38f4b97f2b29d..3c7f154627d58 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs @@ -14,13 +14,14 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractMainMethodSnippetProvider : AbstractSingleChangeSnippetProvider +internal abstract class AbstractMainMethodSnippetProvider : AbstractSingleChangeSnippetProvider + where TMethodDeclarationSyntax : SyntaxNode { protected abstract SyntaxNode GenerateReturnType(SyntaxGenerator generator); protected abstract IEnumerable GenerateInnerStatements(SyntaxGenerator generator); - protected override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) + protected sealed override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var method = generator.MethodDeclaration( @@ -35,9 +36,9 @@ protected override Task GenerateSnippetTextChangeAsync(Document docu return Task.FromResult(new TextChange(TextSpan.FromBounds(position, position), method.NormalizeWhitespace().ToFullString())); } - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TMethodDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsMethodDeclaration; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs index c460de680c2da..0f7199798acec 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs @@ -10,22 +10,23 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractPropertySnippetProvider : AbstractSingleChangeSnippetProvider +internal abstract class AbstractPropertySnippetProvider : AbstractSingleChangeSnippetProvider + where TPropertyDeclarationSyntax : SyntaxNode { /// /// Generates the property syntax. /// Requires language specificity for the TypeSyntax as well as the /// type of the PropertySyntax. /// - protected abstract Task GenerateSnippetSyntaxAsync(Document document, int position, CancellationToken cancellationToken); + protected abstract Task GenerateSnippetSyntaxAsync(Document document, int position, CancellationToken cancellationToken); - protected override async Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) + protected sealed override async Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { var propertyDeclaration = await GenerateSnippetSyntaxAsync(document, position, cancellationToken).ConfigureAwait(false); return new TextChange(TextSpan.FromBounds(position, position), propertyDeclaration.NormalizeWhitespace().ToFullString()); } - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) { return syntaxFacts.IsPropertyDeclaration; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSingleChangeSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSingleChangeSnippetProvider.cs index 46cef6359cf9a..68161aa7637b9 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSingleChangeSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSingleChangeSnippetProvider.cs @@ -9,7 +9,8 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractSingleChangeSnippetProvider : AbstractSnippetProvider +internal abstract class AbstractSingleChangeSnippetProvider : AbstractSnippetProvider + where TSnippetSyntax : SyntaxNode { protected abstract 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 e4f02087b46bb..e33ff643bcfa0 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -20,7 +20,8 @@ namespace Microsoft.CodeAnalysis.Snippets; -internal abstract class AbstractSnippetProvider : ISnippetProvider +internal abstract class AbstractSnippetProvider : ISnippetProvider + where TSnippetSyntax : SyntaxNode { public abstract string Identifier { get; } public abstract string Description { get; } @@ -54,7 +55,7 @@ internal abstract class AbstractSnippetProvider : ISnippetProvider /// /// Method to find the locations that must be renamed and where tab stops must be inserted into the snippet. /// - protected abstract ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken); + protected abstract ImmutableArray GetPlaceHolderLocationsList(TSnippetSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken); /// /// Determines if the location is valid for a snippet, @@ -107,10 +108,9 @@ public async Task GetSnippetAsync(Document document, int position var reformattedRoot = await documentWithIndentation.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var caretTarget = reformattedRoot.GetAnnotatedNodes(CursorAnnotation).FirstOrDefault(); - var mainChangeNode = reformattedRoot.GetAnnotatedNodes(FindSnippetAnnotation).FirstOrDefault(); + var mainChangeNode = (TSnippetSyntax)reformattedRoot.GetAnnotatedNodes(FindSnippetAnnotation).First(); Contract.ThrowIfNull(caretTarget); - Contract.ThrowIfNull(mainChangeNode); var annotatedReformattedDocument = documentWithIndentation.WithSyntaxRoot(reformattedRoot); @@ -236,14 +236,13 @@ protected virtual async Task AnnotateNodesToReformatAsync(Document d return root.ReplaceNode(snippetExpressionNode, reformatSnippetNode); } - protected virtual SyntaxNode? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected virtual TSnippetSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) { - var closestNode = root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true); + if (root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true) is not TSnippetSyntax closestNode) + return null; if (!isCorrectContainer(closestNode)) - { return null; - } return closestNode; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs index 32ce9a49d5eaf..16b98b988c8e9 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractStatementSnippetProvider.cs @@ -6,7 +6,8 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractStatementSnippetProvider : AbstractSingleChangeSnippetProvider +internal abstract class AbstractStatementSnippetProvider : AbstractSingleChangeSnippetProvider + where TStatementSyntax : SyntaxNode { protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) => context.SyntaxContext.IsStatementContext || context.SyntaxContext.IsGlobalStatementContext; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs index 12f4e2a5f11f0..58deb76a0d705 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs @@ -12,13 +12,14 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractTypeSnippetProvider : AbstractSnippetProvider +internal abstract class AbstractTypeSnippetProvider : AbstractSnippetProvider + where TTypeDeclarationSyntax : SyntaxNode { protected abstract void GetTypeDeclarationIdentifier(SyntaxNode node, out SyntaxToken identifier); - protected abstract Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken); + protected abstract Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken); protected abstract Task GetAccessibilityModifiersChangeAsync(Document document, int position, CancellationToken cancellationToken); - protected override async Task> GenerateSnippetTextChangesAsync(Document document, int position, CancellationToken cancellationToken) + protected sealed override async Task> GenerateSnippetTextChangesAsync(Document document, int position, CancellationToken cancellationToken) { var typeDeclaration = await GenerateTypeDeclarationAsync(document, position, cancellationToken).ConfigureAwait(false); @@ -33,7 +34,7 @@ protected override async Task> GenerateSnippetTextCha return [mainChange]; } - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected sealed override ImmutableArray GetPlaceHolderLocationsList(TTypeDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); GetTypeDeclarationIdentifier(node, out var identifier); diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs index 1683ec4ca7db2..c691d630eab1f 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs @@ -9,10 +9,13 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractWhileLoopSnippetProvider : AbstractConditionalBlockSnippetProvider +internal abstract class AbstractWhileLoopSnippetProvider + : AbstractConditionalBlockSnippetProvider + where TWhileStatementSyntax : SyntaxNode + where TExpressionSyntax : SyntaxNode { - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsWhileStatement; + protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsWhileStatement; - protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) - => generator.WhileStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); + protected sealed override TWhileStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) + => (TWhileStatementSyntax)generator.WhileStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); } From 600d80103edd7a76a1ef3f166b6307502579a13e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:22:00 -0700 Subject: [PATCH 02/29] Stronger types --- .../AbstractCSharpTypeSnippetProvider.cs | 7 ++++--- .../Snippets/CSharpClassSnippetProvider.cs | 11 +++++------ .../CSharpForEachLoopSnippetProvider.cs | 19 +++++-------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 3f07f8c9a589f..c35069b7684f3 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -24,7 +24,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; -internal abstract class AbstractCSharpTypeSnippetProvider : AbstractTypeSnippetProvider +internal abstract class AbstractCSharpTypeSnippetProvider : AbstractTypeSnippetProvider + where TTypeDeclarationSyntax : BaseTypeDeclarationSyntax { protected abstract ISet ValidModifiers { get; } @@ -87,10 +88,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, S return line.Span.End; } - protected override SyntaxNode? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected override TTypeDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) { var node = root.FindNode(TextSpan.FromBounds(position, position)); - return node.GetAncestorOrThis(); + return node.GetAncestorOrThis(); } protected override async Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs index fdff09116cb05..2252f59b82c8e 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs @@ -7,6 +7,7 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageService; @@ -20,7 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpClassSnippetProvider() : AbstractCSharpTypeSnippetProvider +internal sealed class CSharpClassSnippetProvider() : AbstractCSharpTypeSnippetProvider { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -42,17 +43,15 @@ internal sealed class CSharpClassSnippetProvider() : AbstractCSharpTypeSnippetPr protected override ISet ValidModifiers => s_validModifiers; - protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) + protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var name = NameGenerator.GenerateUniqueName("MyClass", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); - return generator.ClassDeclaration(name); + return (ClassDeclarationSyntax)generator.ClassDeclaration(name); } protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsClassDeclaration; - } + => syntaxFacts.IsClassDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs index 412feb6e47945..dfb704cfd924d 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs @@ -25,7 +25,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpForEachLoopSnippetProvider() : AbstractForEachLoopSnippetProvider +internal sealed class CSharpForEachLoopSnippetProvider() : AbstractForEachLoopSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.ForEach; @@ -48,7 +48,7 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel return base.IsValidSnippetLocation(in context, cancellationToken); } - protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) + protected override ForEachStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) { var semanticModel = syntaxContext.SemanticModel; var position = syntaxContext.Position; @@ -102,14 +102,13 @@ protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, Synta /// Goes through each piece of the foreach statement and extracts the identifiers /// as well as their locations to create SnippetPlaceholder's of each. /// - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(ForEachStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); - GetPartsOfForEachStatement(node, out var identifier, out var expression, out var _1); - arrayBuilder.Add(new SnippetPlaceholder(identifier.ToString(), identifier.SpanStart)); + arrayBuilder.Add(new SnippetPlaceholder(node.Identifier.ToString(), node.Identifier.SpanStart)); if (!ConstructedFromInlineExpression) - arrayBuilder.Add(new SnippetPlaceholder(expression.ToString(), expression.SpanStart)); + arrayBuilder.Add(new SnippetPlaceholder(node.Expression.ToString(), node.Expression.SpanStart)); return arrayBuilder.ToImmutableArray(); } @@ -130,12 +129,4 @@ protected override Task AddIndentationToDocumentAsync(Document documen static s => (BlockSyntax)s.Statement, cancellationToken); } - - private static void GetPartsOfForEachStatement(SyntaxNode node, out SyntaxToken identifier, out SyntaxNode expression, out SyntaxNode statement) - { - var forEachStatement = (ForEachStatementSyntax)node; - identifier = forEachStatement.Identifier; - expression = forEachStatement.Expression; - statement = forEachStatement.Statement; - } } From 1f3c44fbaf5dfc63ac2eb570945d45d91b92182e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:23:40 -0700 Subject: [PATCH 03/29] Stronger types --- .../AbstractCSharpForLoopSnippetProvider.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs index 333159bd02d46..f309df6f70794 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs @@ -24,7 +24,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; using static SyntaxFactory; -internal abstract class AbstractCSharpForLoopSnippetProvider : AbstractForLoopSnippetProvider +internal abstract class AbstractCSharpForLoopSnippetProvider : AbstractForLoopSnippetProvider { private static readonly string[] s_iteratorBaseNames = ["i", "j", "k"]; @@ -38,7 +38,7 @@ internal abstract class AbstractCSharpForLoopSnippetProvider : AbstractForLoopSn protected abstract void AddSpecificPlaceholders(MultiDictionary placeholderBuilder, ExpressionSyntax initializer, ExpressionSyntax rightOfCondition); - protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) + protected override ForStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) { var semanticModel = syntaxContext.SemanticModel; var compilation = semanticModel.Compilation; @@ -81,11 +81,13 @@ protected override SyntaxNode GenerateStatement(SyntaxGenerator generator, Synta } } - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(ForStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); var placeholderBuilder = new MultiDictionary(); - GetPartsOfForStatement(node, out var declaration, out var condition, out var incrementor, out var _); + var declaration = node.Declaration; + var condition = node.Condition; + var incrementor = node.Incrementors.Single(); var variableDeclarator = ((VariableDeclarationSyntax)declaration!).Variables.Single(); var declaratorIdentifier = variableDeclarator.Identifier; @@ -118,13 +120,4 @@ protected override Task AddIndentationToDocumentAsync(Document documen FindSnippetAnnotation, static s => (BlockSyntax)s.Statement, cancellationToken); - - private static void GetPartsOfForStatement(SyntaxNode node, out SyntaxNode? declaration, out SyntaxNode? condition, out SyntaxNode? incrementor, out SyntaxNode? statement) - { - var forStatement = (ForStatementSyntax)node; - declaration = forStatement.Declaration; - condition = forStatement.Condition; - incrementor = forStatement.Incrementors.Single(); - statement = forStatement.Statement; - } } From 3aa0282eb50b82f8cd28129c8838b9fd46437e3f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:24:02 -0700 Subject: [PATCH 04/29] Stronger types --- .../Snippets/AbstractCSharpMainMethodSnippetProvider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs index 2a8cecf5d794a..b917aced5941e 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs @@ -4,6 +4,7 @@ using System.Threading; using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Utilities; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Snippets; @@ -11,7 +12,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; -internal abstract class AbstractCSharpMainMethodSnippetProvider : AbstractMainMethodSnippetProvider +internal abstract class AbstractCSharpMainMethodSnippetProvider : AbstractMainMethodSnippetProvider { protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) { From 8209c04ceead120cf66525fe94a37f4153bd931b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:24:14 -0700 Subject: [PATCH 05/29] Stronger types --- .../CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs index 42fe433a5b59e..a7069a1a9e025 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConsoleSnippetProvider.cs @@ -4,6 +4,7 @@ using System; using System.Composition; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Snippets; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -13,6 +14,6 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpConsoleSnippetProvider() : AbstractConsoleSnippetProvider +internal sealed class CSharpConsoleSnippetProvider() : AbstractConsoleSnippetProvider { } From 6793559383c0100f14673093fff9eb9d48581de6 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:25:09 -0700 Subject: [PATCH 06/29] Stronger types --- .../CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs | 2 +- .../CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs index e877cfabf694b..c95658aa22087 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpElseSnippetProvider() : AbstractElseSnippetProvider +internal sealed class CSharpElseSnippetProvider() : AbstractElseSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.Else; diff --git a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs index 496a578f23d82..d00f7a8cbc413 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs @@ -19,16 +19,15 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpLockSnippetProvider() : AbstractLockSnippetProvider +internal sealed class CSharpLockSnippetProvider() : AbstractLockSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.Lock; public override string Description => CSharpFeaturesResources.lock_statement; - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(LockStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { - var lockStatement = (LockStatementSyntax)node; - var expression = lockStatement.Expression; + var expression = node.Expression; return [new SnippetPlaceholder(expression.ToString(), expression.SpanStart)]; } From 081f44414e552042ee94732517c58a231860bed4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:25:57 -0700 Subject: [PATCH 07/29] Stronger types --- .../AbstractCSharpAutoPropertySnippetProvider.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index bcc6c780bf9e7..ee71fbf9042ec 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -22,7 +22,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; -internal abstract class AbstractCSharpAutoPropertySnippetProvider : AbstractPropertySnippetProvider +internal abstract class AbstractCSharpAutoPropertySnippetProvider : AbstractPropertySnippetProvider { protected virtual AccessorDeclarationSyntax? GenerateGetAccessorDeclaration(CSharpSyntaxContext syntaxContext, SyntaxGenerator generator) => (AccessorDeclarationSyntax)generator.GetAccessorDeclaration(); @@ -36,7 +36,7 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel SyntaxKindSet.AllMemberModifiers, SyntaxKindSet.ClassInterfaceStructRecordTypeDeclarations, canBePartial: true, cancellationToken); } - protected override async Task GenerateSnippetSyntaxAsync(Document document, int position, CancellationToken cancellationToken) + protected override async Task GenerateSnippetSyntaxAsync(Document document, int position, CancellationToken cancellationToken) { var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); @@ -73,19 +73,18 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, S return propertyDeclaration.AccessorList!.CloseBraceToken.Span.End; } - protected override ImmutableArray GetPlaceHolderLocationsList(SyntaxNode node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(PropertyDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); - var propertyDeclaration = (PropertyDeclarationSyntax)node; - var identifier = propertyDeclaration.Identifier; - var type = propertyDeclaration.Type; + var identifier = node.Identifier; + var type = node.Type; arrayBuilder.Add(new SnippetPlaceholder(type.ToString(), type.SpanStart)); arrayBuilder.Add(new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart)); return arrayBuilder.ToImmutableArray(); } - protected override SyntaxNode? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected override PropertyDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) { var node = root.FindNode(TextSpan.FromBounds(position, position)); return node.GetAncestorOrThis(); From 7a8ba6bc8618431b73b793d3a4eb46e3954118e7 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:28:15 -0700 Subject: [PATCH 08/29] Stronger types --- .../Snippets/CSharpConstructorSnippetProvider.cs | 2 +- .../Portable/Snippets/CSharpEnumSnippetProvider.cs | 11 +++++------ .../Portable/Snippets/CSharpIfSnippetProvider.cs | 9 +++------ .../Snippets/CSharpInterfaceSnippetProvider.cs | 11 +++++------ .../Portable/Snippets/CSharpStructSnippetProvider.cs | 11 +++++------ .../Snippets/CSharpWhileLoopSnippetProvider.cs | 10 ++++------ 6 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs index 1842fd505243f..ce082bafad0ee 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs @@ -26,7 +26,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpConstructorSnippetProvider() : AbstractConstructorSnippetProvider +internal sealed class CSharpConstructorSnippetProvider() : AbstractConstructorSnippetProvider { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs index 894887883ad18..f959bf29d4a97 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs @@ -7,6 +7,7 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageService; @@ -20,7 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpEnumSnippetProvider() : AbstractCSharpTypeSnippetProvider +internal sealed class CSharpEnumSnippetProvider() : AbstractCSharpTypeSnippetProvider { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -37,17 +38,15 @@ internal sealed class CSharpEnumSnippetProvider() : AbstractCSharpTypeSnippetPro protected override ISet ValidModifiers => s_validModifiers; - protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) + protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var name = NameGenerator.GenerateUniqueName("MyEnum", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); - return generator.EnumDeclaration(name); + return (EnumDeclarationSyntax)generator.EnumDeclaration(name); } protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsEnumDeclaration; - } + => syntaxFacts.IsEnumDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs index f62e112de2e69..33fb576c0e27b 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs @@ -18,17 +18,14 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpIfSnippetProvider() : AbstractIfSnippetProvider +internal sealed class CSharpIfSnippetProvider() : AbstractIfSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.If; public override string Description => FeaturesResources.if_statement; - protected override SyntaxNode GetCondition(SyntaxNode node) - { - var ifStatement = (IfStatementSyntax)node; - return ifStatement.Condition; - } + protected override ExpressionSyntax GetCondition(IfStatementSyntax node) + => node.Condition; protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs index 471f4b953238b..6022ab4cd0e21 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs @@ -7,6 +7,7 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageService; @@ -20,7 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpInterfaceSnippetProvider() : AbstractCSharpTypeSnippetProvider +internal sealed class CSharpInterfaceSnippetProvider() : AbstractCSharpTypeSnippetProvider { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -38,17 +39,15 @@ internal sealed class CSharpInterfaceSnippetProvider() : AbstractCSharpTypeSnipp protected override ISet ValidModifiers => s_validModifiers; - protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) + protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var name = NameGenerator.GenerateUniqueName("MyInterface", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); - return generator.InterfaceDeclaration(name); + return (InterfaceDeclarationSyntax)generator.InterfaceDeclaration(name); } protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsInterfaceDeclaration; - } + => syntaxFacts.IsInterfaceDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs index 90a4f1355a6de..593256437d4c3 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs @@ -7,6 +7,7 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.LanguageService; @@ -20,7 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpStructSnippetProvider() : AbstractCSharpTypeSnippetProvider +internal sealed class CSharpStructSnippetProvider() : AbstractCSharpTypeSnippetProvider { private static readonly ISet s_validModifiers = new HashSet(SyntaxFacts.EqualityComparer) { @@ -40,17 +41,15 @@ internal sealed class CSharpStructSnippetProvider() : AbstractCSharpTypeSnippetP protected override ISet ValidModifiers => s_validModifiers; - protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) + protected override async Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var name = NameGenerator.GenerateUniqueName("MyStruct", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); - return generator.StructDeclaration(name); + return (StructDeclarationSyntax)generator.StructDeclaration(name); } protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsStructDeclaration; - } + => syntaxFacts.IsStructDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs index 8288d49ba8d57..a956f0c8f9263 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs @@ -4,6 +4,7 @@ using System; using System.Composition; +using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -18,17 +19,14 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; [ExportSnippetProvider(nameof(ISnippetProvider), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpWhileLoopSnippetProvider() : AbstractWhileLoopSnippetProvider +internal sealed class CSharpWhileLoopSnippetProvider() : AbstractWhileLoopSnippetProvider { public override string Identifier => CSharpSnippetIdentifiers.While; public override string Description => FeaturesResources.while_loop; - protected override SyntaxNode GetCondition(SyntaxNode node) - { - var whileStatement = (WhileStatementSyntax)node; - return whileStatement.Condition; - } + protected override ExpressionSyntax GetCondition(WhileStatementSyntax node) + => node.Condition; protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) { From c5d6a274fe53e597e14b4546a00889213bcd9631 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 12:35:43 -0700 Subject: [PATCH 09/29] Cleanup --- ...stractCSharpAutoPropertySnippetProvider.cs | 3 +-- .../AbstractCSharpTypeSnippetProvider.cs | 3 +-- .../Snippets/CSharpClassSnippetProvider.cs | 4 ---- .../CSharpDoWhileLoopStatementProvider.cs | 3 --- .../Snippets/CSharpEnumSnippetProvider.cs | 4 ---- .../CSharpInterfaceSnippetProvider.cs | 4 ---- .../Snippets/CSharpStructSnippetProvider.cs | 4 ---- .../AbstractConsoleSnippetProvider.cs | 11 +++------ .../AbstractConstructorSnippetProvider.cs | 3 --- .../AbstractElseSnippetProvider.cs | 3 --- .../AbstractForEachLoopSnippetProvider.cs | 5 ---- .../AbstractForLoopSnippetProvider.cs | 5 ---- .../AbstractIfSnippetProvider.cs | 4 ---- .../AbstractInlineStatementSnippetProvider.cs | 5 ++-- .../AbstractLockSnippetProvider.cs | 5 ---- .../AbstractMainMethodSnippetProvider.cs | 4 ---- .../AbstractPropertySnippetProvider.cs | 7 ------ .../AbstractSnippetProvider.cs | 23 ++++--------------- .../AbstractWhileLoopSnippetProvider.cs | 4 ---- 19 files changed, 11 insertions(+), 93 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index ee71fbf9042ec..68c31f8b8323c 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -84,7 +83,7 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return arrayBuilder.ToImmutableArray(); } - protected override PropertyDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected override PropertyDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) { var node = root.FindNode(TextSpan.FromBounds(position, position)); return node.GetAncestorOrThis(); diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index c35069b7684f3..150855f8a82c6 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -88,7 +87,7 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, S return line.Span.End; } - protected override TTypeDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected override TTypeDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) { var node = root.FindNode(TextSpan.FromBounds(position, position)); return node.GetAncestorOrThis(); diff --git a/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs index 2252f59b82c8e..b7c75eab179d7 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpClassSnippetProvider.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Snippets; @@ -51,7 +50,4 @@ protected override async Task GenerateTypeDeclarationAsy var name = NameGenerator.GenerateUniqueName("MyClass", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); return (ClassDeclarationSyntax)generator.ClassDeclaration(name); } - - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsClassDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs index d0c9d825e11bb..54bc7b7c7c5fd 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs @@ -37,9 +37,6 @@ protected override DoStatementSyntax GenerateStatement(SyntaxGenerator generator protected override ExpressionSyntax GetCondition(DoStatementSyntax node) => node.Condition; - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => static node => node is DoStatementSyntax; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) { return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( diff --git a/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs index f959bf29d4a97..1ffa575749b5a 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpEnumSnippetProvider.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Snippets; @@ -46,7 +45,4 @@ protected override async Task GenerateTypeDeclarationAsyn var name = NameGenerator.GenerateUniqueName("MyEnum", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); return (EnumDeclarationSyntax)generator.EnumDeclaration(name); } - - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsEnumDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs index 6022ab4cd0e21..a35d3d72e4a9f 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpInterfaceSnippetProvider.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Snippets; @@ -47,7 +46,4 @@ protected override async Task GenerateTypeDeclaratio var name = NameGenerator.GenerateUniqueName("MyInterface", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); return (InterfaceDeclarationSyntax)generator.InterfaceDeclaration(name); } - - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsInterfaceDeclaration; } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs index 593256437d4c3..d7661e4f466ed 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpStructSnippetProvider.cs @@ -10,7 +10,6 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Snippets; @@ -49,7 +48,4 @@ protected override async Task GenerateTypeDeclarationAs var name = NameGenerator.GenerateUniqueName("MyStruct", name => semanticModel.LookupSymbols(position, name: name).IsEmpty); return (StructDeclarationSyntax)generator.StructDeclaration(name); } - - protected override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsStructDeclaration; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs index a9c09c2e437f2..31816121cd2b7 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs @@ -36,11 +36,6 @@ protected sealed override bool IsValidSnippetLocation(in SnippetContext context, return base.IsValidSnippetLocation(in context, cancellationToken); } - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsExpressionStatement; - } - protected sealed override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { var generator = SyntaxGenerator.GetGenerator(document); @@ -79,7 +74,7 @@ protected sealed override async Task AnnotateNodesToReformatAsync(Do { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); - var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position, syntaxFacts.IsExpressionStatement); + var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position); Contract.ThrowIfNull(snippetExpressionNode); var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); @@ -113,10 +108,10 @@ protected sealed override ImmutableArray GetPlaceHolderLocat private static INamedTypeSymbol? GetConsoleSymbolFromMetaDataName(Compilation compilation) => compilation.GetBestTypeByMetadataName(typeof(Console).FullName!); - protected sealed override TExpressionStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected sealed override TExpressionStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) { var closestNode = root.FindNode(TextSpan.FromBounds(position, position)); - var nearestExpressionStatement = closestNode.FirstAncestorOrSelf(isCorrectContainer); + var nearestExpressionStatement = closestNode.FirstAncestorOrSelf(); if (nearestExpressionStatement is null) return null; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs index 2a7f0e7e1e991..33e33a7a1b4f0 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConstructorSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.LanguageService; @@ -18,8 +17,6 @@ internal abstract class AbstractConstructorSnippetProvider AdditionalFilterTexts { get; } = ["constructor"]; - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsConstructorDeclaration; - protected sealed override ImmutableArray GetPlaceHolderLocationsList(TConstructorDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs index 0a7ca9902fece..22c163756c430 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractElseSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.LanguageService; @@ -12,8 +11,6 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; internal abstract class AbstractElseSnippetProvider : AbstractStatementSnippetProvider where TElseClauseSyntax : SyntaxNode { - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsElseClause; - protected sealed override ImmutableArray GetPlaceHolderLocationsList(TElseClauseSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs index 4af760b508e32..2f5c742d67e40 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForEachLoopSnippetProvider.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -14,7 +12,4 @@ internal abstract class AbstractForEachLoopSnippetProvider : A { protected sealed override bool IsValidAccessingType(ITypeSymbol type, Compilation compilation) => type.CanBeEnumerated() || type.CanBeAsynchronouslyEnumerated(compilation); - - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsForEachStatement; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs index b8d8e53224d60..73458de1f3cd9 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractForLoopSnippetProvider.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Linq; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -26,9 +24,6 @@ protected sealed override bool IsValidAccessingType(ITypeSymbol type, Compilatio return hasLengthProperty ^ hasCountProperty; } - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsForStatement; - protected static bool IsSuitableIntegerType(ITypeSymbol type) => type.IsIntegralType() || type.IsNativeIntegerType; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs index 9e43789c3ecc5..46c0c9e61c866 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractIfSnippetProvider.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -17,8 +15,6 @@ internal abstract class AbstractIfSnippetProvider AdditionalFilterTexts { get; } = ["statement"]; - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsIfStatement; - protected sealed override TIfStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) => (TIfStatementSyntax)generator.IfStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs index 56e0f398a7e56..ac60dc0569394 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractInlineStatementSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; @@ -70,10 +69,10 @@ protected sealed override async Task GenerateSnippetTextChangeAsync( return new TextChange(TextSpan.FromBounds(inlineExpressionInfo?.Node.SpanStart ?? position, position), statement.ToFullString()); } - protected sealed override TStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) + protected sealed override TStatementSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) { var closestNode = root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true); - return closestNode.FirstAncestorOrSelf(isCorrectContainer); + return closestNode.FirstAncestorOrSelf(); } private static bool TryGetInlineExpressionInfo(SyntaxToken targetToken, ISyntaxFactsService syntaxFacts, SemanticModel semanticModel, [NotNullWhen(true)] out InlineExpressionInfo? expressionInfo, CancellationToken cancellationToken) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs index 184287875e307..c37380580b8da 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractLockSnippetProvider.cs @@ -2,11 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -21,7 +19,4 @@ protected sealed override Task GenerateSnippetTextChangeAsync(Docume var statement = generator.LockStatement(generator.ThisExpression(), SpecializedCollections.EmptyEnumerable()); return Task.FromResult(new TextChange(TextSpan.FromBounds(position, position), statement.NormalizeWhitespace().ToFullString())); } - - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsLockStatement; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs index 3c7f154627d58..00b6161e5f614 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; @@ -38,7 +37,4 @@ protected sealed override Task GenerateSnippetTextChangeAsync(Docume protected sealed override ImmutableArray GetPlaceHolderLocationsList(TMethodDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) => []; - - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - => syntaxFacts.IsMethodDeclaration; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs index 0f7199798acec..3aaf3e2668e8b 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractPropertySnippetProvider.cs @@ -2,10 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -25,9 +23,4 @@ protected sealed override async Task GenerateSnippetTextChangeAsync( var propertyDeclaration = await GenerateSnippetSyntaxAsync(document, position, cancellationToken).ConfigureAwait(false); return new TextChange(TextSpan.FromBounds(position, position), propertyDeclaration.NormalizeWhitespace().ToFullString()); } - - protected sealed override Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) - { - return syntaxFacts.IsPropertyDeclaration; - } } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index e33ff643bcfa0..448f56ef11c8f 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -47,11 +46,6 @@ internal abstract class AbstractSnippetProvider : ISnippetProvid /// protected abstract int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText); - /// - /// Helper function to retrieve the specific type of snippet syntax when it needs to be searched for again. - /// - protected abstract Func GetSnippetContainerFunction(ISyntaxFacts syntaxFacts); - /// /// Method to find the locations that must be renamed and where tab stops must be inserted into the snippet. /// @@ -186,7 +180,7 @@ private async Task CleanupDocumentAsync( private async Task GetDocumentWithSnippetAndTriviaAsync(Document snippetDocument, int position, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { var root = await snippetDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var nearestStatement = FindAddedSnippetSyntaxNode(root, position, GetSnippetContainerFunction(syntaxFacts)); + var nearestStatement = FindAddedSnippetSyntaxNode(root, position); if (nearestStatement is null) { @@ -228,24 +222,15 @@ protected virtual async Task AnnotateNodesToReformatAsync(Document d SyntaxAnnotation findSnippetAnnotation, SyntaxAnnotation cursorAnnotation, int position, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var syntaxFacts = document.GetRequiredLanguageService(); - var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position, GetSnippetContainerFunction(syntaxFacts)); + var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position); Contract.ThrowIfNull(snippetExpressionNode); var reformatSnippetNode = snippetExpressionNode.WithAdditionalAnnotations(findSnippetAnnotation, cursorAnnotation, Simplifier.Annotation, Formatter.Annotation); return root.ReplaceNode(snippetExpressionNode, reformatSnippetNode); } - protected virtual TSnippetSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position, Func isCorrectContainer) - { - if (root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true) is not TSnippetSyntax closestNode) - return null; - - if (!isCorrectContainer(closestNode)) - return null; - - return closestNode; - } + protected virtual TSnippetSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) + => root.FindNode(TextSpan.FromBounds(position, position), getInnermostNodeForTie: true) as TSnippetSyntax; /// /// Certain snippets require more indentation - snippets with blocks. diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs index c691d630eab1f..c1ccba04b71b7 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractWhileLoopSnippetProvider.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; @@ -14,8 +12,6 @@ internal abstract class AbstractWhileLoopSnippetProvider GetSnippetContainerFunction(ISyntaxFacts syntaxFacts) => syntaxFacts.IsWhileStatement; - protected sealed override TWhileStatementSyntax GenerateStatement(SyntaxGenerator generator, SyntaxContext syntaxContext, InlineExpressionInfo? inlineExpressionInfo) => (TWhileStatementSyntax)generator.WhileStatement(inlineExpressionInfo?.Node.WithoutLeadingTrivia() ?? generator.TrueLiteralExpression(), []); } From ec7a0e5c3b7044fc0e7430df8e854df8556ce3d8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:04:42 -0700 Subject: [PATCH 10/29] Cleanup --- .../Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs index 31816121cd2b7..19f1aa39ec118 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs @@ -73,7 +73,6 @@ protected sealed override async Task AnnotateNodesToReformatAsync(Do SyntaxAnnotation findSnippetAnnotation, SyntaxAnnotation cursorAnnotation, int position, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var syntaxFacts = document.GetRequiredLanguageService(); var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position); Contract.ThrowIfNull(snippetExpressionNode); From 78b72e73ce09b72354aeef66184b01dd61dd84c8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:18:22 -0700 Subject: [PATCH 11/29] stronger typing --- .../Snippets/AbstractCSharpAutoPropertySnippetProvider.cs | 7 ++----- .../Snippets/AbstractCSharpForLoopSnippetProvider.cs | 4 ++-- .../Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs | 5 ++--- .../Portable/Snippets/CSharpConstructorSnippetProvider.cs | 6 ++---- .../Snippets/CSharpDoWhileLoopStatementProvider.cs | 6 ++---- .../CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs | 6 ++---- .../Portable/Snippets/CSharpForEachLoopSnippetProvider.cs | 6 ++---- .../CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs | 6 ++---- .../Portable/Snippets/CSharpIntMainSnippetProvider.cs | 5 ++--- .../CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs | 6 ++---- .../CSharp/Portable/Snippets/CSharpSnippetHelpers.cs | 5 ++--- .../Portable/Snippets/CSharpVoidMainSnippetProvider.cs | 6 ++---- .../Portable/Snippets/CSharpWhileLoopSnippetProvider.cs | 7 ++----- .../SnippetProviders/AbstractConsoleSnippetProvider.cs | 6 +----- .../Snippets/SnippetProviders/AbstractSnippetProvider.cs | 6 ++---- 15 files changed, 29 insertions(+), 58 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index 68c31f8b8323c..69ef641e573ea 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -66,11 +66,8 @@ protected override async Task GenerateSnippetSyntaxAs accessorList: SyntaxFactory.AccessorList([.. accessors.Where(a => a is not null)!])); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - var propertyDeclaration = (PropertyDeclarationSyntax)caretTarget; - return propertyDeclaration.AccessorList!.CloseBraceToken.Span.End; - } + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, PropertyDeclarationSyntax caretTarget, SourceText sourceText) + => caretTarget.AccessorList!.CloseBraceToken.Span.End; protected override ImmutableArray GetPlaceHolderLocationsList(PropertyDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs index f309df6f70794..e263a738c70b3 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs @@ -108,8 +108,8 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return result.ToImmutableAndClear(); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 150855f8a82c6..9739384d17586 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -78,10 +78,9 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel return new TextChange(TextSpan.FromBounds(targetPosition, targetPosition), SyntaxFacts.GetText(SyntaxKind.PublicKeyword) + " "); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, TTypeDeclarationSyntax caretTarget, SourceText sourceText) { - var typeDeclaration = (BaseTypeDeclarationSyntax)caretTarget; - var triviaSpan = typeDeclaration.CloseBraceToken.LeadingTrivia.Span; + var triviaSpan = caretTarget.CloseBraceToken.LeadingTrivia.Span; var line = sourceText.Lines.GetLineFromPosition(triviaSpan.Start); // Getting the location at the end of the line before the newline. return line.Span.End; diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs index ce082bafad0ee..3504ebbd38f2f 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs @@ -76,13 +76,11 @@ protected override async Task GenerateSnippetTextChangeAsync(Documen return new TextChange(TextSpan.FromBounds(position, position), constructorDeclaration.NormalizeWhitespace().ToFullString()); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ConstructorDeclarationSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static d => d.Body!, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs index 54bc7b7c7c5fd..67d376cce2346 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs @@ -37,13 +37,11 @@ protected override DoStatementSyntax GenerateStatement(SyntaxGenerator generator protected override ExpressionSyntax GetCondition(DoStatementSyntax node) => node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, DoStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs index c95658aa22087..e0386b3b4f939 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs @@ -61,13 +61,11 @@ protected override Task GenerateSnippetTextChangeAsync(Document docu return Task.FromResult(new TextChange(TextSpan.FromBounds(position, position), elseClause.ToFullString())); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ElseClauseSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static c => (BlockSyntax)c.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs index dfb704cfd924d..129ba36d8b82e 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs @@ -113,13 +113,11 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return arrayBuilder.ToImmutableArray(); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForEachStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs index 33fb576c0e27b..2a3e5208bef4e 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs @@ -27,13 +27,11 @@ internal sealed class CSharpIfSnippetProvider() : AbstractIfSnippetProvider node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, IfStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index addce88a21a00..481e0a1120ebb 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -39,10 +39,9 @@ protected override IEnumerable GenerateInnerStatements(SyntaxGenerat return SpecializedCollections.SingletonEnumerable(returnStatement); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax caretTarget, SourceText sourceText) { - var methodDeclaration = (MethodDeclarationSyntax)caretTarget; - var body = methodDeclaration.Body!; + var body = caretTarget.Body!; var returnStatement = body.Statements.First(); var triviaSpan = returnStatement.GetLeadingTrivia().Span; diff --git a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs index d00f7a8cbc413..b531053f183fe 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs @@ -31,13 +31,11 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return [new SnippetPlaceholder(expression.ToString(), expression.SpanStart)]; } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, LockStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs index a4865ed01a04e..9693c465bb6a0 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs @@ -16,11 +16,10 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; internal static class CSharpSnippetHelpers { - public static int GetTargetCaretPositionInBlock(SyntaxNode caretTarget, Func getBlock, SourceText sourceText) + public static int GetTargetCaretPositionInBlock(TTargetNode caretTarget, Func getBlock, SourceText sourceText) where TTargetNode : SyntaxNode { - var targetNode = (TTargetNode)caretTarget; - var block = getBlock(targetNode); + var block = getBlock(caretTarget); var triviaSpan = block.CloseBraceToken.LeadingTrivia.Span; var line = sourceText.Lines.GetLineFromPosition(triviaSpan.Start); diff --git a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs index 416b2850a83a0..f1d9ac72c8800 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs @@ -33,13 +33,11 @@ protected override SyntaxNode GenerateReturnType(SyntaxGenerator generator) protected override IEnumerable GenerateInnerStatements(SyntaxGenerator generator) => SpecializedCollections.EmptyEnumerable(); - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static d => d.Body!, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs index a956f0c8f9263..329a7638c5bd3 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs @@ -4,7 +4,6 @@ using System; using System.Composition; -using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -28,13 +27,11 @@ internal sealed class CSharpWhileLoopSnippetProvider() : AbstractWhileLoopSnippe protected override ExpressionSyntax GetCondition(WhileStatementSyntax node) => node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) - { - return CSharpSnippetHelpers.GetTargetCaretPositionInBlock( + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, WhileStatementSyntax caretTarget, SourceText sourceText) + => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( caretTarget, static s => (BlockSyntax)s.Statement, sourceText); - } protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs index 19f1aa39ec118..c96220cfd9213 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs @@ -51,19 +51,15 @@ protected sealed override Task GenerateSnippetTextChangeAsync(Docume /// Tries to get the location after the open parentheses in the argument list. /// If it can't, then we default to the end of the snippet's span. /// - protected sealed override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText) + protected sealed override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, TExpressionStatementSyntax caretTarget, SourceText sourceText) { var invocationExpression = caretTarget.DescendantNodes().Where(syntaxFacts.IsInvocationExpression).FirstOrDefault(); if (invocationExpression is null) - { return caretTarget.Span.End; - } var argumentListNode = syntaxFacts.GetArgumentListOfInvocationExpression(invocationExpression); if (argumentListNode is null) - { return caretTarget.Span.End; - } syntaxFacts.GetPartsOfArgumentList(argumentListNode, out var openParenToken, out _, out _); return openParenToken.Span.End; diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index 448f56ef11c8f..3b51f913dc3b3 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -44,7 +44,7 @@ internal abstract class AbstractSnippetProvider : ISnippetProvid /// /// Gets the position that we want the caret to be at after all of the indentation/formatting has been done. /// - protected abstract int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, SyntaxNode caretTarget, SourceText sourceText); + protected abstract int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, TSnippetSyntax caretTarget, SourceText sourceText); /// /// Method to find the locations that must be renamed and where tab stops must be inserted into the snippet. @@ -101,11 +101,9 @@ public async Task GetSnippetAsync(Document document, int position var documentWithIndentation = await AddIndentationToDocumentAsync(reformattedDocument, cancellationToken).ConfigureAwait(false); var reformattedRoot = await documentWithIndentation.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var caretTarget = reformattedRoot.GetAnnotatedNodes(CursorAnnotation).FirstOrDefault(); + var caretTarget = (TSnippetSyntax)reformattedRoot.GetAnnotatedNodes(CursorAnnotation).First(); var mainChangeNode = (TSnippetSyntax)reformattedRoot.GetAnnotatedNodes(FindSnippetAnnotation).First(); - Contract.ThrowIfNull(caretTarget); - var annotatedReformattedDocument = documentWithIndentation.WithSyntaxRoot(reformattedRoot); // All the TextChanges from the original document. Will include any imports (if necessary) and all snippet associated From 63c7f56d28ddd55f2d43c30083828c760340812a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:24:57 -0700 Subject: [PATCH 12/29] Remove redundant annotation --- .../Snippets/AbstractCSharpTypeSnippetProvider.cs | 2 +- .../AbstractConsoleSnippetProvider.cs | 6 +++--- .../SnippetProviders/AbstractSnippetProvider.cs | 12 +++++------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 9739384d17586..251303fff7cf5 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -106,7 +106,7 @@ protected override async Task AddIndentationToDocumentAsync(Document d var newTypeDeclaration = originalTypeDeclaration.WithCloseBraceToken( originalTypeDeclaration.CloseBraceToken.WithPrependedLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, indentationString))); - var newRoot = root.ReplaceNode(originalTypeDeclaration, newTypeDeclaration.WithAdditionalAnnotations(CursorAnnotation, FindSnippetAnnotation)); + var newRoot = root.ReplaceNode(originalTypeDeclaration, newTypeDeclaration.WithAdditionalAnnotations(FindSnippetAnnotation)); return document.WithSyntaxRoot(newRoot); } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs index c96220cfd9213..c6e3e723fb4f0 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConsoleSnippetProvider.cs @@ -65,8 +65,8 @@ protected sealed override int GetTargetCaretPosition(ISyntaxFactsService syntaxF return openParenToken.Span.End; } - protected sealed override async Task AnnotateNodesToReformatAsync(Document document, - SyntaxAnnotation findSnippetAnnotation, SyntaxAnnotation cursorAnnotation, int position, CancellationToken cancellationToken) + protected sealed override async Task AnnotateNodesToReformatAsync( + Document document, int position, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position); @@ -74,7 +74,7 @@ protected sealed override async Task AnnotateNodesToReformatAsync(Do var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var consoleSymbol = GetConsoleSymbolFromMetaDataName(compilation); - var reformatSnippetNode = snippetExpressionNode.WithAdditionalAnnotations(findSnippetAnnotation, cursorAnnotation, Simplifier.Annotation, SymbolAnnotation.Create(consoleSymbol!), Formatter.Annotation); + var reformatSnippetNode = snippetExpressionNode.WithAdditionalAnnotations(FindSnippetAnnotation, Simplifier.Annotation, SymbolAnnotation.Create(consoleSymbol!), Formatter.Annotation); return root.ReplaceNode(snippetExpressionNode, reformatSnippetNode); } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index 3b51f913dc3b3..dab1bceb0dae2 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -27,7 +27,6 @@ internal abstract class AbstractSnippetProvider : ISnippetProvid public virtual ImmutableArray AdditionalFilterTexts => []; - protected readonly SyntaxAnnotation CursorAnnotation = new(); protected readonly SyntaxAnnotation FindSnippetAnnotation = new(); /// @@ -101,7 +100,6 @@ public async Task GetSnippetAsync(Document document, int position var documentWithIndentation = await AddIndentationToDocumentAsync(reformattedDocument, cancellationToken).ConfigureAwait(false); var reformattedRoot = await documentWithIndentation.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var caretTarget = (TSnippetSyntax)reformattedRoot.GetAnnotatedNodes(CursorAnnotation).First(); var mainChangeNode = (TSnippetSyntax)reformattedRoot.GetAnnotatedNodes(FindSnippetAnnotation).First(); var annotatedReformattedDocument = documentWithIndentation.WithSyntaxRoot(reformattedRoot); @@ -121,7 +119,7 @@ public async Task GetSnippetAsync(Document document, int position return new SnippetChange( textChanges: changesArray, - cursorPosition: GetTargetCaretPosition(syntaxFacts, caretTarget, sourceText), + cursorPosition: GetTargetCaretPosition(syntaxFacts, mainChangeNode, sourceText), placeholders: placeholders); } @@ -208,7 +206,7 @@ private static async Task GetDocumentWithSnippetAsync(Document documen private async Task AddFormatAnnotationAsync(Document document, int position, CancellationToken cancellationToken) { - var annotatedSnippetRoot = await AnnotateNodesToReformatAsync(document, FindSnippetAnnotation, CursorAnnotation, position, cancellationToken).ConfigureAwait(false); + var annotatedSnippetRoot = await AnnotateNodesToReformatAsync(document, position, cancellationToken).ConfigureAwait(false); document = document.WithSyntaxRoot(annotatedSnippetRoot); return document; } @@ -216,14 +214,14 @@ private async Task AddFormatAnnotationAsync(Document document, int pos /// /// Method to added formatting annotations to the created snippet. /// - protected virtual async Task AnnotateNodesToReformatAsync(Document document, - SyntaxAnnotation findSnippetAnnotation, SyntaxAnnotation cursorAnnotation, int position, CancellationToken cancellationToken) + protected virtual async Task AnnotateNodesToReformatAsync( + Document document, int position, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var snippetExpressionNode = FindAddedSnippetSyntaxNode(root, position); Contract.ThrowIfNull(snippetExpressionNode); - var reformatSnippetNode = snippetExpressionNode.WithAdditionalAnnotations(findSnippetAnnotation, cursorAnnotation, Simplifier.Annotation, Formatter.Annotation); + var reformatSnippetNode = snippetExpressionNode.WithAdditionalAnnotations(FindSnippetAnnotation, Simplifier.Annotation, Formatter.Annotation); return root.ReplaceNode(snippetExpressionNode, reformatSnippetNode); } From 047e65fc0c2319334bdf10265eaf46ad4131d0cb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:32:05 -0700 Subject: [PATCH 13/29] Stronger types --- .../AbstractCSharpForLoopSnippetProvider.cs | 6 +++--- .../Snippets/AbstractCSharpTypeSnippetProvider.cs | 6 +----- .../Snippets/CSharpConstructorSnippetProvider.cs | 8 +++----- .../Snippets/CSharpDoWhileLoopStatementProvider.cs | 8 +++----- .../Portable/Snippets/CSharpElseSnippetProvider.cs | 8 +++----- .../Snippets/CSharpForEachLoopSnippetProvider.cs | 8 +++----- .../Portable/Snippets/CSharpIfSnippetProvider.cs | 8 +++----- .../Snippets/CSharpIntMainSnippetProvider.cs | 6 +----- .../Portable/Snippets/CSharpLockSnippetProvider.cs | 8 +++----- .../Portable/Snippets/CSharpSnippetHelpers.cs | 14 +++++--------- .../Snippets/CSharpVoidMainSnippetProvider.cs | 8 +++----- .../Snippets/CSharpWhileLoopSnippetProvider.cs | 8 +++----- .../SnippetProviders/AbstractSnippetProvider.cs | 13 +++++++++++-- 13 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs index e263a738c70b3..63a855040d16c 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs @@ -114,10 +114,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, F static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, ForStatementSyntax forStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + forStatement, static s => (BlockSyntax)s.Statement, cancellationToken); } diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 251303fff7cf5..3b6e024e82ea4 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -92,13 +92,9 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, T return node.GetAncestorOrThis(); } - protected override async Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) + protected override async Task AddIndentationToDocumentAsync(Document document, TTypeDeclarationSyntax originalTypeDeclaration, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var snippet = root.GetAnnotatedNodes(FindSnippetAnnotation).FirstOrDefault(); - - if (snippet is not BaseTypeDeclarationSyntax originalTypeDeclaration) - return document; var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); var indentationString = CSharpSnippetHelpers.GetBlockLikeIndentationString(document, originalTypeDeclaration.OpenBraceToken.SpanStart, syntaxFormattingOptions, cancellationToken); diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs index 3504ebbd38f2f..306979e8c5538 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs @@ -82,12 +82,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, C static d => d.Body!, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, ConstructorDeclarationSyntax constructorDeclaration, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + constructorDeclaration, static d => d.Body!, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs index 67d376cce2346..6605eddf1712f 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs @@ -43,12 +43,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, D static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, DoStatementSyntax doStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + doStatement, static s => (BlockSyntax)s.Statement, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs index e0386b3b4f939..e6d2414f5d304 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs @@ -67,12 +67,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, E static c => (BlockSyntax)c.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, ElseClauseSyntax elseClause, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + elseClause, static c => (BlockSyntax)c.Statement, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs index 129ba36d8b82e..c87ddc5cad821 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs @@ -119,12 +119,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, F static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, ForEachStatementSyntax forEachStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + forEachStatement, static s => (BlockSyntax)s.Statement, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs index 2a3e5208bef4e..77bc7cf61b14a 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs @@ -33,12 +33,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, I static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, IfStatementSyntax ifStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + ifStatement, static s => (BlockSyntax)s.Statement, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index 481e0a1120ebb..3843d1f493cd3 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -50,13 +50,9 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, M return line.Span.End; } - protected override async Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) + protected override async Task AddIndentationToDocumentAsync(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var snippetNode = root.GetAnnotatedNodes(FindSnippetAnnotation).FirstOrDefault(); - - if (snippetNode is not MethodDeclarationSyntax methodDeclaration) - return document; var body = methodDeclaration.Body!; var returnStatement = body.Statements.First(); diff --git a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs index b531053f183fe..9b85bee23c132 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs @@ -37,12 +37,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, L static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, LockStatementSyntax lockStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + lockStatement, static s => (BlockSyntax)s.Statement, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs index 9693c465bb6a0..76a64bf2a6c14 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpSnippetHelpers.cs @@ -43,24 +43,20 @@ public static string GetBlockLikeIndentationString(Document document, int startP return newIndentation.GetIndentationString(parsedDocument.Text, syntaxFormattingOptions.UseTabs, syntaxFormattingOptions.TabSize) + newLine; } - public static async Task AddBlockIndentationToDocumentAsync(Document document, SyntaxAnnotation findSnippetAnnotation, Func getBlock, CancellationToken cancellationToken) + public static async Task AddBlockIndentationToDocumentAsync( + Document document, TTargetNode targetNode, Func getBlock, CancellationToken cancellationToken) where TTargetNode : SyntaxNode { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var snippetNode = root.GetAnnotatedNodes(findSnippetAnnotation).FirstOrDefault(); - - if (snippetNode is not TTargetNode targetStatement) - return document; - - var block = getBlock(targetStatement); + var block = getBlock(targetNode); var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); var indentationString = GetBlockLikeIndentationString(document, block.SpanStart, syntaxFormattingOptions, cancellationToken); var updatedBlock = block.WithCloseBraceToken(block.CloseBraceToken.WithPrependedLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, indentationString))); - var updatedTargetStatement = targetStatement.ReplaceNode(block, updatedBlock); + var updatedTargetStatement = targetNode.ReplaceNode(block, updatedBlock); - var newRoot = root.ReplaceNode(targetStatement, updatedTargetStatement); + var newRoot = root.ReplaceNode(targetNode, updatedTargetStatement); return document.WithSyntaxRoot(newRoot); } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs index f1d9ac72c8800..4004797f91150 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs @@ -39,12 +39,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, M static d => d.Body!, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + methodDeclaration, static m => m.Body!, cancellationToken); - } } diff --git a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs index 329a7638c5bd3..3559a55d7c44c 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs @@ -33,12 +33,10 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, W static s => (BlockSyntax)s.Statement, sourceText); - protected override Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) - { - return CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( + protected override Task AddIndentationToDocumentAsync(Document document, WhileStatementSyntax whileStatement, CancellationToken cancellationToken) + => CSharpSnippetHelpers.AddBlockIndentationToDocumentAsync( document, - FindSnippetAnnotation, + whileStatement, static s => (BlockSyntax)s.Statement, cancellationToken); - } } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs index dab1bceb0dae2..f0db86368af09 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractSnippetProvider.cs @@ -233,8 +233,17 @@ protected virtual async Task AnnotateNodesToReformatAsync( /// The SyntaxGenerator does not insert this space for us nor does the LSP Snippet Expander. /// We need to manually add that spacing to snippets containing blocks. /// - protected virtual async Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) + private async Task AddIndentationToDocumentAsync(Document document, CancellationToken cancellationToken) { - return await Task.FromResult(document).ConfigureAwait(false); + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var snippetNode = root.GetAnnotatedNodes(FindSnippetAnnotation).FirstOrDefault(); + + if (snippetNode is not TSnippetSyntax snippet) + return document; + + return await AddIndentationToDocumentAsync(document, snippet, cancellationToken).ConfigureAwait(false); } + + protected virtual Task AddIndentationToDocumentAsync(Document document, TSnippetSyntax snippet, CancellationToken cancellationToken) + => Task.FromResult(document); } From e56ce4ad95548e08bc1eb48ece8c7af6f359bcfd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:32:44 -0700 Subject: [PATCH 14/29] naming --- .../AbstractCSharpForLoopSnippetProvider.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs index 63a855040d16c..a468411e1ee15 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpForLoopSnippetProvider.cs @@ -81,15 +81,15 @@ protected override ForStatementSyntax GenerateStatement(SyntaxGenerator generato } } - protected override ImmutableArray GetPlaceHolderLocationsList(ForStatementSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(ForStatementSyntax forStatement, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); var placeholderBuilder = new MultiDictionary(); - var declaration = node.Declaration; - var condition = node.Condition; - var incrementor = node.Incrementors.Single(); + var declaration = forStatement.Declaration; + var condition = forStatement.Condition; + var incrementor = forStatement.Incrementors.Single(); - var variableDeclarator = ((VariableDeclarationSyntax)declaration!).Variables.Single(); + var variableDeclarator = declaration!.Variables.Single(); var declaratorIdentifier = variableDeclarator.Identifier; placeholderBuilder.Add(declaratorIdentifier.ValueText, declaratorIdentifier.SpanStart); @@ -108,9 +108,9 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return result.ToImmutableAndClear(); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForStatementSyntax forStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + forStatement, static s => (BlockSyntax)s.Statement, sourceText); From 825581d18714693f55b4eca780fa9fee2bcc5949 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:33:07 -0700 Subject: [PATCH 15/29] naming --- .../Snippets/AbstractCSharpTypeSnippetProvider.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 3b6e024e82ea4..6bb523d58b01a 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -78,9 +78,9 @@ protected override bool IsValidSnippetLocation(in SnippetContext context, Cancel return new TextChange(TextSpan.FromBounds(targetPosition, targetPosition), SyntaxFacts.GetText(SyntaxKind.PublicKeyword) + " "); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, TTypeDeclarationSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, TTypeDeclarationSyntax typeDeclaration, SourceText sourceText) { - var triviaSpan = caretTarget.CloseBraceToken.LeadingTrivia.Span; + var triviaSpan = typeDeclaration.CloseBraceToken.LeadingTrivia.Span; var line = sourceText.Lines.GetLineFromPosition(triviaSpan.Start); // Getting the location at the end of the line before the newline. return line.Span.End; @@ -92,17 +92,17 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, T return node.GetAncestorOrThis(); } - protected override async Task AddIndentationToDocumentAsync(Document document, TTypeDeclarationSyntax originalTypeDeclaration, CancellationToken cancellationToken) + protected override async Task AddIndentationToDocumentAsync(Document document, TTypeDeclarationSyntax typeDeclaration, CancellationToken cancellationToken) { var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var syntaxFormattingOptions = await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, cancellationToken).ConfigureAwait(false); - var indentationString = CSharpSnippetHelpers.GetBlockLikeIndentationString(document, originalTypeDeclaration.OpenBraceToken.SpanStart, syntaxFormattingOptions, cancellationToken); + var indentationString = CSharpSnippetHelpers.GetBlockLikeIndentationString(document, typeDeclaration.OpenBraceToken.SpanStart, syntaxFormattingOptions, cancellationToken); - var newTypeDeclaration = originalTypeDeclaration.WithCloseBraceToken( - originalTypeDeclaration.CloseBraceToken.WithPrependedLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, indentationString))); + var newTypeDeclaration = typeDeclaration.WithCloseBraceToken( + typeDeclaration.CloseBraceToken.WithPrependedLeadingTrivia(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, indentationString))); - var newRoot = root.ReplaceNode(originalTypeDeclaration, newTypeDeclaration.WithAdditionalAnnotations(FindSnippetAnnotation)); + var newRoot = root.ReplaceNode(typeDeclaration, newTypeDeclaration.WithAdditionalAnnotations(FindSnippetAnnotation)); return document.WithSyntaxRoot(newRoot); } From d2a4935bc9a53ec6a57494ee36babeff6d638783 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:33:27 -0700 Subject: [PATCH 16/29] naming --- .../Portable/Snippets/CSharpConstructorSnippetProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs index 306979e8c5538..7bdf0c9eed434 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpConstructorSnippetProvider.cs @@ -76,9 +76,9 @@ protected override async Task GenerateSnippetTextChangeAsync(Documen return new TextChange(TextSpan.FromBounds(position, position), constructorDeclaration.NormalizeWhitespace().ToFullString()); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ConstructorDeclarationSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ConstructorDeclarationSyntax constructorDeclaration, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + constructorDeclaration, static d => d.Body!, sourceText); From 60e06ef0076c6686626bfafe80e95ae28dc953f5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:33:41 -0700 Subject: [PATCH 17/29] naming --- .../Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs index 6605eddf1712f..3d0ef8f2e47a4 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpDoWhileLoopStatementProvider.cs @@ -37,9 +37,9 @@ protected override DoStatementSyntax GenerateStatement(SyntaxGenerator generator protected override ExpressionSyntax GetCondition(DoStatementSyntax node) => node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, DoStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, DoStatementSyntax doStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + doStatement, static s => (BlockSyntax)s.Statement, sourceText); From 0720aaf54b2924453c93ccacbf708f5ac1a1fb68 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:34:05 -0700 Subject: [PATCH 18/29] naming --- .../CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs index e6d2414f5d304..489e5ad5c425b 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpElseSnippetProvider.cs @@ -61,9 +61,9 @@ protected override Task GenerateSnippetTextChangeAsync(Document docu return Task.FromResult(new TextChange(TextSpan.FromBounds(position, position), elseClause.ToFullString())); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ElseClauseSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ElseClauseSyntax elseClause, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + elseClause, static c => (BlockSyntax)c.Statement, sourceText); From be8186b2a5caff2cf584973474402973883553dc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:34:14 -0700 Subject: [PATCH 19/29] naming --- .../CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs index 77bc7cf61b14a..5b34fe31c3053 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIfSnippetProvider.cs @@ -27,9 +27,9 @@ internal sealed class CSharpIfSnippetProvider() : AbstractIfSnippetProvider node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, IfStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, IfStatementSyntax ifStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + ifStatement, static s => (BlockSyntax)s.Statement, sourceText); From 1abd05923a91bcf63b5f1fa5261b1ba04534a123 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:34:54 -0700 Subject: [PATCH 20/29] naming --- .../Portable/Snippets/CSharpForEachLoopSnippetProvider.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs index c87ddc5cad821..895f844753e10 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpForEachLoopSnippetProvider.cs @@ -110,12 +110,12 @@ protected override ImmutableArray GetPlaceHolderLocationsLis if (!ConstructedFromInlineExpression) arrayBuilder.Add(new SnippetPlaceholder(node.Expression.ToString(), node.Expression.SpanStart)); - return arrayBuilder.ToImmutableArray(); + return arrayBuilder.ToImmutable(); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForEachStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, ForEachStatementSyntax forEachStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + forEachStatement, static s => (BlockSyntax)s.Statement, sourceText); From 7c7b720b4d033b1fc231fc95206dca24debfc79a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:35:13 -0700 Subject: [PATCH 21/29] naming --- .../CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index 3843d1f493cd3..cd5e5f7c8afcc 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Composition; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -39,9 +38,9 @@ protected override IEnumerable GenerateInnerStatements(SyntaxGenerat return SpecializedCollections.SingletonEnumerable(returnStatement); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax methodDeclaration, SourceText sourceText) { - var body = caretTarget.Body!; + var body = methodDeclaration.Body!; var returnStatement = body.Statements.First(); var triviaSpan = returnStatement.GetLeadingTrivia().Span; From 5747084a7d42966acaa2f66b827c85a1ab5440ee Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:36:55 -0700 Subject: [PATCH 22/29] naming --- .../AbstractCSharpMainMethodSnippetProvider.cs | 3 ++- .../Snippets/CSharpVoidMainSnippetProvider.cs | 11 +++++------ .../AbstractMainMethodSnippetProvider.cs | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs index b917aced5941e..aa84a9a5061c8 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpMainMethodSnippetProvider.cs @@ -12,7 +12,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Snippets; -internal abstract class AbstractCSharpMainMethodSnippetProvider : AbstractMainMethodSnippetProvider +internal abstract class AbstractCSharpMainMethodSnippetProvider + : AbstractMainMethodSnippetProvider { protected override bool IsValidSnippetLocation(in SnippetContext context, CancellationToken cancellationToken) { diff --git a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs index 4004797f91150..7cd57110aa4d2 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpVoidMainSnippetProvider.cs @@ -14,7 +14,6 @@ using Microsoft.CodeAnalysis.Snippets; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Snippets; @@ -27,15 +26,15 @@ internal sealed class CSharpVoidMainSnippetProvider() : AbstractCSharpMainMethod public override string Description => CSharpFeaturesResources.static_void_Main; - protected override SyntaxNode GenerateReturnType(SyntaxGenerator generator) + protected override TypeSyntax GenerateReturnType(SyntaxGenerator generator) => SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)); - protected override IEnumerable GenerateInnerStatements(SyntaxGenerator generator) - => SpecializedCollections.EmptyEnumerable(); + protected override IEnumerable GenerateInnerStatements(SyntaxGenerator generator) + => []; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax methodDeclaration, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + methodDeclaration, static d => d.Body!, sourceText); diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs index 00b6161e5f614..d43f02b48dd13 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractMainMethodSnippetProvider.cs @@ -13,12 +13,14 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; -internal abstract class AbstractMainMethodSnippetProvider : AbstractSingleChangeSnippetProvider +internal abstract class AbstractMainMethodSnippetProvider : AbstractSingleChangeSnippetProvider where TMethodDeclarationSyntax : SyntaxNode + where TStatementSyntax : SyntaxNode + where TTypeSyntax : SyntaxNode { - protected abstract SyntaxNode GenerateReturnType(SyntaxGenerator generator); + protected abstract TTypeSyntax GenerateReturnType(SyntaxGenerator generator); - protected abstract IEnumerable GenerateInnerStatements(SyntaxGenerator generator); + protected abstract IEnumerable GenerateInnerStatements(SyntaxGenerator generator); protected sealed override Task GenerateSnippetTextChangeAsync(Document document, int position, CancellationToken cancellationToken) { From 928ae26432a96f0848132d363a639543159b5227 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:37:05 -0700 Subject: [PATCH 23/29] naming --- .../Portable/Snippets/CSharpWhileLoopSnippetProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs index 3559a55d7c44c..0dcc86f2245db 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpWhileLoopSnippetProvider.cs @@ -27,9 +27,9 @@ internal sealed class CSharpWhileLoopSnippetProvider() : AbstractWhileLoopSnippe protected override ExpressionSyntax GetCondition(WhileStatementSyntax node) => node.Condition; - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, WhileStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, WhileStatementSyntax whileStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + whileStatement, static s => (BlockSyntax)s.Statement, sourceText); From dd67cd3abc99b8edd9ca2b4710e9ec102b90d654 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:37:17 -0700 Subject: [PATCH 24/29] naming --- .../CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs index 9b85bee23c132..4c82911d2ecbc 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpLockSnippetProvider.cs @@ -31,9 +31,9 @@ protected override ImmutableArray GetPlaceHolderLocationsLis return [new SnippetPlaceholder(expression.ToString(), expression.SpanStart)]; } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, LockStatementSyntax caretTarget, SourceText sourceText) + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, LockStatementSyntax lockStatement, SourceText sourceText) => CSharpSnippetHelpers.GetTargetCaretPositionInBlock( - caretTarget, + lockStatement, static s => (BlockSyntax)s.Statement, sourceText); From 2b764909d29c4d0d5dbe357a84f9b975a24b8de1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:38:16 -0700 Subject: [PATCH 25/29] naming --- .../AbstractCSharpAutoPropertySnippetProvider.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index 69ef641e573ea..85ffe3357d917 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -66,18 +66,18 @@ protected override async Task GenerateSnippetSyntaxAs accessorList: SyntaxFactory.AccessorList([.. accessors.Where(a => a is not null)!])); } - protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, PropertyDeclarationSyntax caretTarget, SourceText sourceText) - => caretTarget.AccessorList!.CloseBraceToken.Span.End; + protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, PropertyDeclarationSyntax propertyDeclaration, SourceText sourceText) + => propertyDeclaration.AccessorList!.CloseBraceToken.Span.End; - protected override ImmutableArray GetPlaceHolderLocationsList(PropertyDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) + protected override ImmutableArray GetPlaceHolderLocationsList(PropertyDeclarationSyntax propertyDeclaration, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); - var identifier = node.Identifier; - var type = node.Type; + var identifier = propertyDeclaration.Identifier; + var type = propertyDeclaration.Type; arrayBuilder.Add(new SnippetPlaceholder(type.ToString(), type.SpanStart)); arrayBuilder.Add(new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart)); - return arrayBuilder.ToImmutableArray(); + return arrayBuilder.ToImmutable(); } protected override PropertyDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) From 7c2f0a9271ecf112bb8faa4623ca9a501d0395d2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:39:12 -0700 Subject: [PATCH 26/29] naming --- .../Portable/Snippets/CSharpIntMainSnippetProvider.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index cd5e5f7c8afcc..ef76c6fb2eb3f 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -29,13 +29,13 @@ internal sealed class CSharpIntMainSnippetProvider() : AbstractCSharpMainMethodS public override string Description => CSharpFeaturesResources.static_int_Main; - protected override SyntaxNode GenerateReturnType(SyntaxGenerator generator) - => generator.TypeExpression(SpecialType.System_Int32); + protected override TypeSyntax GenerateReturnType(SyntaxGenerator generator) + => (TypeSyntax)generator.TypeExpression(SpecialType.System_Int32); - protected override IEnumerable GenerateInnerStatements(SyntaxGenerator generator) + protected override IEnumerable GenerateInnerStatements(SyntaxGenerator generator) { - var returnStatement = generator.ReturnStatement(generator.LiteralExpression(0)); - return SpecializedCollections.SingletonEnumerable(returnStatement); + var returnStatement = (StatementSyntax)generator.ReturnStatement(generator.LiteralExpression(0)); + return [returnStatement]; } protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, MethodDeclarationSyntax methodDeclaration, SourceText sourceText) From a966b2496c788aeda822386f0dd07c9c186e6dbf Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:39:30 -0700 Subject: [PATCH 27/29] lint --- .../CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs index ef76c6fb2eb3f..0080ac332f027 100644 --- a/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/CSharpIntMainSnippetProvider.cs @@ -16,7 +16,6 @@ using Microsoft.CodeAnalysis.Snippets; using Microsoft.CodeAnalysis.Snippets.SnippetProviders; using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Snippets; From 5a66e892e2c48e0bf72eeeef557e2819d6d17072 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:39:56 -0700 Subject: [PATCH 28/29] inline --- .../AbstractConditionalBlockSnippetProvider.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs index 194ec386a7e28..89829127811cc 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractConditionalBlockSnippetProvider.cs @@ -26,8 +26,6 @@ protected sealed override ImmutableArray GetPlaceHolderLocat return []; var condition = GetCondition(node); - var placeholder = new SnippetPlaceholder(condition.ToString(), condition.SpanStart); - - return [placeholder]; + return [new SnippetPlaceholder(condition.ToString(), condition.SpanStart)]; } } From 4ddd02524b3e0d3dc10d66fbfdaddc6e752f9f9a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 5 Apr 2024 13:42:36 -0700 Subject: [PATCH 29/29] Simplify further --- .../AbstractCSharpAutoPropertySnippetProvider.cs | 9 +++++---- .../Snippets/AbstractCSharpTypeSnippetProvider.cs | 7 ++----- .../SnippetProviders/AbstractTypeSnippetProvider.cs | 9 +++------ 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs index 85ffe3357d917..554f45320a054 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpAutoPropertySnippetProvider.cs @@ -71,13 +71,14 @@ protected override int GetTargetCaretPosition(ISyntaxFactsService syntaxFacts, P protected override ImmutableArray GetPlaceHolderLocationsList(PropertyDeclarationSyntax propertyDeclaration, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); var identifier = propertyDeclaration.Identifier; var type = propertyDeclaration.Type; - arrayBuilder.Add(new SnippetPlaceholder(type.ToString(), type.SpanStart)); - arrayBuilder.Add(new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart)); - return arrayBuilder.ToImmutable(); + return + [ + new SnippetPlaceholder(type.ToString(), type.SpanStart), + new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart), + ]; } protected override PropertyDeclarationSyntax? FindAddedSnippetSyntaxNode(SyntaxNode root, int position) diff --git a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs index 6bb523d58b01a..8d527b7523a2e 100644 --- a/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs +++ b/src/Features/CSharp/Portable/Snippets/AbstractCSharpTypeSnippetProvider.cs @@ -106,9 +106,6 @@ protected override async Task AddIndentationToDocumentAsync(Document d return document.WithSyntaxRoot(newRoot); } - protected override void GetTypeDeclarationIdentifier(SyntaxNode node, out SyntaxToken identifier) - { - var typeDeclaration = (BaseTypeDeclarationSyntax)node; - identifier = typeDeclaration.Identifier; - } + protected sealed override SyntaxToken GetTypeDeclarationIdentifier(TTypeDeclarationSyntax baseTypeDeclaration) + => baseTypeDeclaration.Identifier; } diff --git a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs index 58deb76a0d705..1a03d3168a221 100644 --- a/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs +++ b/src/Features/Core/Portable/Snippets/SnippetProviders/AbstractTypeSnippetProvider.cs @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.Snippets.SnippetProviders; internal abstract class AbstractTypeSnippetProvider : AbstractSnippetProvider where TTypeDeclarationSyntax : SyntaxNode { - protected abstract void GetTypeDeclarationIdentifier(SyntaxNode node, out SyntaxToken identifier); + protected abstract SyntaxToken GetTypeDeclarationIdentifier(TTypeDeclarationSyntax node); protected abstract Task GenerateTypeDeclarationAsync(Document document, int position, CancellationToken cancellationToken); protected abstract Task GetAccessibilityModifiersChangeAsync(Document document, int position, CancellationToken cancellationToken); @@ -36,11 +36,8 @@ protected sealed override async Task> GenerateSnippet protected sealed override ImmutableArray GetPlaceHolderLocationsList(TTypeDeclarationSyntax node, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken) { - using var _ = ArrayBuilder.GetInstance(out var arrayBuilder); - GetTypeDeclarationIdentifier(node, out var identifier); - arrayBuilder.Add(new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart)); - - return arrayBuilder.ToImmutableArray(); + var identifier = GetTypeDeclarationIdentifier(node); + return [new SnippetPlaceholder(identifier.ValueText, identifier.SpanStart)]; } protected static async Task AreAccessibilityModifiersRequiredAsync(Document document, CancellationToken cancellationToken)