83 lines
4.3 KiB
C#
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);
|
|
}
|
|
}
|