Exemple #1
0
        /// <summary>
        /// Loops through all type forwarders in metadata, adding them to the given table
        /// </summary>
        private void PopulateTableWithExportedTypes(Dictionary <NamespaceDefinitionHandle, NamespaceDataBuilder> table)
        {
            Debug.Assert(table != null);

            foreach (var exportedTypeHandle in _metadataReader.ExportedTypes)
            {
                ExportedType exportedType = _metadataReader.GetExportedType(exportedTypeHandle);
                if (exportedType.Implementation.Kind == HandleKind.ExportedType)
                {
                    continue; // skip nested exported types.
                }

                NamespaceDefinitionHandle namespaceHandle = exportedType.Namespace;
                NamespaceDataBuilder      builder;
                if (table.TryGetValue(namespaceHandle, out builder))
                {
                    builder.ExportedTypes.Add(exportedTypeHandle);
                }
                else
                {
                    Debug.Assert(namespaceHandle.HasFullName);
                    StringHandle simpleName = GetSimpleName(namespaceHandle);
                    string       fullName   = _metadataReader.GetString(namespaceHandle);
                    var          newData    = new NamespaceDataBuilder(namespaceHandle, simpleName, fullName);
                    newData.ExportedTypes.Add(exportedTypeHandle);
                    table.Add(namespaceHandle, newData);
                }
            }
        }
Exemple #2
0
 public void MergeInto(NamespaceDataBuilder other)
 {
     Parent = default(NamespaceDefinitionHandle);
     other.Namespaces.AddRange(this.Namespaces);
     other.TypeDefinitions.AddRange(this.TypeDefinitions);
     other.ExportedTypes.AddRange(this.ExportedTypes);
 }
Exemple #3
0
        /// <summary>
        /// This will take 'table' and merge all of the NamespaceData instances that point to the same
        /// namespace. It has to create 'stringTable' as an intermediate dictionary, so it will hand it
        /// back to the caller should the caller want to use it.
        /// </summary>
        private static void MergeDuplicateNamespaces(Dictionary <NamespaceDefinitionHandle, NamespaceDataBuilder> table, out Dictionary <string, NamespaceDataBuilder> stringTable)
        {
            var namespaces = new Dictionary <string, NamespaceDataBuilder>();
            List <KeyValuePair <NamespaceDefinitionHandle, NamespaceDataBuilder> >?remaps = null;

            foreach (var group in table)
            {
                NamespaceDataBuilder data = group.Value;
                NamespaceDataBuilder?existingRecord;
                if (namespaces.TryGetValue(data.FullName, out existingRecord))
                {
                    // Children should not exist until the next step.
                    Debug.Assert(data.Namespaces !.Count == 0);
                    data.MergeInto(existingRecord);

                    remaps ??= new List <KeyValuePair <NamespaceDefinitionHandle, NamespaceDataBuilder> >();
                    remaps.Add(new KeyValuePair <NamespaceDefinitionHandle, NamespaceDataBuilder>(group.Key, existingRecord));
                }
                else
                {
                    namespaces.Add(data.FullName, data);
                }
            }

            // Needs to be done outside of foreach (var group in table) to avoid modifying the dictionary while foreach'ing over it.
            if (remaps != null)
            {
                foreach (var tuple in remaps)
                {
                    table[tuple.Key] = tuple.Value;
                }
            }

            stringTable = namespaces;
        }
Exemple #4
0
        /// <summary>
        /// Loops through all type definitions in metadata, adding them to the given table
        /// </summary>
        private void PopulateTableWithTypeDefinitions(Dictionary <NamespaceDefinitionHandle, NamespaceDataBuilder> table)
        {
            Debug.Assert(table != null);

            foreach (var typeHandle in _metadataReader.TypeDefinitions)
            {
                TypeDefinition type = _metadataReader.GetTypeDefinition(typeHandle);
                if (type.Attributes.IsNested())
                {
                    continue;
                }

                NamespaceDefinitionHandle namespaceHandle = _metadataReader.TypeDefTable.GetNamespace(typeHandle);
                NamespaceDataBuilder      builder;
                if (table.TryGetValue(namespaceHandle, out builder))
                {
                    builder.TypeDefinitions.Add(typeHandle);
                }
                else
                {
                    StringHandle name     = GetSimpleName(namespaceHandle);
                    string       fullName = _metadataReader.GetString(namespaceHandle);
                    var          newData  = new NamespaceDataBuilder(namespaceHandle, name, fullName);
                    newData.TypeDefinitions.Add(typeHandle);
                    table.Add(namespaceHandle, newData);
                }
            }
        }
Exemple #5
0
 /// <summary>
 /// Quick convenience method that handles linking together child + parent
 /// </summary>
 private void LinkChildDataToParentData(NamespaceDataBuilder child, NamespaceDataBuilder parent)
 {
     Debug.Assert(child != null && parent != null);
     Debug.Assert(!child.Handle.IsNil);
     child.Parent = parent.Handle;
     parent.Namespaces.Add(child.Handle);
 }
Exemple #6
0
        /// <summary>
        /// Links a child to its parent namespace. If the parent namespace doesn't exist, this will create a
        /// synthetic one. This will automatically link any synthetic namespaces it creates up to its parents.
        /// </summary>
        private void LinkChildToParentNamespace(Dictionary <string, NamespaceDataBuilder> existingNamespaces,
                                                NamespaceDataBuilder realChild,
                                                ref List <NamespaceDataBuilder> syntheticNamespaces)
        {
            Debug.Assert(realChild.Handle.HasFullName);
            string childName = realChild.FullName;
            var    child     = realChild;

            // The condition for this loop is very complex -- essentially, we keep going
            // until we:
            //   A. Encounter the root namespace as 'child'
            //   B. Find a preexisting namespace as 'parent'
            while (true)
            {
                int    lastIndex = childName.LastIndexOf('.');
                string parentName;
                if (lastIndex == -1)
                {
                    if (childName.Length == 0)
                    {
                        return;
                    }
                    else
                    {
                        parentName = String.Empty;
                    }
                }
                else
                {
                    parentName = childName.Substring(0, lastIndex);
                }

                NamespaceDataBuilder parentData;
                if (existingNamespaces.TryGetValue(parentName, out parentData))
                {
                    LinkChildDataToParentData(child, parentData);
                    return;
                }

                if (syntheticNamespaces != null)
                {
                    foreach (var data in syntheticNamespaces)
                    {
                        if (data.FullName == parentName)
                        {
                            LinkChildDataToParentData(child, data);
                            return;
                        }
                    }
                }
                else
                {
                    syntheticNamespaces = new List <NamespaceDataBuilder>();
                }

                var syntheticParent = SynthesizeNamespaceData(parentName, realChild.Handle);
                LinkChildDataToParentData(child, syntheticParent);
                syntheticNamespaces.Add(syntheticParent);
                childName = syntheticParent.FullName;
                child     = syntheticParent;
            }
        }
Exemple #7
0
 public void MergeInto(NamespaceDataBuilder other)
 {
     Parent = default(NamespaceDefinitionHandle);
     other.Namespaces.AddRange(this.Namespaces);
     other.TypeDefinitions.AddRange(this.TypeDefinitions);
     other.ExportedTypes.AddRange(this.ExportedTypes);
 }
Exemple #8
0
        /// <summary>
        /// Loops through all type forwarders in metadata, adding them to the given table
        /// </summary>
        private void PopulateTableWithExportedTypes(Dictionary<NamespaceDefinitionHandle, NamespaceDataBuilder> table)
        {
            Debug.Assert(table != null);

            foreach (var exportedTypeHandle in _metadataReader.ExportedTypes)
            {
                ExportedType exportedType = _metadataReader.GetExportedType(exportedTypeHandle);
                if (exportedType.Implementation.Kind == HandleKind.ExportedType)
                {
                    continue; // skip nested exported types.
                }

                NamespaceDefinitionHandle namespaceHandle = exportedType.NamespaceDefinition;
                NamespaceDataBuilder builder;
                if (table.TryGetValue(namespaceHandle, out builder))
                {
                    builder.ExportedTypes.Add(exportedTypeHandle);
                }
                else
                {
                    Debug.Assert(namespaceHandle.HasFullName);
                    StringHandle simpleName = GetSimpleName(namespaceHandle);
                    string fullName = _metadataReader.GetString(namespaceHandle);
                    var newData = new NamespaceDataBuilder(namespaceHandle, simpleName, fullName);
                    newData.ExportedTypes.Add(exportedTypeHandle);
                    table.Add(namespaceHandle, newData);
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Loops through all type definitions in metadata, adding them to the given table
        /// </summary>
        private void PopulateTableWithTypeDefinitions(Dictionary<NamespaceDefinitionHandle, NamespaceDataBuilder> table)
        {
            Debug.Assert(table != null);

            foreach (var typeHandle in _metadataReader.TypeDefinitions)
            {
                TypeDefinition type = _metadataReader.GetTypeDefinition(typeHandle);
                if (type.Attributes.IsNested())
                {
                    continue;
                }

                NamespaceDefinitionHandle namespaceHandle = _metadataReader.TypeDefTable.GetNamespaceDefinition(typeHandle);
                NamespaceDataBuilder builder;
                if (table.TryGetValue(namespaceHandle, out builder))
                {
                    builder.TypeDefinitions.Add(typeHandle);
                }
                else
                {
                    StringHandle name = GetSimpleName(namespaceHandle);
                    string fullName = _metadataReader.GetString(namespaceHandle);
                    var newData = new NamespaceDataBuilder(namespaceHandle, name, fullName);
                    newData.TypeDefinitions.Add(typeHandle);
                    table.Add(namespaceHandle, newData);
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Links a child to its parent namespace. If the parent namespace doesn't exist, this will create a
        /// synthetic one. This will automatically link any synthetic namespaces it creates up to its parents.
        /// </summary>
        private void LinkChildToParentNamespace(Dictionary<string, NamespaceDataBuilder> existingNamespaces,
            NamespaceDataBuilder realChild,
            ref List<NamespaceDataBuilder> syntheticNamespaces)
        {
            Debug.Assert(realChild.Handle.HasFullName);
            string childName = realChild.FullName;
            var child = realChild;

            // The condition for this loop is very complex -- essentially, we keep going
            // until we: 
            //   A. Encounter the root namespace as 'child'
            //   B. Find a preexisting namespace as 'parent'
            while (true)
            {
                int lastIndex = childName.LastIndexOf('.');
                string parentName;
                if (lastIndex == -1)
                {
                    if (childName.Length == 0)
                    {
                        return;
                    }
                    else
                    {
                        parentName = String.Empty;
                    }
                }
                else
                {
                    parentName = childName.Substring(0, lastIndex);
                }

                NamespaceDataBuilder parentData;
                if (existingNamespaces.TryGetValue(parentName, out parentData))
                {
                    LinkChildDataToParentData(child, parentData);
                    return;
                }

                if (syntheticNamespaces != null)
                {
                    foreach (var data in syntheticNamespaces)
                    {
                        if (data.FullName == parentName)
                        {
                            LinkChildDataToParentData(child, data);
                            return;
                        }
                    }
                }
                else
                {
                    syntheticNamespaces = new List<NamespaceDataBuilder>();
                }

                var syntheticParent = SynthesizeNamespaceData(parentName, realChild.Handle);
                LinkChildDataToParentData(child, syntheticParent);
                syntheticNamespaces.Add(syntheticParent);
                childName = syntheticParent.FullName;
                child = syntheticParent;
            }
        }
Exemple #11
0
 /// <summary>
 /// Quick convenience method that handles linking together child + parent
 /// </summary>
 private void LinkChildDataToParentData(NamespaceDataBuilder child, NamespaceDataBuilder parent)
 {
     Debug.Assert(child != null && parent != null);
     Debug.Assert(!child.Handle.IsNil);
     child.Parent = parent.Handle;
     parent.Namespaces.Add(child.Handle);
 }