// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Collections.Generic;
using Internal.Metadata.NativeFormat.Writer;
{
partial class Transform<TPolicy>
{
+ private EntityMap<ForwarderKey, TypeForwarder> _forwarders = new EntityMap<ForwarderKey, TypeForwarder>(EqualityComparer<ForwarderKey>.Default);
+
+ private Action<ForwarderKey, TypeForwarder> _initForwarder;
+
private void HandleTypeForwarders(Cts.Ecma.EcmaModule module)
{
foreach (var exportedTypeHandle in module.MetadataReader.ExportedTypes)
Ecma.ExportedType exportedType = module.MetadataReader.GetExportedType(exportedTypeHandle);
if (exportedType.IsForwarder || exportedType.Implementation.Kind == Ecma.HandleKind.ExportedType)
{
- HandleTypeForwarder(module, exportedType);
+ HandleTypeForwarder(module, exportedTypeHandle);
}
else
{
}
}
- private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.ExportedType exportedType)
+ private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.ExportedTypeHandle handle)
+ {
+ return _forwarders.GetOrCreate(new ForwarderKey(module, handle), _initForwarder ?? (_initForwarder = InitializeTypeForwarder));
+ }
+
+ private void InitializeTypeForwarder(ForwarderKey key, TypeForwarder record)
{
+ Cts.Ecma.EcmaModule module = key.Module;
Ecma.MetadataReader reader = module.MetadataReader;
- string name = reader.GetString(exportedType.Name);
- TypeForwarder result;
+ Ecma.ExportedType exportedType = reader.GetExportedType(key.ExportedType);
+
+ record.Name = HandleString(reader.GetString(exportedType.Name));
switch (exportedType.Implementation.Kind)
{
else
refName.SetPublicKeyToken(reader.GetBlobBytes(assemblyRef.PublicKeyOrToken));
- result = new TypeForwarder
- {
- Name = HandleString(name),
- Scope = HandleScopeReference(refName),
- };
+ record.Scope = HandleScopeReference(refName);
- namespaceDefinition.TypeForwarders.Add(result);
+ namespaceDefinition.TypeForwarders.Add(record);
}
break;
case Ecma.HandleKind.ExportedType:
{
- TypeForwarder scope = HandleTypeForwarder(module, reader.GetExportedType((Ecma.ExportedTypeHandle)exportedType.Implementation));
+ TypeForwarder scope = HandleTypeForwarder(module, (Ecma.ExportedTypeHandle)exportedType.Implementation);
- result = new TypeForwarder
- {
- Name = HandleString(name),
- Scope = scope.Scope,
- };
+ record.Scope = scope.Scope;
- scope.NestedTypes.Add(result);
+ scope.NestedTypes.Add(record);
}
break;
default:
throw new BadImageFormatException();
}
+ }
+
+ private readonly struct ForwarderKey : IEquatable<ForwarderKey>
+ {
+ public readonly Cts.Ecma.EcmaModule Module;
+ public readonly Ecma.ExportedTypeHandle ExportedType;
+ public ForwarderKey(Cts.Ecma.EcmaModule module, Ecma.ExportedTypeHandle exportedType)
+ => (Module, ExportedType) = (module, exportedType);
- return result;
+ public bool Equals(ForwarderKey other) => Module == other.Module && ExportedType == other.ExportedType;
+ public override int GetHashCode() => HashCode.Combine(Module.GetHashCode(), ExportedType.GetHashCode());
}
}
}