Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -1,7 +1,7 @@
using System;
using System.IO;

namespace HotChocolate.Fusion.Benchmarks;
namespace Fusion.Execution.Benchmarks;

/// <summary>
/// Resolves the paths of the large federated graph benchmark corpus (the big-federated-graphs checkout) without
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3436,7 +3436,7 @@ private static void RegisterRequirementSelectionSets(
}
}

private OperationDefinitionNode InlineSelections(
internal OperationDefinitionNode InlineSelections(
OperationDefinitionNode operation,
SelectionSetIndexBuilder index,
ITypeDefinition selectionSetType,
Expand All @@ -3447,88 +3447,127 @@ private OperationDefinitionNode InlineSelections(
List<SelectionSetNode>? backlog = null;
var didInline = false;

var rewriter = SyntaxRewriter.Create<List<ISyntaxNode>>(
rewrite: (node, path) =>
{
if (node is not SelectionSetNode selectionSet)
{
return node;
}
// Requirement inlining runs for many search branches. Only field and inline-fragment
// selection sets can change here, so walk that tree directly instead of visiting every
// syntax node in arguments, directives, variable definitions, names and types.
var rewrittenSelectionSet = RewriteSelectionSet(operation.SelectionSet);
var rewrittenOperation = ReferenceEquals(rewrittenSelectionSet, operation.SelectionSet)
? operation
: operation.WithSelectionSet(rewrittenSelectionSet);

// if the node was rewritten we keep track that the rewritten node and
// the original node are semantically equivalent.
var originalSelectionSet = (SelectionSetNode)path.Peek();
var id = index.GetId(originalSelectionSet);
if (!didInline)
{
throw new InvalidOperationException(
$"Selections `{selectionsToInline}` could not be inlined into selection set of type "
+ $"'{selectionSetType.Name}', as no selection set with the id {targetSelectionSetId} was found.");
}

return rewrittenOperation;

if (!ReferenceEquals(originalSelectionSet, selectionSet))
SelectionSetNode RewriteSelectionSet(SelectionSetNode originalSelectionSet)
{
List<ISelectionNode>? rewrittenSelections = null;

for (var i = 0; i < originalSelectionSet.Selections.Count; i++)
{
var originalSelection = originalSelectionSet.Selections[i];
var rewrittenSelection = originalSelection switch
{
index.Register(originalSelectionSet, selectionSet);
}
FieldNode { SelectionSet: { } childSelectionSet } field =>
RewriteField(field, childSelectionSet),
FieldNode => originalSelection,
InlineFragmentNode inlineFragment => RewriteInlineFragment(inlineFragment),
FragmentSpreadNode => originalSelection,
_ => throw new ArgumentOutOfRangeException(nameof(originalSelection))
};

if (targetSelectionSetId != id)
if (rewrittenSelections is null
&& !ReferenceEquals(originalSelection, rewrittenSelection))
{
return node;
rewrittenSelections = new List<ISelectionNode>(originalSelectionSet.Selections.Count);

for (var j = 0; j < i; j++)
{
rewrittenSelections.Add(originalSelectionSet.Selections[j]);
}
}

SelectionSetNode newSelectionSet;
rewrittenSelections?.Add(rewrittenSelection);
}

if (inlineInternal)
{
var size = selectionSet.Selections.Count + selectionsToInline.Selections.Count;
var selections = new List<ISelectionNode>(size);
selections.AddRange(originalSelectionSet.Selections);
var selectionSet = rewrittenSelections is null
? originalSelectionSet
: originalSelectionSet.WithSelections(rewrittenSelections);
var id = index.GetId(originalSelectionSet);

foreach (var selection in selectionsToInline.Selections)
{
var markedSelection = MarkInternalSubtree(selection, index);
if (!ReferenceEquals(originalSelectionSet, selectionSet))
{
index.Register(originalSelectionSet, selectionSet);
}

selections.Add(markedSelection);
if (targetSelectionSetId != id)
{
return selectionSet;
}

switch (markedSelection)
{
case FieldNode field:
IndexInternalSelections(field.SelectionSet, index, ref backlog);
break;
SelectionSetNode newSelectionSet;

case InlineFragmentNode inlineFragment:
IndexInternalSelections(inlineFragment.SelectionSet, index, ref backlog);
break;
}
}
if (inlineInternal)
{
var size = selectionSet.Selections.Count + selectionsToInline.Selections.Count;
var selections = new List<ISelectionNode>(size);
selections.AddRange(originalSelectionSet.Selections);

Comment on lines +3517 to 3520
newSelectionSet = new SelectionSetNode(selections);
}
else
foreach (var selection in selectionsToInline.Selections)
{
newSelectionSet = _mergeRewriter.Merge(
selectionSet,
selectionsToInline,
selectionSetType,
index);
}
var markedSelection = MarkInternalSubtree(selection, index);

didInline = true;
selections.Add(markedSelection);

index.Register(originalSelectionSet, newSelectionSet);
return newSelectionSet;
},
enter: (node, path) =>
switch (markedSelection)
{
case FieldNode field:
IndexInternalSelections(field.SelectionSet, index, ref backlog);
break;

case InlineFragmentNode inlineFragment:
IndexInternalSelections(inlineFragment.SelectionSet, index, ref backlog);
break;
}
}

newSelectionSet = new SelectionSetNode(selections);
}
else
{
path.Push(node);
return path;
},
leave: (_, path) => path.Pop());
newSelectionSet = _mergeRewriter.Merge(
selectionSet,
selectionsToInline,
selectionSetType,
index);
}

var rewrittenOperation = (OperationDefinitionNode)rewriter.Rewrite(operation, [])!;
didInline = true;

if (!didInline)
index.Register(originalSelectionSet, newSelectionSet);
return newSelectionSet;
}

FieldNode RewriteField(FieldNode field, SelectionSetNode childSelectionSet)
{
throw new InvalidOperationException(
$"Selections `{selectionsToInline}` could not be inlined into selection set of type "
+ $"'{selectionSetType.Name}', as no selection set with the id {targetSelectionSetId} was found.");
var rewrittenChildSelectionSet = RewriteSelectionSet(childSelectionSet);
return ReferenceEquals(childSelectionSet, rewrittenChildSelectionSet)
? field
: field.WithSelectionSet(rewrittenChildSelectionSet);
}

return rewrittenOperation;
InlineFragmentNode RewriteInlineFragment(InlineFragmentNode inlineFragment)
{
var rewrittenChildSelectionSet = RewriteSelectionSet(inlineFragment.SelectionSet);
return ReferenceEquals(inlineFragment.SelectionSet, rewrittenChildSelectionSet)
? inlineFragment
: inlineFragment.WithSelectionSet(rewrittenChildSelectionSet);
}

static ISelectionNode MarkInternalSubtree(
ISelectionNode selection,
Expand Down
Loading
Loading