// // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. // using System; using System.Threading; using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes; using Microsoft.SqlTools.ServiceLayer.Utility; namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer { /// /// Utility class for Object Explorer related operations /// public static class ObjectExplorerUtils { /// /// Visitor that walks all nodes from the child to the root node, unless the /// function indicates that this should stop traversing /// /// node to start traversing at /// Predicate function that accesses the tree and /// determines whether to stop going further up the tree /// /// boolean - true to continue navigating up the tree, false to end the loop /// and return early /// public static bool VisitChildAndParents(TreeNode child, Predicate visitor) { if (child == null) { // End case: all nodes have been visited return true; } // Visit the child first, then go up the parents if (!visitor(child)) { return false; } return VisitChildAndParents(child.Parent, visitor); } /// /// Finds a node by traversing the tree starting from the given node through all the children /// /// node to start traversing at /// Predicate function that accesses the tree and /// determines whether to stop going further up the tree /// Predicate function to filter the children when traversing /// A Tree Node that matches the condition public static TreeNode FindNode(TreeNode node, Predicate condition, Predicate filter, bool expandIfNeeded = false) { if(node == null) { return null; } if (condition(node)) { return node; } var children = expandIfNeeded && !node.IsAlwaysLeaf ? node.Expand(new CancellationToken()) : node.GetChildren(); foreach (var child in children) { if (filter != null && filter(child)) { TreeNode childNode = FindNode(child, condition, filter, expandIfNeeded); if (childNode != null) { return childNode; } } } return null; } } }