提交 e1693712 编写于 作者: Š Šimon Koníček

Fixing completion for partially written 'when' consumed as an identifier in a recursive pattern

上级 4281de6c
......@@ -84,7 +84,7 @@ public async Task TestForCatchClause_NotAfterFilter3()
[InlineData("1")]
[InlineData("1 + 1")]
[InlineData("true ? 1 : 1")]
// [InlineData("(1 + )")] // https://github.com/dotnet/roslyn/issues/25998 this resembles a positional pattern that it not handled by the recommender
[InlineData("(1 + )")]
public async Task TestForSwitchCase_AfterExpression(string expression) =>
await VerifyKeywordAsync(AddInsideMethod($@"switch (1) {{ case {expression} $$ }}"));
......@@ -93,7 +93,7 @@ public async Task TestForCatchClause_NotAfterFilter3()
[InlineData("1")]
[InlineData("1 + 1")]
[InlineData("true ? 1 : 1")]
// [InlineData("(1 + )")] // https://github.com/dotnet/roslyn/issues/25998 this resembles a positional pattern that it not handled by the recommender
[InlineData("(1 + )")]
public async Task TestForSwitchCase_AfterExpression_BeforeBreak(string expression) =>
await VerifyKeywordAsync(AddInsideMethod($@"switch (1) {{ case {expression} $$ break; }}"));
......@@ -102,7 +102,7 @@ public async Task TestForCatchClause_NotAfterFilter3()
[InlineData("1")]
[InlineData("1 + 1")]
[InlineData("true ? 1 : 1")]
// [InlineData("(1 + )")] // https://github.com/dotnet/roslyn/issues/25998 this resembles a positional pattern that it not handled by the recommender
[InlineData("(1 + )")]
public async Task TestForSwitchCase_AfterExpression_BeforeWhen(string expression) =>
await VerifyKeywordAsync(AddInsideMethod($@"switch (1) {{ case {expression} $$ when }}"));
......
......@@ -64,19 +64,37 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
return true;
}
if (lastToken == context.LeftToken && expressionOrPattern is DeclarationPatternSyntax declarationPattern)
if (lastToken == context.LeftToken)
{
// case constant w|
// The user is typing a new word (might be a partially written 'when' keyword),
// which is part of the pattern as opposed to appearing outside of it. In a few special cases,
// this word can actually be replaced with 'when' and the resulting pattern would still be valid.
// The user is typing a new word (might be a partially written 'when' keyword), which causes this to be parsed
// as a declaration pattern. lastToken will be 'w' (LeftToken) as opposed to 'constant' (TargetToken).
// However we'd like to pretend that this is not the case and that we just a have single expression
// with 'constant' as if the new word didn't exist. Let's do that by adjusting our variable.
if (expressionOrPattern is DeclarationPatternSyntax declarationPattern)
{
// The new token causes this to be parsed as a declaration pattern:
// case constant w| ('w' = LeftToken, 'constant' = TargetToken)
// However 'constant' itself might end up being a valid constant pattern.
// We will pretend as if 'w' didn't exist so that the later check
// for whether 'constant' is actually a type can still work properly.
expressionOrPattern = declarationPattern.Type;
return true;
}
if (expressionOrPattern is RecursivePatternSyntax recursivePattern)
{
// The new token is consumed as the identifier in a recursive pattern:
// case { } w| ('w' = LeftToken, '}' = TargetToken)
// However the identifier is optional and can be replaced by 'when'.
return true;
}
// In other cases, this would not be true because the pattern would be incomplete without this word:
// case 1 + w|
}
return false;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册