diff --git a/src/Microsoft.DotNet.Interactive.HttpRequestParser/Parser/HttpRequestParser.cs b/src/Microsoft.DotNet.Interactive.HttpRequestParser/Parser/HttpRequestParser.cs index 525f2f0394..cd64aabb6e 100644 --- a/src/Microsoft.DotNet.Interactive.HttpRequestParser/Parser/HttpRequestParser.cs +++ b/src/Microsoft.DotNet.Interactive.HttpRequestParser/Parser/HttpRequestParser.cs @@ -92,7 +92,8 @@ private static void PrependCommentsIfAny(List commentsToPrepend private IEnumerable? ParseVariableDeclarations() { - while (MoreTokens()) + while (MoreTokens() && + !IsRequestSeparator()) { if (GetNextSignificantToken() is { Kind: HttpTokenKind.Punctuation } and { Text: "@" }) { @@ -105,8 +106,8 @@ private static void PrependCommentsIfAny(List commentsToPrepend variableNode.Add(valueNode); yield return variableNode; } - - } else + } + else { break; } @@ -117,8 +118,8 @@ private static void PrependCommentsIfAny(List commentsToPrepend { HttpVariableValueNode? node = null; - while (MoreTokens() && - CurrentToken.Kind is not HttpTokenKind.NewLine) + while (MoreTokens() && + CurrentToken is not { Kind: HttpTokenKind.NewLine }) { if (node is null) { @@ -191,7 +192,10 @@ private HttpVariableDeclarationNode ParseVariableDeclaration() return ParseTrailingWhitespace(node); } - private HttpSyntaxToken CurrentToken => _tokens![_currentTokenIndex]; + private HttpSyntaxToken? CurrentToken => + MoreTokens() + ? _tokens![_currentTokenIndex] + : null; private HttpSyntaxToken? CurrentTokenPlus(int offset) { @@ -216,19 +220,22 @@ private HttpVariableDeclarationNode ParseVariableDeclaration() [DebuggerStepThrough] private void ConsumeCurrentTokenInto(HttpSyntaxNode node) { - node.Add(CurrentToken); - AdvanceToNextToken(); + if (CurrentToken is { } token) + { + node.Add(token); + AdvanceToNextToken(); + } } private T ParseLeadingWhitespaceAndComments(T node) where T : HttpSyntaxNode { while (MoreTokens()) { - if (CurrentToken.Kind is HttpTokenKind.Whitespace) + if (CurrentToken?.Kind is HttpTokenKind.Whitespace) { ConsumeCurrentTokenInto(node); } - else if (CurrentToken.Kind is HttpTokenKind.NewLine) + else if (CurrentToken?.Kind is HttpTokenKind.NewLine) { ConsumeCurrentTokenInto(node); } @@ -249,7 +256,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool { while (MoreTokens()) { - if (CurrentToken.Kind is HttpTokenKind.NewLine) + if (CurrentToken?.Kind is HttpTokenKind.NewLine) { if (stopBeforeNewLine) { @@ -263,7 +270,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool } } - if (CurrentToken.Kind is not (HttpTokenKind.Whitespace or HttpTokenKind.NewLine)) + if (CurrentToken is not { Kind: HttpTokenKind.Whitespace } and not { Kind: HttpTokenKind.NewLine }) { break; } @@ -278,7 +285,11 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool { if (IsComment()) { - // FIX: (ParseRequest) this looks suspect... test with a comment at the start of the request node? + return null; + } + + if (IsRequestSeparator()) + { return null; } @@ -351,7 +362,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool private HttpRequestSeparatorNode? ParseRequestSeparator() { - if (MoreTokens() && IsRequestSeparator()) + if (IsRequestSeparator()) { var node = new HttpRequestSeparatorNode(_sourceText, _syntaxTree); ParseLeadingWhitespaceAndComments(node); @@ -360,7 +371,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool ConsumeCurrentTokenInto(node); ConsumeCurrentTokenInto(node); - ParseTrailingWhitespace(node); + return ParseTrailingWhitespace(node); } return null; @@ -370,28 +381,25 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool { HttpMethodNode? node = null; - if (MoreTokens()) + while (CurrentToken?.Kind is HttpTokenKind.Word && + CurrentTokenPlus(1)?.Kind is HttpTokenKind.Whitespace) { - if (CurrentToken.Kind is HttpTokenKind.Word && - CurrentTokenPlus(1)?.Kind is HttpTokenKind.Whitespace) - { - node = new HttpMethodNode(_sourceText, _syntaxTree); + node = new HttpMethodNode(_sourceText, _syntaxTree); - ParseLeadingWhitespaceAndComments(node); + ParseLeadingWhitespaceAndComments(node); - if (CurrentToken.Text.ToLower() is not ("get" or "post" or "patch" or "put" or "delete" or "head" or "options" or "trace")) - { - var message = $"Unrecognized HTTP verb {CurrentToken.Text}"; + if (CurrentToken.Text.ToLower() is not ("get" or "post" or "patch" or "put" or "delete" or "head" or "options" or "trace")) + { + var message = $"Unrecognized HTTP verb {CurrentToken.Text}"; - var diagnostic = CurrentToken.CreateDiagnostic(message); + var diagnostic = CurrentToken.CreateDiagnostic(message); - node.AddDiagnostic(diagnostic); - } + node.AddDiagnostic(diagnostic); + } - ConsumeCurrentTokenInto(node); + ConsumeCurrentTokenInto(node); - ParseTrailingWhitespace(node, stopBeforeNewLine: true); - } + ParseTrailingWhitespace(node, stopBeforeNewLine: true); } return node; @@ -401,8 +409,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool { HttpUrlNode? node = null; - while (MoreTokens() && - CurrentToken.Kind is HttpTokenKind.Word or HttpTokenKind.Punctuation) + while (CurrentToken?.Kind is HttpTokenKind.Word or HttpTokenKind.Punctuation) { if (node is null) { @@ -440,7 +447,7 @@ private T ParseTrailingWhitespace(T node, bool stopAfterNewLine = false, bool while (MoreTokens()) { - if (token.IsSignificant) + if (token?.IsSignificant == true) { return token; } @@ -509,9 +516,8 @@ private HttpExpressionNode ParseExpression() private HttpExpressionEndNode? ParseExpressionEnd() { - if (MoreTokens() && - CurrentToken.Text is "}" && - CurrentTokenPlus(1)?.Text == "}") + if (CurrentToken?.Text is "}" && + CurrentTokenPlus(1)?.Text is "}") { var node = new HttpExpressionEndNode(_sourceText, _syntaxTree); @@ -528,8 +534,7 @@ CurrentToken.Text is "}" && private HttpVersionNode? ParseVersion() { - if (MoreTokens() && - CurrentToken.Kind is HttpTokenKind.Word) + if (CurrentToken?.Kind is HttpTokenKind.Word) { var node = new HttpVersionNode(_sourceText, _syntaxTree); @@ -552,8 +557,7 @@ CurrentToken.Text is "}" && { HttpHeadersNode? headersNode = null; - while (MoreTokens() && - CurrentToken is { Kind: HttpTokenKind.Word } or { Text: ":" }) + while (CurrentToken is { Kind: HttpTokenKind.Word } or { Text: ":" }) { headersNode ??= new HttpHeadersNode(_sourceText, _syntaxTree); @@ -578,7 +582,7 @@ private HttpHeaderNameNode ParseHeaderName() { var node = new HttpHeaderNameNode(_sourceText, _syntaxTree); - if (MoreTokens() && + if (MoreTokens() && CurrentToken is not { Kind: HttpTokenKind.NewLine } and not { Kind: HttpTokenKind.Punctuation, Text: ":" }) { ParseLeadingWhitespaceAndComments(node); @@ -608,7 +612,7 @@ private HttpHeaderSeparatorNode ParserHeaderSeparator() ParseLeadingWhitespaceAndComments(node); - if (MoreTokens() && CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: ":" }) + if (CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: ":" }) { ConsumeCurrentTokenInto(node); } @@ -622,7 +626,7 @@ private HttpHeaderValueNode ParseHeaderValue() ParseLeadingWhitespaceAndComments(node); - while (MoreTokens() && CurrentToken.Kind is not HttpTokenKind.NewLine) + while (MoreTokens() && CurrentToken is not { Kind: HttpTokenKind.NewLine }) { if (CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "{" } && CurrentTokenPlus(1) is { Kind: HttpTokenKind.Punctuation } and { Text: "{" }) @@ -652,8 +656,8 @@ private HttpHeaderValueNode ParseHeaderValue() var node = new HttpBodyNode(_sourceText, _syntaxTree); - if (MoreTokens() && - CurrentToken.Kind is not (HttpTokenKind.Whitespace or HttpTokenKind.NewLine) && + if (MoreTokens() && + CurrentToken is not { Kind: HttpTokenKind.Whitespace } and not { Kind: HttpTokenKind.NewLine } && !IsRequestSeparator()) { ConsumeCurrentTokenInto(node); @@ -678,7 +682,7 @@ CurrentToken.Kind is not (HttpTokenKind.Whitespace or HttpTokenKind.NewLine) && private HttpCommentNode? ParseComment() { - if (MoreTokens() && IsComment()) + if (IsComment()) { var commentNode = new HttpCommentNode(_sourceText, _syntaxTree); @@ -711,7 +715,8 @@ CurrentToken.Kind is not (HttpTokenKind.Whitespace or HttpTokenKind.NewLine) && var node = new HttpCommentBodyNode(_sourceText, _syntaxTree); ParseLeadingWhitespaceAndComments(node); - while (MoreTokens() && CurrentToken.Kind is not HttpTokenKind.NewLine) + while (MoreTokens() && + CurrentToken is not { Kind: HttpTokenKind.NewLine }) { ConsumeCurrentTokenInto(node); } @@ -723,14 +728,14 @@ CurrentToken.Kind is not (HttpTokenKind.Whitespace or HttpTokenKind.NewLine) && private HttpCommentStartNode? ParseCommentStart() { - if (MoreTokens() && CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "#" }) + if (CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "#" }) { var node = new HttpCommentStartNode(_sourceText, _syntaxTree); ConsumeCurrentTokenInto(node); return ParseTrailingWhitespace(node); } - if (MoreTokens() && CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "/" } && + if (CurrentToken is { Kind: HttpTokenKind.Punctuation } and { Text: "/" } && CurrentTokenPlus(1) is { Kind: HttpTokenKind.Punctuation } and { Text: "/" }) { var node = new HttpCommentStartNode(_sourceText, _syntaxTree);