forked from dotnet/roslyn
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make keyword recommender know about "replace"
"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
Showing
5 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
src/EditorFeatures/CSharpTest2/Recommendations/ReplaceKeywordRecommenderTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 $$ | ||
}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
src/Features/CSharp/Portable/Completion/KeywordRecommenders/ReplaceKeywordRecommender.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |