File: Symbols\LookupSymbolsInfoTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    public class LookupSymbolsInfoTests : CSharpTestBase
    {
        private class TemplateArgEnumerator : IEnumerator<string>
        {
            private short _current;
 
            public TemplateArgEnumerator()
            {
                _current = 0;
            }
 
            public string Current
            {
                get { return string.Format("T{0}", _current.ToString()); }
            }
 
            public void Dispose()
            {
            }
 
            object System.Collections.IEnumerator.Current
            {
                get { return this.Current; }
            }
 
            public bool MoveNext()
            {
                if (_current == short.MaxValue)
                {
                    return false;
                }
 
                _current++;
                return true;
            }
 
            public void Reset()
            {
                _current = 0;
            }
        }
 
        private class TemplateArgEnumerable : IEnumerable<string>
        {
            public static readonly IEnumerable<string> Instance = new TemplateArgEnumerable();
 
            public IEnumerator<string> GetEnumerator()
            {
                return new TemplateArgEnumerator();
            }
 
            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }
 
        private static string GenerateTemplateArgs(int arity)
        {
            if (arity == 0) return string.Empty;
            return string.Format("<{0}>", string.Join(",", TemplateArgEnumerable.Instance.Take(arity)));
        }
 
        private static void AppendEmptyClass(StringBuilder sb, string root, int arity)
        {
            sb.Append("class ");
            sb.Append(root);
            sb.Append(GenerateTemplateArgs(arity));
            sb.AppendLine(" {}");
        }
 
        private static void CompileAndCheckSymbolCount(string source, string symbolName, int expectedSymbolCount)
        {
            var compilation = CreateCompilation(source);
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var symbols = model.LookupSymbols(0, null, symbolName);
 
            Assert.Equal(expectedSymbolCount, symbols.Length);
        }
 
        [Fact]
        public void UniqueSymbolOrAritiesTestBigArity()
        {
            // The LookupSymbols implementation is optimized for small arities (less than 32).
            // Since larger arity values are so rare, they are tested explicitly here.
 
            StringBuilder sb = new StringBuilder();
 
            AppendEmptyClass(sb, "Goo", 50);
 
            // Unique symbol test
            CompileAndCheckSymbolCount(sb.ToString(), "Goo", 1);
 
            AppendEmptyClass(sb, "Goo", 100);
            AppendEmptyClass(sb, "Goo", 150);
            AppendEmptyClass(sb, "Goo", 200);
            AppendEmptyClass(sb, "Goo", 250);
 
            // Multiple symbols test
            CompileAndCheckSymbolCount(sb.ToString(), "Goo", 5);
        }
 
        [Fact]
        public void UniqueSymbolOrAritiesTestSmallArity()
        {
            StringBuilder sb = new StringBuilder();
 
            AppendEmptyClass(sb, "Goo", 1);
 
            // Unique symbol test
            CompileAndCheckSymbolCount(sb.ToString(), "Goo", 1);
 
            AppendEmptyClass(sb, "Goo", 2);
            AppendEmptyClass(sb, "Goo", 3);
 
            // Multiple symbols test
            CompileAndCheckSymbolCount(sb.ToString(), "Goo", 3);
        }
 
        [Fact]
        public void UniqueSymbolOrAritiesTest()
        {
            for (int i = 0; i < 50; i++)
            {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < i; j++)
                {
                    AppendEmptyClass(sb, "Goo", j);
                }
 
                CompileAndCheckSymbolCount(sb.ToString(), "Goo", i);
            }
        }
    }
}