| File: ILCompiler\Metadata\Transform.Scope.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.MetadataTransform\ILCompiler.MetadataTransform.csproj (ILCompiler.MetadataTransform) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using Internal.Metadata.NativeFormat.Writer; using Cts = Internal.TypeSystem; using Ecma = System.Reflection.Metadata; using Debug = System.Diagnostics.Debug; using AssemblyFlags = Internal.Metadata.NativeFormat.AssemblyFlags; using AssemblyNameInfo = System.Reflection.Metadata.AssemblyNameInfo; namespace ILCompiler.Metadata { internal partial class Transform<TPolicy> { internal EntityMap<Cts.ModuleDesc, ScopeDefinition> _scopeDefs = new EntityMap<Cts.ModuleDesc, ScopeDefinition>(EqualityComparer<Cts.ModuleDesc>.Default); private Action<Cts.ModuleDesc, ScopeDefinition> _initScopeDef; private ScopeDefinition HandleScopeDefinition(Cts.ModuleDesc module) { return _scopeDefs.GetOrCreate(module, _initScopeDef ??= InitializeScopeDefinition); } private void InitializeScopeDefinition(Cts.ModuleDesc module, ScopeDefinition scopeDefinition) { var assemblyDesc = module as Cts.IAssemblyDesc; if (assemblyDesc != null) { var assemblyName = assemblyDesc.GetName(); scopeDefinition.Name = HandleString(assemblyName.Name); scopeDefinition.Culture = HandleString(assemblyName.CultureName); scopeDefinition.MajorVersion = checked((ushort)assemblyName.Version.Major); scopeDefinition.MinorVersion = checked((ushort)assemblyName.Version.Minor); scopeDefinition.BuildNumber = checked((ushort)assemblyName.Version.Build); scopeDefinition.RevisionNumber = checked((ushort)assemblyName.Version.Revision); scopeDefinition.Flags = (AssemblyFlags)assemblyName.Flags; scopeDefinition.PublicKey = assemblyName.PublicKeyOrToken.ToArray(); Cts.MetadataType moduleType = module.GetGlobalModuleType(); if (moduleType != null && _policy.GeneratesMetadata(moduleType)) { scopeDefinition.GlobalModuleType = (TypeDefinition)HandleType(moduleType); } Cts.Ecma.EcmaAssembly ecmaAssembly = module as Cts.Ecma.EcmaAssembly; if (ecmaAssembly != null) { Ecma.CustomAttributeHandleCollection customAttributes = ecmaAssembly.AssemblyDefinition.GetCustomAttributes(); if (customAttributes.Count > 0) { scopeDefinition.CustomAttributes = HandleCustomAttributes(ecmaAssembly, customAttributes); } Cts.MethodDesc entryPoint = ecmaAssembly.EntryPoint; if (entryPoint != null && _policy.GeneratesMetadata(entryPoint)) { scopeDefinition.EntryPoint = (QualifiedMethod)HandleQualifiedMethod(entryPoint); } Ecma.MetadataReader reader = ecmaAssembly.MetadataReader; Ecma.ModuleDefinition moduleDefinition = reader.GetModuleDefinition(); scopeDefinition.ModuleName = HandleString(reader.GetString(moduleDefinition.Name)); scopeDefinition.Mvid = reader.GetGuid(moduleDefinition.Mvid).ToByteArray(); // This is rather awkward because ModuleDefinition doesn't offer means to get to the custom attributes Ecma.CustomAttributeHandleCollection moduleAttributes = reader.GetCustomAttributes(Ecma.Ecma335.MetadataTokens.EntityHandle(0x1)); if (moduleAttributes.Count > 0) { scopeDefinition.ModuleCustomAttributes = HandleCustomAttributes(ecmaAssembly, moduleAttributes); } HandleTypeForwarders(ecmaAssembly); } } else { throw new NotSupportedException("Multi-module assemblies"); } } private EntityMap<AssemblyNameInfo, ScopeReference> _scopeRefs = new EntityMap<AssemblyNameInfo, ScopeReference>(new SimpleAssemblyNameComparer()); private Action<AssemblyNameInfo, ScopeReference> _initScopeRef; private ScopeReference HandleScopeReference(Cts.ModuleDesc module) { var assembly = module as Cts.IAssemblyDesc; if (assembly != null) return HandleScopeReference(assembly.GetName()); else throw new NotSupportedException("Multi-module assemblies"); } private ScopeReference HandleScopeReference(AssemblyNameInfo assemblyName) { return _scopeRefs.GetOrCreate(assemblyName, _initScopeRef ??= InitializeScopeReference); } private void InitializeScopeReference(AssemblyNameInfo assemblyName, ScopeReference scopeReference) { scopeReference.Name = HandleString(assemblyName.Name); scopeReference.Culture = HandleString(assemblyName.CultureName); scopeReference.MajorVersion = checked((ushort)assemblyName.Version.Major); scopeReference.MinorVersion = checked((ushort)assemblyName.Version.Minor); scopeReference.BuildNumber = checked((ushort)assemblyName.Version.Build); scopeReference.RevisionNumber = checked((ushort)assemblyName.Version.Revision); scopeReference.Flags = (AssemblyFlags)assemblyName.Flags & (AssemblyFlags.Retargetable | AssemblyFlags.ContentTypeMask); // References use a public key token instead of full public key. ImmutableArray<byte> publicKeyOrToken = assemblyName.PublicKeyOrToken; if ((assemblyName.Flags & AssemblyNameFlags.PublicKey) != 0) { // Use AssemblyName to convert PublicKey to PublicKeyToken to avoid calling crypto APIs directly AssemblyName an = new(); an.SetPublicKey(ImmutableCollectionsMarshal.AsArray<byte>(publicKeyOrToken)); publicKeyOrToken = ImmutableCollectionsMarshal.AsImmutableArray<byte>(an.GetPublicKeyToken()); } scopeReference.PublicKeyOrToken = publicKeyOrToken.ToArray(); } private sealed class SimpleAssemblyNameComparer : IEqualityComparer<AssemblyNameInfo> { public bool Equals(AssemblyNameInfo x, AssemblyNameInfo y) { return Equals(x.Name, y.Name); } public int GetHashCode(AssemblyNameInfo obj) { return obj.Name.GetHashCode(); } } } }