File: CallHierarchy\CSharpCallHierarchyTests.cs
Web Access
Project: src\src\VisualStudio\CSharp\Test\Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.csproj (Microsoft.VisualStudio.LanguageServices.CSharp.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.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.UnitTests.CallHierarchy;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CallHierarchy
{
    [UseExportProvider]
    [Trait(Traits.Feature, Traits.Features.CallHierarchy)]
    public class CSharpCallHierarchyTests
    {
        [WpfFact]
        public async Task InvokeOnMethod()
        {
            var text = @"
namespace N
{
    class C
    {
        void G$$oo()
        {
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()");
        }
 
        [WpfFact]
        public async Task InvokeOnProperty()
        {
            var text = @"
namespace N
{
    class C
    {
        public int G$$oo { get; set;}
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo");
        }
 
        [WpfFact]
        public async Task InvokeOnEvent()
        {
            var text = @"
using System;
namespace N
{
    class C
    {
        public event EventHandler Go$$o;
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo");
        }
 
        [WpfFact]
        public async Task Method_FindCalls()
        {
            var text = @"
namespace N
{
    class C
    {
        void G$$oo()
        {
        }
    }
 
    class G
    {
        void Main()
        {
            var c = new C();
            c.Goo();
        }
 
        void Main2()
        {
            var c = new C();
            c.Goo();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), ["N.G.Main()", "N.G.Main2()"]);
        }
 
        [WpfFact]
        public async Task Method_InterfaceImplementation()
        {
            var text = @"
namespace N
{
    interface I
    {
        void Goo();
    }
 
    class C : I
    {
        public void G$$oo()
        {
        }
    }
 
    class G
    {
        void Main()
        {
            I c = new C();
            c.Goo();
        }
 
        void Main2()
        {
            var c = new C();
            c.Goo();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), string.Format(EditorFeaturesResources.Calls_To_Interface_Implementation_0, "N.I.Goo()")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), ["N.G.Main2()"]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_Interface_Implementation_0, "N.I.Goo()"), ["N.G.Main()"]);
        }
 
        [WpfFact]
        public async Task Method_CallToOverride()
        {
            var text = @"
namespace N
{
    class C
    {
        protected virtual void G$$oo() { }
    }
 
    class D : C
    {
        protected override void Goo() { }
 
        void Bar()
        {
            C c; 
            c.Goo()
        }
 
        void Baz()
        {
            D d;
            d.Goo();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), EditorFeaturesResources.Calls_To_Overrides]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), ["N.D.Bar()"]);
            testState.VerifyResult(root, EditorFeaturesResources.Calls_To_Overrides, ["N.D.Baz()"]);
        }
 
        [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/829705")]
        public async Task Method_CallToBase()
        {
            var text = @"
namespace N
{
    class C
    {
        protected virtual void Goo() { }
    }
 
    class D : C
    {
        protected override void Goo() { }
 
        void Bar()
        {
            C c; 
            c.Goo()
        }
 
        void Baz()
        {
            D d;
            d.Go$$o();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.D.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), string.Format(EditorFeaturesResources.Calls_To_Base_Member_0, "N.C.Goo()")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), ["N.D.Baz()"]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_Base_Member_0, "N.C.Goo()"), ["N.D.Bar()"]);
        }
 
        [WpfFact]
        public async Task FieldInitializers()
        {
            var text = @"
namespace N
{
    class C
    {
        public int goo = Goo();
 
        protected int Goo$$() { return 0; }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo")]);
            testState.VerifyResultName(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), [EditorFeaturesResources.Initializers]);
        }
 
        [WpfFact]
        public async Task FieldReferences()
        {
            var text = @"
namespace N
{
    class C
    {
        public int g$$oo;
 
        protected void Goo() { goo = 3; }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.goo", [string.Format(EditorFeaturesResources.References_To_Field_0, "goo")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.References_To_Field_0, "goo"), ["N.C.Goo()"]);
        }
 
        [WpfFact]
        public async Task PropertyGet()
        {
            var text = @"
namespace N
{
    class C
    {
        public int val
        {
            g$$et
            {
                return 0;
            }
        }
 
        public int goo()
        {
            var x = this.val;
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.val.get", [string.Format(EditorFeaturesResources.Calls_To_0, "get_val")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "get_val"), ["N.C.goo()"]);
        }
 
        [WpfFact]
        public async Task Generic()
        {
            var text = @"
namespace N
{
    class C
    {
        public int gen$$eric<T>(this string generic, ref T stuff)
        {
            return 0;
        }
 
        public int goo()
        {
            int i;
            generic("", ref i);
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.generic<T>(this string, ref T)", [string.Format(EditorFeaturesResources.Calls_To_0, "generic")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "generic"), ["N.C.goo()"]);
        }
 
        [WpfFact]
        public async Task ExtensionMethods()
        {
            var text = @"
namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            var x = ""string"";
            x.BarStr$$ing();
        }
    }
    
    public static class Extensions
    {
        public static string BarString(this string s)
        {
            return s;
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "ConsoleApplication10.Extensions.BarString(this string)", [string.Format(EditorFeaturesResources.Calls_To_0, "BarString")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "BarString"), ["ConsoleApplication10.Program.Main(string[])"]);
        }
 
        [WpfFact]
        public async Task GenericExtensionMethods()
        {
            var text = @"
using System.Collections.Generic;
using System.Linq;
namespace N
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> x = new List<int>();
            var z = x.Si$$ngle();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "System.Linq.Enumerable.Single<TSource>(this System.Collections.Generic.IEnumerable<TSource>)", [string.Format(EditorFeaturesResources.Calls_To_0, "Single")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Single"), ["N.Program.Main(string[])"]);
        }
 
        [WpfFact]
        public async Task InterfaceImplementors()
        {
            var text = @"
namespace N
{
    interface I
    {
        void Go$$o();
    }
 
    class C : I
    {
        public void Goo()
        {
        }
    }
 
    class G
    {
        void Main()
        {
            I c = new C();
            c.Goo();
        }
 
        void Main2()
        {
            var c = new C();
            c.Goo();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.I.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), string.Format(EditorFeaturesResources.Implements_0, "Goo")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), ["N.G.Main()"]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Implements_0, "Goo"), ["N.C.Goo()"]);
        }
 
        [WpfFact]
        public async Task NoFindOverridesOnSealedMethod()
        {
            var text = @"
namespace N
{
    class C
    {
        void G$$oo()
        {
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            Assert.DoesNotContain("Overrides", root.SupportedSearchCategories.Select(s => s.DisplayName));
        }
 
        [WpfFact]
        public async Task FindOverrides()
        {
            var text = @"
namespace N
{
    class C
    {
        public virtual void G$$oo()
        {
        }
    }
 
    class G : C
    {
        public override void Goo()
        {
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), EditorFeaturesResources.Overrides_]);
            testState.VerifyResult(root, EditorFeaturesResources.Overrides_, ["N.G.Goo()"]);
        }
 
        [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/844613")]
        public async Task AbstractMethodInclusionToOverrides()
        {
            var text = @"
using System;
 
abstract class Base
{
    public abstract void $$M();
}
 
class Derived : Base
{
    public override void M()
    {
        throw new NotImplementedException();
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "Base.M()", [string.Format(EditorFeaturesResources.Calls_To_0, "M"), EditorFeaturesResources.Overrides_, EditorFeaturesResources.Calls_To_Overrides]);
            testState.VerifyResult(root, EditorFeaturesResources.Overrides_, ["Derived.M()"]);
        }
 
        [WpfFact]
        public async Task SearchAfterEditWorks()
        {
            var text = @"
namespace N
{
    class C
    {
        void G$$oo()
        {
        }
 
        void M()
        {   
            Goo();
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(text);
            var root = await testState.GetRootAsync();
 
            testState.Workspace.Documents.Single().GetTextBuffer().Insert(0, "/* hello */");
 
            testState.VerifyRoot(root, "N.C.Goo()", [string.Format(EditorFeaturesResources.Calls_To_0, "Goo"),]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "Goo"), expectedCallers: ["N.C.M()"]);
        }
 
        [WpfFact, WorkItem("https://github.com/dotnet/roslyn/issues/57856")]
        public async Task PropertySet()
        {
            var code = @"
namespace N
{
    class C
    {
        public int Property { get; s$$et; }
        void M()
        {
            Property = 2;
        }
    }
}";
            using var testState = CallHierarchyTestState.Create(code);
            var root = await testState.GetRootAsync();
            testState.VerifyRoot(root, "N.C.Property.set", [string.Format(EditorFeaturesResources.Calls_To_0, "set_Property")]);
            testState.VerifyResult(root, string.Format(EditorFeaturesResources.Calls_To_0, "set_Property"), ["N.C.M()"]);
        }
    }
}