コード例 #1
0
            private void ScanInterpolatedStringLiteralContents(ArrayBuilder <Interpolation> interpolations)
            {
                while (true)
                {
                    if (IsAtEnd())
                    {
                        // error: end of line before end of string
                        return;
                    }

                    switch (lexer.TextWindow.PeekChar())
                    {
                    case '"':
                        if (isVerbatim && lexer.TextWindow.PeekChar(1) == '"')
                        {
                            lexer.TextWindow.AdvanceChar();     // "
                            lexer.TextWindow.AdvanceChar();     // "
                            continue;
                        }
                        // found the end of the string
                        return;

                    case '}':
                        var pos = lexer.TextWindow.Position;
                        lexer.TextWindow.AdvanceChar();     // }
                        // ensure any } characters are doubled up
                        if (lexer.TextWindow.PeekChar() == '}')
                        {
                            lexer.TextWindow.AdvanceChar();     // }
                        }
                        else if (error == null)
                        {
                            error = lexer.MakeError(pos, 1, ErrorCode.ERR_UnescapedCurly, "}");
                        }
                        continue;

                    case '{':
                        if (lexer.TextWindow.PeekChar(1) == '{')
                        {
                            lexer.TextWindow.AdvanceChar();
                            lexer.TextWindow.AdvanceChar();
                        }
                        else
                        {
                            int openBracePosition = lexer.TextWindow.Position;
                            lexer.TextWindow.AdvanceChar();
                            int colonPosition = 0;
                            ScanInterpolatedStringLiteralHoleBalancedText('}', true, ref colonPosition);
                            int  closeBracePosition = lexer.TextWindow.Position;
                            bool closeBraceMissing  = false;
                            if (lexer.TextWindow.PeekChar() == '}')
                            {
                                lexer.TextWindow.AdvanceChar();
                            }
                            else
                            {
                                closeBraceMissing = true;
                                if (error == null)
                                {
                                    error = lexer.MakeError(openBracePosition - 1, 2, ErrorCode.ERR_UnclosedExpressionHole);
                                }
                            }

                            interpolations?.Add(new Interpolation(openBracePosition, colonPosition, closeBracePosition, closeBraceMissing));
                        }
                        continue;

                    case '\\':
                        if (isVerbatim)
                        {
                            goto default;
                        }

                        var  escapeStart = lexer.TextWindow.Position;
                        char c2;
                        char ch = lexer.ScanEscapeSequence(out c2);
                        if ((ch == '{' || ch == '}') && error == null)
                        {
                            error = lexer.MakeError(escapeStart, lexer.TextWindow.Position - escapeStart, ErrorCode.ERR_EscapedCurly, ch);
                        }

                        continue;

                    default:
                        // found some other character in the string portion
                        lexer.TextWindow.AdvanceChar();
                        continue;
                    }
                }
            }
コード例 #2
0
            private void ScanInterpolatedStringLiteralContents(ArrayBuilder <Interpolation>?interpolations)
            {
                while (true)
                {
                    if (IsAtEnd())
                    {
                        // error: end of line before end of string
                        return;
                    }

                    switch (_lexer.TextWindow.PeekChar())
                    {
                    case '"' when RecoveringFromRunawayLexing():
                        // When recovering from mismatched delimiters, we consume the next
                        // quote character as the close quote for the interpolated string. In
                        // practice this gets us out of trouble in scenarios we've encountered.
                        // See, for example, https://github.com/dotnet/roslyn/issues/44789
                        return;

                    case '"':
                        if (_isVerbatim && _lexer.TextWindow.PeekChar(1) == '"')
                        {
                            _lexer.TextWindow.AdvanceChar();     // "
                            _lexer.TextWindow.AdvanceChar();     // "
                            continue;
                        }
                        // found the end of the string
                        return;

                    case '}':
                        var pos = _lexer.TextWindow.Position;
                        _lexer.TextWindow.AdvanceChar();     // }
                        // ensure any } characters are doubled up
                        if (_lexer.TextWindow.PeekChar() == '}')
                        {
                            _lexer.TextWindow.AdvanceChar();     // }
                        }
                        else
                        {
                            TrySetUnrecoverableError(_lexer.MakeError(pos, 1, ErrorCode.ERR_UnescapedCurly, "}"));
                        }
                        continue;

                    case '{':
                        if (_lexer.TextWindow.PeekChar(1) == '{')
                        {
                            _lexer.TextWindow.AdvanceChar();
                            _lexer.TextWindow.AdvanceChar();
                        }
                        else
                        {
                            int openBracePosition = _lexer.TextWindow.Position;
                            _lexer.TextWindow.AdvanceChar();
                            int colonPosition = 0;
                            ScanInterpolatedStringLiteralHoleBalancedText('}', isHole: true, ref colonPosition);
                            int  closeBracePosition = _lexer.TextWindow.Position;
                            bool closeBraceMissing  = false;
                            if (_lexer.TextWindow.PeekChar() == '}')
                            {
                                _lexer.TextWindow.AdvanceChar();
                            }
                            else
                            {
                                closeBraceMissing = true;
                                TrySetUnrecoverableError(_lexer.MakeError(openBracePosition - 1, 2, ErrorCode.ERR_UnclosedExpressionHole));
                            }

                            interpolations?.Add(new Interpolation(openBracePosition, colonPosition, closeBracePosition, closeBraceMissing));
                        }
                        continue;

                    case '\\':
                        if (_isVerbatim)
                        {
                            goto default;
                        }

                        var  escapeStart = _lexer.TextWindow.Position;
                        char ch          = _lexer.ScanEscapeSequence(surrogateCharacter: out _);
                        if (ch == '{' || ch == '}')
                        {
                            TrySetUnrecoverableError(_lexer.MakeError(escapeStart, _lexer.TextWindow.Position - escapeStart, ErrorCode.ERR_EscapedCurly, ch));
                        }

                        continue;

                    default:
                        // found some other character in the string portion
                        _lexer.TextWindow.AdvanceChar();
                        continue;
                    }
                }
            }