Files
2026-08-27 10:56:38 -06:00

83 lines
4.3 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Symbols;
using Microsoft.DiaSymReader;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeGen;
internal sealed class CompilationTestData
{
internal readonly struct MethodData(ILBuilder ilBuilder, IMethodSymbolInternal method)
{
public readonly ILBuilder ILBuilder = ilBuilder;
public readonly IMethodSymbolInternal Method = method;
}
public readonly ConcurrentDictionary<IMethodSymbolInternal, MethodData> Methods = new ConcurrentDictionary<IMethodSymbolInternal, MethodData>();
public CommonPEModuleBuilder? Module;
public Func<ISymWriterMetadataProvider, SymUnmanagedWriter>? SymWriterFactory;
private ImmutableDictionary<string, MethodData>? _lazyMethodsByName;
private static readonly SymbolDisplayFormat _testDataKeyFormat = new SymbolDisplayFormat(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames | SymbolDisplayCompilerInternalOptions.IncludeContainingFileForFileTypes, SymbolDisplayGlobalNamespaceStyle.OmittedAsContaining, SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces, SymbolDisplayGenericsOptions.IncludeTypeParameters | SymbolDisplayGenericsOptions.IncludeVariance, SymbolDisplayMemberOptions.IncludeExplicitInterface | SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeContainingType, SymbolDisplayParameterOptions.IncludeExtensionThis | SymbolDisplayParameterOptions.IncludeParamsRefOut | SymbolDisplayParameterOptions.IncludeType, SymbolDisplayDelegateStyle.NameOnly, SymbolDisplayExtensionMethodStyle.Default, SymbolDisplayPropertyStyle.NameOnly, SymbolDisplayLocalOptions.None, SymbolDisplayKindOptions.None, SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseAsterisksInMultiDimensionalArrays | SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName | SymbolDisplayMiscellaneousOptions.ExpandValueTuple);
private static readonly SymbolDisplayFormat _testDataOperatorKeyFormat = new SymbolDisplayFormat(_testDataKeyFormat.CompilerInternalOptions, _testDataKeyFormat.GlobalNamespaceStyle, _testDataKeyFormat.TypeQualificationStyle, _testDataKeyFormat.GenericsOptions, _testDataKeyFormat.MemberOptions | SymbolDisplayMemberOptions.IncludeType, _testDataKeyFormat.ParameterOptions, _testDataKeyFormat.DelegateStyle, _testDataKeyFormat.ExtensionMethodStyle, _testDataKeyFormat.PropertyStyle, _testDataKeyFormat.LocalOptions, _testDataKeyFormat.KindOptions, _testDataKeyFormat.MiscellaneousOptions);
public MetadataWriter? MetadataWriter { get; private set; }
public void SetMetadataWriter(MetadataWriter writer)
{
MetadataWriter = writer;
}
public void SetMethodILBuilder(IMethodSymbolInternal method, ILBuilder builder)
{
Methods.Add(method, new MethodData(builder, method));
}
public ILBuilder GetIL(Func<IMethodSymbolInternal, bool> predicate)
{
return Methods.Single<KeyValuePair<IMethodSymbolInternal, MethodData>>((KeyValuePair<IMethodSymbolInternal, MethodData> p) => predicate(p.Key)).Value.ILBuilder;
}
public ImmutableDictionary<string, MethodData> GetMethodsByName()
{
if (_lazyMethodsByName == null)
{
Dictionary<string, MethodData> dictionary = new Dictionary<string, MethodData>();
foreach (KeyValuePair<IMethodSymbolInternal, MethodData> method in Methods)
{
string methodName = GetMethodName(method.Key);
if (dictionary.ContainsKey(methodName))
{
dictionary[methodName] = default(MethodData);
}
else
{
dictionary.Add(methodName, method.Value);
}
}
ImmutableDictionary<string, MethodData> value = dictionary.Where((KeyValuePair<string, MethodData> p) => p.Value.Method != null).ToImmutableDictionary();
Interlocked.CompareExchange(ref _lazyMethodsByName, value, null);
}
return _lazyMethodsByName;
}
private static string GetMethodName(IMethodSymbolInternal methodSymbol)
{
IMethodSymbol obj = (IMethodSymbol)methodSymbol.GetISymbol();
SymbolDisplayFormat format = ((obj.MethodKind == MethodKind.UserDefinedOperator) ? _testDataOperatorKeyFormat : _testDataKeyFormat);
return obj.ToDisplayString(format);
}
}