Skip to content

Commit d786b2f

Browse files
authored
Added support for directives on scalar types (#7150)
1 parent 9c68057 commit d786b2f

28 files changed

+528
-150
lines changed

src/HotChocolate/Core/src/Types/Configuration/ITypeRegistrar.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ void Register(
2020
void MarkResolved(TypeReference typeReference);
2121

2222
bool IsResolved(TypeReference typeReference);
23-
24-
2523

2624
TypeSystemObjectBase CreateInstance(Type namedSchemaType);
2725

src/HotChocolate/Core/src/Types/Configuration/RegisteredType.CompletionContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internal sealed partial class RegisteredType : ITypeCompletionContext
3333

3434
/// <inheritdoc />
3535
IReadOnlyList<FieldMiddleware> ITypeCompletionContext.GlobalComponents
36-
=> GlobalComponents ?? (IReadOnlyList<FieldMiddleware>)Array.Empty<FieldMiddleware>();
36+
=> GlobalComponents ?? (IReadOnlyList<FieldMiddleware>)[];
3737

3838
/// <inheritdoc />
3939
public IsOfTypeFallback? IsOfType { get; private set; }

src/HotChocolate/Core/src/Types/Configuration/TypeInitializer.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Diagnostics.CodeAnalysis;
44
using System.Globalization;
55
using System.Linq;
6-
using HotChocolate.Configuration.Validation;
76
using HotChocolate.Language;
87
using HotChocolate.Resolvers;
98
using HotChocolate.Types;
@@ -25,7 +24,6 @@ internal sealed class TypeInitializer
2524
private readonly TypeInterceptor _interceptor;
2625
private readonly IsOfTypeFallback? _isOfType;
2726
private readonly Func<TypeSystemObjectBase, RootTypeKind> _getTypeKind;
28-
private readonly IReadOnlySchemaOptions _options;
2927
private readonly TypeRegistry _typeRegistry;
3028
private readonly TypeLookup _typeLookup;
3129
private readonly TypeReferenceResolver _typeReferenceResolver;
@@ -44,6 +42,11 @@ public TypeInitializer(
4442
Func<TypeSystemObjectBase, RootTypeKind> getTypeKind,
4543
IReadOnlySchemaOptions options)
4644
{
45+
if(options is null)
46+
{
47+
throw new ArgumentNullException(nameof(options));
48+
}
49+
4750
_context = descriptorContext ??
4851
throw new ArgumentNullException(nameof(descriptorContext));
4952
_typeRegistry = typeRegistry ??
@@ -52,8 +55,6 @@ public TypeInitializer(
5255
throw new ArgumentNullException(nameof(initialTypes));
5356
_getTypeKind = getTypeKind ??
5457
throw new ArgumentNullException(nameof(getTypeKind));
55-
_options = options ??
56-
throw new ArgumentNullException(nameof(options));
5758

5859
_isOfType = isOfType ?? options.DefaultIsOfTypeCheck;
5960

src/HotChocolate/Core/src/Types/Configuration/TypeRegistrar.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public TypeRegistrar(IDescriptorContext context,
3232
throw new ArgumentNullException(nameof(typeLookup));
3333
_context = context ??
3434
throw new ArgumentNullException(nameof(context));
35-
_interceptor = typeInterceptor ??
35+
_interceptor = typeInterceptor ??
3636
throw new ArgumentNullException(nameof(typeInterceptor));
3737
_schemaServices = context.Services;
3838
_applicationServices = context.Services.GetService<IApplicationServiceProvider>();
@@ -61,15 +61,15 @@ public void Register(
6161
{
6262
return;
6363
}
64-
64+
6565
RegisterTypeAndResolveReferences(registeredType);
6666

67-
if (obj is not IHasRuntimeType hasRuntimeType ||
67+
if (obj is not IHasRuntimeType hasRuntimeType ||
6868
hasRuntimeType.RuntimeType == typeof(object))
6969
{
7070
return;
7171
}
72-
72+
7373
var runtimeTypeRef =
7474
_context.TypeInspector.GetTypeRef(
7575
hasRuntimeType.RuntimeType,
@@ -82,7 +82,7 @@ public void Register(
8282
{
8383
return;
8484
}
85-
85+
8686
MarkResolved(runtimeTypeRef);
8787
_typeRegistry.TryRegister(runtimeTypeRef, registeredType.References[0]);
8888
}

src/HotChocolate/Core/src/Types/Schema.Initialization.cs

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#if NET8_0_OR_GREATER
33
using System.Collections.Frozen;
44
#endif
5-
using System.Collections.Generic;
65
using System.Linq;
76
using HotChocolate.Configuration;
87
using HotChocolate.Types;
@@ -113,84 +112,3 @@ internal void CompleteSchema(SchemaTypesDefinition schemaTypesDefinition)
113112
_sealed = true;
114113
}
115114
}
116-
117-
internal static class SchemaTools
118-
{
119-
public static void AddSchemaConfiguration(
120-
this ISchemaBuilder builder,
121-
Action<ISchemaTypeDescriptor> configure)
122-
{
123-
if (builder is null)
124-
{
125-
throw new ArgumentNullException(nameof(builder));
126-
}
127-
128-
if (configure is null)
129-
{
130-
throw new ArgumentNullException(nameof(configure));
131-
}
132-
133-
List<Action<ISchemaTypeDescriptor>> options;
134-
135-
if (!builder.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value))
136-
{
137-
options = [];
138-
builder.ContextData.Add(WellKnownContextData.InternalSchemaOptions, options);
139-
value = options;
140-
}
141-
142-
options = (List<Action<ISchemaTypeDescriptor>>)value!;
143-
options.Add(configure);
144-
}
145-
146-
public static void AddSchemaConfiguration(
147-
this IDescriptorContext context,
148-
Action<ISchemaTypeDescriptor> configure)
149-
{
150-
if (context is null)
151-
{
152-
throw new ArgumentNullException(nameof(context));
153-
}
154-
155-
if (configure is null)
156-
{
157-
throw new ArgumentNullException(nameof(configure));
158-
}
159-
160-
List<Action<ISchemaTypeDescriptor>> options;
161-
162-
if (!context.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value))
163-
{
164-
options = [];
165-
context.ContextData.Add(WellKnownContextData.InternalSchemaOptions, options);
166-
value = options;
167-
}
168-
169-
options = (List<Action<ISchemaTypeDescriptor>>)value!;
170-
options.Add(configure);
171-
}
172-
173-
public static void ApplySchemaConfigurations(
174-
this IDescriptorContext context,
175-
ISchemaTypeDescriptor descriptor)
176-
{
177-
if (context is null)
178-
{
179-
throw new ArgumentNullException(nameof(context));
180-
}
181-
182-
if (descriptor is null)
183-
{
184-
throw new ArgumentNullException(nameof(descriptor));
185-
}
186-
187-
if (context.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value) &&
188-
value is List<Action<ISchemaTypeDescriptor>> options)
189-
{
190-
foreach (var option in options)
191-
{
192-
option(descriptor);
193-
}
194-
}
195-
}
196-
}

src/HotChocolate/Core/src/Types/SchemaBuilder.Setup.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public static Schema Create(
5757
builder._typeInterceptors.Add(typeof(DirectiveTypeInterceptor));
5858
}
5959

60+
if(builder._schemaFirstTypeInterceptor is not null)
61+
{
62+
typeInterceptors.Add(builder._schemaFirstTypeInterceptor);
63+
}
64+
6065
InitializeInterceptors(
6166
context.Services,
6267
builder._typeInterceptors,
@@ -146,7 +151,9 @@ private static IEnumerable<TypeReference> ParseDocuments(
146151
schemaDocument = schemaDocument.RemoveBuiltInTypes();
147152
documents.Add(schemaDocument);
148153

149-
var visitorContext = new SchemaSyntaxVisitorContext(context);
154+
var visitorContext = new SchemaSyntaxVisitorContext(
155+
context,
156+
builder._schemaFirstTypeInterceptor!.Directives);
150157
var visitor = new SchemaSyntaxVisitor();
151158

152159
visitor.Visit(schemaDocument, visitorContext);

src/HotChocolate/Core/src/Types/SchemaBuilder.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using HotChocolate.Types;
99
using HotChocolate.Types.Descriptors;
1010
using HotChocolate.Types.Descriptors.Definitions;
11+
using HotChocolate.Types.Factories;
1112
using HotChocolate.Types.Interceptors;
1213
using HotChocolate.Types.Introspection;
1314
using HotChocolate.Types.Pagination;
@@ -31,6 +32,7 @@ public partial class SchemaBuilder : ISchemaBuilder
3132
private readonly Dictionary<OperationType, CreateRef> _operations = new();
3233
private readonly Dictionary<(Type, string?), List<CreateConvention>> _conventions = new();
3334
private readonly Dictionary<Type, (CreateRef, CreateRef)> _clrTypes = new();
35+
private SchemaFirstTypeInterceptor? _schemaFirstTypeInterceptor;
3436

3537
private readonly List<object> _typeInterceptors =
3638
[
@@ -146,6 +148,7 @@ public ISchemaBuilder AddDocument(LoadSchemaDocument loadSchemaDocument)
146148
throw new ArgumentNullException(nameof(loadSchemaDocument));
147149
}
148150

151+
_schemaFirstTypeInterceptor ??= new SchemaFirstTypeInterceptor();
149152
_documents.Add(loadSchemaDocument);
150153
return this;
151154
}
@@ -262,7 +265,7 @@ public ISchemaBuilder AddType(INamedTypeExtension typeExtension)
262265
_types.Add(_ => TypeReference.Create(typeExtension));
263266
return this;
264267
}
265-
268+
266269
internal void AddTypeReference(TypeReference typeReference)
267270
{
268271
if (typeReference is null)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
#if NET8_0_OR_GREATER
3+
using System.Collections.Frozen;
4+
#endif
5+
using System.Collections.Generic;
6+
using HotChocolate.Types;
7+
using HotChocolate.Types.Descriptors;
8+
9+
namespace HotChocolate;
10+
11+
internal static class SchemaTools
12+
{
13+
public static void AddSchemaConfiguration(
14+
this ISchemaBuilder builder,
15+
Action<ISchemaTypeDescriptor> configure)
16+
{
17+
if (builder is null)
18+
{
19+
throw new ArgumentNullException(nameof(builder));
20+
}
21+
22+
if (configure is null)
23+
{
24+
throw new ArgumentNullException(nameof(configure));
25+
}
26+
27+
List<Action<ISchemaTypeDescriptor>> options;
28+
29+
if (!builder.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value))
30+
{
31+
options = [];
32+
builder.ContextData.Add(WellKnownContextData.InternalSchemaOptions, options);
33+
value = options;
34+
}
35+
36+
options = (List<Action<ISchemaTypeDescriptor>>)value!;
37+
options.Add(configure);
38+
}
39+
40+
public static void AddSchemaConfiguration(
41+
this IDescriptorContext context,
42+
Action<ISchemaTypeDescriptor> configure)
43+
{
44+
if (context is null)
45+
{
46+
throw new ArgumentNullException(nameof(context));
47+
}
48+
49+
if (configure is null)
50+
{
51+
throw new ArgumentNullException(nameof(configure));
52+
}
53+
54+
List<Action<ISchemaTypeDescriptor>> options;
55+
56+
if (!context.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value))
57+
{
58+
options = [];
59+
context.ContextData.Add(WellKnownContextData.InternalSchemaOptions, options);
60+
value = options;
61+
}
62+
63+
options = (List<Action<ISchemaTypeDescriptor>>)value!;
64+
options.Add(configure);
65+
}
66+
67+
public static void ApplySchemaConfigurations(
68+
this IDescriptorContext context,
69+
ISchemaTypeDescriptor descriptor)
70+
{
71+
if (context is null)
72+
{
73+
throw new ArgumentNullException(nameof(context));
74+
}
75+
76+
if (descriptor is null)
77+
{
78+
throw new ArgumentNullException(nameof(descriptor));
79+
}
80+
81+
if (context.ContextData.TryGetValue(WellKnownContextData.InternalSchemaOptions, out var value) &&
82+
value is List<Action<ISchemaTypeDescriptor>> options)
83+
{
84+
foreach (var option in options)
85+
{
86+
option(descriptor);
87+
}
88+
}
89+
}
90+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Reflection;
3+
using HotChocolate.Types.Descriptors;
4+
5+
#nullable enable
6+
7+
namespace HotChocolate.Types;
8+
9+
[AttributeUsage(
10+
AttributeTargets.Class,
11+
Inherited = true,
12+
AllowMultiple = true)]
13+
public abstract class ScalarTypeDescriptorAttribute : DescriptorAttribute
14+
{
15+
protected internal sealed override void TryConfigure(
16+
IDescriptorContext context,
17+
IDescriptor descriptor,
18+
ICustomAttributeProvider element)
19+
{
20+
if (descriptor is IScalarTypeDescriptor d
21+
&& element is Type t)
22+
{
23+
OnConfigure(context, d, t);
24+
}
25+
}
26+
27+
protected abstract void OnConfigure(
28+
IDescriptorContext context,
29+
IScalarTypeDescriptor descriptor,
30+
Type type);
31+
}

src/HotChocolate/Core/src/Types/Types/Contracts/IObjectField.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ public interface IObjectField : IOutputField
2020
/// Defines if this field can be executed in parallel with other fields.
2121
/// </summary>
2222
bool IsParallelExecutable { get; }
23-
23+
2424
/// <summary>
2525
/// Defines in which DI scope this field is executed.
2626
/// </summary>
27-
DependencyInjectionScope DependencyInjectionScope { get; }
27+
DependencyInjectionScope DependencyInjectionScope { get; }
2828

2929
/// <summary>
3030
/// Defines that the resolver pipeline returns an
@@ -68,4 +68,4 @@ public interface IObjectField : IOutputField
6868
/// this property will return <see cref="Member"/>.
6969
/// </summary>
7070
MemberInfo? ResolverMember { get; }
71-
}
71+
}

0 commit comments

Comments
 (0)