Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -711,13 +711,24 @@ protected void WriteResolverField(Resolver resolver)
{
foreach (var parameter in resolver.Parameters)
{
if (parameter.Kind is ResolverParameterKind.Unknown)
if (parameter.RequiresBinding || parameter.SupportsCustomBinding)
{
Writer.WriteIndentedLine(
"private readonly global::{0} _binding_{1}_{2};",
parameter.SupportsCustomBinding
? "private readonly global::{0}? _binding_{1}_{2};"
: "private readonly global::{0} _binding_{1}_{2};",
WellKnownTypes.ParameterBinding,
resolver.Member.Name,
parameter.Name);

if (resolver.Kind is ResolverKind.BatchResolver && parameter.RequiresBinding)
{
Writer.WriteIndentedLine(
"private readonly global::{0} _binding_{1}_{2}_kind;",
WellKnownTypes.ArgumentKind,
resolver.Member.Name,
parameter.Name);
}
}
}
}
Expand Down Expand Up @@ -790,10 +801,27 @@ protected void WriteResolverBindingInitialization(Resolver resolver)

foreach (var parameter in resolver.Parameters)
{
if (parameter.Kind is ResolverParameterKind.Unknown)
if (parameter.RequiresBinding)
{
if (resolver.Kind is ResolverKind.BatchResolver)
{
Writer.WriteIndentedLine(
"_binding_{0}_{1} = bindingResolver.GetBinding(CreateParameterDescriptor_{0}_{1}(), out _binding_{0}_{1}_kind);",
resolverMethod.Name,
parameter.Name);
}
else
{
Writer.WriteIndentedLine(
"_binding_{0}_{1} = bindingResolver.GetBinding(CreateParameterDescriptor_{0}_{1}());",
resolverMethod.Name,
parameter.Name);
}
}
else if (parameter.SupportsCustomBinding)
{
Writer.WriteIndentedLine(
"_binding_{0}_{1} = bindingResolver.GetBinding(CreateParameterDescriptor_{0}_{1}());",
"_binding_{0}_{1} = bindingResolver.GetCustomBinding(CreateParameterDescriptor_{0}_{1}());",
resolverMethod.Name,
parameter.Name);
}
Expand Down Expand Up @@ -822,7 +850,7 @@ protected void WriteResolver(Resolver resolver, ILocalTypeLookup typeLookup)
{
foreach (var parameter in resolver.Parameters)
{
if (parameter.Kind is ResolverParameterKind.Unknown)
if (parameter.RequiresBinding || parameter.SupportsCustomBinding)
{
Writer.WriteIndentedLine(
"public global::{0} CreateParameterDescriptor_{1}_{2}()",
Expand Down Expand Up @@ -991,7 +1019,7 @@ private void WritePureResolver(Resolver resolver, IMethodSymbol resolverMethod,

foreach (var parameter in resolver.Parameters)
{
if (!parameter.RequiresBinding)
if (!parameter.RequiresBinding && !parameter.SupportsCustomBinding)
{
continue;
}
Expand All @@ -1003,10 +1031,21 @@ private void WritePureResolver(Resolver resolver, IMethodSymbol resolverMethod,

firstParam = false;

Writer.Write(
"_binding_{0}_{1}.IsPure",
resolver.Member.Name,
parameter.Name);
if (parameter.SupportsCustomBinding)
{
Writer.Write(
"(_binding_{0}_{1}?.IsPure ?? {2})",
resolver.Member.Name,
parameter.Name,
parameter.IsPure ? "true" : "false");
}
else
{
Writer.Write(
"_binding_{0}_{1}.IsPure",
resolver.Member.Name,
parameter.Name);
}
}

Writer.WriteLine(";");
Expand Down Expand Up @@ -1101,6 +1140,18 @@ private void WriteBatchResolver(
{
var parameter = resolver.Parameters[i];

if (parameter.SupportsCustomBinding)
{
WriteCustomBindingArgument(
resolver,
resolverMethod,
typeLookup,
parameter,
i,
"contexts[0]");
continue;
}

switch (parameter.Kind)
{
case ResolverParameterKind.Parent:
Expand All @@ -1111,13 +1162,48 @@ private void WriteBatchResolver(
break;

case ResolverParameterKind.Argument:
case ResolverParameterKind.Unknown:
Writer.WriteIndentedLine(
"var args{0} = new {1}(contexts.Length);",
i,
ToFullyQualifiedString(parameter.Type, resolverMethod, typeLookup));
break;

case ResolverParameterKind.Unknown:
var parameterType =
ToFullyQualifiedString(parameter.Type, resolverMethod, typeLookup);
var elementType = GetListElementType(parameter.Type);
Writer.WriteIndentedLine(
"var args{0}_arguments = _binding_{1}_{2}_kind is global::{3}.Argument",
i,
resolver.Member.Name,
parameter.Name,
WellKnownTypes.ArgumentKind);
using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine(
"? new global::System.Collections.Generic.List<{0}>(contexts.Length)",
elementType);
Writer.WriteIndentedLine(": null;");
}
Comment thread
michaelstaib marked this conversation as resolved.
Resolved

Writer.WriteIndentedLine(
"var args{0} = args{0}_arguments is null",
i);
using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine(
"? _binding_{0}_{1}.Execute<{2}>(contexts[0])",
resolver.Member.Name,
parameter.Name,
parameterType);
Writer.WriteIndentedLine(
": ({0})(object)args{1}_arguments;",
parameterType,
i);
}

break;

case ResolverParameterKind.CancellationToken:
Writer.WriteIndentedLine(
"var args{0} = contexts[0].RequestAborted;",
Expand Down Expand Up @@ -1260,7 +1346,6 @@ or ResolverParameterKind.Argument
}

case ResolverParameterKind.Argument:
case ResolverParameterKind.Unknown:
{
var elementType = GetListElementType(parameter.Type);
Writer.WriteIndentedLine(
Expand All @@ -1270,6 +1355,24 @@ or ResolverParameterKind.Argument
parameter.Key ?? parameter.Name);
break;
}

case ResolverParameterKind.Unknown:
{
var elementType = GetListElementType(parameter.Type);
Writer.WriteIndentedLine("if (args{0}_arguments is not null)", i);
Writer.WriteIndentedLine("{");
using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine(
"args{0}_arguments.Add(contexts[i].ArgumentValue<{1}>(\"{2}\"));",
i,
elementType,
parameter.Key ?? parameter.Name);
}

Writer.WriteIndentedLine("}");
break;
}
}
}
}
Expand Down Expand Up @@ -1429,6 +1532,18 @@ private void WriteResolverArguments(Resolver resolver, IMethodSymbol resolverMet
continue;
}

if (parameter.SupportsCustomBinding)
{
WriteCustomBindingArgument(
resolver,
resolverMethod,
typeLookup,
parameter,
i,
"context");
continue;
}

switch (parameter.Kind)
{
case ResolverParameterKind.Parent:
Expand Down Expand Up @@ -1463,14 +1578,14 @@ private void WriteResolverArguments(Resolver resolver, IMethodSymbol resolverMet

case ResolverParameterKind.FieldNode:
Writer.WriteIndentedLine(
"var args{0} = context.Selection.SyntaxNode",
"var args{0} = context.Selection.SyntaxNodes[0].Node;",
i,
parameter.Type.ToFullyQualified());
break;

case ResolverParameterKind.OutputField:
Writer.WriteIndentedLine(
"var args{0} = context.Selection.Field",
"var args{0} = context.Selection.Field;",
i,
parameter.Type.ToFullyQualified());
break;
Expand Down Expand Up @@ -1840,6 +1955,50 @@ private void WriteResolverArguments(Resolver resolver, IMethodSymbol resolverMet
}
}

private void WriteCustomBindingArgument(
Resolver resolver,
IMethodSymbol resolverMethod,
ILocalTypeLookup typeLookup,
ResolverParameter parameter,
int parameterIndex,
string contextExpression)
{
var fallback = parameter.Kind switch
{
ResolverParameterKind.CancellationToken
=> $"{contextExpression}.RequestAborted",
ResolverParameterKind.ClaimsPrincipal
=> $"{contextExpression}.GetGlobalState<global::{WellKnownTypes.ClaimsPrincipal}>(\"ClaimsPrincipal\")",
ResolverParameterKind.DocumentNode
=> $"{contextExpression}.Operation.Document",
ResolverParameterKind.FieldNode
=> $"{contextExpression}.Selection.SyntaxNodes[0].Node",
ResolverParameterKind.OutputField
=> $"{contextExpression}.Selection.Field",
ResolverParameterKind.ConnectionFlags
=> $"global::{WellKnownTypes.ConnectionFlagsHelper}.GetConnectionFlags({contextExpression})",
ResolverParameterKind.Selection
=> $"{contextExpression}.Selection",
_ => throw new ArgumentOutOfRangeException(nameof(parameter))
};

Writer.WriteIndentedLine(
"var args{0} = _binding_{1}_{2} is null",
parameterIndex,
resolver.Member.Name,
parameter.Name);
using (Writer.IncreaseIndent())
{
Writer.WriteIndentedLine("? {0}", fallback);
Writer.WriteIndentedLine(
": _binding_{0}_{1}.Execute<{2}>({3});",
resolver.Member.Name,
parameter.Name,
ToFullyQualifiedString(parameter.Type, resolverMethod, typeLookup),
contextExpression);
}
}

private static bool IsNodeResolverIdParameter(
Resolver resolver,
ResolverParameter parameter,
Expand Down
3 changes: 2 additions & 1 deletion src/HotChocolate/Core/src/Types.Analyzers/Models/Resolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ public bool IsPure

public ImmutableArray<ResolverParameter> Parameters { get; }

public bool RequiresParameterBindings => Parameters.Any(t => t.RequiresBinding);
public bool RequiresParameterBindings
=> Parameters.Any(t => t.RequiresBinding || t.SupportsCustomBinding);

public ImmutableArray<MemberBinding> Bindings { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ ResolverParameterKind.Selection or
public bool RequiresBinding
=> Kind == ResolverParameterKind.Unknown;

public bool SupportsCustomBinding
=> Kind is ResolverParameterKind.CancellationToken or
ResolverParameterKind.ClaimsPrincipal or
ResolverParameterKind.DocumentNode or
ResolverParameterKind.FieldNode or
ResolverParameterKind.OutputField or
ResolverParameterKind.ConnectionFlags or
ResolverParameterKind.Selection;

public bool HasConfiguration => Attributes.Length > 0;

public bool IsNullable { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static class WellKnownTypes
public const string Executable = "HotChocolate.IExecutable";
public const string ClaimsPrincipal = "System.Security.Claims.ClaimsPrincipal";
public const string DocumentNode = "HotChocolate.Language.DocumentNode";
public const string OutputField = "HotChocolate.Types.IOutputField";
public const string OutputField = "HotChocolate.Types.IOutputFieldDefinition";
public const string ParameterBindingResolver = "HotChocolate.Resolvers.ParameterBindingResolver";
public const string CustomAttributeData = "HotChocolate.Internal.GenCustomAttributeData";
public const string ParameterInfo = "HotChocolate.Internal.GenParameterInfo";
Expand Down
Loading
Loading