File: Recommendations\ScopedKeywordRecommenderTests.cs
Web Access
Project: src\src\EditorFeatures\CSharpTest2\Microsoft.CodeAnalysis.CSharp.EditorFeatures2.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.EditorFeatures2.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Completion.KeywordRecommenders;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Recommendations;
 
public sealed class ScopedKeywordRecommenderTests : RecommenderTests
{
    protected override string KeywordText => "scoped";
 
    private readonly ScopedKeywordRecommender _recommender = new();
 
    public ScopedKeywordRecommenderTests()
    {
        this.RecommendKeywordsAsync = (position, context) => Task.FromResult(_recommender.RecommendKeywords(position, context, CancellationToken.None));
    }
 
    [Fact]
    public async Task TestAtRoot_Interactive()
    {
        await VerifyKeywordAsync(SourceCodeKind.Script,
@"$$");
    }
 
    [Fact]
    public async Task TestAfterClass_Interactive()
    {
        await VerifyKeywordAsync(SourceCodeKind.Script,
            """
            class C { }
            $$
            """);
    }
 
    [Fact]
    public async Task TestAfterGlobalStatement()
    {
        await VerifyKeywordAsync(
            """
            System.Console.WriteLine();
            $$
            """);
    }
 
    [Fact]
    public async Task TestAfterGlobalVariableDeclaration_Interactive()
    {
        await VerifyKeywordAsync(SourceCodeKind.Script,
            """
            int i = 0;
            $$
            """);
    }
 
    [Fact]
    public async Task TestNotInUsingAlias()
    {
        await VerifyAbsenceAsync(
@"using Goo = $$");
    }
 
    [Fact]
    public async Task TestNotInGlobalUsingAlias()
    {
        await VerifyAbsenceAsync(
@"global using Goo = $$");
    }
 
    [Fact]
    public async Task TestNotAfterStackAlloc()
    {
        await VerifyAbsenceAsync(
            """
            class C {
                 int* goo = stackalloc $$
            """);
    }
 
    [Fact]
    public async Task TestNotInFixedStatement()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"fixed ($$"));
    }
 
    [Fact]
    public async Task TestNotInDelegateReturnType()
    {
        await VerifyAbsenceAsync(
@"public delegate $$");
    }
 
    [Fact]
    public async Task TestPossibleLambda()
    {
        // Could be `var x = ((scoped ref int x) => x);`
        await VerifyKeywordAsync(AddInsideMethod(
@"var x = (($$"));
    }
 
    [Fact]
    public async Task TestEmptyStatement()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"$$"));
    }
 
    [Fact]
    public async Task TestBeforeStatement()
    {
        await VerifyKeywordAsync(AddInsideMethod(
            """
            $$
            return true;
            """));
    }
 
    [Fact]
    public async Task TestAfterStatement()
    {
        await VerifyKeywordAsync(AddInsideMethod(
            """
            return true;
            $$
            """));
    }
 
    [Fact]
    public async Task TestNotInClass()
    {
        await VerifyAbsenceAsync("""
            class C
            {
              $$
            }
            """);
    }
 
    [Fact]
    public async Task TestInFor()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"for ($$"));
    }
 
    [Fact]
    public async Task TestInFor2()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"for ($$;"));
    }
 
    [Fact]
    public async Task TestInFor3()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"for ($$;;"));
    }
 
    [Fact]
    public async Task TestNotInFor()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"for (var $$"));
    }
 
    [Fact]
    public async Task TestNotAfterVar()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"var $$"));
    }
 
    [Fact]
    public async Task TestInForEach()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"foreach ($$"));
    }
 
    [Fact]
    public async Task TestNotInForEach()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (var $$"));
    }
 
    [Fact]
    public async Task TestInAwaitForEach()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"await foreach ($$"));
    }
 
    [Fact]
    public async Task TestNotInAwaitForEach()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"await foreach (var $$"));
    }
 
    [Fact]
    public async Task TestNotInForEachRefLoop0()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (ref $$"));
    }
 
    [Fact]
    public async Task TestNotInForEachRefLoop1()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (ref $$ x"));
    }
 
    [Fact]
    public async Task TestNotInForEachRefLoop2()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (ref s$$ x"));
    }
 
    [Fact]
    public async Task TestNotInForEachRefReadonlyLoop0()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"foreach (ref readonly $$ x"));
    }
 
    [Fact]
    public async Task TestNotInForRefLoop0()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"for (ref $$"));
    }
 
    [Fact]
    public async Task TestNotInForRefLoop1()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"for (ref s$$"));
    }
 
    [Fact]
    public async Task TestNotInForRefReadonlyLoop0()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"for (ref readonly $$"));
    }
 
    [Fact]
    public async Task TestNotInForRefReadonlyLoop1()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"for (ref readonly s$$"));
    }
 
    [Fact]
    public async Task TestNotInUsing()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"using ($$"));
    }
 
    [Fact]
    public async Task TestNotInUsing2()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"using (var $$"));
    }
 
    [Fact]
    public async Task TestNotInAwaitUsing()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"await using ($$"));
    }
 
    [Fact]
    public async Task TestNotInAwaitUsing2()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"await using (var $$"));
    }
 
    [Fact]
    public async Task TestNotAfterConstLocal()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"const $$"));
    }
 
    [Fact]
    public async Task TestNotAfterConstField()
    {
        await VerifyAbsenceAsync(
            """
            class C {
                const $$
            """);
    }
 
    [Fact]
    public async Task TestAfterOutKeywordInArgument()
    {
        await VerifyKeywordAsync(AddInsideMethod(
@"M(out $$"));
    }
 
    [Fact]
    public async Task TestNotAfterRefInMemberContext()
    {
        await VerifyAbsenceAsync(
            """
            class C {
                ref $$
            """);
    }
 
    [Fact]
    public async Task TestNotAfterRefReadonlyInMemberContext()
    {
        await VerifyAbsenceAsync(
            """
            class C {
                ref readonly $$
            """);
    }
 
    [Fact]
    public async Task TestNotAfterRefInStatementContext()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"ref $$"));
    }
 
    [Fact]
    public async Task TestNotAfterRefReadonlyInStatementContext()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"ref readonly $$"));
    }
 
    [Fact]
    public async Task TestNotAfterRefLocalDeclaration()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"ref $$ int local;"));
    }
 
    [Fact]
    public async Task TestNotAfterRefReadonlyLocalDeclaration()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"ref readonly $$ int local;"));
    }
 
    [Fact]
    public async Task TestNotAfterRefExpression()
    {
        await VerifyAbsenceAsync(AddInsideMethod(
@"ref int x = ref $$"));
    }
 
    [Fact]
    public async Task TestInParameter1()
    {
        await VerifyKeywordAsync("""
            class C
            {
                public void M($$)
            }
            """);
    }
 
    [Fact]
    public async Task TestInParameter2()
    {
        await VerifyKeywordAsync("""
            class C
            {
                public void M($$ ref)
            }
            """);
    }
 
    [Fact]
    public async Task TestInParameter3()
    {
        await VerifyKeywordAsync("""
            class C
            {
                public void M($$ ref int i)
            }
            """);
    }
 
    [Fact]
    public async Task TestInParameter4()
    {
        await VerifyKeywordAsync("""
            class C
            {
                public void M($$ ref int i)
            }
            """);
    }
 
    [Fact]
    public async Task TestInOperatorParameter()
    {
        await VerifyKeywordAsync("""
            class C
            {
                public static C operator +($$ in C c)
            }
            """);
    }
 
    [Fact]
    public async Task TestInAnonymousMethodParameter()
    {
        await VerifyKeywordAsync("""
            class C
            {
                void M()
                {
                    var x = delegate ($$) { };
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInParameterAfterThisScoped()
    {
        await VerifyKeywordAsync("""
            static class C
            {
                static void M(this $$)
            }
            """);
    }
}