|
// 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.
#nullable disable
using System;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders;
public class SpeculativeTCompletionProviderTests : AbstractCSharpCompletionProviderTests
{
internal override Type GetCompletionProviderType()
=> typeof(SpeculativeTCompletionProvider);
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task IsCommitCharacterTest()
{
const string markup = """
class C
{
$$
}
""";
await VerifyCommonCommitCharactersAsync(markup, textTypedSoFar: "");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public void IsTextualTriggerCharacterTest()
=> TestCommonIsTextualTriggerCharacter();
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task SendEnterThroughToEditorTest()
{
const string markup = """
class C
{
$$
}
""";
await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.Never, expected: false);
await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.AfterFullyTypedWord, expected: true);
await VerifySendEnterThroughToEnterAsync(markup, "T", sendThroughEnterOption: EnterKeyRule.Always, expected: true);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InClass()
{
var markup = """
class C
{
$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InInterface()
{
var markup = """
interface I
{
$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InStruct()
{
var markup = """
struct S
{
$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotInNamespace()
{
var markup = """
namespace N
{
$$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotInEnum()
{
var markup = """
enum E
{
$$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task AfterDelegate()
{
var markup = """
class C
{
delegate $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotAfterVoid()
{
var markup = """
class C
{
void $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotAfterInt()
{
var markup = """
class C
{
int $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InGeneric()
{
var markup = """
using System;
class C
{
Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRef0()
{
var markup = """
using System;
class C
{
ref $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRef1()
{
var markup = """
using System;
class C
{
ref T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRefGeneric0()
{
var markup = """
using System;
class C
{
ref Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRefGeneric1()
{
var markup = """
using System;
class C
{
ref Func<$$>
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRefGeneric2()
{
var markup = """
using System;
class C
{
ref Func<T$$>
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRefGeneric3()
{
var markup = """
using System;
class C
{
ref Func<int, $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
public async Task InRefReadonlyGeneric()
{
var markup = """
using System;
class C
{
ref readonly Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InQualifiedGeneric0()
{
var markup = """
using System;
class C
{
System.Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InQualifiedGeneric1()
{
var markup = """
using System;
class C
{
System.Collections.Generic.List<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedGeneric0()
{
var markup = """
using System;
class C
{
ref System.Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedGeneric1()
{
var markup = """
using System;
class C
{
internal ref System.Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedNestedGeneric0()
{
var markup = """
using System;
class C
{
partial ref System.Func<Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedNestedGeneric1()
{
var markup = """
using System;
class C
{
private ref Func<System.Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedNestedGeneric2()
{
var markup = """
using System;
class C
{
public ref Func<int, System.Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37224")]
[WorkItem("https://github.com/dotnet/roslyn/issues/37268")]
public async Task InRefAndQualifiedNestedGeneric3()
{
var markup = """
using System;
class C
{
private protected ref Func<int, System.Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTuple0()
{
var markup = """
using System;
class C
{
protected ($$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task TupleInMethod0()
{
var markup = """
using System;
class C
{
void M()
{
($$
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task TupleInMethod1()
{
var markup = """
using System;
class C
{
void M()
{
var a = 0;
($$
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task TupleInMethod2()
{
var markup = """
using System;
class C
{
void M()
{
($$)
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task TupleInMethod3()
{
var markup = """
using System;
class C
{
void M()
{
var a = 0;
(T$$)
a = 1;
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTupleNot0()
{
var markup = """
using System;
class C
{
protected sealed (int $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTuple1()
{
var markup = """
using System;
class C
{
sealed (int, $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTupleNot1()
{
var markup = """
using System;
class C
{
virtual (int x, C $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTupleGeneric0()
{
var markup = """
using System;
class C
{
(Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTupleGeneric1()
{
var markup = """
using System;
class C
{
(int, Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InTupleGeneric2()
{
var markup = """
using System;
class C
{
(int, Func<int, $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple0()
{
var markup = """
using System;
class C
{
Func<($$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple1()
{
var markup = """
using System;
class C
{
Func<int, ($$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple1Not()
{
var markup = """
using System;
class C
{
Func<int, (T $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple2()
{
var markup = """
using System;
class C
{
Func<(int, $$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple2Not()
{
var markup = """
using System;
class C
{
Func<(C c, int $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple3()
{
var markup = """
using System;
class C
{
Func<int, (int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InGenericTuple3Not()
{
var markup = """
using System;
class C
{
Func<C, (int, C $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric0()
{
var markup = """
using System;
class C
{
ref (Func<System.Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric1()
{
var markup = """
using System;
class C
{
ref (C c, Func<System.Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric2()
{
var markup = """
using System;
class C
{
ref (C c, Func<int, System.Func<(int,T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric3()
{
var markup = """
using System;
class C
{
ref (C c, System.Func<Func<int,(T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric4()
{
var markup = """
using System;
class C
{
ref (System.Func<(int,C), (Func<int,T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric5()
{
var markup = """
using System;
class C
{
ref readonly (System.Func<(int, (C, (Func<int,T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("https://github.com/dotnet/roslyn/issues/37361")]
public async Task InRefTupleQualifiedNestedGeneric6()
{
var markup = """
using System;
class C
{
ref readonly (System.Collections.Generic.List<(int, (C, (Func<int,T$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InNestedGeneric1()
{
var markup = """
using System;
class C
{
Func<Func<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InNestedGeneric2()
{
var markup = """
using System;
class C
{
Func<Func<int,$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InScript()
{
var markup = @"$$";
await VerifyItemExistsAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotAfterVoidInScript()
{
var markup = @"void $$";
await VerifyItemIsAbsentAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotAfterIntInScript()
{
var markup = @"int $$";
await VerifyItemIsAbsentAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InGenericInScript()
{
var markup = """
using System;
Func<$$
""";
await VerifyItemExistsAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InNestedGenericInScript1()
{
var markup = """
using System;
Func<Func<$$
""";
await VerifyItemExistsAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task InNestedGenericInScript2()
{
var markup = """
using System;
Func<Func<int,$$
""";
await VerifyItemExistsAsync(markup, "T", expectedDescriptionOrNull: null, sourceCodeKind: SourceCodeKind.Script);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotInComment()
{
var markup = """
class C
{
// $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotInXmlDocComment()
{
var markup = """
class C
{
/// <summary>
/// $$
/// </summary>
void Goo() { }
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task AfterAsyncTask()
{
var markup = """
using System.Threading.Tasks;
class Program
{
async Task<$$
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotOkAfterAsync()
{
var markup = """
using System.Threading.Tasks;
class Program
{
async $$
}
""";
await VerifyItemIsAbsentAsync(markup, "T");
}
[Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
[WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/968256")]
public async Task UnionOfItemsFromBothContexts()
{
var markup = """
<Workspace>
<Project Language="C#" CommonReferences="true" AssemblyName="Proj1" PreprocessorSymbols="GOO">
<Document FilePath="CurrentDocument.cs"><![CDATA[
class C
{
#if GOO
void goo() {
#endif
$$
#if GOO
}
#endif
}
]]>
</Document>
</Project>
<Project Language="C#" CommonReferences="true" AssemblyName="Proj2">
<Document IsLinkFile="true" LinkAssemblyName="Proj1" LinkFilePath="CurrentDocument.cs"/>
</Project>
</Workspace>
""";
await VerifyItemInLinkedFilesAsync(markup, "T", null);
}
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
[WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1020654")]
public async Task AfterAsyncTaskWithBraceCompletion()
{
var markup = """
using System.Threading.Tasks;
class Program
{
async Task<$$>
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/13480")]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public async Task LocalFunctionReturnType()
{
var markup = """
class C
{
public void M()
{
$$
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/14525")]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public async Task LocalFunctionAfterAyncTask()
{
var markup = """
class C
{
public void M()
{
async Task<$$>
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/14525")]
[CompilerTrait(CompilerFeature.LocalFunctions)]
public async Task LocalFunctionAfterAsync()
{
var markup = """
class C
{
public void M()
{
async $$
}
}
""";
await VerifyItemExistsAsync(markup, "T");
}
}
|