diff --git a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs index ca876be4c1acc..eeeb3a9ee3448 100644 --- a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs +++ b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs @@ -185,7 +185,8 @@ private static bool MoveCaretToSemicolonPosition( SyntaxKind.DefaultExpression, SyntaxKind.CheckedExpression, SyntaxKind.UncheckedExpression, - SyntaxKind.TypeOfExpression)) + SyntaxKind.TypeOfExpression, + SyntaxKind.TupleExpression)) { // make sure the closing delimiter exists if (RequiredDelimiterIsMissing(currentNode)) @@ -531,6 +532,10 @@ private static (SyntaxToken openingDelimeter, SyntaxToken closingDelimiter) GetD var typeOfExpressionSyntax = (TypeOfExpressionSyntax)currentNode; return (typeOfExpressionSyntax.OpenParenToken, typeOfExpressionSyntax.CloseParenToken); + case SyntaxKind.TupleExpression: + var tupleExpressionSyntax = (TupleExpressionSyntax)currentNode; + return (tupleExpressionSyntax.OpenParenToken, tupleExpressionSyntax.CloseParenToken); + default: // Type of node does not have delimiters used by this feature return default; diff --git a/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs index f7a844e6184f9..5cc4a557cf81a 100644 --- a/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs @@ -2401,6 +2401,7 @@ void M() } [WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)] + [WorkItem(52137, "https://github.com/dotnet/roslyn/issues/52137")] [InlineData("typeof(object$$)", "typeof(object)")] [InlineData("typeof($$object)", "typeof(object)")] public void TypeOfExpression_Handled(string expression, string expectedExpression) @@ -2426,6 +2427,31 @@ void M() VerifyTypingSemicolon(code, expected); } + [WpfFact, Trait(Traits.Feature, Traits.Features.CompleteStatement)] + [WorkItem(52365, "https://github.com/dotnet/roslyn/issues/52365")] + public void TupleExpression_Handled() + { + var code = @" +public class Class1 +{ + void M() + { + var x = (0, 0$$) + } +}"; + + var expected = @" +public class Class1 +{ + void M() + { + var x = (0, 0);$$ + } +}"; + + VerifyTypingSemicolon(code, expected); + } + [WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)] [InlineData("default$$(object)")] [InlineData("def$$ault(object)")] diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs index 37bc9684d3860..947cb16c1f770 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs @@ -136,7 +136,7 @@ public static bool IsKind([NotNullWhen(returnValue: true)] this SyntaxNode? node return csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3 || csharpKind == kind4 || csharpKind == kind5 || csharpKind == kind6 || csharpKind == kind7 || csharpKind == kind8; } - public static bool IsKind([NotNullWhen(returnValue: true)] this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5, SyntaxKind kind6, SyntaxKind kind7, SyntaxKind kind8, SyntaxKind kind9) + public static bool IsKind([NotNullWhen(returnValue: true)] this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5, SyntaxKind kind6, SyntaxKind kind7, SyntaxKind kind8, SyntaxKind kind9, SyntaxKind kind10) { if (node == null) { @@ -144,7 +144,7 @@ public static bool IsKind([NotNullWhen(returnValue: true)] this SyntaxNode? node } var csharpKind = node.Kind(); - return csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3 || csharpKind == kind4 || csharpKind == kind5 || csharpKind == kind6 || csharpKind == kind7 || csharpKind == kind8 || csharpKind == kind9; + return csharpKind == kind1 || csharpKind == kind2 || csharpKind == kind3 || csharpKind == kind4 || csharpKind == kind5 || csharpKind == kind6 || csharpKind == kind7 || csharpKind == kind8 || csharpKind == kind9 || csharpKind == kind10; } public static bool IsKind([NotNullWhen(returnValue: true)] this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5, SyntaxKind kind6, SyntaxKind kind7, SyntaxKind kind8, SyntaxKind kind9, SyntaxKind kind10, SyntaxKind kind11)