private bool ContainsPublics(IMemberDatabase source, int index) { SymbolType type = source.GetMemberType(index); SymbolModifier modifier = source.GetMemberModifiers(index); // If this is a public type or extension method, we contain them if ((type.IsType() || type.IsExtensionMethod()) && modifier.HasFlag(SymbolModifier.Public)) { return(true); } // If any descendants contain public types, we contain them int childIndex = source.DeclaredMembers.GetFirstChild(index); while (childIndex > 0) { if (ContainsPublics(source, childIndex)) { return(true); } childIndex = source.DeclaredMembers.GetNextSibling(childIndex); } // Otherwise, we don't return(false); }
private static void WriteTextTree(TextWriter w, IMemberDatabase db, int index, int indent, bool[] nodesToDraw) { if (indent >= 0) { if (nodesToDraw[index] == false) { return; } for (int i = 0; i < indent; ++i) { w.Write("\t"); } w.Write((char)db.GetMemberType(index)); w.Write(" "); db.StringStore[db.DeclaredMembers.GetNameIdentifier(index)].WriteTo(w); w.WriteLine(); } int child = db.DeclaredMembers.GetFirstChild(index); while (child > 0) { WriteTextTree(w, db, child, indent + 1, nodesToDraw); child = db.DeclaredMembers.GetNextSibling(child); } }
private bool MatchesDetailed(ItemTree declaredMembers, StringStore strings, IMemberDatabase db, int symbolIndex) { if (!Matches(declaredMembers, strings, symbolIndex)) { return(false); } if (Type != SymbolType.Any && db.GetMemberType(symbolIndex) != Type) { return(false); } if (!Modifiers.Matches(db.GetMemberModifiers(symbolIndex))) { return(false); } // ISSUE: Need a way to specify you want the empty params overload of a method (other than full match) // NOTE: Parameters8 was a copy gotten from StringStore to make this comparison fast (rather than a byte-by-byte comparison) // NOTE: Case insensitive comparison because StringStore lookup was case-insensitive, so Parameters8 casing isn't specific // NOTE: Need String8 rather than just checking Range.Contains because IMemberDatabase doesn't offer returning the identifier if ((IsFullSuffix || !this.ParametersIdentifiers.IsEmpty()) && db.GetMemberParameters(symbolIndex).CompareTo(Parameters8, true) != 0) { return(false); } return(true); }
public static bool TryGetFirstChildOfType(this IMemberDatabase db, int memberIndex, SymbolType symbolType, out int childIndex) { childIndex = db.DeclaredMembers.GetFirstChild(memberIndex); while (childIndex > 0) { if (db.GetMemberType(childIndex) == symbolType) { return(true); } childIndex = db.DeclaredMembers.GetNextSibling(childIndex); } return(false); }
public static bool TryGetAncestorOfType(this IMemberDatabase db, int memberIndex, SymbolType ancestorType, out int ancestor) { ancestor = memberIndex; while (ancestor > 0) { if (db.GetMemberType(ancestor) == ancestorType) { return(true); } ancestor = db.DeclaredMembers.GetParent(ancestor); } return(false); }
/// <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); }