Skip to content

Commit d0f3629

Browse files
authored
[Fusion] Adds Full FieldSelectionMap support (#8460)
1 parent fe85e6a commit d0f3629

File tree

91 files changed

+2025
-2197
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+2025
-2197
lines changed

src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ internal sealed class SourceSchemaMerger
2929
private readonly FrozenDictionary<string, ITypeDefinition> _fusionTypeDefinitions;
3030
private readonly FrozenDictionary<string, MutableDirectiveDefinition>
3131
_fusionDirectiveDefinitions;
32-
private readonly Dictionary<string, SelectedValueToSelectionSetRewriter>
32+
private readonly Dictionary<string, ValueSelectionToSelectionSetRewriter>
3333
_selectedValueToSelectionSetRewriters = [];
3434
private readonly Dictionary<string, MergeSelectionSetRewriter> _mergeSelectionSetRewriters = [];
3535

@@ -978,7 +978,7 @@ private void AddFusionLookupDirectives(
978978
GetSelectedValueToSelectionSetRewriter(sourceSchema);
979979
var selectionSets = selectedValues
980980
.Select(
981-
s => selectedValueToSelectionSetRewriter.SelectedValueToSelectionSet(s, type))
981+
s => selectedValueToSelectionSetRewriter.Rewrite(s, type))
982982
.ToImmutableArray();
983983
var mergedSelectionSet = selectionSets.Length == 1
984984
? selectionSets[0]
@@ -1060,7 +1060,7 @@ private void AddFusionRequiresDirectives(
10601060
.Select(
10611061
s =>
10621062
selectedValueToSelectionSetRewriter
1063-
.SelectedValueToSelectionSet(s, complexType))
1063+
.Rewrite(s, complexType))
10641064
.ToImmutableArray();
10651065
var mergedSelectionSet = selectionSets.Length == 1
10661066
? selectionSets[0]
@@ -1226,15 +1226,15 @@ private void AddFusionDefinitions(MutableSchemaDefinition mergedSchema)
12261226
}
12271227
}
12281228

1229-
private SelectedValueToSelectionSetRewriter GetSelectedValueToSelectionSetRewriter(
1229+
private ValueSelectionToSelectionSetRewriter GetSelectedValueToSelectionSetRewriter(
12301230
MutableSchemaDefinition schema)
12311231
{
12321232
if (_selectedValueToSelectionSetRewriters.TryGetValue(schema.Name, out var rewriter))
12331233
{
12341234
return rewriter;
12351235
}
12361236

1237-
rewriter = new SelectedValueToSelectionSetRewriter(schema);
1237+
rewriter = new ValueSelectionToSelectionSetRewriter(schema);
12381238
_selectedValueToSelectionSetRewriters.Add(schema.Name, rewriter);
12391239

12401240
return rewriter;

src/HotChocolate/Fusion-vnext/src/Fusion.Execution.Types/Completion/AggregateCompositeTypeInterceptor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ public AggregateCompositeTypeInterceptor(CompositeTypeInterceptor[] interceptors
1414
_interceptors = interceptors;
1515
}
1616

17-
public override void OnCompleteSchema(
17+
public override void OnBeforeCompleteSchema(
1818
ICompositeSchemaBuilderContext context,
1919
ref IFeatureCollection features)
2020
{
2121
foreach (var interceptor in _interceptors)
2222
{
23-
interceptor.OnCompleteSchema(context, ref features);
23+
interceptor.OnBeforeCompleteSchema(context, ref features);
2424
}
2525
}
2626

src/HotChocolate/Fusion-vnext/src/Fusion.Execution.Types/Completion/CompletionTools.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System.Collections.Immutable;
22
using System.Runtime.InteropServices;
3+
using HotChocolate.Fusion.Language;
34
using HotChocolate.Fusion.Types.Collections;
45
using HotChocolate.Fusion.Types.Directives;
5-
using HotChocolate.Fusion.Utilities;
66
using HotChocolate.Language;
77
using HotChocolate.Types;
88

@@ -96,16 +96,19 @@ public static SourceObjectTypeCollection CreateSourceObjectTypeCollection(
9696
CompositeSchemaBuilderContext context)
9797
{
9898
var types = TypeDirectiveParser.Parse(typeDef.Directives);
99-
var lookups = LookupDirectiveParser.Parse(typeDef.Directives);
99+
var lookupDirectives = LookupDirectiveParser.Parse(typeDef.Directives);
100100
var temp = new SourceObjectType[types.Length];
101101

102102
for (var i = 0; i < types.Length; i++)
103103
{
104104
var type = types[i];
105+
var lookups = GetLookupBySchema(lookupDirectives, type.SchemaName, typeDef.Name.Value);
106+
context.RegisterForCompletionRange(lookups);
107+
105108
temp[i] = new SourceObjectType(
106109
typeDef.Name.Value,
107110
type.SchemaName,
108-
GetLookupBySchema(lookups, type.SchemaName));
111+
lookups);
109112
}
110113

111114
return new SourceObjectTypeCollection(temp);
@@ -116,30 +119,34 @@ public static SourceInterfaceTypeCollection CreateSourceInterfaceTypeCollection(
116119
CompositeSchemaBuilderContext context)
117120
{
118121
var types = TypeDirectiveParser.Parse(typeDef.Directives);
119-
var lookups = LookupDirectiveParser.Parse(typeDef.Directives);
122+
var lookupDirectives = LookupDirectiveParser.Parse(typeDef.Directives);
120123
var temp = new SourceInterfaceType[types.Length];
121124

122125
for (var i = 0; i < types.Length; i++)
123126
{
124127
var type = types[i];
128+
var lookups = GetLookupBySchema(lookupDirectives, type.SchemaName, typeDef.Name.Value);
129+
context.RegisterForCompletionRange(lookups);
130+
125131
temp[i] = new SourceInterfaceType(
126132
typeDef.Name.Value,
127133
type.SchemaName,
128-
GetLookupBySchema(lookups, type.SchemaName));
134+
lookups);
129135
}
130136

131137
return new SourceInterfaceTypeCollection(temp);
132138
}
133139

134140
private static ImmutableArray<Lookup> GetLookupBySchema(
135141
ImmutableArray<LookupDirective> allLookups,
136-
string schemaName)
142+
string schemaName,
143+
string declaringTypeName)
137144
{
138145
var lookups = ImmutableArray.CreateBuilder<Lookup>();
139146

140147
foreach (var lookup in allLookups)
141148
{
142-
if (lookup.SchemaName.Equals(schemaName, StringComparison.Ordinal))
149+
if (lookup.Schema.Equals(schemaName, StringComparison.Ordinal))
143150
{
144151
var arguments = ImmutableArray.CreateBuilder<LookupArgument>(lookup.Field.Arguments.Count);
145152

@@ -148,23 +155,23 @@ private static ImmutableArray<Lookup> GetLookupBySchema(
148155
arguments.Add(new LookupArgument(argument.Name.Value, argument.Type));
149156
}
150157

151-
var fieldsBuilder = ImmutableArray.CreateBuilder<FieldPath>();
158+
var fieldsBuilder = ImmutableArray.CreateBuilder<IValueSelectionNode>();
152159

153160
foreach (var field in lookup.Map)
154161
{
155-
fieldsBuilder.Add(FieldPath.Parse(field));
162+
var parser = new FieldSelectionMapParser(field);
163+
fieldsBuilder.Add(parser.Parse());
156164
}
157165

158166
var fields = fieldsBuilder.ToImmutable();
159-
var selectionSet = fields.ToSelectionSetNode();
160167

161168
lookups.Add(
162169
new Lookup(
163-
lookup.SchemaName,
170+
lookup.Schema,
171+
declaringTypeName,
164172
lookup.Field.Name.Value,
165173
arguments.ToImmutable(),
166-
fields,
167-
selectionSet));
174+
fields));
168175
}
169176
}
170177

src/HotChocolate/Fusion-vnext/src/Fusion.Execution.Types/Completion/CompositeSchemaBuilder.cs

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
using System.Collections.Immutable;
22
using HotChocolate.Features;
3+
using HotChocolate.Fusion.Language;
4+
using HotChocolate.Fusion.Rewriters;
35
using HotChocolate.Fusion.Types.Collections;
46
using HotChocolate.Fusion.Types.Directives;
5-
using HotChocolate.Fusion.Utilities;
67
using HotChocolate.Language;
78
using HotChocolate.Types;
89
using Microsoft.Extensions.DependencyInjection;
@@ -117,7 +118,7 @@ private static CompositeSchemaBuilderContext CreateTypes(
117118
}
118119
}
119120

120-
features ??= FeatureCollection.Empty;
121+
features ??= new FeatureCollection();
121122

122123
return new CompositeSchemaBuilderContext(
123124
name,
@@ -131,8 +132,8 @@ private static CompositeSchemaBuilderContext CreateTypes(
131132
typeDefinitions.ToImmutable(),
132133
directiveTypes.ToImmutable(),
133134
directiveDefinitions.ToImmutable(),
134-
features.ToReadOnly(),
135-
CreateTypeInterceptor(services));
135+
features,
136+
typeInterceptor);
136137
}
137138

138139
private static CompositeTypeInterceptor CreateTypeInterceptor(IServiceProvider services)
@@ -221,14 +222,14 @@ private static FusionOutputFieldDefinitionCollection CreateOutputFields(
221222
if (isQuery)
222223
{
223224
sourceFields[0] = new FusionOutputFieldDefinition(
224-
"__schema",
225+
IntrospectionFieldNames.Schema,
225226
null,
226227
isDeprecated: false,
227228
deprecationReason: null,
228229
arguments: FusionInputFieldDefinitionCollection.Empty);
229230

230231
sourceFields[1] = new FusionOutputFieldDefinition(
231-
"__type",
232+
IntrospectionFieldNames.Type,
232233
null,
233234
isDeprecated: false,
234235
deprecationReason: null,
@@ -239,11 +240,11 @@ private static FusionOutputFieldDefinitionCollection CreateOutputFields(
239240
null,
240241
null,
241242
isDeprecated: false,
242-
deprecationReason: null)
243+
deprecationReason: null)
243244
]));
244245

245246
sourceFields[2] = new FusionOutputFieldDefinition(
246-
"__typename",
247+
IntrospectionFieldNames.TypeName,
247248
null,
248249
isDeprecated: false,
249250
deprecationReason: null,
@@ -419,9 +420,10 @@ private static FusionSchemaDefinition CompleteTypes(CompositeSchemaBuilderContex
419420
var directives = CompletionTools.CreateDirectiveCollection(context.Directives, context);
420421
var features = context.Features;
421422

422-
context.Interceptor.OnCompleteSchema(context, ref features);
423+
context.Interceptor.OnBeforeCompleteSchema(context, ref features);
424+
features.Set<ValueSelectionToSelectionSetRewriter>(null);
423425

424-
return new FusionSchemaDefinition(
426+
var schema = new FusionSchemaDefinition(
425427
context.Name,
426428
context.Description,
427429
context.Services,
@@ -436,6 +438,9 @@ context.SubscriptionType is not null
436438
new FusionTypeDefinitionCollection(AsArray(context.TypeDefinitions)!),
437439
new FusionDirectiveDefinitionCollection(AsArray(context.DirectiveDefinitions)!),
438440
features.ToReadOnly());
441+
442+
context.Complete(schema);
443+
return schema;
439444
}
440445

441446
private static void CompleteObjectType(
@@ -460,21 +465,21 @@ private static void CompleteObjectType(
460465
CompleteOutputField(
461466
type,
462467
operationType,
463-
type.Fields["__schema"],
468+
type.Fields[IntrospectionFieldNames.Schema],
464469
Utf8GraphQLParser.Syntax.ParseFieldDefinition("__schema: __Schema!"),
465470
context);
466471

467472
CompleteOutputField(
468473
type,
469474
operationType,
470-
type.Fields["__type"],
475+
type.Fields[IntrospectionFieldNames.Type],
471476
Utf8GraphQLParser.Syntax.ParseFieldDefinition("__type(name: String!): __Type"),
472477
context);
473478

474479
CompleteOutputField(
475480
type,
476481
operationType,
477-
type.Fields["__typename"],
482+
type.Fields[IntrospectionFieldNames.TypeName],
478483
Utf8GraphQLParser.Syntax.ParseFieldDefinition("__typename: String!"),
479484
context);
480485
}
@@ -548,7 +553,7 @@ private static void CompleteOutputField(
548553

549554
var directives = CompletionTools.CreateDirectiveCollection(fieldDef.Directives, context);
550555
var type = context.GetType(fieldDef.Type).ExpectOutputType();
551-
var sources = BuildSourceObjectFieldCollection(fieldDefinition, fieldDef, context);
556+
var sources = BuildSourceObjectFieldCollection(declaringType.Name, fieldDefinition, fieldDef, context);
552557
var features = FeatureCollection.Empty;
553558

554559
context.Interceptor.OnCompleteOutputField(
@@ -568,6 +573,7 @@ private static void CompleteOutputField(
568573
}
569574

570575
private static SourceObjectFieldCollection BuildSourceObjectFieldCollection(
576+
string declaringTypeName,
571577
FusionOutputFieldDefinition fieldDefinition,
572578
FieldDefinitionNode fieldDef,
573579
CompositeSchemaBuilderContext context)
@@ -578,17 +584,25 @@ private static SourceObjectFieldCollection BuildSourceObjectFieldCollection(
578584

579585
foreach (var fieldDirective in fieldDirectives)
580586
{
587+
var requirements = ParseRequirements(declaringTypeName, requireDirectives, fieldDirective.SchemaName);
588+
589+
if (requirements is not null)
590+
{
591+
context.RegisterForCompletion(requirements);
592+
}
593+
581594
temp.Add(
582595
new SourceOutputField(
583596
fieldDirective.SourceName ?? fieldDefinition.Name,
584597
fieldDirective.SchemaName,
585-
ParseRequirements(requireDirectives, fieldDirective.SchemaName),
598+
requirements,
586599
CompleteType(fieldDef.Type, fieldDirective.SourceType, context)));
587600
}
588601

589602
return new SourceObjectFieldCollection(temp.ToImmutable());
590603

591604
static FieldRequirements? ParseRequirements(
605+
string declaringTypeName,
592606
ImmutableArray<RequireDirective> requireDirectives,
593607
string schemaName)
594608
{
@@ -603,18 +617,25 @@ private static SourceObjectFieldCollection BuildSourceObjectFieldCollection(
603617
argumentsBuilder.Add(new RequiredArgument(argument.Name.Value, argument.Type));
604618
}
605619

606-
var fieldsBuilder = ImmutableArray.CreateBuilder<FieldPath?>();
620+
var fieldsBuilder = ImmutableArray.CreateBuilder<IValueSelectionNode?>();
607621

608622
foreach (var field in requireDirective.Map)
609623
{
610-
fieldsBuilder.Add(field is not null ? FieldPath.Parse(field) : null);
624+
IValueSelectionNode? selection = null;
625+
626+
if (field is not null)
627+
{
628+
var parser = new FieldSelectionMapParser(field);
629+
selection = parser.Parse();
630+
}
631+
632+
fieldsBuilder.Add(selection);
611633
}
612634

613635
var arguments = argumentsBuilder.ToImmutable();
614636
var fields = fieldsBuilder.ToImmutable();
615-
var selectionSet = fields.ToSelectionSetNode();
616637

617-
return new FieldRequirements(schemaName, arguments, fields, selectionSet);
638+
return new FieldRequirements(schemaName, declaringTypeName, arguments, fields);
618639
}
619640

620641
return null;
@@ -768,11 +789,4 @@ private sealed class EmptyServiceProvider : IServiceProvider
768789

769790
public static EmptyServiceProvider Instance { get; } = new();
770791
}
771-
772-
private enum ComplexType
773-
{
774-
Query,
775-
Object,
776-
Interface
777-
}
778792
}

0 commit comments

Comments
 (0)