Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing completion in async foreach/using #23960

Merged
merged 3 commits into from
Jan 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,64 @@ async void goo()
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestAsyncUsingStatement()
{
await VerifyKeywordAsync(@"
class Program
{
void goo()
{
using $$
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestUsingDirective()
{
await VerifyAbsenceAsync("using $$");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestAfterAsyncUsingStatement()
{
await VerifyAbsenceAsync(@"
class Program
{
void goo()
{
using await $$
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestAsyncForeachStatement()
{
await VerifyKeywordAsync(@"
class Program
{
void goo()
{
foreach $$
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestAfterAsyncForeachStatement()
{
await VerifyAbsenceAsync(@"
class Program
{
void goo()
{
foreach await $$
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInQuery()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,13 @@ await VerifyKeywordAsync(AddInsideMethod(
@"foreach (var v in $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInAsyncForeachIn()
{
await VerifyKeywordAsync(AddInsideMethod(
@"foreach await (var v in $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInFromIn()
{
Expand Down Expand Up @@ -547,6 +554,13 @@ await VerifyKeywordAsync(AddInsideMethod(
@"using ($$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInAsyncUsing()
{
await VerifyKeywordAsync(AddInsideMethod(
@"using await ($$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInLock()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;

Expand Down Expand Up @@ -206,6 +205,20 @@ await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (var $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInAsyncForEach()
{
await VerifyKeywordAsync(AddInsideMethod(
@"foreach await ($$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestnotInAsyncForEach()
{
await VerifyAbsenceAsync(AddInsideMethod(
@"foreach await (var $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInUsing()
{
Expand All @@ -220,6 +233,20 @@ await VerifyAbsenceAsync(AddInsideMethod(
@"using (var $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestInAsyncUsing()
{
await VerifyKeywordAsync(AddInsideMethod(
@"using await ($$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInAsyncUsing()
{
await VerifyAbsenceAsync(AddInsideMethod(
@"using await (var $$"));
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestAfterConstLocal()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ protected override bool IsValidContext(int position, CSharpSyntaxContext context
return true;
}

if (context.TargetToken.IsKind(SyntaxKind.UsingKeyword, SyntaxKind.ForEachKeyword)
&& !context.TargetToken.Parent.IsKind(SyntaxKind.UsingDirective))
{
return true;
}

return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1512,7 +1512,9 @@ public static bool IsLocalVariableDeclarationContext(
// out var
// for (var
// foreach (var
// foreach await (var
// using (var
// using await (var
// from var
// join var

Expand All @@ -1532,15 +1534,12 @@ public static bool IsLocalVariableDeclarationContext(
return true;
}

if (token.IsKind(SyntaxKind.OpenParenToken))
if (token.IsKind(SyntaxKind.OpenParenToken) &&
token.Parent.IsKind(
SyntaxKind.ForStatement, SyntaxKind.ForEachStatement,
SyntaxKind.ForEachVariableStatement, SyntaxKind.UsingStatement))
{
var previous = token.GetPreviousToken(includeSkipped: true);
if (previous.IsKind(SyntaxKind.ForKeyword) ||
previous.IsKind(SyntaxKind.ForEachKeyword) ||
previous.IsKind(SyntaxKind.UsingKeyword))
{
return true;
}
return true;
}

var tokenOnLeftOfStart = syntaxTree.FindTokenOnLeftOfPosition(token.SpanStart, cancellationToken);
Expand Down Expand Up @@ -2270,6 +2269,7 @@ public static bool IsExpressionContext(
}

// foreach (var v in |
// foreach await (var v in |
// from a in |
// join b in |
if (token.IsKind(SyntaxKind.InKeyword))
Expand Down Expand Up @@ -2357,8 +2357,8 @@ public static bool IsExpressionContext(
// todo: handle 'for' cases.

// using ( |
if (token.IsKind(SyntaxKind.OpenParenToken) &&
token.GetPreviousToken(includeSkipped: true).IsKind(SyntaxKind.UsingKeyword))
// using await ( |
if (token.IsKind(SyntaxKind.OpenParenToken) && token.Parent.IsKind(SyntaxKind.UsingStatement))
{
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public static bool IsParentKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKi
return node != null && IsKind(node.Parent, kind1, kind2, kind3);
}

public static bool IsParentKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4)
{
return node != null && IsKind(node.Parent, kind1, kind2, kind3, kind4);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, use =>


public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2)
{
if (node == null)
Expand Down