Skip to content

Commit

Permalink
Make keyword recommender know about "replace"
Browse files Browse the repository at this point in the history
"replace" is roughly allowed in the same contexts as "async", so the "replace" ecommender is basically a copy of "async" recommender.

Fixes: dotnet#11191
  • Loading branch information
VSadov committed May 11, 2016
1 parent ce2e2f0 commit b1524cb
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
<Compile Include="Recommendations\AsKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\AssemblyKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\AsyncKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\ReplaceKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\AwaitKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\BaseKeywordRecommenderTests.cs" />
<Compile Include="Recommendations\BoolKeywordRecommenderTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Roslyn.Test.Utilities;
using Xunit;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations
{
[Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.SourceGenerators)]
public class ReplaceKeywordRecommenderTests : KeywordRecommenderTests
{
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestMethodDeclaration1()
{
await VerifyKeywordAsync(@"class C
{
$$
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestMethodDeclaration2()
{
await VerifyKeywordAsync(@"class C
{
public $$
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestMethodDeclaration3()
{
await VerifyKeywordAsync(@"class C
{
$$ public void foo() { }
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestMethodDeclarationInGlobalStatement1()
{
const string text = @"$$";
await VerifyKeywordAsync(SourceCodeKind.Script, text);
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestMethodDeclarationInGlobalStatement2()
{
const string text = @"public $$";
await VerifyKeywordAsync(SourceCodeKind.Script, text);
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestExpressionContext()
{
await VerifyKeywordAsync(@"class C
{
void foo()
{
foo($$
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInParameter()
{
await VerifyAbsenceAsync(@"class C
{
void foo($$)
{
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestBeforeLambda()
{
await VerifyKeywordAsync(@"
class Program
{
static void Main(string[] args)
{
var z = $$ () => 2;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotIfAlreadyAsync2()
{
await VerifyAbsenceAsync(@"
class Program
{
static void Main(string[] args)
{
var z = async $$ () => 2;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotInNamespace()
{
await VerifyAbsenceAsync(@"
namespace Foo
{
$$
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAfterPartialInNamespace()
{
await VerifyAbsenceAsync(@"
namespace Foo
{
partial $$
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
public async Task TestNotAfterPartialInClass()
{
await VerifyAbsenceAsync(@"
class Foo
{
partial $$
}");
}
}
}
1 change: 1 addition & 0 deletions src/Features/CSharp/Portable/CSharpFeatures.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
<Compile Include="Completion\CompletionProviders\SpeculativeTCompletionProvider.cs" />
<Compile Include="Completion\CompletionProviders\XmlDocCommentCompletionProvider.cs" />
<Compile Include="Completion\KeywordRecommenders\LoadKeywordRecommender.cs" />
<Compile Include="Completion\KeywordRecommenders\ReplaceKeywordRecommender.cs" />
<Compile Include="Completion\SuggestionMode\CSharpSuggestionModeCompletionProvider.cs" />
<Compile Include="Completion\CompletionProviders\SymbolCompletionProvider.cs" />
<Compile Include="Completion\CSharpCompletionOptions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ private static ImmutableArray<IKeywordRecommender<CSharpSyntaxContext>> GetKeywo
new RefKeywordRecommender(),
new RegionKeywordRecommender(),
new RemoveKeywordRecommender(),
new ReplaceKeywordRecommender(),
new RestoreKeywordRecommender(),
new ReturnKeywordRecommender(),
new SByteKeywordRecommender(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Utilities;
using Microsoft.CodeAnalysis.Shared.Extensions;

namespace Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders
{
internal class ReplaceKeywordRecommender : AbstractSyntacticSingleKeywordRecommender
{
public ReplaceKeywordRecommender() :
base(SyntaxKind.ReplaceKeyword, isValidInPreprocessorContext: false)
{
}

protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
{
if (context.IsAnyExpressionContext)
{
return true;
}

return !context.TargetToken.IsKindOrHasMatchingText(SyntaxKind.PartialKeyword)
&& InMemberDeclarationContext(position, context, cancellationToken);
}

private static bool InMemberDeclarationContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
{
return context.IsGlobalStatementContext
|| context.SyntaxTree.IsGlobalMemberDeclarationContext(position, SyntaxKindSet.AllGlobalMemberModifiers, cancellationToken)
|| context.IsMemberDeclarationContext(
validModifiers: SyntaxKindSet.AllMemberModifiers,
validTypeDeclarations: SyntaxKindSet.ClassStructTypeDeclarations,
canBePartial: true,
cancellationToken: cancellationToken);
}
}
}

0 comments on commit b1524cb

Please sign in to comment.