| File: ILCompiler\Metadata\Transform.Namespace.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 Internal.Metadata.NativeFormat.Writer; using Cts = Internal.TypeSystem; using Debug = System.Diagnostics.Debug; namespace ILCompiler.Metadata { internal partial class Transform<TPolicy> { private Dictionary<NamespaceKey, NamespaceDefinition> _namespaceDefs = new Dictionary<NamespaceKey, NamespaceDefinition>(); private NamespaceDefinition HandleNamespaceDefinition(Cts.ModuleDesc parentScope, string namespaceString) { Debug.Assert(namespaceString != null); NamespaceDefinition result; NamespaceKey key = new NamespaceKey(parentScope, namespaceString); if (_namespaceDefs.TryGetValue(key, out result)) { return result; } if (namespaceString.Length == 0) { var rootNamespace = new NamespaceDefinition { Name = null, }; _namespaceDefs.Add(key, rootNamespace); ScopeDefinition rootScope = HandleScopeDefinition(parentScope); rootScope.RootNamespaceDefinition = rootNamespace; rootNamespace.ParentScopeOrNamespace = rootScope; return rootNamespace; } string currentNamespaceName = string.Empty; NamespaceDefinition currentNamespace = HandleNamespaceDefinition(parentScope, currentNamespaceName); foreach (var segment in namespaceString.Split('.')) { string nextNamespaceName = currentNamespaceName; if (nextNamespaceName.Length > 0) nextNamespaceName += '.'; nextNamespaceName += segment; NamespaceDefinition nextNamespace; key = new NamespaceKey(parentScope, nextNamespaceName); if (!_namespaceDefs.TryGetValue(key, out nextNamespace)) { nextNamespace = new NamespaceDefinition { Name = HandleString(segment.Length == 0 ? null : segment), ParentScopeOrNamespace = currentNamespace }; _namespaceDefs.Add(key, nextNamespace); currentNamespace.NamespaceDefinitions.Add(nextNamespace); } currentNamespace = nextNamespace; currentNamespaceName = nextNamespaceName; } return currentNamespace; } private Dictionary<NamespaceKey, NamespaceReference> _namespaceRefs = new Dictionary<NamespaceKey, NamespaceReference>(); private NamespaceReference HandleNamespaceReference(Cts.ModuleDesc parentScope, string namespaceString) { // The format represents root namespace as a namespace with null name, in contrast with ECMA-335 if (namespaceString.Length == 0) namespaceString = null; NamespaceReference result; NamespaceKey key = new NamespaceKey(parentScope, namespaceString); if (_namespaceRefs.TryGetValue(key, out result)) { return result; } ScopeReference scope = HandleScopeReference(parentScope); NamespaceReference rootNamespace; key = new NamespaceKey(parentScope, null); if (!_namespaceRefs.TryGetValue(key, out rootNamespace)) { rootNamespace = new NamespaceReference { Name = null, ParentScopeOrNamespace = scope, }; _namespaceRefs.Add(key, rootNamespace); } if (namespaceString == null) return rootNamespace; NamespaceReference currentNamespace = rootNamespace; string currentNamespaceName = string.Empty; foreach (var segment in namespaceString.Split('.')) { string nextNamespaceName = currentNamespaceName; if (nextNamespaceName.Length > 0) nextNamespaceName += '.'; nextNamespaceName += segment; NamespaceReference nextNamespace; key = new NamespaceKey(parentScope, nextNamespaceName); if (!_namespaceRefs.TryGetValue(key, out nextNamespace)) { nextNamespace = new NamespaceReference { Name = HandleString(segment.Length == 0 ? null : segment), ParentScopeOrNamespace = currentNamespace }; _namespaceRefs.Add(key, nextNamespace); } currentNamespace = nextNamespace; currentNamespaceName = nextNamespaceName; } return currentNamespace; } } internal struct NamespaceKey : IEquatable<NamespaceKey> { public readonly Cts.ModuleDesc Module; public readonly string Namespace; public NamespaceKey(Cts.ModuleDesc module, string namespaceName) { Module = module; Namespace = namespaceName; } public bool Equals(NamespaceKey other) { return Module == other.Module && Namespace == other.Namespace; } public override bool Equals(object obj) { if (obj is NamespaceKey) return Equals((NamespaceKey)obj); return false; } public override int GetHashCode() { return Namespace != null ? Namespace.GetHashCode() : 0; } } }