/// <summary>
        /// Returns true if the given <paramref name="node"/> does not ends with a semicolon.
        /// </summary>
        public static bool IsSemicolonMissingAfter(INode node, TextSource text, out int position)
        {
            position = -1;

            if (!s_syntaxKindsToAnalyzer.Contains(node.Kind))
            {
                return(false);
            }

            var charPosition       = node.End - 1;
            var charCodeAtPosition = text.CharCodeAt(charPosition);

            if (charCodeAtPosition != CharacterCodes.Semicolon)
            {
                // When files are parsed while preserving whitespace, the semicolon might be followed by whitespace characters which is ok.
                // We therefore have to walk back until the first non-whitespace character.
                while (true)
                {
                    if (!Scanner.IsLineBreak(charCodeAtPosition) && !Scanner.IsWhiteSpace(charCodeAtPosition))
                    {
                        break;
                    }

                    charPosition--;
                    if (charPosition == 0)
                    {
                        break;
                    }

                    charCodeAtPosition = text.CharCodeAt(charPosition);

                    if (charCodeAtPosition == CharacterCodes.Semicolon)
                    {
                        // This node is fine
                        return(false);
                    }
                }

                position = charPosition;
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// Computes a map with line breaks.
        /// </summary>
        /// <remarks>
        /// This is heavyweight computation and the result of it definitely should be cached to avoid perf impact.
        /// </remarks>
        public static int[] ComputeLineStarts(TextSource text)
        {
            List <int> result    = new List <int>();
            var        pos       = 0;
            var        lineStart = 0;

            while (pos < text.Length)
            {
                var ch = text.CharCodeAt(pos++);
                switch (ch)
                {
                case CharacterCodes.CarriageReturn:
                    if (text.CharCodeAt(pos) == CharacterCodes.LineFeed)
                    {
                        pos++;
                    }

                    goto case CharacterCodes.LineFeed;

                case CharacterCodes.LineFeed:
                    result.Add(lineStart);
                    lineStart = pos;
                    break;

                default:
                    if (ch > CharacterCodes.MaxAsciiCharacter && Scanner.IsLineBreak(ch))
                    {
                        result.Add(lineStart);
                        lineStart = pos;
                    }

                    break;
                }
            }

            result.Add(lineStart);
            return(result.ToArray());
        }