private static int SkipToPrefixWithWhiteSpace(ref DocSlice text, string prefix, int i)
        {
            Contract.Requires(i >= 0);
            Contract.Requires(!String.IsNullOrEmpty(prefix));
            Contract.Ensures(Contract.Result <int>() >= -1);
            Contract.Ensures(Contract.Result <int>() < text.Length);

            Contract.Assert(prefix != null);
            while (i < text.Length && Char.IsWhiteSpace(text[i]))
            {
                i++;
            }
            if (i >= text.Length)
            {
                return(-1);
            }
            int start = i;
            int j     = 0;

            while (i < text.Length && j < prefix.Length && text[i] == prefix[j])
            {
                i++; j++;
            }

            if (j == prefix.Length && i < text.Length && Char.IsWhiteSpace(text[i]))
            {
                return(start);
            }
            return(-1);
        }
Example #2
0
        private string /*?*/ GetSource(string prefix, SourceContext sctx, out bool isVB, bool islegacy = false)
        {
            isVB = false;
            if (!sctx.IsValid)
            {
                return(null);
            }

            if (sctx.StartLine <= 0)
            {
                return(null);
            }

            SourceDocument doc = GetDocument(sctx.Document);

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

            DocSlice slice      = new DocSlice(doc, sctx.StartLine, (islegacy) ? 0 : sctx.StartColumn, sctx.EndLine);
            var      parsedText = Parse(prefix, slice, out isVB);

            return(parsedText);
        }
Example #3
0
        private static string ParseVBIfThenText(DocSlice text, int start)
        {
            Contract.Requires(start >= 0);

            int i = start;

            while (i < text.Length)
            {
                // find space before Then
                while (i < text.Length && !Char.IsWhiteSpace(text[i]))
                {
                    i++;
                }

                // skip white space (or past text)
                i++;

                // check Then
                if (HasChar('T', text, i) && HasChar('h', text, i + 1) && HasChar('e', text, i + 2) &&
                    HasChar('n', text, i + 3))
                {
                    return(text.Substring(start, i - start));
                }
            }

            return(null);
        }
 private static bool HasChar(char c, DocSlice text, int i)
 {
     Contract.Requires(i >= 0);
     Contract.Ensures(i < text.Length || !Contract.Result <bool>());
     if (i >= text.Length)
     {
         return(false);
     }
     return(text[i] == c);
 }
        private static int FindPreceedingComma(ref DocSlice text, int i)
        {
            Contract.Requires(i >= 0);
            Contract.Requires(i < text.Length);
            Contract.Ensures(Contract.Result <int>() >= -1);
            Contract.Ensures(Contract.Result <int>() <= i);

            bool insideQuotes       = false;
            bool insideDoubleQuotes = false;
            int  parenCount         = 0;
            int  angleCount         = 0;

            i--; // skip closing paren
            while (i >= 0)
            {
                Contract.Assert(i < text.Length);
                if (!insideDoubleQuotes && text[i] == '\'' && !IsEscape(ref text, i - 1))
                {
                    insideQuotes = !insideQuotes;
                }
                if (!insideQuotes && text[i] == '"' && !IsEscape(ref text, i - 1))
                {
                    insideDoubleQuotes = !insideDoubleQuotes;
                }
                if (insideDoubleQuotes || insideQuotes)
                {
                    // skip
                }
                else
                {
                    if (text[i] == ',' && angleCount == 0 && parenCount == 0)
                    {
                        return(i);
                    }
                    else if (text[i] == ')')
                    {
                        parenCount++;
                    }
                    else if (text[i] == '(')
                    {
                        parenCount--;
                    }
                    else if (text[i] == '>')
                    {
                        angleCount++;
                    }
                    else if (text[i] == '<')
                    {
                        angleCount--;
                    }
                }
                i--;
            }
            return(-1);
        }
Example #6
0
        private static string /*?*/ Parse(string prefix, DocSlice /*?*/ text, out bool isVB)
        {
            int i;

            if (prefix == "if")
            {
                // legacy. Watch for VB If ... Then, in which case we are not seeing any parentheses
                i = SkipToPrefixWithWhiteSpace(ref text, "If", 0);
                if (i >= 0)
                {
                    isVB = true;
                    return(ParseVBIfThenText(text, i + 3));
                }
            }

            isVB = false;

            // skip to first open paren
            i = SkipToOpenParen(ref text, 0);
            if (i < 0)
            {
                return(null);
            }

            i++; // skip open paren
            // handle VB generics (Of
            if (i < text.Length && i + 1 < text.Length && text[i] == 'O' && text[i + 1] == 'f')
            {
                i = SkipToMatchingCloseParen(ref text, i + 2, false);
                if (i < 0)
                {
                    return(null);
                }

                i = SkipToOpenParen(ref text, i + 1);
                if (i < 0)
                {
                    return(null);
                }

                i++; // skip open paren
            }

            int indexOfFirstCharOfCondition = i;

            int closingParen = SkipToMatchingCloseParen(ref text, i, true);

            if (closingParen < indexOfFirstCharOfCondition)
            {
                return(null);
            }

            return(text.Substring(indexOfFirstCharOfCondition, closingParen - indexOfFirstCharOfCondition));
        }
        private static int SkipToOpenParen(ref DocSlice text, int i)
        {
            Contract.Requires(i >= 0);
            Contract.Ensures(Contract.Result <int>() >= -1);
            Contract.Ensures(Contract.Result <int>() < text.Length);

            while (i < text.Length && text[i] != '(')
            {
                i++;
            }
            if (i < text.Length)
            {
                return(i);
            }
            return(-1);
        }
        private static bool IsEscape(ref DocSlice text, int i)
        {
            Contract.Requires(i < text.Length);

            if (i < 0)
            {
                return(false);
            }
            if (text[i] != '\\')
            {
                return(false);
            }
            // avoid escaped backslash
            if (!IsEscape(ref text, i - 1))
            {
                return(true);
            }
            return(false);
        }
        private static int SkipToMatchingCloseParen(ref DocSlice text, int i, bool allowCommaAsEndingParen)
        {
            Contract.Requires(i >= 0);
            Contract.Ensures(Contract.Result <int>() >= -1);
            Contract.Ensures(Contract.Result <int>() < text.Length);

            bool containsComma;
            var  closingParen = FindClosingParenthesis(ref text, i, out containsComma);

            if (closingParen < 0 || !allowCommaAsEndingParen || !containsComma)
            {
                return(closingParen);
            }

            var commaPos = FindPreceedingComma(ref text, closingParen);

            if (commaPos >= 0)
            {
                return(commaPos);
            }
            return(closingParen);
        }