Skip to content

Commit

Permalink
Added Type Rename Merge Middleware for new Gateway (#5142)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Jun 13, 2022
1 parent 76da4a1 commit 74f5a82
Show file tree
Hide file tree
Showing 30 changed files with 1,134 additions and 82 deletions.
Expand Up @@ -195,12 +195,12 @@ public virtual async Task InvokeAsync(HttpContext context)
DiagnosticEvents.HttpRequestError(context, error);
}

HANDLE_RESULT:
HANDLE_RESULT:
IDisposable? formatScope = null;

try
{
// if cancellation is requested we will not try to attempt to write the result to the
// if cancellation is requested we will not try to attempt to write the result to the
// response stream.
if (context.RequestAborted.IsCancellationRequested)
{
Expand Down
Expand Up @@ -3,6 +3,7 @@
using HotChocolate.AspNetCore.Instrumentation;
using HotChocolate.AspNetCore.Serialization;
using HotChocolate.Language;
using Microsoft.Net.Http.Headers;
using RequestDelegate = Microsoft.AspNetCore.Http.RequestDelegate;

namespace HotChocolate.AspNetCore;
Expand Down
Expand Up @@ -10,11 +10,6 @@ namespace HotChocolate.Language.Visitors;
/// </summary>
public interface ISyntaxNavigator
{
/// <summary>
/// Returns the immediate parent of the current Syntax Node
/// </summary>
ISyntaxNode? Parent { get; }

/// <summary>
/// Returns the count of items in the current path.
/// </summary>
Expand Down Expand Up @@ -65,6 +60,15 @@ public interface ISyntaxNavigator
/// False when a syntax node was not removed.</returns>
bool TryPeek([NotNullWhen(true)] out ISyntaxNode? node);

/// <summary>
/// Attempts to return the current parent node from the Syntax Navigator without removing it.
/// </summary>
/// <param name="count">The ancestor level.</param>
/// <param name="node">The removed parent node.</param>
/// <returns>True when a syntax node was successfully removed from the Syntax Navigator.
/// False when a syntax node was not removed.</returns>
bool TryPeek(int count, [NotNullWhen(true)] out ISyntaxNode? node);

/// <summary>
/// Returns the first ancestor of the provided <see cref="TNode" /> type.
/// </summary>
Expand Down
Expand Up @@ -17,20 +17,6 @@ public class DefaultSyntaxNavigator : ISyntaxNavigator
/// <inheritdoc cref="ISyntaxNavigator.Count"/>
public int Count => _ancestors.Count;

/// <inheritdoc cref="ISyntaxNavigator.Parent"/>
public ISyntaxNode? Parent
{
get
{
if (_ancestors.Count == 0)
{
return null;
}

return _ancestors[_ancestors.Count - 1];
}
}

/// <inheritdoc cref="ISyntaxNavigator.Push"/>
public void Push(ISyntaxNode node)
{
Expand Down Expand Up @@ -100,6 +86,7 @@ public bool TryPop([NotNullWhen(true)] out ISyntaxNode? node)
return true;
}

/// <inheritdoc cref="ISyntaxNavigator.TryPeek(out HotChocolate.Language.ISyntaxNode?)"/>
public bool TryPeek([NotNullWhen(true)] out ISyntaxNode? node)
{
if (_ancestors.Count == 0)
Expand All @@ -109,7 +96,19 @@ public bool TryPeek([NotNullWhen(true)] out ISyntaxNode? node)
}

node = _ancestors[_ancestors.Count - 1];
_ancestors.RemoveAt(_ancestors.Count - 1);
return true;
}

/// <inheritdoc cref="ISyntaxNavigator.TryPeek(int,out HotChocolate.Language.ISyntaxNode?)"/>
public bool TryPeek(int count, [NotNullWhen(true)] out ISyntaxNode? node)
{
if (_ancestors.Count < count)
{
node = default;
return false;
}

node = _ancestors[_ancestors.Count - 1 - count];
return true;
}

Expand Down
Expand Up @@ -542,7 +542,7 @@ protected virtual ISyntaxNode OnRewrite(ISyntaxNode node, TContext context)
NamedTypeNode node,
TContext context)
{
NameNode name = RewriteName(node.Name, context);
NameNode name = RewriteNode(node.Name, context);

if (!ReferenceEquals(name, node.Name))
{
Expand Down
Expand Up @@ -98,51 +98,6 @@ public void Pop_Empty()
Assert.Throws<InvalidOperationException>(Fail);
}

[Fact]
public void Parent_With_One()
{
// arrange
var node = new NameNode("abc");
var navigator = new DefaultSyntaxNavigator();
navigator.Push(node);

// act
ISyntaxNode? parent = navigator.Parent;

// assert
Assert.Same(node, parent);
}

[Fact]
public void Parent_With_Two()
{
// arrange
var one = new NameNode("abc");
var two = new NameNode("def");
var navigator = new DefaultSyntaxNavigator();
navigator.Push(one);
navigator.Push(two);

// act
ISyntaxNode? parent = navigator.Parent;

// assert
Assert.Same(two, parent);
}

[Fact]
public void Parent_With_Empty()
{
// arrange
var navigator = new DefaultSyntaxNavigator();

// act
ISyntaxNode? parent = navigator.Parent;

// assert
Assert.Null(parent);
}

[Fact]
public void Peek()
{
Expand Down
Expand Up @@ -16,4 +16,8 @@
<ProjectReference Include="..\..\..\Core\src\Core\HotChocolate.Core.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Pipeline\ApplyRemove" />
</ItemGroup>

</Project>
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using HotChocolate.Execution;
using HotChocolate.Language;
using static HotChocolate.Stitching.Types.ThrowHelper;

namespace HotChocolate.Stitching.Types.Pipeline.ApplyExtensions;

Expand Down Expand Up @@ -107,7 +108,7 @@ protected override TDef Apply(TDef definition, TExt extension)
// we first need to validate that the field structure can be merged.
if (definition.Arguments.Count != extension.Arguments.Count)
{
throw ExceptionHelper.ApplyExtensionsMiddleware_ArgumentCountMismatch(typeName, definition, extension);
throw ApplyExtensionsMiddleware_ArgumentCountMismatch(typeName, definition, extension);
}

IReadOnlyList<InputValueDefinitionNode> arguments = definition.Arguments;
Expand All @@ -124,7 +125,7 @@ protected override TDef Apply(TDef definition, TExt extension)

if (!arg.Name.Equals(argExt.Name, SyntaxComparison.Syntax))
{
throw ExceptionHelper.ApplyExtensionsMiddleware_UnexpectedArgumentName(
throw ApplyExtensionsMiddleware_UnexpectedArgumentName(
arg.Name.Value,
argExt.Name.Value,
i,
Expand All @@ -134,7 +135,7 @@ protected override TDef Apply(TDef definition, TExt extension)

if (!arg.Type.Equals(argExt.Type, SyntaxComparison.Syntax))
{
throw ExceptionHelper.ApplyExtensionsMiddleware_ArgumentTypeMismatch(
throw ApplyExtensionsMiddleware_ArgumentTypeMismatch(
arg,
argExt,
i,
Expand Down
@@ -1,15 +1,17 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using HotChocolate.Language;
using HotChocolate.Language.Visitors;
using HotChocolate.Utilities;
using static System.Array;

namespace HotChocolate.Stitching.Types.Pipeline.ApplyExtensions;

public sealed class ApplyExtensionsMiddleware
{

private const string _schema = "$schema";

private readonly IApplyExtension[] _applyExtensions =
Expand Down Expand Up @@ -40,7 +42,7 @@ public async ValueTask InvokeAsync(ISchemaMergeContext context)
}

DocumentNode subgraph = ApplyExtensions(definitions, extensions);
context.Documents = context.Documents.Add(subgraph);
context.Documents = context.Documents.Add(new Document(configuration.Name, subgraph));
}

await _next(context);
Expand Down
@@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HotChocolate.Language;

namespace HotChocolate.Stitching.Types.Pipeline.ApplyRenaming;

public sealed class ApplyRenamingMiddleware
{
private readonly RenameIndexer _indexer = new();
private readonly RenameRewriter _rewriter = new();
private readonly MergeSchema _next;

public ApplyRenamingMiddleware(MergeSchema next)
{
_next = next;
}

public async ValueTask InvokeAsync(ISchemaMergeContext context)
{
for (var i = 0; i < context.Documents.Count; i++)
{
Document doc = context.Documents[i];

var renameContext = new RenameContext(doc.Name);
_indexer.Visit(doc.SyntaxTree, renameContext);

if (renameContext.RenamedFields.Count > 0)
{
foreach ((var coordinate, var renameInfo) in renameContext.RenamedFields.ToArray())
{
var possibleInterface = coordinate.Name.Value;
if (renameContext.ImplementedBy.TryGetValue(possibleInterface, out var types))
{
foreach (var implementor in types)
{
var implCoordinate = coordinate.WithName(new(implementor));
renameContext.RenamedFields[implCoordinate] = renameInfo;
}
}
}

foreach (var coordinate in renameContext.RenamedFields.Keys)
{
renameContext.TypesWithFieldRenames.Add(coordinate.Name.Value);
}
}

var syntaxTree = (DocumentNode)_rewriter.Rewrite(doc.SyntaxTree, renameContext);
context.Documents = context.Documents.SetItem(i, new Document(doc.Name, syntaxTree));
}

await _next(context);
}
}
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using HotChocolate.Language;
using HotChocolate.Language.Visitors;

namespace HotChocolate.Stitching.Types.Pipeline.ApplyRenaming;

internal sealed class RenameContext : INavigatorContext
{
public RenameContext(string sourceName)
{
SourceName = sourceName;
}

public string SourceName { get; }

public Dictionary<string, RenameInfo> RenamedTypes { get; } =
new(StringComparer.Ordinal);

public Dictionary<string, HashSet<string>> ImplementedBy { get; } =
new(StringComparer.Ordinal);

public Dictionary<SchemaCoordinateNode, RenameInfo> RenamedFields { get; } =
new(SyntaxComparer.BySyntax);

public HashSet<string> TypesWithFieldRenames { get; } =
new HashSet<string>(StringComparer.Ordinal);

public ISyntaxNavigator Navigator { get; } = new DefaultSyntaxNavigator();
}

0 comments on commit 74f5a82

Please sign in to comment.