Example #1
0
 /// <nodoc />
 public static Range ToRange(this ISourceFile spec)
 {
     return(new Range
     {
         Start = new Position {
             Character = 0, Line = 0
         },
         End = LineInfoExtensions.GetLineAndColumnBy(spec.End, spec, false).ToPosition(),
     });
 }
        /// <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"/>.
        /// </summary>
        public static bool TryGetNodeAtPosition(
            ISourceFile sourceFile,
            int position,
            Func <INode, bool> isNodeAcceptable,
            out INode nodeAtPosition)
        {
            var lineAndColumn = LineInfoExtensions.GetLineAndColumnBy(
                position: position,
                sourceFile: sourceFile,
                skipTrivia: false);

            return(TryGetNodeAtPosition(sourceFile, lineAndColumn, isNodeAcceptable, out nodeAtPosition));
        }
        /// <summary>
        /// Tries to find the node with the smallest width in the <paramref name="sourceFile"/>
        /// that contains the input <paramref name="lineAndColumn"/>, and is deemed acceptable by
        /// <paramref name="isNodeAcceptable"/>.
        /// </summary>
        /// <param name="sourceFile">Source file to search for node in.</param>
        /// <param name="lineAndColumn">The line-and-column location to get the node for.</param>
        /// <param name="isNodeAcceptable">A function that lets the caller have a say about which node to pick.</param>
        /// <param name="nodeAtPosition">Holds the returned node if the function returns true, and null otherwise.</param>
        /// <remarks>
        /// This function can return null in cases were there is no node at the current position. For example, asking
        /// for a node at an empty source line, or asking for a node when the position is inside a comment that
        /// encompasses the remainder of the file.
        /// </remarks>
        public static bool TryGetNodeAtPosition(
            ISourceFile sourceFile,
            LineAndColumn lineAndColumn,
            Func <INode, bool> isNodeAcceptable,
            out INode nodeAtPosition)
        {
            INode currentNode = null;

            NodeWalker.ForEachChildRecursively(sourceFile, (node) =>
            {
                if (node.IsInjectedForDScript())
                {
                    // Need to skip injected nodes.
                    return(null);
                }

                var nodeStart = LineInfoExtensions.GetLineAndColumnBy(
                    position: Types.NodeUtilities.GetTokenPosOfNode(node, sourceFile),
                    sourceFile: sourceFile,
                    skipTrivia: false);

                var nodeEnd = LineInfoExtensions.GetLineAndColumnBy(
                    position: node.End,
                    sourceFile: sourceFile,
                    skipTrivia: false);

                if (nodeStart > lineAndColumn || nodeEnd < lineAndColumn)
                {
                    // If this node starts after or ends before the position we are searching for, then we skip it
                    return(null);
                }

                if (currentNode == null || node.GetWidth() <= currentNode.GetWidth())
                {
                    if (isNodeAcceptable(node))
                    {
                        currentNode = node;
                    }
                }

                return((object)null);
            });

            nodeAtPosition = currentNode;
            return(currentNode != null);
        }