未验证 提交 5dc0a900 编写于 作者: G Gen Lu 提交者: GitHub

Merge pull request #43043 from genlu/stackallocCompletion

show stackalloc completion in expression context
......@@ -12,32 +12,32 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
public class StackAllocKeywordRecommenderTests : KeywordRecommenderTests
{
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAtRoot_Interactive()
public async Task TestAtRoot_Interactive()
{
await VerifyAbsenceAsync(SourceCodeKind.Script,
await VerifyKeywordAsync(SourceCodeKind.Script,
@"$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAfterClass_Interactive()
public async Task TestAfterClass_Interactive()
{
await VerifyAbsenceAsync(SourceCodeKind.Script,
await VerifyKeywordAsync(SourceCodeKind.Script,
@"class C { }
$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAfterGlobalStatement_Interactive()
public async Task TestAfterGlobalStatement_Interactive()
{
await VerifyAbsenceAsync(SourceCodeKind.Script,
await VerifyKeywordAsync(SourceCodeKind.Script,
@"System.Console.WriteLine();
$$");
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAfterGlobalVariableDeclaration_Interactive()
public async Task TestAfterGlobalVariableDeclaration_Interactive()
{
await VerifyAbsenceAsync(SourceCodeKind.Script,
await VerifyKeywordAsync(SourceCodeKind.Script,
@"int i = 0;
$$");
}
......@@ -50,9 +50,11 @@ public async Task TestNotInUsingAlias()
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInEmptyStatement()
public async Task TestInEmptyStatement()
{
await VerifyAbsenceAsync(AddInsideMethod(
// e.g. this is a valid statement
// stackalloc[] { 1, 2, 3 }.IndexOf(1);
await VerifyKeywordAsync(AddInsideMethod(
@"$$"));
}
......@@ -92,11 +94,14 @@ public async Task TestInUnsafeEmptySpace_AfterPointer()
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInField()
public async Task TestInField()
{
await VerifyAbsenceAsync(
@"unsafe class C {
int* v = $$");
// While assigning stackalloc'd value to a field is invalid,
// using one in the initializer is OK. e.g.
// int _f = stackalloc[] { 1, 2, 3 }.IndexOf(1);
await VerifyKeywordAsync(
@"class C {
int v = $$");
}
[WorkItem(544504, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544504")]
......@@ -268,5 +273,39 @@ public async Task TestNotInLHSOfAssignment()
await VerifyAbsenceAsync(AddInsideMethod(@"
x $$ ="));
}
[WorkItem(41736, "https://github.com/dotnet/roslyn/issues/41736")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInArgument()
{
await VerifyKeywordAsync(@"
class Program
{
static void Method(System.Span<byte> span)
{
Method($$);
}
}");
await VerifyKeywordAsync(@"
class Program
{
static void Method(int x, System.Span<byte> span)
{
Method(1, $$);
}
}");
}
[WorkItem(41736, "https://github.com/dotnet/roslyn/issues/41736")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInConstFieldInitializer()
{
await VerifyAbsenceAsync(@"
class Program
{
private const int _f = $$
}");
}
}
}
......@@ -17,52 +17,11 @@ public StackAllocKeywordRecommender()
protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
{
var node = context.TargetToken.Parent;
// At start of a file
if (node == null)
{
return false;
}
// After a cast or parenthesized expression: (Span<int>)stackalloc
if (context.TargetToken.IsAfterPossibleCast())
{
node = node.Parent;
}
// Inside a conditional expression: value ? stackalloc : stackalloc
while (node.IsKind(SyntaxKind.ConditionalExpression) &&
(context.TargetToken.IsKind(SyntaxKind.QuestionToken, SyntaxKind.ColonToken) || context.TargetToken.IsAfterPossibleCast()))
{
node = node.Parent;
}
// assignment: x = stackalloc
if (node.IsKind(SyntaxKind.SimpleAssignmentExpression))
{
return node.Parent.IsKind(SyntaxKind.ExpressionStatement);
}
// declaration: var x = stackalloc
if (node.IsKind(SyntaxKind.EqualsValueClause))
{
node = node.Parent;
if (node.IsKind(SyntaxKind.VariableDeclarator))
{
node = node.Parent;
if (node.IsKind(SyntaxKind.VariableDeclaration))
{
node = node.Parent;
return node.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement);
}
}
}
return false;
// Beginning with C# 8.0, stackalloc expression can be used inside other expressions
// whenever a Span<T> or ReadOnlySpan<T> variable is allowed.
return (context.IsAnyExpressionContext && !context.IsConstantExpressionContext) ||
context.IsStatementContext ||
context.IsGlobalStatementContext;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册