Exemplo n.º 1
0
        public bool PathExists(string path)
        {
            string ns = path;

            int lastIndex = 0;
            CliNamespaceKeyedTree topLevel = this.info;

nextPart:
            int next = ns.IndexOf('.', lastIndex);

            if (next != -1)
            {
                string current     = ns.Substring(lastIndex, next - lastIndex);
                uint   currentHash = (uint)current.GetHashCode();
                if (topLevel.ContainsKey(currentHash))
                {
                    topLevel = topLevel[currentHash];
                }
                else
                {
                    return(false);
                }
                lastIndex = next + 1;
                goto nextPart;
            }
            else
            {
                string current     = ns.Substring(lastIndex);
                uint   currentHash = (uint)current.GetHashCode();
                return(topLevel.ContainsKey(currentHash));
            }
        }
Exemplo n.º 2
0
 internal CliNamespaceDictionary(CliAssembly owner, INamespaceParent parent, CliNamespaceKeyedTree info)
     : base(info.Keys)
 {
     this.owner  = owner;
     this.info   = info;
     this.parent = parent;
 }
Exemplo n.º 3
0
        public INamespaceDeclaration this[string path]
        {
            get
            {
                string ns = path;

                int lastIndex = 0;
                CliNamespaceKeyedTree topLevel         = this.info;
                INamespaceDictionary  topNamespaceDict = this;
                StringBuilder         pathBuilder      = new StringBuilder();
                bool first = true;
nextPart:
                int next = ns.IndexOf('.', lastIndex);
                if (first)
                {
                    first = false;
                }
                else
                {
                    pathBuilder.Append('.');
                }
                if (next != -1)
                {
                    string current = ns.Substring(lastIndex, next - lastIndex);
                    pathBuilder.Append(current);
                    uint currentHash = (uint)current.GetHashCode();
                    if (topLevel.ContainsKey(currentHash))
                    {
                        topLevel         = topLevel[currentHash];
                        topNamespaceDict = topNamespaceDict[TypeSystemIdentifiers.GetDeclarationIdentifier(pathBuilder.ToString())].Namespaces;
                    }
                    else
                    {
                        return(null);
                    }
                    lastIndex = next + 1;
                    goto nextPart;
                }
                else
                {
                    string current = ns.Substring(lastIndex);
                    pathBuilder.Append(current);
                    uint currentHash = (uint)current.GetHashCode();
                    if (topLevel.ContainsKey(currentHash))
                    {
                        topLevel = topLevel[currentHash];
                        return(topNamespaceDict[TypeSystemIdentifiers.GetDeclarationIdentifier(pathBuilder.ToString())]);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }
Exemplo n.º 4
0
 protected override void Dispose(bool disposing)
 {
     this.metadataRoot.Dispose();
     this.metadataRoot         = null;
     this.namespaceInformation = null;
 }
Exemplo n.º 5
0
        internal void InitializeCommon()
        {
            ICliMetadataModuleTableRow[] modules = this.Modules.GetMetadata();

            var typeTables = (from moduleRow in modules
                              let ts = moduleRow.MetadataRoot.TableStream
                                       where ts.TypeDefinitionTable != null
                                       select ts.TypeDefinitionTable).ToArray();

            if (typeTables.Length == 0)
            {
                return;
            }
            HashSet <Tuple <int, uint> > namespaceIndices = new HashSet <Tuple <int, uint> >();

            Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]> nonNestedTypes = new Dictionary <uint, CliMetadataTypeDefinitionLockedTableRow[]>();
            Dictionary <uint, int> nonNestedCounts = new Dictionary <uint, int>();

            /* *
             * Breakdown the types by their namespace index, and
             * create a unique list of namespaceIndices via a HashSet<T>.
             * *
             * Copy the table to a local set to avoid redundant load
             * checks, and to instruct it to read the full table sequentially.
             * */
            int totalTypeCount = 0;

            for (int typeTable = 0; typeTable < typeTables.Length; typeTable++)
            {
                totalTypeCount += typeTables[typeTable].Count;
            }
            ICliMetadataTypeDefinitionTableRow[] types = new ICliMetadataTypeDefinitionTableRow[totalTypeCount];
            for (int moduleIndex = 0, cOff = 0; moduleIndex < typeTables.Length; cOff += typeTables[moduleIndex++].Count)
            {
                typeTables[moduleIndex].CopyTo(types, cOff);
            }
            ICliMetadataTypeDefinitionTable moduleTypes = typeTables[0];

            for (int typeIndex = 0, moduleIndex = 0, moduleOffset = 0; typeIndex < types.Length; typeIndex++, moduleOffset++)
            {
moduleCheck:
                if (moduleOffset >= moduleTypes.Count)
                {
                    moduleIndex++;
                    if (moduleIndex < typeTables.Length)
                    {
                        moduleTypes = typeTables[moduleIndex];
                    }
                    moduleOffset = 0;
                    goto moduleCheck;
                }
                var typeRow = types[typeIndex];
                if ((typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic ||
                    (typeRow.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public)
                {
                    uint nsIndex = typeRow.NamespaceIndex;
                    namespaceIndices.Add(Tuple.Create(moduleIndex, nsIndex));
                    CliMetadataTypeDefinitionLockedTableRow[] currentRows;
                    if (!nonNestedTypes.TryGetValue(nsIndex, out currentRows))
                    {
                        nonNestedTypes.Add(nsIndex, currentRows = new CliMetadataTypeDefinitionLockedTableRow[4]);
                        nonNestedCounts.Add(nsIndex, 0);
                    }
                    CliMetadataTypeDefinitionLockedTableRow[] spaceAvailableRows = currentRows.EnsureSpaceExists(nonNestedCounts[nsIndex], 1);
                    if (spaceAvailableRows != currentRows)
                    {
                        nonNestedTypes[nsIndex] = currentRows = spaceAvailableRows;
                    }
                    currentRows[nonNestedCounts[nsIndex]++] = typeRow as CliMetadataTypeDefinitionLockedTableRow;
                }
            }

            var namespaceIndicesArray = namespaceIndices.ToArray();

            CliMetadataTypeDefinitionLockedTableRow[] topLevelRows;
            if (nonNestedTypes.TryGetValue(0, out topLevelRows))
            {
                int topLevelCount = nonNestedCounts[0];
                int noModuleCount = 0;
                for (int typeIndex = 0; typeIndex < topLevelCount; typeIndex++)
                {
                    if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__)
                    {
                        noModuleCount++;
                    }
                }

                if (topLevelRows.Length != noModuleCount)
                {
                    CliMetadataTypeDefinitionLockedTableRow[] topLevelRowsActual = new CliMetadataTypeDefinitionLockedTableRow[noModuleCount];

                    /* *
                     * Filter the entries based off of their index.  The special <Module> type
                     * is the global fields and methods.  There's no need to include them and
                     * have to inject checks elsewhere to filter it out.
                     * */
                    for (int typeIndex = 0, cOffset = 0; typeIndex < topLevelCount; typeIndex++)
                    {
                        if (topLevelRows[typeIndex].Index != CliMetadataTypeDefinitionTableReader.__COR_TYPEDEFINITION_MODULE_INDEX__)
                        {
                            topLevelRowsActual[cOffset++] = topLevelRows[typeIndex];
                        }
                    }

                    Array.Sort(topLevelRowsActual, _CompareTo_);
                    topLevelRows = topLevelRowsActual;
                }
                else
                {
                    Array.Sort(topLevelRows, _CompareTo_);
                }
            }
            else
            {
                topLevelRows = new CliMetadataTypeDefinitionLockedTableRow[0];
            }

            CliNamespaceKeyedTree     partialOrFullNamespaces = new CliNamespaceKeyedTree(topLevelRows);
            Dictionary <string, uint> partIndex = new Dictionary <string, uint>();

            for (int namespaceIndex = 0; namespaceIndex < namespaceIndicesArray.Length; namespaceIndex++)
            {
                uint currentIndex = namespaceIndicesArray[namespaceIndex].Item2;
                if (currentIndex == 0)
                {
                    continue;
                }
                var    currentRows   = nonNestedTypes[currentIndex];
                var    currentCount  = nonNestedCounts[currentIndex];
                var    module        = modules[namespaceIndicesArray[namespaceIndex].Item1];
                string currentString = module.MetadataRoot.StringsHeap[currentIndex];

                /* *
                 * Eliminate the null row entries by reducing the sizes
                 * of the arrays.
                 * */
                if (currentRows.Length != currentCount)
                {
                    var currentRowsCopy = new CliMetadataTypeDefinitionLockedTableRow[currentCount];
                    Array.ConstrainedCopy(currentRows, 0, currentRowsCopy, 0, currentCount);
                    Array.Sort(currentRowsCopy, _CompareTo_);
                    currentRows = currentRowsCopy;
                }
                else
                {
                    Array.Sort(currentRows, _CompareTo_);
                }

                CliNamespaceKeyedTree current = partialOrFullNamespaces;
                string[] breakdown            = currentString.Split(new[] { "." }, StringSplitOptions.None);
                int      currentLength        = 0;
                bool     first = true;
                foreach (var part in breakdown)
                {
                    /* *
                     * Position tracking, there is no period preceeding
                     * the first namespace identifier.
                     * */
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        currentLength++;
                    }
                    uint partId;

                    /* *
                     * Don't use the namespace index as a key for the
                     * partial or full dictionary.
                     * *
                     * Use the substring of the current namespace as a guide,
                     * since the 'System' of 'System'.Collections.Generic would
                     * be a different string heap index than 'System' alone,
                     * create our own reference lookup for the individual
                     * segments of the namespace's name.
                     * *
                     * Use the segment's hash code to determine the part index;
                     * while there's a chance for collision, the chances are slim.
                     * Main reason is: while the space of possible character combinations
                     * is small, the chance of a user-written name overlapping, in the
                     * realm of its sibling namespaces, is unlikely.
                     * */
                    if (!partIndex.TryGetValue(part, out partId))
                    {
                        partIndex.Add(part, partId = (uint)part.GetHashCode());
                    }
                    int startIndex = currentLength;
                    currentLength += part.Length;
                    bool fullName = currentLength == currentString.Length;
                    CliNamespaceKeyedTreeNode next;
                    if (!current.TryGetValue(partId, out next))
                    {
                        if (fullName)
                        {
                            current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, currentRows, module.MetadataRoot.StringsHeap);
                        }
                        else
                        {
                            current = current.Add(partId, currentIndex, startIndex, currentLength - startIndex, module.MetadataRoot.StringsHeap);
                        }
                    }
                    else
                    {
                        current = next;
                        if (fullName)
                        {
                            current.PushModuleTypes(currentRows);
                        }
                    }
                }
            }
            this.namespaceInformation = partialOrFullNamespaces;
        }