Пример #1
0
        private bool Matches(ItemTree declaredMembers, StringStore strings, int symbolIndex)
        {
            int candidateNameIdentifier = declaredMembers.GetNameIdentifier(symbolIndex);

            if (!SymbolNameSuffixIdentifiers.Contains(candidateNameIdentifier))
            {
                return(false);
            }

            if (this.IgnoreCase == true)
            {
                return(true);
            }
            else
            {
                String8 candidateName8 = strings[candidateNameIdentifier];
                if (this.IsFullSuffix)
                {
                    return(this.SymbolNameSuffix.CompareTo(candidateName8, false) == 0);
                }
                else
                {
                    return(this.SymbolNameSuffix.CompareAsPrefixTo(candidateName8, false) == 0);
                }
            }
        }
Пример #2
0
        /// <summary>
        ///  Search the given IMemberDatabase for matches to this query and put
        ///  results into the results array provided. The capacity of the results
        ///  array determines how many results are returned.
        /// </summary>
        /// <param name="db">Database to search</param>
        /// <param name="results">PartialArray to contain results, sized for the count desired.</param>
        /// <returns>True if results were added, False otherwise</returns>
        public bool TryFindMembers(IMemberDatabase db, ref PartialArray <Symbol> results)
        {
            // Ensure strings must be found again so that benchmarks are realistic
            ForceReresolve();

            // Clear results from a previous query
            results.Clear();

            // If there was no query, return with no results
            if (String.IsNullOrEmpty(SymbolName))
            {
                return(false);
            }

            // Get required members from database
            StringStore strings         = db.StringStore;
            ItemTree    declaredMembers = db.DeclaredMembers;
            MemberIndex index           = db.Index;

            // Map strings to the local StringStore. Stop immediately if any values aren't found.
            if (!ResolveStringsTo(strings))
            {
                return(false);
            }

            // Cache whether this query needs details to match
            bool usesDetails = !this.Parameters8.IsEmpty() || this.Type != SymbolType.Any || this.Modifiers != SymbolModifier.None;

            int[] matches;
            int   matchesIndex, matchesCount;

            if (SplitSymbolName8.Count == 1)
            {
                // Find the set of symbols with names in range. If no symbols in index, return nothing
                if (!index.TryGetMatchesInRange(SymbolNameSuffixIdentifiers, out matches, out matchesIndex, out matchesCount))
                {
                    return(false);
                }

                // If there was just one name part searched for, all matches count
                for (int i = matchesIndex; i < matchesIndex + matchesCount; ++i)
                {
                    if ((usesDetails ? MatchesDetailed(declaredMembers, strings, db, matches[i]) : Matches(declaredMembers, strings, matches[i])))
                    {
                        results.Add(new Symbol(db, matches[i]));
                        if (results.IsFull)
                        {
                            return(true);
                        }
                    }
                }
            }
            else
            {
                // Find all entries with exactly the second-to-last name
                if (!index.TryGetMatchesInRange(SymbolNamePrefixIdentifiers[SymbolNamePrefixIdentifiers.Length - 1], out matches, out matchesIndex, out matchesCount))
                {
                    return(false);
                }

                for (int i = matchesIndex; i < matchesIndex + matchesCount; ++i)
                {
                    int currentMatchIndex = matches[i];

                    // First, do all previous name parts in the query match?
                    int currentAncestorIndex = currentMatchIndex;
                    int namePartIndex        = SymbolNamePrefixIdentifiers.Length - 2;
                    for (; namePartIndex >= 0; --namePartIndex)
                    {
                        currentAncestorIndex = declaredMembers.GetParent(currentAncestorIndex);
                        int currentAncestorNameIdentifier = declaredMembers.GetNameIdentifier(currentAncestorIndex);
                        if (!SymbolNamePrefixIdentifiers[namePartIndex].Contains(currentAncestorNameIdentifier))
                        {
                            break;
                        }
                    }

                    if (namePartIndex != -1)
                    {
                        continue;
                    }

                    // If this was a full match, are we out of namespaces?
                    if (IsFullNamespace)
                    {
                        currentAncestorIndex = declaredMembers.GetParent(currentAncestorIndex);
                        SymbolType symbolAboveFullNameType = db.GetMemberType(currentAncestorIndex);
                        if (!symbolAboveFullNameType.IsAboveNamespace())
                        {
                            return(false);
                        }
                    }

                    // Next, find children of this item which match the last part typed
                    int leafId = declaredMembers.GetFirstChild(currentMatchIndex);
                    while (leafId > 0)
                    {
                        if ((usesDetails ? MatchesDetailed(declaredMembers, strings, db, leafId) : Matches(declaredMembers, strings, leafId)))
                        {
                            results.Add(new Symbol(db, leafId));
                            if (results.IsFull)
                            {
                                return(true);
                            }
                        }

                        leafId = declaredMembers.GetNextSibling(leafId);
                    }
                }
            }

            return(results.Count > 0);
        }
Пример #3
0
        public void ItemTree_Basic()
        {
            byte[]     byteBuffer = new byte[100];
            int[]      intBuffer  = new int[10];
            String8Set splitPath8;

            StringStore strings  = new StringStore();
            ItemTree    fileTree = new ItemTree();

            string[] filePaths =
            {
                @"C:\Code\Arriba\Arriba\Diagnostics\DailyLogTraceListener.cs",
                @"C:\Code\Arriba\Arriba\Diagnostics\ProgressWriter.cs",
                @"C:\Code\Arriba\Arriba\Diagnostics\Log4NetDiagnosticConsumer.cs",
                @"C:\Code\Arriba\Arriba\Diagnostics\Memory.cs",
                @"C:\Code\Arriba\Arriba\Diagnostics\TraceWriter.cs"
            };

            List <int> fileTreeIndexes = new List <int>();

            // Index each file path
            foreach (string filePath in filePaths)
            {
                splitPath8 = String8.Convert(filePath, byteBuffer).Split('\\', intBuffer);
                fileTreeIndexes.Add(fileTree.AddPath(0, splitPath8, strings));
            }

            for (int i = 0; i < filePaths.Length; ++i)
            {
                // Reconstruct each file path and confirm they match
                string rebuiltPath = fileTree.GetPath(fileTreeIndexes[i], strings, '\\').ToString();
                Assert.AreEqual(filePaths[i], rebuiltPath);

                // Verify find by path works
                splitPath8 = String8.Convert(filePaths[i], byteBuffer).Split('\\', intBuffer);
                int foundAtIndex;
                Assert.IsTrue(fileTree.TryFindByPath(0, splitPath8, strings, out foundAtIndex));
                Assert.AreEqual(fileTreeIndexes[i], foundAtIndex);
            }

            // Verify find works
            int foundIndex;

            // Root found under sentinel root
            Assert.IsTrue(fileTree.TryFindChildByName(0, strings.FindOrAddString("C:"), out foundIndex));
            Assert.AreEqual(1, foundIndex);

            // Root not found under another node
            Assert.IsFalse(fileTree.TryFindChildByName(1, strings.FindOrAddString("C:"), out foundIndex));

            // Node not found at root
            Assert.IsFalse(fileTree.TryFindChildByName(0, strings.FindOrAddString("Code"), out foundIndex));

            // Node found under the right parent
            Assert.IsTrue(fileTree.TryFindChildByName(1, strings.FindOrAddString("Code"), out foundIndex));
            Assert.AreEqual(2, foundIndex);


            // FindByPath works under a partial path
            splitPath8 = String8.Convert(@"Code\Arriba", byteBuffer).Split('\\', intBuffer);
            int arribaIndex;

            Assert.IsTrue(fileTree.TryFindByPath(1, splitPath8, strings, out arribaIndex));

            splitPath8 = String8.Convert(@"Arriba\Diagnostics\DailyLogTraceListener.cs", byteBuffer).Split('\\', intBuffer);
            int dailyLogIndex;

            Assert.IsTrue(fileTree.TryFindByPath(arribaIndex, splitPath8, strings, out dailyLogIndex));
            Assert.AreEqual(fileTreeIndexes[0], dailyLogIndex);


            // FindByPath returns the closest element when it fails
            splitPath8 = String8.Convert(@"C:\Nope", byteBuffer).Split('\\', intBuffer);
            int nopeIndex;

            Assert.IsFalse(fileTree.TryFindByPath(0, splitPath8, strings, out nopeIndex));
            Assert.AreEqual(1, nopeIndex, @"Failed find for C:\Nope should return 'C:' index; the successful portion of the search.");

            splitPath8 = String8.Convert(@"C:\Code\Arriba\Arriba\Diagnostics\TraceWriter.cs\Nope", byteBuffer).Split('\\', intBuffer);
            Assert.IsFalse(fileTree.TryFindByPath(0, splitPath8, strings, out nopeIndex));
            Assert.AreEqual(fileTreeIndexes[4], nopeIndex);


            // Verify depth works
            Assert.AreEqual(0, fileTree.GetDepth(0));
            Assert.AreEqual(1, fileTree.GetDepth(1));
            Assert.AreEqual(6, fileTree.GetDepth(fileTreeIndexes[0]));
            Assert.AreEqual("C:", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 1))].ToString());
            Assert.AreEqual("Code", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 2))].ToString());
            Assert.AreEqual("Arriba", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 3))].ToString());
            Assert.AreEqual("Arriba", strings[fileTree.GetNameIdentifier(fileTree.GetAncestorAtDepth(fileTreeIndexes[0], 4))].ToString());

            // Sort the tree by name
            fileTree.SortByName(strings);

            // Log the tree
            Trace.WriteLine(Write.ToString((w) => fileTree.WriteTree(w, strings, 1)));

            // Verify roundtrip
            ItemTree readTree = new ItemTree();

            Verify.RoundTrip(fileTree, readTree);
            fileTree = readTree;

            // Reconstruct each file path
            for (int i = 0; i < filePaths.Length; ++i)
            {
                string rebuiltPath = fileTree.GetPath(fileTreeIndexes[i], strings, '\\').ToString();
                Assert.AreEqual(filePaths[i], rebuiltPath);
            }
        }