/// <summary> /// Tries to find the node with the smallest width in the <paramref name="sourceFile"/> /// that contains the input <paramref name="position"/>, and is deemed acceptable by /// <paramref name="isNodeAcceptable"/>. /// If the position points to a comment, the resulting node is null. /// </summary> public static bool TryGetNodeAtPosition(ISourceFile sourceFile, int position, Func <INode, bool> isNodeAcceptable, System.Threading.CancellationToken token, out INode currentNode) { Contract.Requires(sourceFile != null); Contract.Requires(position >= 0); INode result = null; NodeWalker.TraverseDepthFirstAndSelfInOrder( sourceFile, node => { var startPosition = node.GetNodeStartPositionWithoutTrivia(sourceFile); if (result != null && startPosition > position) { // We can stop the traversal already because the next node starts after the expected position. // And we know that the traversal is depth first from left to right. return(false); } if (startPosition <= position && position <= node.End) { if (result == null || node.GetNodeWidth(sourceFile) <= result.GetNodeWidth(sourceFile)) { if (isNodeAcceptable(node)) { result = node; } } } return(true); }, token); currentNode = result; return(result != null); }