File: InheritanceMargin\InheritanceMarginTests.cs
Web Access
Project: src\src\EditorFeatures\Test\Microsoft.CodeAnalysis.EditorFeatures.UnitTests.csproj (Microsoft.CodeAnalysis.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.
 
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.InheritanceMargin;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Remote.Testing;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.VisualBasic;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.UnitTests.InheritanceMargin;
 
[Trait(Traits.Feature, Traits.Features.InheritanceMargin)]
[UseExportProvider]
public class InheritanceMarginTests
{
    private const string SearchAreaTag = nameof(SearchAreaTag);
    private static readonly TestComposition s_inProcessComposition = EditorTestCompositions.EditorFeatures;
    private static readonly TestComposition s_outOffProcessComposition = s_inProcessComposition.WithTestHostParts(TestHost.OutOfProcess);
 
    #region Helpers
 
    private static Task VerifyNoItemForDocumentAsync(string markup, string languageName, TestHost testHost)
        => VerifyInSingleDocumentAsync(markup, languageName, testHost);
 
    private static async Task VerifyInSingleDocumentAsync(
        string markup,
        string languageName,
        TestHost testHost,
        params TestInheritanceMemberItem[] memberItems)
    {
        markup = @$"<![CDATA[
{markup}]]>";
 
        var workspaceFile = $@"
<Workspace>
   <Project Language=""{languageName}"" CommonReferences=""true"">
       <Document>
            {markup}
       </Document>
   </Project>
</Workspace>";
 
        var cancellationToken = CancellationToken.None;
 
        using var testWorkspace = TestWorkspace.Create(
            workspaceFile,
            composition: testHost == TestHost.InProcess ? s_inProcessComposition : s_outOffProcessComposition);
 
        var testHostDocument = testWorkspace.Documents[0];
        await VerifyTestMemberInDocumentAsync(testWorkspace, testHostDocument, memberItems, cancellationToken).ConfigureAwait(false);
    }
 
    private static async Task VerifyInMultipleDocumentsAsync(
        string markup1,
        string markup2,
        string languageName,
        TestHost testHost,
        params TestInheritanceMemberItem[] memberItems)
    {
        var workspaceFile = $@"
<Workspace>
   <Project Language=""{languageName}"" CommonReferences=""true"">
       <Document>
            <![CDATA[{markup1}]]>
       </Document>
       <Document>
            <![CDATA[{markup2}]]>
       </Document>
   </Project>
</Workspace>";
 
        var cancellationToken = CancellationToken.None;
 
        using var testWorkspace = TestWorkspace.Create(
            workspaceFile,
            composition: testHost == TestHost.InProcess ? s_inProcessComposition : s_outOffProcessComposition);
 
        var testHostDocument = testWorkspace.Documents[0];
        await VerifyTestMemberInDocumentAsync(testWorkspace, testHostDocument, memberItems, cancellationToken).ConfigureAwait(false);
    }
 
    private static async Task VerifyTestMemberInDocumentAsync(
        TestWorkspace testWorkspace,
        TestHostDocument testHostDocument,
        TestInheritanceMemberItem[] memberItems,
        CancellationToken cancellationToken)
    {
        var document = testWorkspace.CurrentSolution.GetRequiredDocument(testHostDocument.Id);
        var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
        var searchingSpan = root.Span;
        // Look for the search span, if not found, then pass the whole document span to the service.
        if (testHostDocument.AnnotatedSpans.TryGetValue(SearchAreaTag, out var spans) && spans.IsSingle())
        {
            searchingSpan = spans[0];
        }
 
        var service = document.GetRequiredLanguageService<IInheritanceMarginService>();
        var actualItems = await service.GetInheritanceMemberItemsAsync(
            document,
            searchingSpan,
            includeGlobalImports: true,
            frozenPartialSemantics: true,
            cancellationToken).ConfigureAwait(false);
 
        var sortedActualItems = actualItems.OrderBy(item => item.LineNumber).ToImmutableArray();
        var sortedExpectedItems = memberItems.OrderBy(item => item.LineNumber).ToImmutableArray();
        Assert.Equal(sortedExpectedItems.Length, sortedActualItems.Length);
 
        for (var i = 0; i < sortedActualItems.Length; i++)
        {
            await VerifyInheritanceMemberAsync(testWorkspace, sortedExpectedItems[i], sortedActualItems[i]);
        }
    }
 
    private static async Task VerifyInheritanceMemberAsync(TestWorkspace testWorkspace, TestInheritanceMemberItem expectedItem, InheritanceMarginItem actualItem)
    {
        Assert.True(!actualItem.TargetItems.IsEmpty);
        Assert.Equal(expectedItem.LineNumber, actualItem.LineNumber);
        Assert.Equal(expectedItem.MemberName, actualItem.DisplayTexts.JoinText());
        Assert.Equal(expectedItem.Targets.Length, actualItem.TargetItems.Length);
        var expectedTargets = expectedItem.Targets
            .Select(info => TestInheritanceTargetItem.Create(info, testWorkspace))
            .OrderBy(target => target.TargetSymbolName)
            .ToImmutableArray();
 
        for (var i = 0; i < expectedTargets.Length; i++)
            await VerifyInheritanceTargetAsync(testWorkspace, expectedTargets[i], actualItem.TargetItems[i]);
    }
 
    private static async Task VerifyInheritanceTargetAsync(Workspace workspace, TestInheritanceTargetItem expectedTarget, InheritanceTargetItem actualTarget)
    {
        Assert.Equal(expectedTarget.TargetSymbolName, actualTarget.DisplayName);
        Assert.Equal(expectedTarget.RelationshipToMember, actualTarget.RelationToMember);
 
        if (expectedTarget.LanguageGlyph != null)
            Assert.Equal(expectedTarget.LanguageGlyph, actualTarget.LanguageGlyph);
 
        if (expectedTarget.ProjectName != null)
            Assert.Equal(expectedTarget.ProjectName, actualTarget.ProjectName);
 
        if (expectedTarget.IsInMetadata)
        {
            Assert.True(actualTarget.DefinitionItem.Properties.ContainsKey("MetadataSymbolKey"));
            Assert.True(actualTarget.DefinitionItem.SourceSpans.IsEmpty);
        }
        else
        {
            var actualDocumentSpans = actualTarget.DefinitionItem.SourceSpans.OrderBy(documentSpan => documentSpan.SourceSpan.Start).ToImmutableArray();
            var expectedDocumentSpans = expectedTarget.DocumentSpans.OrderBy(documentSpan => documentSpan.SourceSpan.Start).ToImmutableArray();
            Assert.Equal(expectedDocumentSpans.Length, actualDocumentSpans.Length);
            for (var i = 0; i < actualDocumentSpans.Length; i++)
            {
                var docSpan = await actualDocumentSpans[i].TryRehydrateAsync(workspace.CurrentSolution, CancellationToken.None);
                Assert.Equal(expectedDocumentSpans[i].SourceSpan, docSpan.Value.SourceSpan);
                Assert.Equal(expectedDocumentSpans[i].Document.FilePath, docSpan.Value.Document.FilePath);
            }
 
            if (actualDocumentSpans.Length == 1)
            {
                Assert.Empty(actualTarget.DefinitionItem.Tags);
                Assert.Empty(actualTarget.DefinitionItem.Properties);
                Assert.Empty(actualTarget.DefinitionItem.DisplayableProperties);
                Assert.Empty(actualTarget.DefinitionItem.NameDisplayParts);
                Assert.Empty(actualTarget.DefinitionItem.DisplayParts);
            }
        }
    }
 
    /// <summary>
    /// Project of markup1 is referencing project of markup2
    /// </summary>
    private static async Task VerifyInDifferentProjectsAsync(
        (string markupInProject1, string languageName) markup1,
        (string markupInProject2, string languageName) markup2,
        TestInheritanceMemberItem[] memberItemsInMarkup1,
        TestInheritanceMemberItem[] memberItemsInMarkup2,
        TestHost testHost)
    {
        var workspaceFile =
            $@"
<Workspace>
    <Project Language=""{markup1.languageName}"" AssemblyName=""Assembly1"" CommonReferences=""true"">
        <ProjectReference>Assembly2</ProjectReference>
        <Document>
            <![CDATA[
                {markup1.markupInProject1}]]>
        </Document>
    </Project>
    <Project Language=""{markup2.languageName}"" AssemblyName=""Assembly2"" CommonReferences=""true"">
        <Document>
            <![CDATA[
                {markup2.markupInProject2}]]>
        </Document>
    </Project>
</Workspace>";
 
        var cancellationToken = CancellationToken.None;
        using var testWorkspace = TestWorkspace.Create(
            workspaceFile,
            composition: testHost == TestHost.InProcess ? s_inProcessComposition : s_outOffProcessComposition);
 
        var testHostDocument1 = testWorkspace.Documents.Single(doc => doc.Project.AssemblyName.Equals("Assembly1"));
        var testHostDocument2 = testWorkspace.Documents.Single(doc => doc.Project.AssemblyName.Equals("Assembly2"));
        await VerifyTestMemberInDocumentAsync(testWorkspace, testHostDocument1, memberItemsInMarkup1, cancellationToken).ConfigureAwait(false);
        await VerifyTestMemberInDocumentAsync(testWorkspace, testHostDocument2, memberItemsInMarkup2, cancellationToken).ConfigureAwait(false);
    }
 
    private class TestInheritanceMemberItem
    {
        public readonly int LineNumber;
        public readonly string MemberName;
        public readonly ImmutableArray<TargetInfo> Targets;
 
        public TestInheritanceMemberItem(
            int lineNumber,
            string memberName,
            ImmutableArray<TargetInfo> targets)
        {
            LineNumber = lineNumber;
            MemberName = memberName;
            Targets = targets;
        }
 
        public override string ToString()
            => MemberName;
    }
 
    private class TargetInfo
    {
        public readonly string TargetSymbolDisplayName;
        public readonly ImmutableArray<string> LocationTags;
        public readonly InheritanceRelationship Relationship;
        public readonly bool InMetadata;
        public readonly Glyph? LanguageGlyph;
        public readonly string? ProjectName;
 
        public TargetInfo(
            string targetSymbolDisplayName,
            string locationTag,
            InheritanceRelationship relationship,
            Glyph? languageGlyph = null,
            string? projectName = null)
        {
            TargetSymbolDisplayName = targetSymbolDisplayName;
            LocationTags = [locationTag];
            Relationship = relationship;
            LanguageGlyph = languageGlyph;
            InMetadata = false;
            ProjectName = projectName;
        }
 
        public TargetInfo(
            string targetSymbolDisplayName,
            InheritanceRelationship relationship,
            bool inMetadata)
        {
            TargetSymbolDisplayName = targetSymbolDisplayName;
            Relationship = relationship;
            InMetadata = inMetadata;
            LocationTags = ImmutableArray<string>.Empty;
        }
 
        public TargetInfo(
            string targetSymbolDisplayName,
            InheritanceRelationship relationship,
            params string[] locationTags)
        {
            TargetSymbolDisplayName = targetSymbolDisplayName;
            LocationTags = locationTags.ToImmutableArray();
            Relationship = relationship;
        }
    }
 
    private class TestInheritanceTargetItem
    {
        public readonly string TargetSymbolName;
        public readonly InheritanceRelationship RelationshipToMember;
        public readonly ImmutableArray<DocumentSpan> DocumentSpans;
        public readonly bool IsInMetadata;
        public readonly Glyph? LanguageGlyph;
        public readonly string? ProjectName;
 
        public TestInheritanceTargetItem(
            string targetSymbolName,
            InheritanceRelationship relationshipToMember,
            ImmutableArray<DocumentSpan> documentSpans,
            bool isInMetadata,
            Glyph? languageGlyph,
            string? projectName)
        {
            TargetSymbolName = targetSymbolName;
            RelationshipToMember = relationshipToMember;
            DocumentSpans = documentSpans;
            IsInMetadata = isInMetadata;
            LanguageGlyph = languageGlyph;
            ProjectName = projectName;
        }
 
        public static TestInheritanceTargetItem Create(
            TargetInfo targetInfo,
            TestWorkspace testWorkspace)
        {
            if (targetInfo.InMetadata)
            {
                return new TestInheritanceTargetItem(
                    targetInfo.TargetSymbolDisplayName,
                    targetInfo.Relationship,
                    ImmutableArray<DocumentSpan>.Empty,
                    isInMetadata: true,
                    targetInfo.LanguageGlyph,
                    targetInfo.ProjectName);
            }
            else
            {
                using var _ = ArrayBuilder<DocumentSpan>.GetInstance(out var builder);
                // If the target is not in metadata, there must be a location tag to give the span!
                Assert.True(targetInfo.LocationTags != null);
                foreach (var testHostDocument in testWorkspace.Documents)
                {
                    if (targetInfo.LocationTags != null)
                    {
                        var annotatedSpans = testHostDocument.AnnotatedSpans;
 
                        foreach (var tag in targetInfo.LocationTags)
                        {
                            if (annotatedSpans.TryGetValue(tag, out var spans))
                            {
                                var document = testWorkspace.CurrentSolution.GetRequiredDocument(testHostDocument.Id);
                                builder.AddRange(spans.Select(span => new DocumentSpan(document, span)));
                            }
                        }
                    }
                }
 
                return new TestInheritanceTargetItem(
                    targetInfo.TargetSymbolDisplayName,
                    targetInfo.Relationship,
                    builder.ToImmutable(),
                    isInMetadata: false,
                    targetInfo.LanguageGlyph,
                    targetInfo.ProjectName);
            }
        }
    }
 
    #endregion
 
    #region TestsForCSharp
 
    [Theory, CombinatorialData]
    public Task TestCSharpClassWithErrorBaseType(TestHost testHost)
    {
        var markup = @"
public class Bar : SomethingUnknown
{
}";
        return VerifyNoItemForDocumentAsync(markup, LanguageNames.CSharp, testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpReferencingMetadata(TestHost testHost)
    {
        var markup = @"
using System.Collections;
public class Bar : IEnumerable
{
    public IEnumerator GetEnumerator () { return null };
}";
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IEnumerable",
                    relationship: InheritanceRelationship.ImplementedInterface,
                    inMetadata: true)]);
 
        var itemForGetEnumerator = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "IEnumerator Bar.GetEnumerator()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IEnumerable.GetEnumerator",
                    relationship: InheritanceRelationship.ImplementedMember,
                    inMetadata: true)]);
 
        return VerifyInSingleDocumentAsync(markup, LanguageNames.CSharp, testHost, itemForBar, itemForGetEnumerator);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpClassImplementingInterface(TestHost testHost)
    {
        var markup = @"
interface {|target1:IBar|} { }
public class {|target2:Bar|} : IBar
{
}
            ";
 
        var itemOnLine2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemOnLine3 = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemOnLine2,
            itemOnLine3);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpInterfaceImplementingInterface(TestHost testHost)
    {
        var markup = @"
        interface {|target1:IBar|} { }
        interface {|target2:IBar2|} : IBar { }
                    ";
 
        var itemOnLine2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar2",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingType)]
            );
        var itemOnLine3 = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "interface IBar2",
            targets: ImmutableArray<TargetInfo>.Empty
                .Add(new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.InheritedInterface))
            );
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemOnLine2,
            itemOnLine3);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpClassInheritsClass(TestHost testHost)
    {
        var markup = @"
        class {|target2:A|} { }
        class {|target1:B|} : A { }
                    ";
 
        var itemOnLine2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "class A",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "B",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.DerivedType)]
        );
        var itemOnLine3 = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "class B",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "A",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.BaseType)]
        );
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemOnLine2,
            itemOnLine3);
    }
 
    [Theory]
    [InlineData("class", TestHost.InProcess)]
    [InlineData("class", TestHost.OutOfProcess)]
    [InlineData("struct", TestHost.InProcess)]
    [InlineData("struct", TestHost.OutOfProcess)]
    [InlineData("enum", TestHost.InProcess)]
    [InlineData("enum", TestHost.OutOfProcess)]
    [InlineData("interface", TestHost.InProcess)]
    [InlineData("interface", TestHost.OutOfProcess)]
    public Task TestCSharpTypeWithoutBaseType(string typeName, TestHost testHost)
    {
        var markup = $@"
        public {typeName} Bar
        {{
        }}";
        return VerifyNoItemForDocumentAsync(markup, LanguageNames.CSharp, testHost);
    }
 
    [Theory]
    [InlineData("public Bar() { }", TestHost.InProcess)]
    [InlineData("public Bar() { }", TestHost.OutOfProcess)]
    [InlineData("public static void Bar3() { }", TestHost.InProcess)]
    [InlineData("public static void Bar3() { }", TestHost.OutOfProcess)]
    [InlineData("public static void ~Bar() { }", TestHost.InProcess)]
    [InlineData("public static void ~Bar() { }", TestHost.OutOfProcess)]
    [InlineData("public static Bar operator +(Bar a, Bar b) => new Bar();", TestHost.InProcess)]
    [InlineData("public static Bar operator +(Bar a, Bar b) => new Bar();", TestHost.OutOfProcess)]
    public Task TestCSharpSpecialMember(string memberDeclaration, TestHost testHost)
    {
        var markup = $@"
        public abstract class {{|target1:Bar1|}}
        {{}}
        public class {{|{SearchAreaTag}:Bar : Bar1
        {{
            {{{memberDeclaration}|}}
        }}";
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            new TestInheritanceMemberItem(
                lineNumber: 4,
                memberName: "class Bar",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "Bar1",
                        locationTag: "target1",
                        relationship: InheritanceRelationship.BaseType)]));
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpEventDeclaration(TestHost testHost)
    {
        var markup = @"
        using System;
        interface {|target2:IBar|}
        {
            event EventHandler {|target4:e|};
        }
        public class {|target1:Bar|} : IBar
        {
            public event EventHandler {|target3:e|}
            {
                add {} remove {}
            }
        }";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForEventInInterface = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "event EventHandler IBar.e",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar.e",
                locationTag: "target3",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForEventInClass = new TestInheritanceMemberItem(
            lineNumber: 9,
            memberName: "event EventHandler Bar.e",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar.e",
                locationTag: "target4",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForIBar,
            itemForBar,
            itemForEventInInterface,
            itemForEventInClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpEventFieldDeclarations(TestHost testHost)
    {
        var markup = @"using System;
        interface {|target2:IBar|}
        {
            event EventHandler {|target5:e1|}, {|target6:e2|};
        }
        public class {|target1:Bar|} : IBar
        {
            public event EventHandler {|target3:e1|}, {|target4:e2|};
        }";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForE1InInterface = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "event EventHandler IBar.e1",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar.e1",
                locationTag: "target3",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForE2InInterface = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "event EventHandler IBar.e2",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar.e2",
                locationTag: "target4",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForE1InClass = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "event EventHandler Bar.e1",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar.e1",
                locationTag: "target5",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForE2InClass = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "event EventHandler Bar.e2",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar.e2",
                locationTag: "target6",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForIBar,
            itemForBar,
            itemForE1InInterface,
            itemForE2InInterface,
            itemForE1InClass,
            itemForE2InClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpInterfaceMembers(TestHost testHost)
    {
        var markup = @"using System;
        interface {|target1:IBar|}
        {
            void {|target4:Foo|}();
            int {|target6:Poo|} { get; set; }
            event EventHandler {|target8:Eoo|};
            int {|target9:this|}[int i] { get; set; }
        }
        public class {|target2:Bar|} : IBar
        {
            public void {|target3:Foo|}() { }
            public int {|target5:Poo|} { get; set; }
            public event EventHandler {|target7:Eoo|};
            public int {|target10:this|}[int i] { get => 1; set { } }
        }";
        var itemForEooInClass = new TestInheritanceMemberItem(
            lineNumber: 13,
            memberName: "event EventHandler Bar.Eoo",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.Eoo",
                    locationTag: "target8",
                    relationship: InheritanceRelationship.ImplementedMember)]
            );
 
        var itemForEooInInterface = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "event EventHandler IBar.Eoo",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar.Eoo",
                    locationTag: "target7",
                    relationship: InheritanceRelationship.ImplementingMember)]
            );
 
        var itemForPooInInterface = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "int IBar.Poo { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar.Poo",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.ImplementingMember)]
            );
 
        var itemForPooInClass = new TestInheritanceMemberItem(
            lineNumber: 12,
            memberName: "int Bar.Poo { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.Poo",
                    locationTag: "target6",
                    relationship: InheritanceRelationship.ImplementedMember)]
            );
 
        var itemForFooInInterface = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "void IBar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingMember)]
            );
 
        var itemForFooInClass = new TestInheritanceMemberItem(
            lineNumber: 11,
            memberName: "void Bar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedMember)]
            );
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingType)]
            );
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 9,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]
            );
 
        var itemForIndexerInClass = new TestInheritanceMemberItem(
            lineNumber: 14,
            memberName: "int Bar.this[int] { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.this",
                    locationTag: "target9",
                    relationship: InheritanceRelationship.ImplementedMember)]
            );
 
        var itemForIndexerInInterface = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "int IBar.this[int] { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar.this",
                    locationTag: "target10",
                    relationship: InheritanceRelationship.ImplementingMember)]
            );
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForEooInClass,
            itemForEooInInterface,
            itemForPooInInterface,
            itemForPooInClass,
            itemForFooInInterface,
            itemForFooInClass,
            itemForIBar,
            itemForBar,
            itemForIndexerInInterface,
            itemForIndexerInClass);
    }
 
    [Theory]
    [InlineData("abstract", TestHost.InProcess)]
    [InlineData("abstract", TestHost.OutOfProcess)]
    [InlineData("virtual", TestHost.InProcess)]
    [InlineData("virtual", TestHost.OutOfProcess)]
    public Task TestCSharpAbstractClassMembers(string modifier, TestHost testHost)
    {
        var markup = $@"using System;
        public abstract class {{|target2:Bar|}}
        {{
            public {modifier} void {{|target4:Foo|}}();
            public {modifier} int {{|target6:Poo|}} {{ get; set; }}
            public {modifier} event EventHandler {{|target8:Eoo|}};
        }}
        public class {{|target1:Bar2|}} : Bar
        {{
            public override void {{|target3:Foo|}}() {{ }}
            public override int {{|target5:Poo|}} {{ get; set; }}
            public override event EventHandler {{|target7:Eoo|}};
        }}
                    ";
 
        var itemForEooInClass = new TestInheritanceMemberItem(
            lineNumber: 12,
            memberName: "override event EventHandler Bar2.Eoo",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: $"Bar.Eoo",
                    locationTag: "target8",
                    relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForEooInAbstractClass = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: $"{modifier} event EventHandler Bar.Eoo",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Eoo",
                    locationTag: "target7",
                    relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForPooInClass = new TestInheritanceMemberItem(
                lineNumber: 11,
                memberName: "override int Bar2.Poo { get; set; }",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: $"Bar.Poo",
                        locationTag: "target6",
                        relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForPooInAbstractClass = new TestInheritanceMemberItem(
                lineNumber: 5,
                memberName: $"{modifier} int Bar.Poo {{ get; set; }}",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "Bar2.Poo",
                        locationTag: "target5",
                        relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForFooInAbstractClass = new TestInheritanceMemberItem(
                lineNumber: 4,
                memberName: $"{modifier} void Bar.Foo()",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "Bar2.Foo",
                        locationTag: "target3",
                        relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForFooInClass = new TestInheritanceMemberItem(
            lineNumber: 10,
            memberName: "override void Bar2.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: $"Bar.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar2",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.DerivedType)]);
 
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "class Bar2",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.BaseType)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForBar,
            itemForBar2,
            itemForFooInAbstractClass,
            itemForFooInClass,
            itemForPooInClass,
            itemForPooInAbstractClass,
            itemForEooInClass,
            itemForEooInAbstractClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpOverrideMemberCanFindImplementingInterface(bool testDuplicate, TestHost testHost)
    {
        var markup1 = @"using System;
        public interface {|target4:IBar|}
        {
            void {|target6:Foo|}();
        }
        public class {|target1:Bar1|} : IBar
        {
            public virtual void {|target2:Foo|}() { }
        }
        public class {|target5:Bar2|} : Bar1
        {
            public override void {|target3:Foo|}() { }
        }";
 
        var markup2 = @"using System;
        public interface {|target4:IBar|}
        {
            void {|target6:Foo|}();
        }
        public class {|target1:Bar1|} : IBar
        {
            public virtual void {|target2:Foo|}() { }
        }
        public class {|target5:Bar2|} : Bar1, IBar
        {
            public override void {|target3:Foo|}() { }
        }";
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.ImplementingType),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.ImplementingType),
            ]);
 
        var itemForFooInIBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "void IBar.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1.Foo",
                            locationTag: "target2",
                            relationship: InheritanceRelationship.ImplementingMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingMember),
            ]);
 
        var itemForBar1 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "class Bar1",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "IBar",
                            locationTag: "target4",
                            relationship: InheritanceRelationship.ImplementedInterface),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.DerivedType),
            ]);
 
        var itemForFooInBar1 = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "virtual void Bar1.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "IBar.Foo",
                            locationTag: "target6",
                            relationship: InheritanceRelationship.ImplementedMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.OverridingMember),
            ]);
 
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 10,
            memberName: "class Bar2",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.BaseType),
                new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedInterface),
            ]);
 
        var itemForFooInBar2 = new TestInheritanceMemberItem(
            lineNumber: 12,
            memberName: "override void Bar2.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "IBar.Foo",
                            locationTag: "target6",
                            relationship: InheritanceRelationship.ImplementedMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar1.Foo",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.OverriddenMember),
            ]);
 
        return VerifyInSingleDocumentAsync(
            testDuplicate ? markup2 : markup1,
            LanguageNames.CSharp,
            testHost,
            itemForIBar,
            itemForFooInIBar,
            itemForBar1,
            itemForFooInBar1,
            itemForBar2,
            itemForFooInBar2);
    }
 
    [Theory]
    [InlineData("abstract", TestHost.InProcess)]
    [InlineData("abstract", TestHost.OutOfProcess)]
    [InlineData("virtual", TestHost.InProcess)]
    [InlineData("virtual", TestHost.OutOfProcess)]
    public Task TestCSharpAbstractClassMembers_LooseMatch(string modifier, TestHost testHost)
    {
        var markup = $@"using System;
        public abstract class {{|target2:Bar|}}
        {{
            public {modifier} void {{|target4:Foo|}}();
            public {modifier} int {{|target6:Poo|}} {{ get; set; }}
            public {modifier} event EventHandler {{|target8:Eoo|}};
        }}
        public class {{|target1:Bar2|}} : Bar
        {{
            public override void {{|target3:Foo|}}(int i) {{ }}
            public override string {{|target5:Poo|}} {{ get; set; }}
            public override event Action {{|target7:Eoo|}};
        }}
                    ";
 
        var itemForEooInClass = new TestInheritanceMemberItem(
            lineNumber: 12,
            memberName: "override event Action Bar2.Eoo",
            targets: [new TargetInfo(
                targetSymbolDisplayName: $"Bar.Eoo",
                locationTag: "target8",
                relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForEooInAbstractClass = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: $"{modifier} event EventHandler Bar.Eoo",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar2.Eoo",
                locationTag: "target7",
                relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForPooInClass = new TestInheritanceMemberItem(
            lineNumber: 11,
            memberName: "override string Bar2.Poo { get; set; }",
            targets: [new TargetInfo(
                targetSymbolDisplayName: $"Bar.Poo",
                locationTag: "target6",
                relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForPooInAbstractClass = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: $"{modifier} int Bar.Poo {{ get; set; }}",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar2.Poo",
                locationTag: "target5",
                relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForFooInAbstractClass = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: $"{modifier} void Bar.Foo()",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar2.Foo",
                locationTag: "target3",
                relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForFooInClass = new TestInheritanceMemberItem(
            lineNumber: 10,
            memberName: "override void Bar2.Foo(int)",
            targets: [new TargetInfo(
                targetSymbolDisplayName: $"Bar.Foo",
                locationTag: "target4",
                relationship: InheritanceRelationship.OverriddenMember)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar2",
                locationTag: "target1",
                relationship: InheritanceRelationship.DerivedType)]);
 
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "class Bar2",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target2",
                relationship: InheritanceRelationship.BaseType)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForBar,
            itemForBar2,
            itemForFooInAbstractClass,
            itemForFooInClass,
            itemForPooInClass,
            itemForPooInAbstractClass,
            itemForEooInClass,
            itemForEooInAbstractClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpFindGenericsBaseType(TestHost testHost)
    {
        var markup = @"
public interface {|target2:IBar|}<T>
{
    void {|target4:Foo|}();
}
 
public class {|target1:Bar2|} : IBar<int>, IBar<string>
{
    public void {|target3:Foo|}();
}";
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar<T>",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar2",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForFooInIBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "void IBar<T>.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        // Only have one IBar<T> item
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "class Bar2",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar<T>",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        // Only have one IBar<T>.Foo item
        var itemForFooInBar2 = new TestInheritanceMemberItem(
            lineNumber: 9,
            memberName: "void Bar2.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar<T>.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForIBar,
            itemForFooInIBar,
            itemForBar2,
            itemForFooInBar2);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpExplicitInterfaceImplementation(TestHost testHost)
    {
        var markup = @"
interface {|target2:IBar|}<T>
{
    void {|target3:Foo|}(T t);
}
 
abstract class {|target1:AbsBar|} : IBar<int>
{
    void IBar<int>.{|target4:Foo|}(int t)
    {
        throw new System.NotImplementedException();
    }
}";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar<T>",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "AbsBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForFooInIBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "void IBar<T>.Foo(T)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "AbsBar.IBar<int>.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForAbsBar = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "class AbsBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar<T>",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForFooInAbsBar = new TestInheritanceMemberItem(
            lineNumber: 9,
            memberName: "void AbsBar.IBar<int>.Foo(int)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar<T>.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForIBar,
            itemForFooInIBar,
            itemForAbsBar,
            itemForFooInAbsBar);
    }
 
    [Theory, CombinatorialData]
    public Task TestStaticAbstractMemberInterface(TestHost testHost)
    {
        var markup = @"
interface {|target5:I1|}<T> where T : I1<T>
{
    static abstract void {|target4:M1|}();
    static abstract int {|target7:P1|} { get; set; }
    static abstract event EventHandler {|target9:e1|};
    static abstract int operator {|target11:+|}(T i1);
    static abstract implicit operator {|target12:int|}(T i1);
}
 
public class {|target1:Class1|} : I1<Class1>
{
    public static void {|target2:M1|}() {}
    public static int {|target6:P1|} { get => 1; set { } }
    public static event EventHandler {|target8:e1|};
    public static int operator {|target10:+|}(Class1 i) => 1;
    public static implicit operator {|target13:int|}(Class1 i) => 0;
}";
        var itemForI1 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface I1<T>",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForM1InI1 = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "void I1<T>.M1()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1.M1",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForAbsClass1 = new TestInheritanceMemberItem(
            lineNumber: 11,
            memberName: "class Class1",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForM1InClass1 = new TestInheritanceMemberItem(
            lineNumber: 13,
            memberName: "static void Class1.M1()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>.M1",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForP1InI1 = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "int I1<T>.P1 { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1.P1",
                    locationTag: "target6",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForP1InClass1 = new TestInheritanceMemberItem(
            lineNumber: 14,
            memberName: "static int Class1.P1 { get; set; }",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>.P1",
                    locationTag: "target7",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForE1InI1 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "event EventHandler I1<T>.e1",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1.e1",
                    locationTag: "target8",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForE1InClass1 = new TestInheritanceMemberItem(
            lineNumber: 15,
            memberName: "static event EventHandler Class1.e1",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>.e1",
                    locationTag: "target9",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForPlusOperatorInI1 = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "int I1<T>.operator +(T)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1.operator +",
                    locationTag: "target10",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForPlusOperatorInClass1 = new TestInheritanceMemberItem(
            lineNumber: 16,
            memberName: "static int Class1.operator +(Class1)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>.operator +",
                    locationTag: "target11",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForIntOperatorInI1 = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "I1<T>.implicit operator int(T)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Class1.implicit operator int",
                    locationTag: "target13",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForIntOperatorInClass1 = new TestInheritanceMemberItem(
            lineNumber: 17,
            memberName: "static Class1.implicit operator int(Class1)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "I1<T>.implicit operator int",
                    locationTag: "target12",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemForI1,
            itemForAbsClass1,
            itemForM1InI1,
            itemForM1InClass1,
            itemForP1InI1,
            itemForP1InClass1,
            itemForE1InI1,
            itemForE1InClass1,
            itemForPlusOperatorInI1,
            itemForPlusOperatorInClass1,
            itemForIntOperatorInI1,
            itemForIntOperatorInClass1);
    }
 
    [Theory, CombinatorialData]
    public Task TestCSharpPartialClass(TestHost testHost)
    {
        var markup = @"
interface {|target1:IBar|}
{ 
}
 
public partial class {|target2:Bar|} : IBar
{
}
 
public partial class {|target3:Bar|}
{
}
            ";
 
        var itemOnLine2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    relationship: InheritanceRelationship.ImplementingType,
                    "target2", "target3")]);
 
        var itemOnLine6 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemOnLine10 = new TestInheritanceMemberItem(
            lineNumber: 10,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.CSharp,
            testHost,
            itemOnLine2,
            itemOnLine6,
            itemOnLine10);
    }
 
    [Theory, CombinatorialData]
    public Task TestEmptyFileSingleGlobalImportInOtherFile(TestHost testHost)
    {
        var markup1 = @"";
        var markup2 = @"{|target1:global using System;|}";
 
        return VerifyInMultipleDocumentsAsync(
            markup1, markup2, LanguageNames.CSharp,
            testHost,
            new TestInheritanceMemberItem(
            lineNumber: 0,
            memberName: string.Format(FeaturesResources.Directives_from_0, "Test2.cs"),
            targets: [new TargetInfo(
                targetSymbolDisplayName: "System",
                relationship: InheritanceRelationship.InheritedImport, "target1")]));
    }
 
    [Theory, CombinatorialData]
    public Task TestEmptyFileMultipleGlobalImportInOtherFile(TestHost testHost)
    {
        var markup1 = @"";
        var markup2 = @"
{|target1:global using System;|}
{|target2:global using System.Collections;|}";
 
        return VerifyInMultipleDocumentsAsync(
            markup1, markup2, LanguageNames.CSharp,
            testHost,
            new TestInheritanceMemberItem(
            lineNumber: 0,
            memberName: string.Format(FeaturesResources.Directives_from_0, "Test2.cs"),
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "System",
                            relationship: InheritanceRelationship.InheritedImport, "target1"),
                new TargetInfo(
                    targetSymbolDisplayName: "System.Collections",
                    relationship: InheritanceRelationship.InheritedImport, "target2"),
            ]));
    }
 
    [Theory, CombinatorialData]
    public Task TestFileWithUsing_SingleGlobalImportInOtherFile(TestHost testHost)
    {
        var markup1 = @"
using System.Collections;";
        var markup2 = @"{|target1:global using System;|}";
 
        return VerifyInMultipleDocumentsAsync(
            markup1, markup2, LanguageNames.CSharp,
            testHost,
            new TestInheritanceMemberItem(
            lineNumber: 1,
            memberName: string.Format(FeaturesResources.Directives_from_0, "Test2.cs"),
            targets: [new TargetInfo(
                targetSymbolDisplayName: "System",
                relationship: InheritanceRelationship.InheritedImport, "target1")]));
    }
 
    [Theory, CombinatorialData]
    public Task TestIgnoreGlobalImportFromSameFile(TestHost testHost)
    {
        var markup1 = @"
global using System.Collections.Generic;
using System.Collections;";
        var markup2 = @"{|target1:global using System;|}";
 
        return VerifyInMultipleDocumentsAsync(
            markup1, markup2, LanguageNames.CSharp,
            testHost,
            new TestInheritanceMemberItem(
            lineNumber: 1,
            memberName: string.Format(FeaturesResources.Directives_from_0, "Test2.cs"),
            targets: [new TargetInfo(
                targetSymbolDisplayName: "System",
                relationship: InheritanceRelationship.InheritedImport, "target1")]));
    }
 
    #endregion
 
    #region TestsForVisualBasic
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicWithErrorBaseType(TestHost testHost)
    {
        var markup = @"
        Namespace MyNamespace
            Public Class Bar
                Implements SomethingNotExist
            End Class
        End Namespace";
 
        return VerifyNoItemForDocumentAsync(markup, LanguageNames.VisualBasic, testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicReferencingMetadata(TestHost testHost)
    {
        var markup = @"
        Namespace MyNamespace
            Public Class Bar
                Implements System.Collections.IEnumerable
                Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
                    Throw New NotImplementedException()
                End Function
            End Class
        End Namespace";
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IEnumerable",
                    relationship: InheritanceRelationship.ImplementedInterface,
                    inMetadata: true)]);
 
        var itemForGetEnumerator = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "Function Bar.GetEnumerator() As IEnumerator",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IEnumerable.GetEnumerator",
                    relationship: InheritanceRelationship.ImplementedMember,
                    inMetadata: true)]);
 
        return VerifyInSingleDocumentAsync(markup, LanguageNames.VisualBasic, testHost, itemForBar, itemForGetEnumerator);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicClassImplementingInterface(TestHost testHost)
    {
        var markup = @"
        Interface {|target2:IBar|}
        End Interface
        Class {|target1:Bar|}
            Implements IBar
        End Class";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForBar);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicInterfaceImplementingInterface(TestHost testHost)
    {
        var markup = @"
        Interface {|target2:IBar2|}
        End Interface
        Interface {|target1:IBar|}
            Inherits IBar2
        End Interface";
 
        var itemForIBar2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar2",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar2",
                locationTag: "target2",
                relationship: InheritanceRelationship.InheritedInterface)]);
        return VerifyInSingleDocumentAsync(markup, LanguageNames.VisualBasic, testHost, itemForIBar2, itemForIBar);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicClassInheritsClass(TestHost testHost)
    {
        var markup = @"
        Class {|target2:Bar2|}
        End Class
        Class {|target1:Bar|}
            Inherits Bar2
        End Class";
 
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Class Bar2",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.DerivedType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar2",
                locationTag: "target2",
                relationship: InheritanceRelationship.BaseType)]);
        return VerifyInSingleDocumentAsync(markup, LanguageNames.VisualBasic, testHost, itemForBar2, itemForBar);
    }
 
    [Theory]
    [InlineData("Class", TestHost.InProcess)]
    [InlineData("Class", TestHost.OutOfProcess)]
    [InlineData("Structure", TestHost.InProcess)]
    [InlineData("Structure", TestHost.OutOfProcess)]
    [InlineData("Enum", TestHost.InProcess)]
    [InlineData("Enum", TestHost.OutOfProcess)]
    [InlineData("Interface", TestHost.InProcess)]
    [InlineData("Interface", TestHost.OutOfProcess)]
    public Task TestVisualBasicTypeWithoutBaseType(string typeName, TestHost testHost)
    {
        var markup = $@"
        {typeName} Bar
        End {typeName}";
 
        return VerifyNoItemForDocumentAsync(markup, LanguageNames.VisualBasic, testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicMetadataInterface(TestHost testHost)
    {
        var markup = @"
        Imports System.Collections
        Class Bar
            Implements IEnumerable
        End Class";
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            new TestInheritanceMemberItem(
                lineNumber: 2,
                memberName: VBFeaturesResources.Project_level_Imports,
                targets:
                [
                    new TargetInfo("System", InheritanceRelationship.InheritedImport),
                    new TargetInfo("System.Collections.Generic", InheritanceRelationship.InheritedImport),
                    new TargetInfo("System.Linq", InheritanceRelationship.InheritedImport),
                ]),
            new TestInheritanceMemberItem(
                lineNumber: 3,
                memberName: "Class Bar",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "IEnumerable",
                        relationship: InheritanceRelationship.ImplementedInterface,
                        inMetadata: true)]));
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicEventStatement(TestHost testHost)
    {
        var markup = @"
        Interface {|target2:IBar|}
            Event {|target4:e|} As EventHandler
        End Interface
        Class {|target1:Bar|}
            Implements IBar
            Public Event {|target3:e|} As EventHandler Implements IBar.e
        End Class";
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "Class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForEventInInterface = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Event IBar.e As EventHandler",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar.e",
                locationTag: "target3",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForEventInClass = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "Event Bar.e As EventHandler",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar.e",
                locationTag: "target4",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForBar,
            itemForEventInInterface,
            itemForEventInClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicEventBlock(TestHost testHost)
    {
        var markup = @"
        Interface {|target2:IBar|}
            Event {|target4:e|} As EventHandler
        End Interface
        Class {|target1:Bar|}
            Implements IBar
            Public Custom Event {|target3:e|} As EventHandler Implements IBar.e
            End Event
        End Class";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "Class Bar",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForEventInInterface = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Event IBar.e As EventHandler",
            [new TargetInfo(
                targetSymbolDisplayName: "Bar.e",
                locationTag: "target3",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForEventInClass = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "Event Bar.e As EventHandler",
            [new TargetInfo(
                targetSymbolDisplayName: "IBar.e",
                locationTag: "target4",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForBar,
            itemForEventInInterface,
            itemForEventInClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicInterfaceMembers(TestHost testHost)
    {
        var markup = @"
        Interface {|target2:IBar|}
            Property {|target4:Poo|} As Integer
            Function {|target6:Foo|}() As Integer
        End Interface
 
        Class {|target1:Bar|}
            Implements IBar
            Public Property {|target3:Poo|} As Integer Implements IBar.Poo
                Get
                    Return 1
                End Get
                Set(value As Integer)
                End Set
            End Property
            Public Function {|target5:Foo|}() As Integer Implements IBar.Foo
                Return 1
            End Function
        End Class";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar",
                locationTag: "target1",
                relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "Class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForPooInInterface = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Property IBar.Poo As Integer",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar.Poo",
                locationTag: "target3",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForPooInClass = new TestInheritanceMemberItem(
            lineNumber: 9,
            memberName: "Property Bar.Poo As Integer",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar.Poo",
                locationTag: "target4",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForFooInInterface = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Function IBar.Foo() As Integer",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "Bar.Foo",
                locationTag: "target5",
                relationship: InheritanceRelationship.ImplementingMember)]);
 
        var itemForFooInClass = new TestInheritanceMemberItem(
            lineNumber: 16,
            memberName: "Function Bar.Foo() As Integer",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar.Foo",
                locationTag: "target6",
                relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForBar,
            itemForPooInInterface,
            itemForPooInClass,
            itemForFooInInterface,
            itemForFooInClass);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicMustInheritClassMember(TestHost testHost)
    {
        var markup = @"
        MustInherit Class {|target2:Bar1|}
            Public MustOverride Sub {|target4:Foo|}()
        End Class
 
        Class {|target1:Bar|}
            Inherits Bar1
            Public Overrides Sub {|target3:Foo|}()
            End Sub
        End Class";
        var itemForBar1 = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Class Bar1",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: $"Bar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.DerivedType)]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "Class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar1",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.BaseType)]);
 
        var itemForFooInBar1 = new TestInheritanceMemberItem(
                lineNumber: 3,
                memberName: "MustOverride Sub Bar1.Foo()",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "Bar.Foo",
                        locationTag: "target3",
                        relationship: InheritanceRelationship.OverridingMember)]);
 
        var itemForFooInBar = new TestInheritanceMemberItem(
                lineNumber: 8,
                memberName: "Overrides Sub Bar.Foo()",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "Bar1.Foo",
                        locationTag: "target4",
                        relationship: InheritanceRelationship.OverriddenMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
             testHost,
            itemForBar1,
            itemForBar,
            itemForFooInBar1,
            itemForFooInBar);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicOverrideMemberCanFindImplementingInterface(bool testDuplicate, TestHost testHost)
    {
        var markup1 = @"
        Interface {|target4:IBar|}
            Sub {|target6:Foo|}()
        End Interface
 
        Class {|target1:Bar1|}
            Implements IBar
            Public Overridable Sub {|target2:Foo|}() Implements IBar.Foo
            End Sub
        End Class
 
        Class {|target5:Bar2|}
            Inherits Bar1
            Public Overrides Sub {|target3:Foo|}()
            End Sub
        End Class";
 
        var markup2 = @"
        Interface {|target4:IBar|}
            Sub {|target6:Foo|}()
        End Interface
 
        Class {|target1:Bar1|}
            Implements IBar
            Public Overridable Sub {|target2:Foo|}() Implements IBar.Foo
            End Sub
        End Class
 
        Class {|target5:Bar2|}
            Inherits Bar1
            Public Overrides Sub {|target3:Foo|}()
            End Sub
        End Class";
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.ImplementingType),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.ImplementingType),
            ]);
 
        var itemForFooInIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Sub IBar.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1.Foo",
                            locationTag: "target2",
                            relationship: InheritanceRelationship.ImplementingMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingMember),
            ]);
 
        var itemForBar1 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "Class Bar1",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar2",
                            locationTag: "target5",
                            relationship: InheritanceRelationship.DerivedType),
                new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedInterface)
,
            ]);
 
        var itemForFooInBar1 = new TestInheritanceMemberItem(
            lineNumber: 8,
            memberName: "Overridable Sub Bar1.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "IBar.Foo",
                            locationTag: "target6",
                            relationship: InheritanceRelationship.ImplementedMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar2.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.OverridingMember),
            ]);
 
        var itemForBar2 = new TestInheritanceMemberItem(
            lineNumber: 12,
            memberName: "Class Bar2",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar1",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.BaseType),
                new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementedInterface),
            ]);
 
        var itemForFooInBar2 = new TestInheritanceMemberItem(
            lineNumber: 14,
            memberName: "Overrides Sub Bar2.Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "IBar.Foo",
                            locationTag: "target6",
                            relationship: InheritanceRelationship.ImplementedMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar1.Foo",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.OverriddenMember),
            ]);
 
        return VerifyInSingleDocumentAsync(
            testDuplicate ? markup2 : markup1,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForFooInIBar,
            itemForBar1,
            itemForFooInBar1,
            itemForBar2,
            itemForFooInBar2);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicFindGenericsBaseType(TestHost testHost)
    {
        var markup = @"
        Public Interface {|target5:IBar|}(Of T)
            Sub {|target6:Foo|}()
        End Interface
 
        Public Class {|target1:Bar|}
            Implements IBar(Of Integer)
            Implements IBar(Of String)
 
            Public Sub {|target3:Foo|}() Implements IBar(Of Integer).Foo
                Throw New NotImplementedException()
            End Sub
 
            Private Sub {|target4:IBar_Foo|}() Implements IBar(Of String).Foo
                Throw New NotImplementedException()
            End Sub
        End Class";
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 2,
            memberName: "Interface IBar(Of T)",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForFooInIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Sub IBar(Of T).Foo()",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar.Foo",
                            locationTag: "target3",
                            relationship: InheritanceRelationship.ImplementingMember),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar.IBar_Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementingMember),
            ]);
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "Class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar(Of T)",
                    locationTag: "target5",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForFooInBar = new TestInheritanceMemberItem(
            lineNumber: 10,
            memberName: "Sub Bar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar(Of T).Foo",
                    locationTag: "target6",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForIBar_FooInBar = new TestInheritanceMemberItem(
            lineNumber: 14,
            memberName: "Sub Bar.IBar_Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar(Of T).Foo",
                    locationTag: "target6",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        return VerifyInSingleDocumentAsync(
            markup,
            LanguageNames.VisualBasic,
            testHost,
            itemForIBar,
            itemForFooInIBar,
            itemForBar,
            itemForFooInBar,
            itemForIBar_FooInBar);
    }
 
    #endregion
 
    [Theory, CombinatorialData]
    public Task TestCSharpProjectReferencingVisualBasicProject(TestHost testHost)
    {
        var markup1 = @"
        using MyNamespace;
        namespace BarNs
        {
            public class {|target2:Bar|} : IBar
            {
                public void {|target4:Foo|}() { }
            }
        }";
 
        var markup2 = @"
        Namespace MyNamespace
            Public Interface {|target1:IBar|}
                Sub {|target3:Foo|}()
            End Interface
        End Namespace";
 
        var itemForBar = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "class Bar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForFooInMarkup1 = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "void Bar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForFooInMarkup2 = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Sub IBar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        return VerifyInDifferentProjectsAsync(
            (markup1, LanguageNames.CSharp),
            (markup2, LanguageNames.VisualBasic),
            [itemForBar, itemForFooInMarkup1],
            [itemForIBar, itemForFooInMarkup2],
            testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestVisualBasicProjectReferencingCSharpProject(TestHost testHost)
    {
        var markup1 = @"
        Imports BarNs
        Namespace MyNamespace
            Public Class {|target2:Bar44|}
                Implements IBar
 
                Public Sub {|target4:Foo|}() Implements IBar.Foo
                End Sub
            End Class
        End Namespace";
 
        var markup2 = @"
        namespace BarNs
        {
            public interface {|target1:IBar|}
            {
                void {|target3:Foo|}();
            }
        }";
        var itemForProjectImports =
            new TestInheritanceMemberItem(
                lineNumber: 2,
                memberName: VBFeaturesResources.Project_level_Imports,
                targets:
                [
                    new TargetInfo("System", InheritanceRelationship.InheritedImport),
                    new TargetInfo("System.Collections.Generic", InheritanceRelationship.InheritedImport),
                    new TargetInfo("System.Linq", InheritanceRelationship.InheritedImport),
                ]);
 
        var itemForBar44 = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "Class Bar44",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar",
                    locationTag: "target1",
                    relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForFooInMarkup1 = new TestInheritanceMemberItem(
            lineNumber: 7,
            memberName: "Sub Bar44.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "IBar.Foo",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementedMember)]);
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 4,
            memberName: "interface IBar",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar44",
                    locationTag: "target2",
                    relationship: InheritanceRelationship.ImplementingType)]);
 
        var itemForFooInMarkup2 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "void IBar.Foo()",
            targets: [new TargetInfo(
                    targetSymbolDisplayName: "Bar44.Foo",
                    locationTag: "target4",
                    relationship: InheritanceRelationship.ImplementingMember)]);
 
        return VerifyInDifferentProjectsAsync(
            (markup1, LanguageNames.VisualBasic),
            (markup2, LanguageNames.CSharp),
            [itemForProjectImports, itemForBar44, itemForFooInMarkup1],
            [itemForIBar, itemForFooInMarkup2],
            testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestSameNameSymbolInDifferentLanguageProjects(TestHost testHost)
    {
        var markup1 = @"
        using MyNamespace;
        namespace BarNs
        {
            public class {|target1:Bar|} : IBar
            {
            }
        }";
 
        var markup2 = @"
        Namespace MyNamespace
            Public Interface {|target2:IBar|}
            End Interface
 
            Public Class {|target3:Bar|}
                Implements IBar
            End Class
        End Namespace";
 
        var itemForBarInMarkup1 = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "Interface IBar",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.ImplementingType,
                            languageGlyph: Glyph.CSharpFile,
                            projectName: "Assembly1"),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingType,
                    languageGlyph: Glyph.BasicFile,
                    projectName: "Assembly2"),
            ]);
 
        var itemForBarInMarkup2 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "Class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        return VerifyInDifferentProjectsAsync(
            (markup1, LanguageNames.CSharp),
            (markup2, LanguageNames.VisualBasic),
            [itemForBarInMarkup1],
            [itemForIBar, itemForBarInMarkup2],
            testHost);
    }
 
    [Theory, CombinatorialData]
    public Task TestSameNameSymbolInSameLanguageProjects(TestHost testHost)
    {
        var markup1 = @"
        using MyNamespace;
        namespace BarNs
        {
            public class {|target1:Bar|} : IBar
            {
            }
        }";
 
        var markup2 = @"
        namespace MyNamespace {
            public interface {|target2:IBar|}
            {}
 
            public class {|target3:Bar|}
                : IBar
            {}
        }";
 
        var itemForBarInMarkup1 = new TestInheritanceMemberItem(
            lineNumber: 5,
            memberName: "class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        var itemForIBar = new TestInheritanceMemberItem(
            lineNumber: 3,
            memberName: "interface IBar",
            targets:
            [
                new TargetInfo(
                            targetSymbolDisplayName: "Bar",
                            locationTag: "target1",
                            relationship: InheritanceRelationship.ImplementingType,
                            languageGlyph: Glyph.CSharpFile,
                            projectName: "Assembly1"),
                new TargetInfo(
                    targetSymbolDisplayName: "Bar",
                    locationTag: "target3",
                    relationship: InheritanceRelationship.ImplementingType,
                    languageGlyph: Glyph.CSharpFile,
                    projectName: "Assembly2"),
            ]);
 
        var itemForBarInMarkup2 = new TestInheritanceMemberItem(
            lineNumber: 6,
            memberName: "class Bar",
            targets: [new TargetInfo(
                targetSymbolDisplayName: "IBar",
                locationTag: "target2",
                relationship: InheritanceRelationship.ImplementedInterface)]);
 
        return VerifyInDifferentProjectsAsync(
            (markup1, LanguageNames.CSharp),
            (markup2, LanguageNames.CSharp),
            [itemForBarInMarkup1],
            [itemForIBar, itemForBarInMarkup2],
            testHost);
    }
 
    [Theory, CombinatorialData]
    public async Task TestHiddenLocationSymbol(TestHost testHost)
    {
        await VerifyNoItemForDocumentAsync(@"
public class {|target2:B|} : C
{
}
 
#line hidden
public class {|target1:C|}
{
}",
            LanguageNames.CSharp,
            testHost);
    }
 
    [Theory, CombinatorialData]
    [WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1988154/")]
    public async Task TestNoResultOutsideSpan(TestHost testHost)
    {
        // 1. If the searching span is the empty body, nothing should be returned.
        var noResultCode = $@"
public class B : C
{{
 
{{|{SearchAreaTag}:
 
 
 
 
|}}
 
}}
 
public class C
{{
}}";
 
        await VerifyNoItemForDocumentAsync(noResultCode,
            LanguageNames.CSharp,
            testHost);
 
        // 2. If the searching span contains the identifier, correct result should be returned.
        var correctSearchingCode = $@"
public class {{|{SearchAreaTag}:B|}} : C
{{
 
 
 
 
 
 
}}
 
public class {{|target:C|}}
{{
}}";
 
        await VerifyInSingleDocumentAsync(correctSearchingCode,
            LanguageNames.CSharp,
            testHost,
            memberItems: [new TestInheritanceMemberItem(
                lineNumber: 2,
                memberName: "class B",
                targets: [new TargetInfo(
                        targetSymbolDisplayName: "C",
                        locationTag: "target",
                        relationship: InheritanceRelationship.BaseType)])]);
    }
}