@@ -86,10 +86,8 @@ CoerceVariableValues(schema, operation, variableValues):
8686- Let {coercedValues} be an empty unordered Map.
8787- Let {variablesDefinition} be the variables defined by {operation}.
8888- For each {variableDefinition} in {variablesDefinition}:
89- - Let {variableName} be the name of {variableDefinition}.
90- - Let {variableType} be the expected type of {variableDefinition}.
91- - Assert: {IsInputType(variableType)} must be {true}.
92- - Let {defaultValue} be the default value for {variableDefinition}.
89+ - Let {variableName}, {variableType}, and {defaultValue} be the result of
90+ {GetVariableSignature(variableDefinition)}.
9391 - Let {hasValue} be {true} if {variableValues} provides a value for the name
9492 {variableName}.
9593 - Let {value} be the value provided in {variableValues} for the name
@@ -114,6 +112,14 @@ CoerceVariableValues(schema, operation, variableValues):
114112
115113Note: This algorithm is very similar to {CoerceArgumentValues()}.
116114
115+ GetVariableSignature(variableDefinition):
116+
117+ - Let {variableName} be the name of {variableDefinition}.
118+ - Let {variableType} be the expected type of {variableDefinition}.
119+ - Assert: {IsInputType(variableType)} must be {true}.
120+ - Let {defaultValue} be the default value for {variableDefinition}.
121+ - Return {variableName}, {variableType}, and {defaultValue}.
122+
117123## Executing Operations
118124
119125The type system, as described in the "Type System" section of the spec, must
@@ -498,45 +504,54 @@ is maintained through execution, ensuring that fields appear in the executed
498504response in a stable and predictable order.
499505
500506CollectFields(objectType, selectionSet, variableValues, visitedFragments,
501- localVariableValues ):
507+ fragmentVariables ):
502508
503509- If {visitedFragments} is not provided, initialize it to the empty set.
504510- Initialize {groupedFields} to an empty ordered map of lists.
505511- For each {selection} in {selectionSet}:
506512 - If {selection} provides the directive ` @skip ` , let {skipDirective} be that
507513 directive.
508- - If {skipDirective}'s {if} argument is {true} or is a variable in
509- {localVariableValues} or {variableValues} with the value {true}, continue
510- with the next {selection} in {selectionSet}.
514+ - Let {directiveValues} be the result of {GetDirectiveValues(skipDirective,
515+ variableValues, fragmentVariables)}.
516+ - If the entry for the {if} argument within {directiveValues} is {true},
517+ continue with the next {selection} in {selectionSet}.
511518 - If {selection} provides the directive ` @include ` , let {includeDirective} be
512519 that directive.
513- - If {includeDirective}'s {if} argument is not {true} and is not a variable
514- in {localVariableValues} or { variableValues} with the value {true},
515- continue with the next {selection} in {selectionSet}.
520+ - Let {directiveValues} be the result of
521+ {GetDirectiveValues(includeDirective, variableValues, fragmentVariables)}.
522+ - If the entry for the {if} argument within {directiveValues} is not {true},
516523 - If {selection} is a {Field}:
517524 - Let {responseKey} be the response key of {selection} (the alias if
518525 defined, otherwise the field name).
519526 - Let {groupForResponseKey} be the list in {groupedFields} for
520527 {responseKey}; if no such list exists, create it as an empty list.
521- - Append {selection} and {localVariableValues} to the {groupForResponseKey}.
528+ - Let {fieldDetails} be a new unordered map containing {fragmentVariables}.
529+ - Set the entry for {field} on {fieldDetails} to {selection}.
530+ - Append {fieldDetails} to the {groupForResponseKey}.
522531 - If {selection} is a {FragmentSpread}:
523532 - Let {fragmentSpreadName} be the name of {selection}.
533+ - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
534+ {selection} in {selectionSet}.
535+ - Add {fragmentSpreadName} to {visitedFragments}.
524536 - Let {fragment} be the Fragment in the current Document whose name is
525537 {fragmentSpreadName}.
526538 - If no such {fragment} exists, continue with the next {selection} in
527539 {selectionSet}.
528- - If {fragmentSpreadName} is in {visitedFragments}, continue with the next
529- {selection} in {selectionSet}.
530- - Add {fragmentSpreadName} to {visitedFragments}.
531540 - Let {fragmentType} be the type condition on {fragment}.
532541 - If {DoesFragmentTypeApply(objectType, fragmentType)} is {false}, continue
533542 with the next {selection} in {selectionSet}.
534- - Let {localVariableValues} be the result of calling
535- {getArgumentValuesFromSpread(selection, fragmentDefinition,
536- variableValues, localVariableValues)}.
543+ - Let {variableDefinitions} be the variable definitions for {fragment}.
544+ - Initialize {signatures} to an empty list.
545+ - For each {variableDefinition} of {variableDefinitions}:
546+ - Append the result of {GetVariableSignature(variableDefinition)} to
547+ {signatures}.
548+ - Let {values} be the result of {CoerceArgumentValues(fragment,
549+ argumentDefinitions, variableValues, fragmentVariables)}.
550+ - Let {newFragmentVariables} be an unordered map containing {signatures} and
551+ {values}.
537552 - Let {fragmentGroupedFieldSet} be the result of calling
538553 {CollectFields(objectType, fragmentSelectionSet, variableValues,
539- visitedFragments)}.
554+ visitedFragments, newFragmentVariables )}.
540555 - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
541556 - Let {responseKey} be the response key shared by all fields in
542557 {fragmentGroup}.
@@ -551,7 +566,7 @@ localVariableValues):
551566 - Let {fragmentSelectionSet} be the top-level selection set of {selection}.
552567 - Let {fragmentGroupedFieldSet} be the result of calling
553568 {CollectFields(objectType, fragmentSelectionSet, variableValues,
554- visitedFragments)}.
569+ visitedFragments, fragmentVariables )}.
555570 - For each {fragmentGroup} in {fragmentGroupedFieldSet}:
556571 - Let {responseKey} be the response key shared by all fields in
557572 {fragmentGroup}.
@@ -572,32 +587,19 @@ DoesFragmentTypeApply(objectType, fragmentType):
572587 - If {objectType} is a possible type of {fragmentType}, return {true}
573588 otherwise return {false}.
574589
575- getArgumentValuesFromSpread(fragmentSpread, fragmentDefinition, variableValues,
576- fragmentArgumentValues):
577-
578- - Let {coercedValues} be an empty unordered Map.
579- - For each {variableDefinition} in {fragmentDefinition}:
580- - Let {variableName} be the name of {variableDefinition}.
581- - Let {variableType} be the type of {variableDefinition}.
582- - Let {defaultValue} be the default value for {variableDefinition}.
583- - Let {argumentNode} be the node provided in the fragment-spread for
584- {variableName}
585- - If {argumentNode} isn't present or is null
586- - If {defaultValue} exists
587- - Add an entry to {coercedValues} named {argumentName} with the value
588- {defaultValue}.
589- - If {variableType} is non-nullable raise a field-error
590- - Let {hasValue} be {true} if {fragmentArgumentValues} or {variableValues}
591- provides a value for the name {variableName}.
592- - If {variableType} is non-nullable and {hasValue} is {false} raise a
593- field-error
594- - Add an entry to {coercedValues} named {argumentName} with the value found in
595- {variableValues} or {fragmentArgumentValues}.
596- - Return {coercedValues}.
597-
598590Note: The steps in {CollectFields()} evaluating the ` @skip ` and ` @include `
599591directives may be applied in either order since they apply commutatively.
600592
593+ GetDirectiveValues(directive, variableValues, fragmentVariables):
594+
595+ - Let {directiveName} be the name of {directive}.
596+ - Let {directiveDefinition} be the definition for {directiveName} within the
597+ schema.
598+ - Assert {directiveDefinition} is defined.
599+ - Let {argumentDefinitions} be the arguments defined by {directiveDefinition}.
600+ - Return the result of {CoerceArgumentValues(directiveDefinition,
601+ argumentDefinitions, variableValues, fragmentVariables)}.
602+
601603## Executing Fields
602604
603605Each field requested in the grouped field set that is defined on the selected
@@ -606,6 +608,8 @@ coerces any provided argument values, then resolves a value for the field, and
606608finally completes that value either by recursively executing another selection
607609set or coercing a scalar value.
608610
611+ ### TODO: this needs updating
612+
609613ExecuteField(objectType, objectValue, fieldType, fields, variableValues,
610614fragmentVariableValues):
611615
@@ -618,11 +622,13 @@ fragmentVariableValues):
618622- Return the result of {CompleteValue(fieldType, fields, resolvedValue,
619623 variableValues)}.
620624
621- ### Coercing Field Arguments
625+ ### Coercing Arguments
622626
623- Fields may include arguments which are provided to the underlying runtime in
624- order to correctly produce a value. These arguments are defined by the field in
625- the type system to have a specific input type.
627+ Fields, directives, and fragment spreads may include arguments which are
628+ provided to the underlying runtime in order to correctly produce a value. For
629+ fields and directives, these arguments are defined by the field or directive in
630+ the type system to have a specific input type; for fragment spreads, the
631+ fragment definition within the document specifies the input type.
626632
627633At each argument position in an operation may be a literal {Value}, or a
628634{Variable} to be provided at runtime.
@@ -637,7 +643,7 @@ fragmentVariableValues):
637643- Return {CoerceArgumentValues(argumentDefinitions, argumentValues,
638644 variableValues, fragmentVariableValues)}
639645
640- CoerceArgumentValues(argumentDefinitions, argumentValues, variableValues,
646+ CoerceArgumentValues(node, argumentDefinitions, argumentValues, variableValues,
641647fragmentVariableValues):
642648
643649- For each {argumentDefinition} in {argumentDefinitions}:
@@ -650,12 +656,12 @@ fragmentVariableValues):
650656 {argumentName}.
651657 - If {argumentValue} is a {Variable}:
652658 - Let {variableName} be the name of {argumentValue}.
653- - Let {hasValue} be {true} if {fragmentVariableValues} provides a value for
659+ - Let {signatures} and {values} be the corresponding entries on
660+ {fragmentVariables}.
661+ - Let {scopedVariableValues} be {values} if an entry in {signatures} exists
662+ for {variableName}; otherwise, let it be {variableValues}.
663+ - Let {hasValue} be {true} if {scopedVariableValues} provides a value for
654664 the name {variableName}.
655- - Let {value} be the value provided in {fragmentVariableValues} for the name
656- {variableName}.
657- - Let {hasValue} be {true} if {variableValues} provides a value for the name
658- {variableName}.
659665 - Let {value} be the value provided in {variableValues} for the name
660666 {variableName}.
661667 - Otherwise, let {value} be {argumentValue}.
@@ -713,6 +719,8 @@ After resolving the value for a field, it is completed by ensuring it adheres to
713719the expected return type. If the return type is another Object type, then the
714720field execution process continues recursively.
715721
722+ ### TODO: needs updating with fieldDetails
723+
716724CompleteValue(fieldType, fields, result, variableValues):
717725
718726- If the {fieldType} is a Non-Null type:
0 commit comments