Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Named Request Support #3584

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7ab9e41
staging for clean
bleaphar May 24, 2024
44b4ce6
Removal of test node
bleaphar May 24, 2024
f5ebd1e
Save but the tests are breaking
bleaphar Jun 7, 2024
2864315
staging for clean
bleaphar May 24, 2024
fbd8b43
Removal of test node
bleaphar May 24, 2024
02739cd
Save but the tests are breaking
bleaphar Jun 7, 2024
681fe63
Merge branch 'bleaphar/NamedRequests' of https://github.com/bleaphar/…
bleaphar Jun 7, 2024
69fc779
Progress but failing named requests tests
bleaphar Jun 18, 2024
e0b8529
Merge branch 'dotnet:main' into bleaphar/NamedRequests
bleaphar Jun 18, 2024
fc0a811
Addition of better diagnostics and testing
bleaphar Jun 19, 2024
e9f8325
Rough draft of named requests changes
bleaphar Jun 21, 2024
c0863ff
Merge branch 'dotnet:main' into bleaphar/NamedRequests
bleaphar Jun 21, 2024
97cf976
Test improvements
bleaphar Jun 25, 2024
d5c1769
Name changes and additional theory test
bleaphar Jun 26, 2024
64b994b
Removal of exclude in http package
bleaphar Jun 26, 2024
9a6eb88
Test update to reflect removal of name node
bleaphar Jun 26, 2024
eb7ffda
More tests
bleaphar Jun 26, 2024
4b49ba2
Addition of header tests
bleaphar Jun 27, 2024
d2a7a99
Minor changes
bleaphar Jun 28, 2024
089e1d9
Merge branch 'bleaphar/NamedRequests' into NamedRequestMergeConflict
bleaphar Jun 28, 2024
dace65c
Merge pull request #2 from bleaphar/NamedRequestMergeConflict
bleaphar Jun 28, 2024
7183c4e
Additional test
bleaphar Jul 1, 2024
8dbf3a2
PR suggestions
bleaphar Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ internal class HttpCommentNode : HttpSyntaxNode

public HttpCommentBodyNode? CommentBodyNode { get; private set; }

public HttpNamedRequestNode? NamedRequestNode { get; private set; }

public override bool IsSignificant => false;

public void Add(HttpCommentStartNode node)
Expand All @@ -43,4 +45,15 @@ public void Add(HttpCommentBodyNode node)
CommentBodyNode = node;
AddInternal(node);
}

public void Add(HttpNamedRequestNode node)
{
if (NamedRequestNode is not null)
{
throw new InvalidOperationException($"{nameof(NamedRequestNode)} was already added.");
}

NamedRequestNode = node;
AddInternal(node);
}
}
426 changes: 250 additions & 176 deletions src/Microsoft.DotNet.Interactive.Http.Parsing/Parsing/HttpDiagnostics.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.DotNet.Interactive.Http.Parsing;
internal class HttpNamedRequestNameNode : HttpSyntaxNode
{
public HttpNamedRequestNameNode(SourceText sourceText, HttpSyntaxTree syntaxTree) : base(sourceText, syntaxTree)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#nullable enable

using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.DotNet.Interactive.Http.Parsing;
internal class HttpNamedRequestNode : HttpSyntaxNode
{
public HttpNamedRequestNode(SourceText sourceText, HttpSyntaxTree syntaxTree) : base(sourceText, syntaxTree)
{
}

public HttpNamedRequestNameNode? ValueNode { get; private set; }

public void Add(HttpNamedRequestNameNode node)
{
if (ValueNode is not null)
{
throw new InvalidOperationException($"{nameof(ValueNode)} was already added.");
}

ValueNode = node;
AddInternal(node);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using Microsoft.DotNet.Interactive.Http.Parsing.Parsing;

namespace Microsoft.DotNet.Interactive.Http.Parsing;

Expand All @@ -31,6 +34,8 @@ internal HttpRequestNode(SourceText sourceText, HttpSyntaxTree? syntaxTree) : ba

public HttpBodyNode? BodyNode { get; private set; }

public bool IsNamedRequest => ChildNodes.OfType<HttpCommentNode>().Any(cn => cn.NamedRequestNode is not null);

public void Add(HttpMethodNode node)
{
if (MethodNode is not null)
Expand Down Expand Up @@ -81,31 +86,52 @@ public void Add(HttpBodyNode node)
AddInternal(node);
}

public void Add(HttpCommentNode node)
public HttpNamedRequestNode? TryGetCommentNamedRequestNode()
{
AddInternal(node);
if (IsNamedRequest)
{
return DescendantNodesAndTokens().OfType<HttpNamedRequestNode>().FirstOrDefault();
}
else
{
return null;
}

}

public HttpBindingResult<HttpRequestMessage> TryGetHttpRequestMessage(HttpBindingDelegate bind)
{
var originalBind = bind;
var declaredVariables = SyntaxTree?.RootNode.GetDeclaredVariables();
if (declaredVariables?.Count > 0)
var diagnostics = new List<Diagnostic>(base.GetDiagnostics());

if (SyntaxTree is not null)
{
bind = node =>
(Dictionary<string, DeclaredVariable> declaredVariables, List<Diagnostic>? diagnostics) declaredVariableResults = SyntaxTree.RootNode.TryGetDeclaredVariables(originalBind);
bleaphar marked this conversation as resolved.
Show resolved Hide resolved
var declaredVariables = declaredVariableResults.declaredVariables;
var declaredVariableDiagnostics = declaredVariableResults.diagnostics;

if (declaredVariables?.Count > 0)
{
if (declaredVariables.TryGetValue(node.Text, out var declaredValue))
{
return HttpBindingResult<object?>.Success(declaredValue.Value);
}
else
bind = node =>
{
return originalBind(node);
}
};
if (declaredVariables.TryGetValue(node.Text, out var declaredValue))
{
return HttpBindingResult<object?>.Success(declaredValue.Value);
}
else
{
return originalBind(node);
}
};
}

if (declaredVariableDiagnostics is not null)
{
diagnostics.AddRange(declaredVariableDiagnostics);
}
}

var request = new HttpRequestMessage();
var diagnostics = new List<Diagnostic>(base.GetDiagnostics());

if (MethodNode is { Span.IsEmpty: false })
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,12 @@ private void ConsumeCurrentTokenInto(HttpSyntaxNode node)
{
while (MoreTokens())
{
if (CurrentToken?.Kind is HttpTokenKind.Whitespace)
if (CurrentToken is { Kind: HttpTokenKind.Punctuation }
and { Text: "@" })
{
ConsumeCurrentTokenInto(node);
}
else if (CurrentToken?.Kind is HttpTokenKind.Whitespace)
{
ConsumeCurrentTokenInto(node);
}
Expand All @@ -260,6 +265,7 @@ private void ConsumeCurrentTokenInto(HttpSyntaxNode node)
foreach (var commentNode in ParseComments())
{
node.Add(commentNode, addBefore: true);

}
}
else
Expand Down Expand Up @@ -374,7 +380,7 @@ private void ConsumeCurrentTokenInto(HttpSyntaxNode node)

foreach (var comment in ParseComments())
{
requestNode.Add(comment);
requestNode.Add(comment, false);
}

ParseTrailingWhitespace(requestNode);
Expand All @@ -401,6 +407,7 @@ private void ConsumeCurrentTokenInto(HttpSyntaxNode node)
var node = new HttpRequestSeparatorNode(_sourceText, _syntaxTree);
ParseLeadingWhitespaceAndComments(node);

//Three tokens of # representing the request separator
ConsumeCurrentTokenInto(node);
ConsumeCurrentTokenInto(node);
ConsumeCurrentTokenInto(node);
Expand Down Expand Up @@ -630,6 +637,55 @@ private HttpExpressionNode ParseExpression()
return headersNode;
}

private HttpNamedRequestNode? ParseNamedRequestNode()
{
if (!isCommentNamedRequest())
{
return null;
}
var node = new HttpNamedRequestNode(_sourceText, _syntaxTree);

//Three tokens representing the @name and whitespace signifying a named request node
ConsumeCurrentTokenInto(node);
ConsumeCurrentTokenInto(node);
ParseTrailingWhitespace(node);

node.Add(ParseNamedRequestNameNode());

return node;
}

private HttpNamedRequestNameNode ParseNamedRequestNameNode()
{
var node = new HttpNamedRequestNameNode(_sourceText, _syntaxTree);

ParseLeadingWhitespaceAndComments(node);

while (MoreTokens() && CurrentToken is not {Kind: HttpTokenKind.NewLine})
{
if (CurrentToken is not null && !(CurrentToken is { Kind: HttpTokenKind.Word } or { Text: "_" or "@" or "."}))
{
var diagnostic = CurrentToken.CreateDiagnostic(HttpDiagnostics.InvalidNamedRequestName());

node.AddDiagnostic(diagnostic);
}

ConsumeCurrentTokenInto(node);

}

return ParseTrailingWhitespace(node, stopAfterNewLine: true);

}

private bool isCommentNamedRequest()
{
return (CurrentToken is { Text: "@" } &&
CurrentTokenPlus(1) is { Text: "name" } &&
CurrentTokenPlus(2) is { Kind: HttpTokenKind.Whitespace }
);
}

private HttpHeaderNode ParseHeader()
{
var headerNode = new HttpHeaderNode(_sourceText, _syntaxTree);
Expand Down Expand Up @@ -756,10 +812,19 @@ private IEnumerable<HttpCommentNode> ParseComments()
commentNode.Add(commentStartNode);
}

var commentBodyNode = ParseCommentBody();
if (commentBodyNode is not null)
var commentNamedRequestNode = ParseNamedRequestNode();
if (commentNamedRequestNode is not null)
{
commentNode.Add(commentBodyNode);
commentNode.Add(commentNamedRequestNode);
}
else
{

var commentBodyNode = ParseCommentBody();
if (commentBodyNode is not null)
{
commentNode.Add(commentBodyNode);
}
}

yield return commentNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace Microsoft.DotNet.Interactive.Http.Parsing;

using Diagnostic = CodeAnalysis.Diagnostic;

internal class HttpRootSyntaxNode : HttpSyntaxNode
{
internal HttpRootSyntaxNode(SourceText sourceText, HttpSyntaxTree? tree) : base(sourceText, tree)
Expand All @@ -36,11 +38,13 @@ public void Add(HttpRequestSeparatorNode separatorNode)
AddInternal(separatorNode);
}

public Dictionary<string, DeclaredVariable> GetDeclaredVariables()
public (Dictionary<string, DeclaredVariable> declaredVariables, List<Diagnostic>? diagnostics) TryGetDeclaredVariables(HttpBindingDelegate? bind = null)
bleaphar marked this conversation as resolved.
Show resolved Hide resolved
{

var variableAndDeclarationNodes = ChildNodes.OfType<HttpVariableDeclarationAndAssignmentNode>();

List<Diagnostic>? diagnostics = null;

var foundVariableValues = new Dictionary<string, string>();
var declaredVariables = new Dictionary<string, DeclaredVariable>();

Expand All @@ -62,21 +66,41 @@ public void Add(HttpRequestSeparatorNode separatorNode)
{
return node.CreateBindingSuccess(strinValue);
}
else if (bind != null)
{
return bind(node);
}
else
{
return DynamicExpressionUtilities.ResolveExpressionBinding(node, node.Text);
}

});

if (value is not null && value.Value is not null)

if(value?.Value != null)
{
declaredVariables[node.DeclarationNode.VariableName] = new DeclaredVariable(node.DeclarationNode.VariableName, value.Value, value);
}
else
{
if(diagnostics is null)
{
diagnostics = value?.Diagnostics;
}
else
{
if (value is not null)
{
diagnostics.AddRange(value.Diagnostics);
}

}
}
}
}
}

return declaredVariables;
return (declaredVariables, diagnostics);
}
}
Loading