未验证 提交 a8279d01 编写于 作者: O Omar Tawfik 提交者: GitHub

Suggest stackalloc keyword in Span legal places (#23655)

* Suggest stackalloc keyword in Span legal places

* Address PR Comments

* More PR Feedback

* Clean up
上级 57fd934d
......@@ -55,9 +55,9 @@ public async Task TestNotInEmptyStatement()
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInEmptySpace()
public async Task TestInEmptySpaceAfterAssignment()
{
await VerifyAbsenceAsync(AddInsideMethod(
await VerifyKeywordAsync(AddInsideMethod(
@"var v = $$"));
}
......@@ -71,9 +71,10 @@ public async Task TestInUnsafeEmptySpace()
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInUnsafeEmptySpace_NotAfterNonPointer()
public async Task TestInUnsafeEmptySpace_AfterNonPointer()
{
await VerifyAbsenceAsync(
// There can be an implicit conversion to int
await VerifyKeywordAsync(
@"unsafe class C {
void Goo() {
int v = $$");
......@@ -124,12 +125,146 @@ unsafe static void Main(string[] args)
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInsideForStatementVarDecl3()
{
await VerifyAbsenceAsync(
await VerifyKeywordAsync(
@"class C
{
unsafe static void Main(string[] args)
{
for (string i = $$");
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSOfAssignment_Span()
{
await VerifyKeywordAsync(AddInsideMethod(@"
Span<int> s = $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSOfAssignment_Pointer()
{
await VerifyKeywordAsync(AddInsideMethod(
@"int* v = $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSOfAssignment_ReAssignment()
{
await VerifyKeywordAsync(AddInsideMethod(
@"v = $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithCast()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = (Span<char>)$$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = (Span<char>)$$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_True()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value ? $$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value ? $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_True_WithCast()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value ? (Span<int>)$$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value ? (Span<int>)$$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_False()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value ? stackalloc int[10] : $$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value ? stackalloc int[10] : $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_False_WithCast()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value ? stackalloc int[10] : (Span<int>)$$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value ? stackalloc int[10] : (Span<int>)$$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_NestedConditional_True()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value1 ? value2 ? $$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value1 ? value2 ? $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_NestedConditional_WithCast_True()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value1 ? value2 ? (Span<int>)$$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value1 ? value2 ? (Span<int>)$$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_NestedConditional_False()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value1 ? value2 ? stackalloc int [10] : $$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value1 ? value2 ? stackalloc int [10] : $$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestOnRHSWithConditionalExpression_NestedConditional_WithCast_False()
{
await VerifyKeywordAsync(AddInsideMethod(@"
var s = value1 ? value2 ? stackalloc int [10] : (Span<int>)$$"));
await VerifyKeywordAsync(AddInsideMethod(@"
s = value1 ? value2 ? stackalloc int [10] : (Span<int>)$$"));
}
[WorkItem(23584, "https://github.com/dotnet/roslyn/issues/23584")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInLHSOfAssignment()
{
await VerifyAbsenceAsync(AddInsideMethod(@"
var x $$ ="));
await VerifyAbsenceAsync(AddInsideMethod(@"
x $$ ="));
}
}
}
......@@ -16,20 +16,47 @@ public StackAllocKeywordRecommender()
protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
{
// type t = |
var token = context.TargetToken;
if (token.IsUnsafeContext())
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))
{
if (token.Kind() == SyntaxKind.EqualsToken &&
token.Parent.IsKind(SyntaxKind.EqualsValueClause) &&
token.Parent.IsParentKind(SyntaxKind.VariableDeclarator) &&
token.Parent.Parent.IsParentKind(SyntaxKind.VariableDeclaration))
node = node.Parent;
if (node.IsKind(SyntaxKind.VariableDeclarator))
{
var variableDeclaration = (VariableDeclarationSyntax)token.Parent.Parent.Parent;
if (variableDeclaration.IsParentKind(SyntaxKind.LocalDeclarationStatement) ||
variableDeclaration.IsParentKind(SyntaxKind.ForStatement))
node = node.Parent;
if (node.IsKind(SyntaxKind.VariableDeclaration))
{
return variableDeclaration.Type.IsVar || variableDeclaration.Type.IsKind(SyntaxKind.PointerType);
node = node.Parent;
return node.IsKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册