146 lines
7.6 KiB
C#
146 lines
7.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using Microsoft.Cci;
|
|
using Microsoft.CodeAnalysis.Collections;
|
|
using Microsoft.CodeAnalysis.PooledObjects;
|
|
using Microsoft.CodeAnalysis.Symbols;
|
|
using Roslyn.Utilities;
|
|
|
|
namespace Microsoft.CodeAnalysis.Emit;
|
|
|
|
internal abstract class SymbolMatcher
|
|
{
|
|
public abstract ITypeReference? MapReference(ITypeReference reference);
|
|
|
|
public abstract IDefinition? MapDefinition(IDefinition definition);
|
|
|
|
public abstract INamespace? MapNamespace(INamespace @namespace);
|
|
|
|
public ISymbolInternal? MapDefinitionOrNamespace(ISymbolInternal symbol)
|
|
{
|
|
IReference cciAdapter = symbol.GetCciAdapter();
|
|
if (!(cciAdapter is IDefinition definition))
|
|
{
|
|
return MapNamespace((INamespace)cciAdapter)?.GetInternalSymbol();
|
|
}
|
|
return MapDefinition(definition)?.GetInternalSymbol();
|
|
}
|
|
|
|
public EmitBaseline MapBaselineToCompilation(EmitBaseline baseline, Compilation targetCompilation, CommonPEModuleBuilder targetModuleBuilder, ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> mappedSynthesizedMembers, ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> mappedDeletedMembers)
|
|
{
|
|
IReadOnlyDictionary<ITypeDefinition, int> typesAdded = MapDefinitions(baseline.TypesAdded);
|
|
IReadOnlyDictionary<IEventDefinition, int> eventsAdded = MapDefinitions(baseline.EventsAdded);
|
|
IReadOnlyDictionary<IFieldDefinition, int> fieldsAdded = MapDefinitions(baseline.FieldsAdded);
|
|
IReadOnlyDictionary<IMethodDefinition, int> methodsAdded = MapDefinitions(baseline.MethodsAdded);
|
|
IReadOnlyDictionary<IPropertyDefinition, int> propertiesAdded = MapDefinitions(baseline.PropertiesAdded);
|
|
IReadOnlyDictionary<IDefinition, int> generationOrdinals = MapDefinitions(baseline.GenerationOrdinals);
|
|
return baseline.With(targetCompilation, targetModuleBuilder, baseline.Ordinal, baseline.EncId, generationOrdinals, typesAdded, eventsAdded, fieldsAdded, methodsAdded, baseline.FirstParamRowMap, propertiesAdded, baseline.EventMapAdded, baseline.PropertyMapAdded, baseline.MethodImplsAdded, baseline.CustomAttributesAdded, baseline.TableEntriesAdded, baseline.BlobStreamLengthAdded, baseline.StringStreamLengthAdded, baseline.UserStringStreamLengthAdded, baseline.GuidStreamLengthAdded, new SynthesizedTypeMaps(MapAnonymousTypes(baseline.SynthesizedTypes.AnonymousTypes), MapAnonymousDelegates(baseline.SynthesizedTypes.AnonymousDelegates), MapAnonymousDelegatesWithIndexedNames(baseline.SynthesizedTypes.AnonymousDelegatesWithIndexedNames)), mappedSynthesizedMembers, mappedDeletedMembers, MapAddedOrChangedMethods(baseline.AddedOrChangedMethods), baseline.DebugInformationProvider, baseline.LocalSignatureProvider);
|
|
}
|
|
|
|
private IReadOnlyDictionary<K, V> MapDefinitions<K, V>(IReadOnlyDictionary<K, V> items) where K : class, IDefinition
|
|
{
|
|
Dictionary<K, V> dictionary = new Dictionary<K, V>(SymbolEquivalentEqualityComparer.Instance);
|
|
foreach (KeyValuePair<K, V> item in items)
|
|
{
|
|
K val = (K)MapDefinition(item.Key);
|
|
if (val != null)
|
|
{
|
|
dictionary.Add(val, item.Value);
|
|
}
|
|
}
|
|
return dictionary;
|
|
}
|
|
|
|
private IReadOnlyDictionary<int, AddedOrChangedMethodInfo> MapAddedOrChangedMethods(IReadOnlyDictionary<int, AddedOrChangedMethodInfo> addedOrChangedMethods)
|
|
{
|
|
Dictionary<int, AddedOrChangedMethodInfo> dictionary = new Dictionary<int, AddedOrChangedMethodInfo>();
|
|
foreach (KeyValuePair<int, AddedOrChangedMethodInfo> addedOrChangedMethod in addedOrChangedMethods)
|
|
{
|
|
dictionary.Add(addedOrChangedMethod.Key, addedOrChangedMethod.Value.MapTypes(this));
|
|
}
|
|
return dictionary;
|
|
}
|
|
|
|
private ImmutableSegmentedDictionary<AnonymousTypeKey, AnonymousTypeValue> MapAnonymousTypes(IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap)
|
|
{
|
|
ImmutableSegmentedDictionary<AnonymousTypeKey, AnonymousTypeValue>.Builder builder = ImmutableSegmentedDictionary.CreateBuilder<AnonymousTypeKey, AnonymousTypeValue>();
|
|
foreach (KeyValuePair<AnonymousTypeKey, AnonymousTypeValue> item in anonymousTypeMap)
|
|
{
|
|
KeyValuePairUtil.Deconstruct(item, out var key, out var value);
|
|
AnonymousTypeKey key2 = key;
|
|
AnonymousTypeValue anonymousTypeValue = value;
|
|
ITypeDefinition type = (ITypeDefinition)MapDefinition(anonymousTypeValue.Type);
|
|
builder.Add(key2, new AnonymousTypeValue(anonymousTypeValue.Name, anonymousTypeValue.UniqueIndex, type));
|
|
}
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
private ImmutableSegmentedDictionary<SynthesizedDelegateKey, SynthesizedDelegateValue> MapAnonymousDelegates(IReadOnlyDictionary<SynthesizedDelegateKey, SynthesizedDelegateValue> anonymousDelegates)
|
|
{
|
|
ImmutableSegmentedDictionary<SynthesizedDelegateKey, SynthesizedDelegateValue>.Builder builder = ImmutableSegmentedDictionary.CreateBuilder<SynthesizedDelegateKey, SynthesizedDelegateValue>();
|
|
foreach (KeyValuePair<SynthesizedDelegateKey, SynthesizedDelegateValue> anonymousDelegate in anonymousDelegates)
|
|
{
|
|
KeyValuePairUtil.Deconstruct(anonymousDelegate, out var key, out var value);
|
|
SynthesizedDelegateKey key2 = key;
|
|
SynthesizedDelegateValue synthesizedDelegateValue = value;
|
|
ITypeDefinition typeDefinition = (ITypeDefinition)MapDefinition(synthesizedDelegateValue.Delegate);
|
|
builder.Add(key2, new SynthesizedDelegateValue(typeDefinition));
|
|
}
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
private ImmutableSegmentedDictionary<string, AnonymousTypeValue> MapAnonymousDelegatesWithIndexedNames(IReadOnlyDictionary<string, AnonymousTypeValue> anonymousDelegates)
|
|
{
|
|
ImmutableSegmentedDictionary<string, AnonymousTypeValue>.Builder builder = ImmutableSegmentedDictionary.CreateBuilder<string, AnonymousTypeValue>();
|
|
foreach (KeyValuePair<string, AnonymousTypeValue> anonymousDelegate in anonymousDelegates)
|
|
{
|
|
KeyValuePairUtil.Deconstruct(anonymousDelegate, out var key, out var value);
|
|
string key2 = key;
|
|
AnonymousTypeValue anonymousTypeValue = value;
|
|
ITypeDefinition type = (ITypeDefinition)MapDefinition(anonymousTypeValue.Type);
|
|
builder.Add(key2, new AnonymousTypeValue(anonymousTypeValue.Name, anonymousTypeValue.UniqueIndex, type));
|
|
}
|
|
return builder.ToImmutable();
|
|
}
|
|
|
|
internal ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> MapSynthesizedOrDeletedMembers(ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> previousMembers, ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>> newMembers, bool isDeletedMemberMapping)
|
|
{
|
|
if (previousMembers.Count == 0)
|
|
{
|
|
return newMembers;
|
|
}
|
|
ImmutableDictionary<ISymbolInternal, ImmutableArray<ISymbolInternal>>.Builder builder = ImmutableDictionary.CreateBuilder<ISymbolInternal, ImmutableArray<ISymbolInternal>>();
|
|
builder.AddRange(newMembers);
|
|
foreach (KeyValuePair<ISymbolInternal, ImmutableArray<ISymbolInternal>> previousMember in previousMembers)
|
|
{
|
|
KeyValuePairUtil.Deconstruct(previousMember, out var key, out var value);
|
|
ISymbolInternal symbolInternal = key;
|
|
ImmutableArray<ISymbolInternal> value2 = value;
|
|
ISymbolInternal symbolInternal2 = MapDefinitionOrNamespace(symbolInternal);
|
|
if (symbolInternal2 == null)
|
|
{
|
|
builder.Add(symbolInternal, value2);
|
|
continue;
|
|
}
|
|
if (!newMembers.TryGetValue(symbolInternal2, out ImmutableArray<ISymbolInternal> value3))
|
|
{
|
|
builder.Add(symbolInternal2, value2);
|
|
continue;
|
|
}
|
|
ArrayBuilder<ISymbolInternal> instance = ArrayBuilder<ISymbolInternal>.GetInstance();
|
|
instance.AddRange(value3);
|
|
ImmutableArray<ISymbolInternal>.Enumerator enumerator2 = value2.GetEnumerator();
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
ISymbolInternal current = enumerator2.Current;
|
|
if (MapDefinitionOrNamespace(current) == null)
|
|
{
|
|
instance.Add(current);
|
|
}
|
|
}
|
|
builder[symbolInternal2] = instance.ToImmutableAndFree();
|
|
}
|
|
return builder.ToImmutable();
|
|
}
|
|
}
|