Skip to content
Merged
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
Expand Up @@ -40,6 +40,24 @@ public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
return AsSelector<TValue>(casted);
}

/// <summary>
/// Creates a selector expression from a GraphQL selection and applies
/// runtime include/skip directive flags.
/// </summary>
public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
this ISelection selection,
ulong includeFlags)
{
if (selection is not Selection casted)
{
throw new ArgumentException(
$"Expected {typeof(Selection).FullName!}.",
nameof(selection));
}

return AsSelector<TValue>(casted, includeFlags);
}

/// <summary>
/// Creates a selector expression from a GraphQL selection.
/// </summary>
Expand All @@ -54,10 +72,17 @@ public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
/// </returns>
public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
this Selection selection)
=> AsSelector<TValue>(selection, 0);

public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
this Selection selection,
ulong includeFlags)
{
var isConditional = selection.DeclaringOperation.RootSelectionSet.IsConditional;

// we first check if we already have an expression for this selection,
// this would be the cheapest way to get the expression.
if (TryGetExpression<TValue>(selection, out var expression))
if (!isConditional && TryGetExpression<TValue>(selection, out var expression))
{
return expression;
}
Expand All @@ -74,10 +99,15 @@ public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
var count = GetConnectionSelections(selection, buffer);
for (var i = 0; i < count; i++)
{
builder.Add(buffer[i].GetOrCreateExpression<TValue>());
builder.Add(
isConditional
? buffer[i].GetExpression<TValue>(includeFlags)
: buffer[i].GetOrCreateExpression<TValue>());
}
ArrayPool<Selection>.Shared.Return(buffer);
return selection.GetOrCreateExpression<TValue>(builder);
return isConditional
? selection.GetExpression<TValue>(builder)
: selection.GetOrCreateExpression<TValue>(builder);
}

if ((flags & CoreFieldFlags.CollectionSegment) == CoreFieldFlags.CollectionSegment)
Expand All @@ -87,19 +117,28 @@ public static Expression<Func<TValue, TValue>> AsSelector<TValue>(
var count = GetCollectionSelections(selection, buffer);
for (var i = 0; i < count; i++)
{
builder.Add(buffer[i].GetOrCreateExpression<TValue>());
builder.Add(
isConditional
? buffer[i].GetExpression<TValue>(includeFlags)
: buffer[i].GetOrCreateExpression<TValue>());
}
ArrayPool<Selection>.Shared.Return(buffer);
return selection.GetOrCreateExpression<TValue>(builder);
return isConditional
? selection.GetExpression<TValue>(builder)
: selection.GetOrCreateExpression<TValue>(builder);
}

if ((flags & CoreFieldFlags.GlobalIdNodeField) == CoreFieldFlags.GlobalIdNodeField
|| (flags & CoreFieldFlags.GlobalIdNodesField) == CoreFieldFlags.GlobalIdNodesField)
{
return selection.GetOrCreateNodeExpression<TValue>();
return isConditional
? selection.GetNodeExpression<TValue>(includeFlags)
: selection.GetOrCreateNodeExpression<TValue>();
}

return selection.GetOrCreateExpression<TValue>();
return isConditional
? selection.GetExpression<TValue>(includeFlags)
: selection.GetOrCreateExpression<TValue>();
}

private static bool TryGetExpression<TValue>(
Expand Down Expand Up @@ -179,10 +218,19 @@ file static class Extensions
public Expression<Func<TValue, TValue>> GetOrCreateExpression<TValue>()
=> selection.Features.GetOrSetSafe(() => s_builder.BuildExpression<TValue>(selection));

public Expression<Func<TValue, TValue>> GetExpression<TValue>(ulong includeFlags)
=> s_builder.BuildExpression<TValue>(selection, includeFlags);

public Expression<Func<TValue, TValue>> GetOrCreateExpression<TValue>(ISelectorBuilder expressionBuilder)
=> selection.Features.GetOrSetSafe(() => expressionBuilder.TryCompile<TValue>()!);

public Expression<Func<TValue, TValue>> GetExpression<TValue>(ISelectorBuilder expressionBuilder)
=> expressionBuilder.TryCompile<TValue>()!;

public Expression<Func<TValue, TValue>> GetOrCreateNodeExpression<TValue>()
=> selection.Features.GetOrSetSafe(() => s_builder.BuildNodeExpression<TValue>(selection));

public Expression<Func<TValue, TValue>> GetNodeExpression<TValue>(ulong includeFlags)
=> s_builder.BuildNodeExpression<TValue>(selection, includeFlags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ internal sealed class SelectionExpressionBuilder
typeof(char?)
];

public Expression<Func<TRoot, TRoot>> BuildExpression<TRoot>(Selection selection)
public Expression<Func<TRoot, TRoot>> BuildExpression<TRoot>(
Selection selection,
ulong includeFlags = 0)
{
var rootType = typeof(TRoot);
var parameter = Expression.Parameter(rootType, "root");
var requirements = selection.DeclaringOperation.Schema.Features.GetRequired<FieldRequirementsMetadata>();
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext());
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext(), includeFlags);
var root = new TypeContainer();

CollectTypes(context, selection, root);
Expand All @@ -56,12 +58,14 @@ public Expression<Func<TRoot, TRoot>> BuildExpression<TRoot>(Selection selection
return Expression.Lambda<Func<TRoot, TRoot>>(selectionSetExpression, parameter);
}

public Expression<Func<TRoot, TRoot>> BuildNodeExpression<TRoot>(Selection selection)
public Expression<Func<TRoot, TRoot>> BuildNodeExpression<TRoot>(
Selection selection,
ulong includeFlags = 0)
{
var rootType = typeof(TRoot);
var parameter = Expression.Parameter(rootType, "root");
var requirements = selection.DeclaringOperation.Schema.Features.GetRequired<FieldRequirementsMetadata>();
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext());
var context = new Context(parameter, rootType, requirements, new NullabilityInfoContext(), includeFlags);
var root = new TypeContainer();

var entityType = selection.DeclaringOperation
Expand Down Expand Up @@ -272,6 +276,11 @@ private void CollectSelections(
{
foreach (var selection in selectionSet.Selections)
{
if (!selection.IsIncluded(context.IncludeFlags))
{
continue;
}

var requirements = context.GetRequirements(selection);
if (requirements is not null)
{
Expand Down Expand Up @@ -342,7 +351,8 @@ private readonly record struct Context(
Expression Parent,
Type ParentType,
FieldRequirementsMetadata Requirements,
NullabilityInfoContext NullabilityInfoContext)
NullabilityInfoContext NullabilityInfoContext,
ulong IncludeFlags)
{
public TypeNode? GetRequirements(Selection selection)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ private void WriteResolverArguments(Resolver resolver, IMethodSymbol resolverMet
using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine(
"global::{0}.AsSelector<{1}>(args{2}_selection),",
"global::{0}.AsSelector<{1}>(args{2}_selection, context.IncludeFlags),",
WellKnownTypes.HotChocolateExecutionSelectionExtensions,
entityType,
i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ namespace TestNamespace
var args1_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args1_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args1 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection, context.IncludeFlags),
args1_filter?.AsPredicate<global::TestNamespace.Product>(),
args1_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args2 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace TestNamespace
var args2_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args2_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args2 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args2_selection, context.IncludeFlags),
args2_filter?.AsPredicate<global::TestNamespace.Product>(),
args2_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args3 = context.RequestAborted;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ namespace TestNamespace
var args0_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args0_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args0 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Foo>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Foo>(args0_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Foo>(args0_selection, context.IncludeFlags),
args0_filter?.AsPredicate<global::TestNamespace.Foo>(),
args0_sorting?.AsSortDefinition<global::TestNamespace.Foo>());
var result = global::TestNamespace.Query.GetTest(args0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ namespace TestNamespace
var args1_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args1_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args1 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection, context.IncludeFlags),
args1_filter?.AsPredicate<global::TestNamespace.Product>(),
args1_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args2 = _binding_GetProductsAsync_productService.Execute<global::TestNamespace.ProductService>(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ namespace TestNamespace
var args1_filter = global::HotChocolate.Data.Filters.FilterContextResolverContextExtensions.GetFilterContext(context);
var args1_sorting = global::HotChocolate.Data.Sorting.SortingContextResolverContextExtensions.GetSortingContext(context);
var args1 = new global::GreenDonut.Data.QueryContext<global::TestNamespace.Product>(
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection),
global::HotChocolate.Execution.Processing.HotChocolateExecutionSelectionExtensions.AsSelector<global::TestNamespace.Product>(args1_selection, context.IncludeFlags),
args1_filter?.AsPredicate<global::TestNamespace.Product>(),
args1_sorting?.AsSortDefinition<global::TestNamespace.Product>());
var args2 = _binding_GetProductsAsync_productService.Execute<global::TestNamespace.ProductService>(context);
Expand Down
Loading
Loading