Skip to content

Commit

Permalink
Fixed type inference issues when binding explicitly (#5754)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib committed Feb 2, 2023
1 parent b53c112 commit 2ce5de5
Show file tree
Hide file tree
Showing 23 changed files with 240 additions and 53 deletions.
1 change: 0 additions & 1 deletion src/CookieCrumble/src/CookieCrumble/CookieCrumble.csproj
Expand Up @@ -5,7 +5,6 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
<AssemblyName>CookieCrumble</AssemblyName>
<RootNamespace>CookieCrumble</RootNamespace>
</PropertyGroup>
Expand Down
Expand Up @@ -5,7 +5,7 @@

namespace HotChocolate.Execution.Configuration;

public class RequestExecutorSetup
public sealed class RequestExecutorSetup
{
private readonly List<SchemaBuilderAction> _schemaBuilderActions = new();
private readonly List<RequestExecutorOptionsAction> _requestExecutorOptionsActions = new();
Expand Down
Expand Up @@ -6,6 +6,7 @@
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using HotChocolate.Execution.Processing;
Expand Down Expand Up @@ -644,6 +645,10 @@ private void WriteIncremental(Utf8JsonWriter writer, IReadOnlyList<IQueryResult>
break;

#if NET6_0_OR_GREATER
case JsonDocument doc:
WriteJsonElement(writer, doc.RootElement);
break;

case JsonElement element:
WriteJsonElement(writer, element);
break;
Expand Down
Expand Up @@ -9,11 +9,12 @@ namespace HotChocolate.Execution.Serialization;
/// and writes it without validation to the JSON response object.
/// </summary>
/// <remarks>
/// <para>
/// The downside of this helper is that we bind it explicitly to JSON.
/// If there were alternative query formatter that use different formats we would get
/// into trouble with this.
///
/// This is also the reason for keeping this internal.
/// </para>
/// <para>This is also the reason for keeping this internal.</para>
/// </remarks>
internal readonly struct RawJsonValue
{
Expand Down
Expand Up @@ -45,5 +45,6 @@ public DirectiveTypeAttribute(string name, DirectiveLocation location)
}

descriptor.Location(Location);
descriptor.Extend().Definition.Arguments.BindingBehavior = BindingBehavior.Implicit;
}
}
Expand Up @@ -42,5 +42,7 @@ public EnumTypeAttribute(string? name = null)
{
descriptor.Name(Name);
}

descriptor.BindValuesImplicitly();
}
}
Expand Up @@ -10,8 +10,7 @@ namespace HotChocolate.Types;
AttributeTargets.Enum | AttributeTargets.Class | AttributeTargets.Struct,
Inherited = true,
AllowMultiple = true)]
public abstract class EnumTypeDescriptorAttribute
: DescriptorAttribute
public abstract class EnumTypeDescriptorAttribute : DescriptorAttribute
{
protected internal sealed override void TryConfigure(
IDescriptorContext context,
Expand Down
Expand Up @@ -10,8 +10,7 @@ namespace HotChocolate.Types;
AttributeTargets.Field,
Inherited = true,
AllowMultiple = true)]
public abstract class EnumValueDescriptorAttribute
: DescriptorAttribute
public abstract class EnumValueDescriptorAttribute : DescriptorAttribute
{
protected internal sealed override void TryConfigure(
IDescriptorContext context,
Expand Down
Expand Up @@ -102,9 +102,12 @@ public ExtendObjectTypeAttribute(Type extendsType)
descriptor.Name(Name);
}

var definition = descriptor.Extend().Definition;
definition.Fields.BindingBehavior = BindingBehavior.Implicit;

if (IncludeStaticMembers)
{
descriptor.Extend().Definition.FieldBindingFlags = Instance | Static;
definition.FieldBindingFlags = Instance | Static;
}

if (IgnoreFields is not null)
Expand Down
Expand Up @@ -41,5 +41,7 @@ public InputObjectTypeAttribute(string? name = null)
{
descriptor.Name(Name);
}

descriptor.Extend().Definition.Fields.BindingBehavior = BindingBehavior.Implicit;
}
}
Expand Up @@ -41,5 +41,7 @@ public InterfaceTypeAttribute(string? name = null)
{
descriptor.Name(Name);
}

descriptor.Extend().Definition.Fields.BindingBehavior = BindingBehavior.Implicit;
}
}
Expand Up @@ -16,6 +16,11 @@ public sealed class MutationTypeAttribute
/// </summary>
public bool Inherited { get; set; }

/// <summary>
/// Defines that static members are included.
/// </summary>
public bool IncludeStaticMembers { get; set; }

TypeKind ITypeAttribute.Kind => TypeKind.Object;

bool ITypeAttribute.IsTypeExtension => true;
Expand All @@ -24,5 +29,15 @@ public sealed class MutationTypeAttribute
IDescriptorContext context,
IObjectTypeDescriptor descriptor,
Type type)
=> descriptor.Name(OperationTypeNames.Mutation);
{
descriptor.Name(OperationTypeNames.Mutation);

var definition = descriptor.Extend().Definition;
definition.Fields.BindingBehavior = BindingBehavior.Implicit;

if (IncludeStaticMembers)
{
definition.FieldBindingFlags = FieldBindingFlags.Instance | FieldBindingFlags.Static;
}
}
}
Expand Up @@ -53,9 +53,12 @@ public ObjectTypeAttribute(string? name = null)
descriptor.Name(Name);
}

var definition = descriptor.Extend().Definition;
definition.Fields.BindingBehavior = BindingBehavior.Implicit;

if (IncludeStaticMembers)
{
descriptor.Extend().Definition.FieldBindingFlags = Instance | Static;
definition.FieldBindingFlags = Instance | Static;
}
}
}
Expand Up @@ -16,6 +16,11 @@ public sealed class QueryTypeAttribute
/// </summary>
public bool Inherited { get; set; }

/// <summary>
/// Defines that static members are included.
/// </summary>
public bool IncludeStaticMembers { get; set; }

TypeKind ITypeAttribute.Kind => TypeKind.Object;

bool ITypeAttribute.IsTypeExtension => true;
Expand All @@ -24,5 +29,15 @@ public sealed class QueryTypeAttribute
IDescriptorContext context,
IObjectTypeDescriptor descriptor,
Type type)
=> descriptor.Name(OperationTypeNames.Query);
{
descriptor.Name(OperationTypeNames.Query);

var definition = descriptor.Extend().Definition;
definition.Fields.BindingBehavior = BindingBehavior.Implicit;

if (IncludeStaticMembers)
{
definition.FieldBindingFlags = FieldBindingFlags.Instance | FieldBindingFlags.Static;
}
}
}
Expand Up @@ -16,7 +16,5 @@ public sealed class StreamResultAttribute : ObjectFieldDescriptorAttribute
IDescriptorContext context,
IObjectFieldDescriptor descriptor,
MemberInfo member)
{
descriptor.StreamResult();
}
=> descriptor.StreamResult();
}
Expand Up @@ -16,6 +16,11 @@ public sealed class SubscriptionTypeAttribute
/// </summary>
public bool Inherited { get; set; }

/// <summary>
/// Defines that static members are included.
/// </summary>
public bool IncludeStaticMembers { get; set; }

TypeKind ITypeAttribute.Kind => TypeKind.Object;

bool ITypeAttribute.IsTypeExtension => true;
Expand All @@ -24,5 +29,15 @@ public sealed class SubscriptionTypeAttribute
IDescriptorContext context,
IObjectTypeDescriptor descriptor,
Type type)
=> descriptor.Name(OperationTypeNames.Subscription);
{
descriptor.Name(OperationTypeNames.Subscription);

var definition = descriptor.Extend().Definition;
definition.Fields.BindingBehavior = BindingBehavior.Implicit;

if (IncludeStaticMembers)
{
definition.FieldBindingFlags = FieldBindingFlags.Instance | FieldBindingFlags.Static;
}
}
}
Expand Up @@ -10,7 +10,7 @@ namespace HotChocolate.Types.Descriptors;

public class DefaultNamingConventions
: Convention
, INamingConventions
, INamingConventions
{
private const string _inputPostfix = "Input";
private const string _inputTypePostfix = "InputType";
Expand Down
9 changes: 1 addition & 8 deletions src/HotChocolate/Core/src/Types/Types/InputObjectType~1.cs
Expand Up @@ -2,6 +2,7 @@
using HotChocolate.Configuration;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
using HotChocolate.Types.Helpers;

#nullable enable

Expand Down Expand Up @@ -29,14 +30,6 @@ public InputObjectType(Action<IInputObjectTypeDescriptor<T>> configure)
_configure!(descriptor);
_configure = null;

// if the object type is inferred from a runtime time we will bind fields implicitly
// even if the schema building option are set to bind explicitly by default;
// otherwise we would end up with types that have no fields.
if (context.IsInferred)
{
descriptor.BindFieldsImplicitly();
}

return descriptor.CreateDefinition();
}

Expand Down
8 changes: 0 additions & 8 deletions src/HotChocolate/Core/src/Types/Types/InterfaceType~1.cs
Expand Up @@ -24,14 +24,6 @@ protected override InterfaceTypeDefinition CreateDefinition(ITypeDiscoveryContex
_configure!(descriptor);
_configure = null;

// if the object type is inferred from a runtime time we will bind fields implicitly
// even if the schema building option are set to bind explicitly by default;
// otherwise we would end up with types that have no fields.
if (context.IsInferred)
{
descriptor.BindFieldsImplicitly();
}

return descriptor.CreateDefinition();
}

Expand Down
Expand Up @@ -46,14 +46,6 @@ public ObjectTypeExtension(Action<IObjectTypeDescriptor<T>> configure)
_configure!(descriptor);
_configure = null;

// if the object type is inferred from a runtime time we will bind fields implicitly
// even if the schema building option are set to bind explicitly by default;
// otherwise we would end up with types that have no fields.
if (context.IsInferred)
{
descriptor.BindFieldsImplicitly();
}

return descriptor.CreateDefinition();
}

Expand Down
17 changes: 7 additions & 10 deletions src/HotChocolate/Core/src/Types/Types/ObjectType~1.cs
Expand Up @@ -2,24 +2,29 @@
using HotChocolate.Configuration;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
using HotChocolate.Types.Helpers;

#nullable enable

namespace HotChocolate.Types;

/// <summary>
/// <para>
/// GraphQL operations are hierarchical and composed, describing a tree of information.
/// While Scalar types describe the leaf values of these hierarchical operations,
/// Objects describe the intermediate levels.
///
/// </para>
/// <para>
/// GraphQL Objects represent a list of named fields, each of which yield a value of a
/// specific type. Object values should be serialized as ordered maps, where the selected
/// field names (or aliases) are the keys and the result of evaluating the field is the value,
/// ordered by the order in which they appear in the selection set.
///
/// </para>
/// <para>
/// All fields defined within an Object type must not have a name which begins
/// with "__" (two underscores), as this is used exclusively by
/// GraphQL’s introspection system.
/// </para>
/// </summary>
public class ObjectType<T> : ObjectType
{
Expand All @@ -45,14 +50,6 @@ public ObjectType(Action<IObjectTypeDescriptor<T>> configure)
_configure!(descriptor);
_configure = null;

// if the object type is inferred from a runtime time we will bind fields implicitly
// even if the schema building option are set to bind explicitly by default;
// otherwise we would end up with types that have no fields.
if (context.IsInferred)
{
descriptor.BindFieldsImplicitly();
}

return descriptor.CreateDefinition();
}

Expand Down
3 changes: 1 addition & 2 deletions src/HotChocolate/Core/src/Types/Types/UnionType~1.cs
Expand Up @@ -8,8 +8,7 @@

namespace HotChocolate.Types;

public class UnionType<T>
: UnionType
public class UnionType<T> : UnionType
{
private Action<IUnionTypeDescriptor>? _configure;

Expand Down

0 comments on commit 2ce5de5

Please sign in to comment.