Skip to content

Commit

Permalink
Fixed an issue that causes input types in an output context. (#6044)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Apr 12, 2023
1 parent f0974c4 commit 423e8a3
Show file tree
Hide file tree
Showing 20 changed files with 428 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@

namespace HotChocolate.Configuration;

internal sealed class ExtendedTypeReferenceEqualityComparer
: IEqualityComparer<ExtendedTypeReference>
internal sealed class ExtendedTypeRefEqualityComparer : IEqualityComparer<ExtendedTypeReference>
{
public bool Equals([AllowNull] ExtendedTypeReference x, [AllowNull] ExtendedTypeReference y)
public bool Equals(ExtendedTypeReference? x, ExtendedTypeReference? y)
{
if (ReferenceEquals(x, y))
{
Expand All @@ -39,7 +38,7 @@ public bool Equals([AllowNull] ExtendedTypeReference x, [AllowNull] ExtendedType
return Equals(x.Type, y.Type);
}

private static bool Equals([AllowNull] IExtendedType x, [AllowNull] IExtendedType y)
private static bool Equals(IExtendedType? x, IExtendedType? y)
{
if (ReferenceEquals(x, y))
{
Expand All @@ -54,7 +53,7 @@ private static bool Equals([AllowNull] IExtendedType x, [AllowNull] IExtendedTyp
return ReferenceEquals(x.Type, y.Type) && x.Kind == y.Kind;
}

public int GetHashCode([DisallowNull] ExtendedTypeReference obj)
public int GetHashCode(ExtendedTypeReference obj)
{
unchecked
{
Expand All @@ -69,7 +68,7 @@ public int GetHashCode([DisallowNull] ExtendedTypeReference obj)
}
}

private static int GetHashCode([DisallowNull] IExtendedType obj)
private static int GetHashCode(IExtendedType obj)
{
unchecked
{
Expand All @@ -78,11 +77,10 @@ private static int GetHashCode([DisallowNull] IExtendedType obj)

for (var i = 0; i < obj.TypeArguments.Count; i++)
{
hashCode ^= (GetHashCode(obj.TypeArguments[i]) * 397 * i);
hashCode ^= GetHashCode(obj.TypeArguments[i]) * 397 * i;
}

return hashCode;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,7 @@ private static void TryMapToExistingRegistration(

foreach (var component in typeInfo.Components)
{
normalizedTypeRef = TypeReference.Create(
component.Type,
context,
scope);
normalizedTypeRef = TypeReference.Create(component.Type, context, scope);

if (typeRegistrar.IsResolved(normalizedTypeRef))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ private bool TryInferTypes()

if (unresolvedTypeRef is ExtendedTypeReference typeRef)
{
// we normalize the type context so that we can correctly lookup
// if a type is already registered.
typeRef = typeRef.WithContext(schemaTypeRef.Context);
_typeRegistry.TryRegister(typeRef, schemaTypeRef);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/HotChocolate/Core/src/Types/Configuration/TypeRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal sealed class TypeRegistry
{
private readonly Dictionary<TypeReference, RegisteredType> _typeRegister = new();
private readonly Dictionary<ExtendedTypeReference, TypeReference> _runtimeTypeRefs =
new(new ExtendedTypeReferenceEqualityComparer());
new(new ExtendedTypeRefEqualityComparer());
private readonly Dictionary<string, TypeReference> _nameRefs = new(StringComparer.Ordinal);
private readonly List<RegisteredType> _types = new();
private readonly TypeInterceptor _typeRegistryInterceptor;
Expand Down Expand Up @@ -47,9 +47,9 @@ public bool IsRegistered(TypeReference typeReference)
return true;
}

if (typeReference is ExtendedTypeReference clrTypeReference)
if (typeReference is ExtendedTypeReference extendedTypeRef)
{
return _runtimeTypeRefs.ContainsKey(clrTypeReference);
return _runtimeTypeRefs.ContainsKey(extendedTypeRef);
}

return false;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/HotChocolate/Core/src/Types/Properties/TypeResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1083,4 +1083,10 @@ Type: `{0}`</value>
<data name="ErrorHelper_FetchedToManyNodesAtOnce" xml:space="preserve">
<value>The maximum number of nodes that can be fetched at once is {0}. This selection tried to fetch {1} nodes that exceeded the maximum allowed amount.</value>
</data>
<data name="ThrowHelper_InputTypeExpected_Message" xml:space="preserve">
<value>The specified type `{0}` is expected to be an input type.</value>
</data>
<data name="ThrowHelper_OutputTypeExpected_Message" xml:space="preserve">
<value>The specified type `{0}` is expected to be an output type.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/HotChocolate/Core/src/Types/Types/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ protected override void OnCompleteField(

base.OnCompleteField(context, declaringMember, definition);

Type = context.GetType<IInputType>(definition.Type!);
Type = context.GetType<IInputType>(definition.Type!).EnsureInputType();
_runtimeType = definition.RuntimeType ?? definition.Parameter?.ParameterType!;
_runtimeType = CompleteRuntimeType(Type, _runtimeType, out var isOptional);
DefaultValue = CompleteDefaultValue(context, definition, Type, Coordinate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ public sealed class ExtendedTypeReference
: TypeReference
, IEquatable<ExtendedTypeReference>
{
/// <summary>
/// Initializes a new instance of <see cref="ExtendedTypeReference"/>.
/// </summary>
/// <param name="type">
/// The extended type.
/// </param>
/// <param name="context">
/// The type context.
/// </param>
/// <param name="scope">
/// The type scope.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="type"/> is <c>null</c>.
/// </exception>
internal ExtendedTypeReference(
IExtendedType type,
TypeContext context,
Expand Down Expand Up @@ -91,54 +106,113 @@ public override bool Equals(object? obj)

/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return base.GetHashCode() ^ Type.GetHashCode() * 397;
}
}
=> HashCode.Combine(base.GetHashCode(), Type.GetHashCode());

/// <inheritdoc />
public override string ToString()
=> ToString(Type);

/// <summary>
/// Creates a new <see cref="ExtendedTypeReference"/> and
/// replaces the <see cref="Type"/> with the provided <paramref name="type"/>.
/// </summary>
/// <param name="type">
/// The extended type.
/// </param>
/// <returns>
/// Returns a new <see cref="ExtendedTypeReference"/>.
/// </returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="type"/> is <c>null</c>.
/// </exception>
public ExtendedTypeReference WithType(IExtendedType type)
{
if (type is null)
{
throw new ArgumentNullException(nameof(type));
}

return Create(
type,
Context,
Scope);
if (type.Equals(Type))
{
return this;
}

return Create(type, Context, Scope);
}

/// <summary>
/// Creates a new <see cref="ExtendedTypeReference"/> and replaces the
/// <see cref="TypeReference.Context"/> with the provided <paramref name="context"/>.
/// </summary>
/// <param name="context">
/// The type context.
/// </param>
/// <returns>
/// Returns a new <see cref="ExtendedTypeReference"/>.
/// </returns>
public ExtendedTypeReference WithContext(TypeContext context = TypeContext.None)
{
if (context == Context)
{
return this;
}

return Create(
Type,
context,
Scope);
}

/// <summary>
/// Creates a new <see cref="ExtendedTypeReference"/> and replaces the
/// <see cref="TypeReference.Scope"/> with the provided
/// <paramref name="scope"/>.
/// </summary>
/// <param name="scope">
/// The type scope.
/// </param>
/// <returns>
/// Returns a new <see cref="ExtendedTypeReference"/>.
/// </returns>
public ExtendedTypeReference WithScope(string? scope = null)
{
if (string.Equals(scope, Scope, StringComparison.Ordinal))
{
return this;
}

return Create(
Type,
Context,
scope);
}

/// <summary>
/// Creates a new <see cref="ExtendedTypeReference"/> and allows to replace certain aspects
/// of the original instance.
/// </summary>
/// <param name="type">
/// The extended type.
/// </param>
/// <param name="context">
/// The type context.
/// </param>
/// <param name="scope">
/// The type scope.
/// </param>
/// <returns>
/// Returns a new <see cref="ExtendedTypeReference"/>.
/// </returns>
public ExtendedTypeReference With(
IExtendedType? type = default,
Optional<TypeContext> context = default,
Optional<string?> scope = default)
{
return Create(
=> Create(
type ?? Type,
context.HasValue ? context.Value : Context,
scope.HasValue ? scope.Value : Scope);
}
context.HasValue
? context.Value
: Context,
scope.HasValue
? scope.Value
: Scope);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using HotChocolate.Internal;
using HotChocolate.Language;
using HotChocolate.Utilities;
Expand All @@ -24,15 +25,32 @@ protected TypeReference(
Scope = scope;
}

/// <inheritdoc />
/// <summary>
/// Gets the kind of the type reference.
/// </summary>
public TypeReferenceKind Kind { get; }

/// <inheritdoc />
/// <summary>
/// Specifies in which context the type reference is used
/// (input types, output types, neutral context).
/// </summary>
public TypeContext Context { get; }

/// <inheritdoc />
/// <summary>
/// Gets the scope of the type reference.
/// The scope allows us to branch the type system.
/// </summary>
public string? Scope { get; }

/// <summary>
/// A helper method to compare a type reference.
/// </summary>
/// <param name="other">
/// The other type reference.
/// </param>
/// <returns>
/// <c>true</c> if the type references are equal; otherwise, <c>false</c>.
/// </returns>
protected bool IsEqual(TypeReference other)
{
if (Context != other.Context
Expand Down
Loading

0 comments on commit 423e8a3

Please sign in to comment.