/// <summary> /// Initializes namespaces and types maps with information about /// namespaces and types immediately contained within this namespace. /// </summary> /// <param name="typesByNS"> /// The sequence of groups of TypeDef row ids for types contained within the namespace, /// recursively including those from nested namespaces. The row ids must be grouped by the /// fully-qualified namespace name case-sensitively. There could be multiple groups /// for each fully-qualified namespace name. The groups must be sorted by /// their key in case-sensitive manner. Empty string must be used as namespace name for types /// immediately contained within Global namespace. Therefore, all types in this namespace, if any, /// must be in several first IGroupings. /// </param> protected void LoadAllMembers(IEnumerable <IGrouping <string, TypeDefinitionHandle> > typesByNS) { Debug.Assert(typesByNS != null); // A sequence of groups of TypeDef row ids for types immediately contained within this namespace. IEnumerable <IGrouping <string, TypeDefinitionHandle> > nestedTypes = null; // A sequence with information about namespaces immediately contained within this namespace. // For each pair: // Key - contains simple name of a child namespace. // Value - contains a sequence similar to the one passed to this function, but // calculated for the child namespace. IEnumerable <KeyValuePair <string, IEnumerable <IGrouping <string, TypeDefinitionHandle> > > > nestedNamespaces = null; bool isGlobalNamespace = this.IsGlobalNamespace; MetadataHelpers.GetInfoForImmediateNamespaceMembers( isGlobalNamespace, isGlobalNamespace ? 0 : GetQualifiedNameLength(), typesByNS, StringComparer.Ordinal, out nestedTypes, out nestedNamespaces); LazyInitializeNamespaces(nestedNamespaces); LazyInitializeTypes(nestedTypes); }
public void ObfuscatedNamespaceNames_02() { var result = new ArrayBuilder <IGrouping <string, TypeDefinitionHandle> >(); foreach (var namespaceName in new[] { ".a", ".b" }) { result.Add( new Grouping <string, TypeDefinitionHandle>( namespaceName, new[] { new TypeDefinitionHandle() } ) ); } result.Sort(new PEModule.TypesByNamespaceSortComparer(StringComparer.Ordinal)); // This is equivalent to the result of PEModule.GroupTypesByNamespaceOrThrow IEnumerable <IGrouping <string, TypeDefinitionHandle> > typesByNS = result; // The following code is equivalent to code in PENamespaceSymbol.LoadAllMembers IEnumerable <IGrouping <string, TypeDefinitionHandle> > nestedTypes = null; IEnumerable < KeyValuePair <string, IEnumerable <IGrouping <string, TypeDefinitionHandle> > > > nestedNamespaces = null; MetadataHelpers.GetInfoForImmediateNamespaceMembers( true, // global namespace 0, // global namespace typesByNS, StringComparer.Ordinal, out nestedTypes, out nestedNamespaces ); var nestedNS = nestedNamespaces.Single(); Assert.Equal("", nestedNS.Key); Assert.Equal(2, nestedNS.Value.Count()); MetadataHelpers.GetInfoForImmediateNamespaceMembers( false, nestedNS.Key.Length, nestedNS.Value, StringComparer.Ordinal, out nestedTypes, out nestedNamespaces ); Assert.Equal(2, nestedNamespaces.Count()); Assert.Equal("a", nestedNamespaces.ElementAt(0).Key); Assert.Equal("b", nestedNamespaces.ElementAt(1).Key); }
public void ObfuscatedNamespaceNames_01() { var result = new ArrayBuilder <IGrouping <string, TypeDefinitionHandle> >(); foreach (var namespaceName in new[] { "A.", "A.a", "A..", "A.-" }) { result.Add( new Grouping <string, TypeDefinitionHandle>( namespaceName, new[] { new TypeDefinitionHandle() } ) ); } result.Sort(new PEModule.TypesByNamespaceSortComparer(StringComparer.Ordinal)); // This is equivalent to the result of PEModule.GroupTypesByNamespaceOrThrow IEnumerable <IGrouping <string, TypeDefinitionHandle> > typesByNS = result; // The following code is equivalent to code in PENamespaceSymbol.LoadAllMembers IEnumerable <IGrouping <string, TypeDefinitionHandle> > nestedTypes = null; IEnumerable < KeyValuePair <string, IEnumerable <IGrouping <string, TypeDefinitionHandle> > > > nestedNamespaces = null; MetadataHelpers.GetInfoForImmediateNamespaceMembers( false, "A".Length, typesByNS, StringComparer.Ordinal, out nestedTypes, out nestedNamespaces ); // We don't expect duplicate keys in nestedNamespaces at this point. Assert.False( nestedNamespaces.GroupBy(pair => pair.Key).Where(g => g.Count() > 1).Any() ); var array = nestedNamespaces.ToArray(); Assert.Equal(3, array.Length); Assert.Equal("", array[0].Key); Assert.Equal(2, array[0].Value.Count()); Assert.Equal("-", array[1].Key); Assert.Equal(1, array[1].Value.Count()); Assert.Equal("a", array[2].Key); Assert.Equal(1, array[2].Value.Count()); }