提交 d005cd50 编写于 作者: S Sam Harwell

Support default, checked, and unchecked expressions

上级 ada49f46
......@@ -112,11 +112,13 @@ private static void BeforeExecuteCommand(TypeCharCommandArgs args, CommandExecut
startingNode = token.Parent;
// If the caret is right before an opening delimiter or right after a closing delimeter,
// If the caret is before an opening delimiter or after a closing delimeter,
// start analysis with node outside of delimiters.
//
// Examples,
// `obj.ToString$()` where `token` references `(` but the caret isn't actually inside the argument list.
// `obj.ToString()$` or `obj.method()$ .method()` where `token` references `)` but the caret isn't inside the argument list.
// `defa$$ult(object)` where `token` references `default` but the caret isn't inside the parentheses.
var (openingDelimeter, closingDelimiter) = GetDelimiters(startingNode);
if (!openingDelimeter.IsKind(SyntaxKind.None) && openingDelimeter.Span.Start >= caretPosition
|| !closingDelimiter.IsKind(SyntaxKind.None) && closingDelimiter.Span.End <= caretPosition)
......@@ -149,7 +151,10 @@ private static void BeforeExecuteCommand(TypeCharCommandArgs args, CommandExecut
SyntaxKind.ArrayRankSpecifier,
SyntaxKind.BracketedArgumentList,
SyntaxKind.ParenthesizedExpression,
SyntaxKind.ParameterList))
SyntaxKind.ParameterList,
SyntaxKind.DefaultExpression,
SyntaxKind.CheckedExpression,
SyntaxKind.UncheckedExpression))
{
// make sure the closing delimiter exists
if (RequiredDelimiterIsMissing(currentNode))
......@@ -472,6 +477,15 @@ private static (SyntaxToken openingDelimeter, SyntaxToken closingDelimiter) GetD
var parameterList = (ParameterListSyntax)currentNode;
return (parameterList.OpenParenToken, parameterList.CloseParenToken);
case SyntaxKind.DefaultExpression:
var defaultExpressionSyntax = (DefaultExpressionSyntax)currentNode;
return (defaultExpressionSyntax.OpenParenToken, defaultExpressionSyntax.CloseParenToken);
case SyntaxKind.CheckedExpression:
case SyntaxKind.UncheckedExpression:
var checkedExpressionSyntax = (CheckedExpressionSyntax)currentNode;
return (checkedExpressionSyntax.OpenParenToken, checkedExpressionSyntax.CloseParenToken);
default:
// Type of node does not have delimiters used by this feature
return default;
......
......@@ -2316,6 +2316,102 @@ static void Main()
#endregion
[WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)]
[InlineData("default(object$$)", "default(object)")]
[InlineData("default($$object)", "default(object)")]
public void DefaultExpression_Handled(string expression, string expectedExpression)
{
var code = $@"
public class Class1
{{
void M()
{{
int i = {expression}
}}
}}";
var expected = $@"
public class Class1
{{
void M()
{{
int i = {expectedExpression};$$
}}
}}";
VerifyTypingSemicolon(code, expected);
}
[WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)]
[InlineData("default$$(object)")]
[InlineData("def$$ault(object)")]
[InlineData("default(object$$")]
[InlineData("default($$object")]
public void DefaultExpression_NotHandled(string expression)
{
var code = $@"
public class Class1
{{
void M()
{{
int i = {expression}
}}
}}";
VerifyNoSpecialSemicolonHandling(code);
}
[WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)]
[InlineData("checked(3 + 3$$)", "checked(3 + 3)")]
[InlineData("checked($$3 + 3)", "checked(3 + 3)")]
[InlineData("unchecked(3 + 3$$)", "unchecked(3 + 3)")]
[InlineData("unchecked($$3 + 3)", "unchecked(3 + 3)")]
public void CheckedExpression_Handled(string expression, string expectedExpression)
{
var code = $@"
public class Class1
{{
void M()
{{
int i = {expression}
}}
}}";
var expected = $@"
public class Class1
{{
void M()
{{
int i = {expectedExpression};$$
}}
}}";
VerifyTypingSemicolon(code, expected);
}
[WpfTheory, Trait(Traits.Feature, Traits.Features.CompleteStatement)]
[InlineData("checked$$(3 + 3)")]
[InlineData("che$$cked(3 + 3)")]
[InlineData("checked(3 + 3$$")]
[InlineData("checked($$3 + 3")]
[InlineData("unchecked$$(3 + 3)")]
[InlineData("unche$$cked(3 + 3)")]
[InlineData("unchecked(3 + 3$$")]
[InlineData("unchecked($$3 + 3")]
public void CheckedExpression_NotHandled(string expression)
{
var code = $@"
public class Class1
{{
void M()
{{
int i = {expression}
}}
}}";
VerifyNoSpecialSemicolonHandling(code);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CompleteStatement)]
public void ThrowStatement_MissingBoth()
{
......
......@@ -131,6 +131,17 @@ 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;
}
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)
{
if (node == null)
{
return false;
}
var csharpKind = node.Kind();
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, SyntaxKind kind10, SyntaxKind kind11)
{
if (node == null)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册