File: SignatureHelp\GenericNameSignatureHelpProviderTests.cs
Web Access
Project: src\src\EditorFeatures\CSharpTest\Microsoft.CodeAnalysis.CSharp.EditorFeatures.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.EditorFeatures.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.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.SignatureHelp;
using Microsoft.CodeAnalysis.Editor.UnitTests.SignatureHelp;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SignatureHelp;
 
[Trait(Traits.Feature, Traits.Features.SignatureHelp)]
public class GenericNameSignatureHelpProviderTests : AbstractCSharpSignatureHelpProviderTests
{
    internal override Type GetSignatureHelpProviderType()
        => typeof(GenericNameSignatureHelpProvider);
 
    #region "Declaring generic type objects"
 
    [Fact]
    public async Task NestedGenericTerminated()
    {
        var markup = """
            class G<T> { };
 
            class C
            {
                void Goo()
                {
                    G<G<int>$$>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWith1ParameterTerminated()
    {
        var markup = """
            class G<T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWith2ParametersOn1()
    {
        var markup = """
            class G<S, T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWith2ParametersOn2()
    {
        var markup = """
            class G<S, T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<int, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T>", string.Empty, string.Empty, currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWith2ParametersOn1XmlDoc()
    {
        var markup = """
            /// <summary>
            /// Summary for G
            /// </summary>
            /// <typeparam name="S">TypeParamS. Also see <see cref="T"/></typeparam>
            /// <typeparam name="T">TypeParamT</typeparam>
            class G<S, T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T>",
                "Summary for G",
                "TypeParamS. Also see T",
                currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWith2ParametersOn2XmlDoc()
    {
        var markup = """
            /// <summary>
            /// Summary for G
            /// </summary>
            /// <typeparam name="S">TypeParamS</typeparam>
            /// <typeparam name="T">TypeParamT. Also see <see cref="S"/></typeparam>
            class G<S, T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<int, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T>", "Summary for G", "TypeParamT. Also see S", currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    #endregion
 
    #region "Constraints on generic types"
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsStruct()
    {
        var markup = """
            class G<S> where S : struct
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : struct", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsClass()
    {
        var markup = """
            class G<S> where S : class
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : class", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsNew()
    {
        var markup = """
            class G<S> where S : new()
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : new()", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsBase()
    {
        var markup = """
            class Base { }
 
            class G<S> where S : Base
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : Base", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsBaseGenericWithGeneric()
    {
        var markup = """
            class Base<T> { }
 
            class G<S> where S : Base<S>
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : Base<S>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsBaseGenericWithNonGeneric()
    {
        var markup = """
            class Base<T> { }
 
            class G<S> where S : Base<int>
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : Base<int>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsBaseGenericNested()
    {
        var markup = """
            class Base<T> { }
 
            class G<S> where S : Base<Base<int>>
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : Base<Base<int>>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsDeriveFromAnotherGenericParameter()
    {
        var markup = """
            class G<S, T> where S : T
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T> where S : T", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsMixed1()
    {
        var markup = """
            /// <summary>
            /// Summary1
            /// </summary>
            /// <typeparam name="S">SummaryS</typeparam>
            /// <typeparam name="T">SummaryT</typeparam>
            class G<S, T>
                where S : Base, new()
                where T : class, S, IGoo, new()
            { };
 
            internal interface IGoo { }
 
            internal class Base { }
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T> where S : Base, new()", "Summary1", "SummaryS", currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsMixed2()
    {
        var markup = """
            /// <summary>
            /// Summary1
            /// </summary>
            /// <typeparam name="S">SummaryS</typeparam>
            /// <typeparam name="T">SummaryT</typeparam>
            class G<S, T>
                where S : Base, new()
                where T : class, S, IGoo, new()
            { };
 
            internal interface IGoo { }
 
            internal class Base { }
 
            class C
            {
                void Goo()
                {
                    [|G<bar, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T> where T : class, S, IGoo, new()", "Summary1", "SummaryT", currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task DeclaringGenericTypeWithConstraintsAllowRefStruct()
    {
        var markup = """
            class G<S> where S : allows ref struct
            { };
 
            class C
            {
                void Goo()
                {
                    [|G<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S> where S : allows ref struct", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    #endregion
 
    #region "Generic member invocation"
 
    [Fact]
    public async Task InvokingGenericMethodWith1ParameterTerminated()
    {
        var markup = """
            class C
            {
                void Goo<T>() { }
 
                void Bar()
                {
                    [|Goo<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.Goo<T>()", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWith2ParametersOn1()
    {
        var markup = """
            class C
            {
                /// <summary>
                /// Method summary
                /// </summary>
                /// <typeparam name="S" > type param S. see <see cref="T"/> </typeparam>
                /// <typeparam name="T">type param T. </typeparam>
                /// <param name="s">parameter s</param>
                /// <param name="t">parameter t</param>
                void Goo<S, T>(S s, T t) { }
 
                void Bar()
                {
                    [|Goo<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.Goo<S, T>(S s, T t)",
                "Method summary", "type param S. see T", currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWith2ParametersOn2()
    {
        var markup = """
            class C
            {
                void Goo<S, T>(S s, T t) { }
 
                void Bar()
                {
                    [|Goo<int, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.Goo<S, T>(S s, T t)", string.Empty, string.Empty, currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWith2ParametersOn1XmlDoc()
    {
        var markup = """
            class C
            {
                /// <summary>
                /// SummaryForGoo
                /// </summary>
                /// <typeparam name="S">SummaryForS</typeparam>
                /// <typeparam name="T">SummaryForT</typeparam>
                void Goo<S, T>(S s, T t) { }
 
                void Bar()
                {
                    [|Goo<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.Goo<S, T>(S s, T t)", "SummaryForGoo", "SummaryForS", currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWith2ParametersOn2XmlDoc()
    {
        var markup = """
            class C
            {
                /// <summary>
                /// SummaryForGoo
                /// </summary>
                /// <typeparam name="S">SummaryForS</typeparam>
                /// <typeparam name="T">SummaryForT</typeparam>
                void Goo<S, T>(S s, T t) { }
 
                void Bar()
                {
                    [|Goo<int, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.Goo<S, T>(S s, T t)", "SummaryForGoo", "SummaryForT", currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task CallingGenericExtensionMethod()
    {
        var markup = """
            class G
            { };
 
            class C
            {
                void Bar()
                {
                    G g = null;
                    g.[|Goo<$$|]>
                }
            }
 
            static class GooClass
            {
                public static void Goo<T>(this G g) { }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem($"({CSharpFeaturesResources.extension}) void G.Goo<T>()", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        // TODO: Enable the script case when we have support for extension methods in scripts
        await TestAsync(markup, expectedOrderedItems, usePreviousCharAsTrigger: false, sourceCodeKind: Microsoft.CodeAnalysis.SourceCodeKind.Regular);
    }
 
    #endregion
 
    #region "Constraints on generic methods"
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWithConstraintsMixed1()
    {
        var markup = """
            class Base { }
            interface IGoo { }
 
            class C
            {
                /// <summary>
                /// GooSummary
                /// </summary>
                /// <typeparam name="S">ParamS</typeparam>
                /// <typeparam name="T">ParamT</typeparam>
                S Goo<S, T>(S s, T t)
                    where S : Base, new()
                    where T : class, S, IGoo, new()
                { return null; }
 
                void Bar()
                {
                    [|Goo<$$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("S C.Goo<S, T>(S s, T t) where S : Base, new()", "GooSummary", "ParamS", currentParameterIndex: 0)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544091")]
    public async Task InvokingGenericMethodWithConstraintsMixed2()
    {
        var markup = """
            class Base { }
            interface IGoo { }
 
            class C
            {
                /// <summary>
                /// GooSummary
                /// </summary>
                /// <typeparam name="S">ParamS</typeparam>
                /// <typeparam name="T">ParamT</typeparam>
                S Goo<S, T>(S s, T t)
                    where S : Base, new()
                    where T : class, S, IGoo, new()
                { return null; }
 
                void Bar()
                {
                    [|Goo<Base, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("S C.Goo<S, T>(S s, T t) where T : class, S, IGoo, new()", "GooSummary", "ParamT", currentParameterIndex: 1)
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact]
    public async Task TestUnmanagedConstraint()
    {
        var markup = """
            class C
            {
                /// <summary>
                /// summary headline
                /// </summary>
                /// <typeparam name="T">T documentation</typeparam>
                void M<T>(T arg) where T : unmanaged
                {
                }
 
                void Bar()
                {
                    [|M<$$|]>
                }
            }
            """;
 
        await TestAsync(markup, new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("void C.M<T>(T arg) where T : unmanaged", "summary headline", "T documentation", currentParameterIndex: 0)
        });
    }
 
    #endregion
 
    #region "Trigger tests"
 
    [Fact]
    public void TestTriggerCharacters()
    {
        char[] expectedCharacters = [',', '<'];
        char[] unexpectedCharacters = [' ', '[', '('];
 
        VerifyTriggerCharacters(expectedCharacters, unexpectedCharacters);
    }
 
    [Fact]
    public async Task FieldUnavailableInOneLinkedFile()
    {
        var markup = """
            <Workspace>
                <Project Language="C#" CommonReferences="true" AssemblyName="Proj1" PreprocessorSymbols="GOO">
                    <Document FilePath="SourceDocument"><![CDATA[
            class C
            {
            #if GOO
                class D<T>
                {
                }
            #endif
                void goo()
                {
                    var x = new D<$$
                }
            }
            ]]>
                    </Document>
                </Project>
                <Project Language="C#" CommonReferences="true" AssemblyName="Proj2">
                    <Document IsLinkFile="true" LinkAssemblyName="Proj1" LinkFilePath="SourceDocument"/>
                </Project>
            </Workspace>
            """;
        var expectedDescription = new SignatureHelpTestItem($"D<T>\r\n\r\n{string.Format(FeaturesResources._0_1, "Proj1", FeaturesResources.Available)}\r\n{string.Format(FeaturesResources._0_1, "Proj2", FeaturesResources.Not_Available)}\r\n\r\n{FeaturesResources.You_can_use_the_navigation_bar_to_switch_contexts}", currentParameterIndex: 0);
        await VerifyItemWithReferenceWorkerAsync(markup, [expectedDescription], false);
    }
 
    [Fact]
    public async Task ExcludeFilesWithInactiveRegions()
    {
        var markup = """
            <Workspace>
                <Project Language="C#" CommonReferences="true" AssemblyName="Proj1" PreprocessorSymbols="GOO,BAR">
                    <Document FilePath="SourceDocument"><![CDATA[
            class C
            {
            #if GOO
                class D<T>
                {
                }
            #endif
 
            #if BAR
                void goo()
                {
                    var x = new D<$$
                }
            #endif
            }
            ]]>
                    </Document>
                </Project>
                <Project Language="C#" CommonReferences="true" AssemblyName="Proj2">
                    <Document IsLinkFile="true" LinkAssemblyName="Proj1" LinkFilePath="SourceDocument" />
                </Project>
                <Project Language="C#" CommonReferences="true" AssemblyName="Proj3" PreprocessorSymbols="BAR">
                    <Document IsLinkFile="true" LinkAssemblyName="Proj1" LinkFilePath="SourceDocument"/>
                </Project>
            </Workspace>
            """;
 
        var expectedDescription = new SignatureHelpTestItem($"D<T>\r\n\r\n{string.Format(FeaturesResources._0_1, "Proj1", FeaturesResources.Available)}\r\n{string.Format(FeaturesResources._0_1, "Proj3", FeaturesResources.Not_Available)}\r\n\r\n{FeaturesResources.You_can_use_the_navigation_bar_to_switch_contexts}", currentParameterIndex: 0);
        await VerifyItemWithReferenceWorkerAsync(markup, [expectedDescription], false);
    }
 
    #endregion
 
    #region "EditorBrowsable tests"
 
    [Fact, WorkItem(7336, "DevDiv_Projects/Roslyn")]
    public async Task EditorBrowsable_GenericType_BrowsableAlways()
    {
        var markup = """
            class Program
            {
                void M()
                {
                    var c = new C<$$
                }
            }
            """;
 
        var referencedCode = """
            [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Always)]
            public class C<T>
            {
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("C<T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestSignatureHelpInEditorBrowsableContextsAsync(markup: markup,
                                                   referencedCode: referencedCode,
                                                   expectedOrderedItemsMetadataReference: expectedOrderedItems,
                                                   expectedOrderedItemsSameSolution: expectedOrderedItems,
                                                   sourceLanguage: LanguageNames.CSharp,
                                                   referencedLanguage: LanguageNames.CSharp);
    }
 
    [Fact, WorkItem(7336, "DevDiv_Projects/Roslyn")]
    public async Task EditorBrowsable_GenericType_BrowsableNever()
    {
        var markup = """
            class Program
            {
                void M()
                {
                    var c = new C<$$
                }
            }
            """;
 
        var referencedCode = """
            [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
            public class C<T>
            {
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("C<T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestSignatureHelpInEditorBrowsableContextsAsync(markup: markup,
                                                   referencedCode: referencedCode,
                                                   expectedOrderedItemsMetadataReference: new List<SignatureHelpTestItem>(),
                                                   expectedOrderedItemsSameSolution: expectedOrderedItems,
                                                   sourceLanguage: LanguageNames.CSharp,
                                                   referencedLanguage: LanguageNames.CSharp);
    }
 
    [Fact, WorkItem(7336, "DevDiv_Projects/Roslyn")]
    public async Task EditorBrowsable_GenericType_BrowsableAdvanced()
    {
        var markup = """
            class Program
            {
                void M()
                {
                    var c = new C<$$
                }
            }
            """;
 
        var referencedCode = """
            [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)]
            public class C<T>
            {
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("C<T>", string.Empty, string.Empty, currentParameterIndex: 0)
        };
 
        await TestSignatureHelpInEditorBrowsableContextsAsync(markup: markup,
                                                   referencedCode: referencedCode,
                                                   expectedOrderedItemsMetadataReference: new List<SignatureHelpTestItem>(),
                                                   expectedOrderedItemsSameSolution: expectedOrderedItems,
                                                   sourceLanguage: LanguageNames.CSharp,
                                                   referencedLanguage: LanguageNames.CSharp,
                                                   hideAdvancedMembers: true);
 
        await TestSignatureHelpInEditorBrowsableContextsAsync(markup: markup,
                                                   referencedCode: referencedCode,
                                                   expectedOrderedItemsMetadataReference: expectedOrderedItems,
                                                   expectedOrderedItemsSameSolution: expectedOrderedItems,
                                                   sourceLanguage: LanguageNames.CSharp,
                                                   referencedLanguage: LanguageNames.CSharp,
                                                   hideAdvancedMembers: false);
    }
    #endregion
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1083601")]
    public async Task DeclaringGenericTypeWithBadTypeArgumentList()
    {
        var markup = """
            class G<T> { };
 
            class C
            {
                void Goo()
                {
                    G{$$>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>();
        await TestAsync(markup, expectedOrderedItems);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/50114")]
    public async Task DeclaringGenericTypeWithDocCommentList()
    {
        var markup = """
            /// <summary>
            /// List:
            /// <list>
            /// <item>
            /// <description>
            /// Item 1.
            /// </description>
            /// </item>
            /// </list>
            /// </summary>
            class G<S, T> { };
 
            class C
            {
                void Goo()
                {
                    [|G<int, $$|]>
                }
            }
            """;
 
        var expectedOrderedItems = new List<SignatureHelpTestItem>
        {
            new SignatureHelpTestItem("G<S, T>", """
            List:
 
            Item 1.
            """,
            classificationTypeNames: ImmutableArray.Create(
                ClassificationTypeNames.Text,
                ClassificationTypeNames.WhiteSpace,
                ClassificationTypeNames.WhiteSpace,
                ClassificationTypeNames.WhiteSpace,
                ClassificationTypeNames.Text,
                ClassificationTypeNames.WhiteSpace))
        };
 
        await TestAsync(markup, expectedOrderedItems);
    }
}