public override ISpecificCodeCompletionContext GetCompletionContext(CodeCompletionContext context)
        {
            TreeOffset startOffset = context.SelectedTreeRange.StartOffset;
            ITokenNode tokenNode   = GetTokenNode(context);

            if (tokenNode == null)
            {
                return(null);
            }

            int offset = tokenNode.GetTreeStartOffset().Offset;
            int start  = startOffset.Offset - offset;

            if (start <= 2)
            {
                return(null);
            }

            string text = tokenNode.GetText();

            if (start > text.Length)
            {
                return(null);
            }

            string commentText = text.Substring(2, start - 2);
            int    emojiStart  = commentText.LastIndexOf(':');

            if (emojiStart < 0)
            {
                return(null);
            }
            for (int index = emojiStart + 1; index < commentText.Length; ++index)
            {
                if ((index != emojiStart + 1 || !IsEmojiChar(commentText[index])) && (index <= emojiStart + 1 || !IsEmojiChar(commentText[index])))
                {
                    return(null);
                }
            }
            DocumentRange documentRange = context.File.GetDocumentRange(new TreeTextRange(new TreeOffset(offset + emojiStart + 2), new TreeOffset(offset + start)));

            if (!documentRange.IsValid())
            {
                return(null);
            }
            return(new ContextInDocComment(context, documentRange, new TextLookupRanges(documentRange.TextRange, documentRange.TextRange)));
        }
        private static ICSharpInvocationReference FindInvocationReference([NotNull] IReference reference)
        {
            if (reference is ICSharpInvocationReference invocationReference)
            {
                return(invocationReference);
            }

            ITreeNode  treeNode       = reference.GetTreeNode();
            var        argumentsOwner = treeNode.GetContainingNode <ICSharpArgumentsOwner>();
            ITokenNode lBound         = argumentsOwner?.LBound;

            if (lBound != null && treeNode.GetTreeEndOffset() <= lBound.GetTreeStartOffset())
            {
                return(argumentsOwner.Reference);
            }

            return(null);
        }
        /// <summary>
        /// Returns the count of whitespace at the front of the line provided.
        /// </summary>
        /// <param name="tokenNode">
        /// The tokenNode to start at.
        /// </param>
        /// <returns>
        /// The count of the leftmost whitespace.
        /// </returns>
        public static int GetOffsetToStartOfLine(ITokenNode tokenNode)
        {
            ITokenNode firstTokenOnLine = Utils.GetFirstNewLineTokenToLeft(tokenNode).GetNextToken();

            TreeOffset startPosition = firstTokenOnLine.GetTreeStartOffset();

            return tokenNode.GetTreeStartOffset() - startPosition;
        }