@@ -561,21 +561,51 @@ ExecuteField(objectType, objectValue, fieldType, fields, variableValues):
561561## Accounting For Client Controlled Nullability Designators
562562
563563A field can have its nullability status set either in its service's schema, or
564- it can be overriden by a designator (! or ?) for the duration of an execution.
564+ a nullability designator (! or ?) can override it for the duration of an execution.
565565In order to determine a field's true nullability, both are taken into account
566566and a final type is produced.
567567
568568ModifiedOutputType(outputType, requiredStatus):
569- * If {requiredStatus} is 'required' and {outputType} is not a Non-Nullable type:
570- * Return ` Non-Null ` with an inner type of {outputType}.
571- * Otherwise if {requiredStatus} is 'optional':
572- * If {outputType} is not a Non-Nullable type:
573- * Return {outputType}.
574- * Otherwise if {outputType} is a Non-Nullable type:
575- * Let {innerOutputType} be the inner type of {outputType}.
576- * Return {innerOutputType}.
577- * Otherwise:
578- * Return {outputType}.
569+ * Create a {stack} initially containing {type}.
570+ * As long as the top of {stack} is a list:
571+ * Let {currentType} be the top item of {stack}.
572+ * Push the {elementType} of {currentType} to the {stack}.
573+ * If {requiredStatus} exists:
574+ * Start visiting {node}s in {requiredStatus} and building up a {resultingType}:
575+ * For each {node} that is a RequiredDesignator:
576+ * If {resultingType} exists:
577+ * Let {nullableResult} be the nullable type of {resultingType}.
578+ * Set {resultingType} to the Non-Nullable type of {nullableResult}.
579+ * Continue onto the next node.
580+ * Pop the top of {stack} and let {nextType} be the result.
581+ * Let {nullableType} be the nullable type of {nextType}.
582+ * Set {resultingType} to the Non-Nullable type of {nullableType}.
583+ * Continue onto the next node.
584+ * For each {node} that is a OptionalDesignator:
585+ * If {resultingType} exists:
586+ * Set {resultingType} to the nullableType type of {resultingType}.
587+ * Continue onto the next node.
588+ * Pop the top of {stack} and let {nextType} be the result.
589+ * Set {resultingType} to the nullable type of {resultingType}
590+ * Continue onto the next node.
591+ * For each {node} that is a ListNullabilityDesignator:
592+ * Pop the top of {stack} and let {listType} be the result
593+ * If the nullable type of {listType} is not a list
594+ * Pop the top of {stack} and set {listType} to the result
595+ * If {listType} does not exist:
596+ * Throw an error because {requiredStatus} had more list dimensions than {outputType} and is invalid.
597+ * If {resultingType} exist:
598+ * If {listType} is Non-Nullable:
599+ * Set {resultingType} to a Non-Nullable list where the element is {resultingType}.
600+ * Otherwise:
601+ * Set {resultingType} to a list where the element is {resultingType}.
602+ * Continue onto the next node.
603+ * Set {resultingType} to {listType}
604+ * If {stack} is not empty:
605+ * Throw an error because {requiredStatus} had fewer list dimensions than {outputType} and is invalid.
606+ * Return {resultingType}.
607+ * Otherwise:
608+ * Return {outputType}.
579609
580610
581611### Coercing Field Arguments
0 commit comments