示例#1
0
        private void AddMultiLineRawStringLiteralLineContents(
            StringBuilder indentationWhitespace,
            StringBuilder currentLineWhitespace,
            bool firstContentLine)
        {
            Debug.Assert(SyntaxFacts.IsNewLine(TextWindow.PeekChar()));

            var newLineWidth = TextWindow.GetNewLineWidth();

            for (var i = 0; i < newLineWidth; i++)
            {
                // the initial newline in `"""   \r\n` is not added to the contents.
                if (!firstContentLine)
                {
                    _builder.Append(TextWindow.PeekChar());
                }

                TextWindow.AdvanceChar();
            }

            var lineStartPosition = TextWindow.Position;

            currentLineWhitespace.Clear();
            ConsumeWhitespace(currentLineWhitespace);

            if (!StartsWith(currentLineWhitespace, indentationWhitespace))
            {
                // We have a line where the indentation of that line isn't a prefix of indentation
                // whitespace.
                //
                // If we're not on a blank line then this is bad.  That's a content line that doesn't start
                // with the indentation whitespace.  If we are on a blank line then it's ok if the whitespace
                // we do have is a prefix of the indentation whitespace.
                var isBlankLine      = SyntaxFacts.IsNewLine(TextWindow.PeekChar());
                var isLegalBlankLine = isBlankLine && StartsWith(indentationWhitespace, currentLineWhitespace);
                if (!isLegalBlankLine)
                {
                    // Specialized error message if this is a spacing difference.
                    if (CheckForSpaceDifference(
                            currentLineWhitespace, indentationWhitespace,
                            out var currentLineWhitespaceChar, out var indentationWhitespaceChar))
                    {
                        this.AddError(
                            lineStartPosition,
                            width: TextWindow.Position - lineStartPosition,
                            ErrorCode.ERR_LineContainsDifferentWhitespace,
                            currentLineWhitespaceChar, indentationWhitespaceChar);
                    }
                    else
                    {
                        this.AddError(
                            lineStartPosition,
                            width: TextWindow.Position - lineStartPosition,
                            ErrorCode.ERR_LineDoesNotStartWithSameWhitespace);
                    }
                    return;
                }
            }
示例#2
0
        private void ScanSingleLineRawStringLiteral(ref TokenInfo info, int startingQuoteCount)
        {
            info.Kind = SyntaxKind.SingleLineRawStringLiteralToken;

            while (true)
            {
                var currentChar = TextWindow.PeekChar();

                // See if we reached the end of the line or file before hitting the end.
                if (SyntaxFacts.IsNewLine(currentChar))
                {
                    this.AddError(TextWindow.Position, width: TextWindow.GetNewLineWidth(), ErrorCode.ERR_UnterminatedRawString);
                    return;
                }
                else if (IsAtEndOfText(currentChar))
                {
                    this.AddError(TextWindow.Position, width: 0, ErrorCode.ERR_UnterminatedRawString);
                    return;
                }

                if (currentChar != '"')
                {
                    // anything not a quote sequence just moves it forward.
                    TextWindow.AdvanceChar();
                    continue;
                }

                var beforeEndDelimiter = TextWindow.Position;
                var currentQuoteCount  = ConsumeQuoteSequence();

                // A raw string literal starting with some number of quotes can contain a quote sequence with fewer quotes.
                if (currentQuoteCount < startingQuoteCount)
                {
                    continue;
                }

                // A raw string could never be followed by another string.  So once we've consumed all the closing quotes
                // if we have any more closing quotes then that's an error we can give a message for.
                if (currentQuoteCount > startingQuoteCount)
                {
                    var excessQuoteCount = currentQuoteCount - startingQuoteCount;
                    this.AddError(
                        position: TextWindow.Position - excessQuoteCount,
                        width: excessQuoteCount,
                        ErrorCode.ERR_TooManyQuotesForRawString);
                }

                // We have enough quotes to finish this string at this point.
                var afterStartDelimiter = TextWindow.LexemeStartPosition + startingQuoteCount;
                var valueLength         = beforeEndDelimiter - afterStartDelimiter;

                info.StringValue = TextWindow.GetText(
                    position: afterStartDelimiter,
                    length: valueLength,
                    intern: true);
                return;
            }
        }