Skip to content

Commit e118af9

Browse files
wip
1 parent dd5b95b commit e118af9

File tree

3 files changed

+93
-10
lines changed

3 files changed

+93
-10
lines changed

src/HotChocolate/Fusion-vnext/src/Fusion.Utilities/Rewriters/OperationRewriter.Collecting.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ private void CollectField(FieldNode fieldNode, BaseContext context)
4949

5050
var field = ((IComplexTypeDefinition)context.Type).Fields[fieldNode.Name.Value];
5151

52-
var fieldContext = context.AddField(fieldNode, field.Type.AsTypeDefinition());
52+
var fieldContext = context.GetOrCreateFieldContext(fieldNode, field.Type.AsTypeDefinition());
5353

5454
if (fieldContext is not null && fieldNode.SelectionSet is not null)
5555
{

src/HotChocolate/Fusion-vnext/src/Fusion.Utilities/Rewriters/OperationRewriter.Contexts.cs

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ private abstract class BaseContext(
2323
public FragmentDefinitionNode GetFragmentDefinition(string name)
2424
=> fragmentLookup[name];
2525

26-
public void AddSelection(ISelectionNode selection)
27-
{
28-
Selections ??= new HashSet<ISelectionNode>(SyntaxNodeComparer.Instance);
29-
Selections.Add(selection);
30-
}
31-
3226
public virtual BaseContext GetOrCreateFragmentContext(
3327
InlineFragmentNode inlineFragmentNode,
3428
ITypeDefinition typeCondition)
@@ -46,7 +40,7 @@ public virtual BaseContext GetOrCreateFragmentContext(
4640
return fragmentContext;
4741
}
4842

49-
public virtual BaseContext? AddField(FieldNode fieldNode, ITypeDefinition fieldType)
43+
public virtual BaseContext? GetOrCreateFieldContext(FieldNode fieldNode, ITypeDefinition fieldType)
5044
{
5145
if (fieldNode.SelectionSet is not null)
5246
{
@@ -89,13 +83,63 @@ public ConditionalContext GetOrCreateConditionalContext(Conditional conditional)
8983

9084
return conditionalContext;
9185
}
86+
87+
protected void AddSelection(ISelectionNode selection)
88+
{
89+
Selections ??= new HashSet<ISelectionNode>(SyntaxNodeComparer.Instance);
90+
Selections.Add(selection);
91+
}
92+
93+
protected internal void RemoveSelection(ISelectionNode selection)
94+
{
95+
Selections?.Remove(selection);
96+
97+
if (selection is FieldNode fieldNode)
98+
{
99+
FieldContexts?.Remove(fieldNode);
100+
}
101+
else if (selection is InlineFragmentNode inlineFragmentNode)
102+
{
103+
FragmentContexts?.Remove(inlineFragmentNode);
104+
}
105+
}
92106
}
93107

94108
private sealed class Context(
95109
ITypeDefinition type,
96110
Dictionary<string, FragmentDefinitionNode> fragmentLookup)
97111
: BaseContext(type, fragmentLookup)
98112
{
113+
public Dictionary<ISelectionNode, List<ConditionalContext>>? ConditionalParentContexts { get; set; }
114+
115+
public override BaseContext? GetOrCreateFieldContext(FieldNode fieldNode, ITypeDefinition fieldType)
116+
{
117+
var fieldContext = base.GetOrCreateFieldContext(fieldNode, fieldType);
118+
119+
if (ConditionalParentContexts is not null
120+
&& ConditionalParentContexts.TryGetValue(fieldNode, out var conditionalContexts))
121+
{
122+
foreach (var conditionalContext in conditionalContexts)
123+
{
124+
if (conditionalContext.FieldContexts is not null
125+
&& conditionalContext.FieldContexts.TryGetValue(fieldNode, out var conditionalFieldContext))
126+
{
127+
// TODO: This should actually recreate the entire conditional hierarchy up until the first non-conditional parent
128+
var conditionalContextBelowUnconditionalField =
129+
GetOrCreateConditionalContext(conditionalContext.Conditional);
130+
131+
// TODO: Merge conditionalFieldContext into conditionalContextBelowUnconditionalField
132+
}
133+
134+
conditionalContext.RemoveSelection(fieldNode);
135+
}
136+
137+
ConditionalParentContexts.Remove(fieldNode);
138+
}
139+
140+
return fieldContext;
141+
}
142+
99143
public override BaseContext GetOrCreateFragmentContext(
100144
InlineFragmentNode inlineFragmentNode,
101145
ITypeDefinition typeCondition)
@@ -115,6 +159,45 @@ private sealed class ConditionalContext(
115159
{
116160
public Context UnconditionalContext { get; } = unconditionalContext;
117161

162+
public Conditional Conditional { get; } = conditional;
163+
164+
public override BaseContext? GetOrCreateFieldContext(FieldNode fieldNode, ITypeDefinition fieldType)
165+
{
166+
if (UnconditionalContext.Selections?.Contains(fieldNode) == true)
167+
{
168+
if (fieldNode.SelectionSet is null)
169+
{
170+
return null;
171+
}
172+
173+
if (UnconditionalContext.FieldContexts!.TryGetValue(fieldNode, out var unconditionalFieldContext))
174+
{
175+
// TODO: This should actually recreate the entire conditional hierarchy up until the first non-conditional parent
176+
var conditionalContext = unconditionalFieldContext.GetOrCreateConditionalContext(Conditional);
177+
178+
return conditionalContext;
179+
}
180+
else
181+
{
182+
throw new InvalidOperationException(
183+
"Expected to be able to a find a field context, if the selection exists.");
184+
}
185+
}
186+
187+
UnconditionalContext.ConditionalParentContexts ??=
188+
new Dictionary<ISelectionNode, List<ConditionalContext>>(SyntaxNodeComparer.Instance);
189+
190+
if (!UnconditionalContext.ConditionalParentContexts.TryGetValue(fieldNode, out var conditionalContexts))
191+
{
192+
conditionalContexts = [];
193+
UnconditionalContext.ConditionalParentContexts[fieldNode] = conditionalContexts;
194+
}
195+
196+
conditionalContexts.Add(this);
197+
198+
return base.GetOrCreateFieldContext(fieldNode, fieldType);
199+
}
200+
118201
public override BaseContext GetOrCreateFragmentContext(
119202
InlineFragmentNode inlineFragmentNode,
120203
ITypeDefinition typeCondition)
@@ -123,7 +206,7 @@ public override BaseContext GetOrCreateFragmentContext(
123206
&& UnconditionalContext.FragmentContexts.TryGetValue(inlineFragmentNode, out var unconditionalFragmentContext))
124207
{
125208
// TODO: This should actually recreate the entire conditional hierarchy up until the first non-conditional parent
126-
var conditionalContext = unconditionalFragmentContext.GetOrCreateConditionalContext(conditional);
209+
var conditionalContext = unconditionalFragmentContext.GetOrCreateConditionalContext(Conditional);
127210

128211
return conditionalContext;
129212
}

src/HotChocolate/Fusion-vnext/test/Fusion.Utilities.Tests/Rewriters/OperationRewriterTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ type Product implements Votable {
11091109
... on Product @skip(if: $skip1) {
11101110
voteCount
11111111
}
1112-
... on Product @skip(if: $skip2) {
1112+
... on Product @skip(if: $skip2) {
11131113
voteCount
11141114
viewerCanVote
11151115
}

0 commit comments

Comments
 (0)