@@ -207,7 +207,7 @@ struct SelectionSetTemplate {
207207 \( $0)
208208
209209 """
210- } ,
210+ } ,
211211 else: " \( dataInitStatement) "
212212 ) }
213213 """
@@ -400,9 +400,17 @@ struct SelectionSetTemplate {
400400 }
401401
402402 private func FragmentSelectionTemplate( _ fragment: IR . NamedFragmentSpread ) -> TemplateString {
403- """
404- .fragment( \( fragment. definition. name. asFragmentName) .self)
405- """
403+ if let deferCondition = fragment. typeInfo. deferCondition {
404+ return DeferredNamedFragmentSelectionTemplate (
405+ deferCondition: deferCondition,
406+ fragment: fragment
407+ )
408+
409+ } else {
410+ return """
411+ .fragment( \( fragment. definition. name. asFragmentName) .self)
412+ """
413+ }
406414 }
407415
408416 private func DeferredInlineFragmentSelectionTemplate(
@@ -415,6 +423,17 @@ struct SelectionSetTemplate {
415423 """
416424 }
417425
426+ private func DeferredNamedFragmentSelectionTemplate(
427+ deferCondition: CompilationResult . DeferCondition ,
428+ fragment: IR . NamedFragmentSpread
429+ ) -> TemplateString {
430+ """
431+ .deferred( \
432+ \( ifLet: deferCondition. variable, { " if: \" \( $0) \" , " } ) \
433+ \( fragment. definition. name. asFragmentName) .self, label: " \( deferCondition. label) " )
434+ """
435+ }
436+
418437 // MARK: - Accessors
419438 private func FieldAccessorsTemplate(
420439 _ selectionSet: ComputedSelectionSet
@@ -481,8 +500,8 @@ struct SelectionSetTemplate {
481500 ) -> TemplateString {
482501 guard
483502 !( selectionSet. direct? . namedFragments. isEmpty ?? true )
484- || !selectionSet. merged. namedFragments. isEmpty
485- || ( selectionSet. direct? . inlineFragments. containsDeferredFragment ?? false )
503+ || !selectionSet. merged. namedFragments. isEmpty
504+ || ( selectionSet. direct? . inlineFragments. containsDeferredFragment ?? false )
486505 else {
487506 return " "
488507 }
@@ -500,26 +519,42 @@ struct SelectionSetTemplate {
500519 \( selectionSet. merged. namedFragments. values. map {
501520 NamedFragmentAccessorTemplate ( $0, in: scope)
502521 } , separator: " \n " )
503- \( forEachIn: selectionSet. direct? . inlineFragments. values. elements ?? [ ] , {
504- " \( ifLet: $0. typeInfo. deferCondition, DeferredFragmentAccessorTemplate) "
505- } )
522+ \(
523+ forEachIn: selectionSet. direct? . inlineFragments. values. elements ?? [ ] ,
524+ separator: " \n " , {
525+ """
526+ \( ifLet: $0. typeInfo. deferCondition, {
527+ DeferredFragmentAccessorTemplate ( propertyName: $0. label, typeName: $0. renderedTypeName)
528+ } )
529+ """
530+ }
531+ )
506532 }
507533 """
508534 }
509535
510536 private func FragmentInitializerTemplate(
511537 _ selectionSet: ComputedSelectionSet
512538 ) -> String {
513- if let inlineFragments = selectionSet. direct? . inlineFragments,
514- inlineFragments. containsDeferredFragment
539+ if let directSelections = selectionSet. direct,
540+ ( directSelections. inlineFragments. containsDeferredFragment
541+ || directSelections. namedFragments. containsDeferredFragment)
515542 {
516543 return DesignatedInitializerTemplate (
517544 """
518- \( forEachIn: inlineFragments. values, {
519- guard let deferCondition = $0. typeInfo. deferCondition else {
520- return nil
545+ \( forEachIn: directSelections . inlineFragments. values, separator : " \n " , {
546+ if let deferCondition = $0. typeInfo. deferCondition {
547+ return DeferredPropertyInitializationStatement ( deferCondition . label )
521548 }
522- return DeferredPropertyInitializationStatement ( deferCondition)
549+
550+ return " "
551+ } )
552+ \( forEachIn: directSelections. namedFragments. values, separator: " \n " , {
553+ if let _ = $0. typeInfo. deferCondition {
554+ return DeferredPropertyInitializationStatement ( $0. definition. name. firstLowercased)
555+ }
556+
557+ return " "
523558 } )
524559 """
525560 )
@@ -529,10 +564,8 @@ struct SelectionSetTemplate {
529564 }
530565 }
531566
532- private func DeferredPropertyInitializationStatement(
533- _ deferCondition: CompilationResult . DeferCondition
534- ) -> TemplateString {
535- " _ \( deferCondition. label) = Deferred(_dataDict: _dataDict) "
567+ private func DeferredPropertyInitializationStatement( _ propertyName: String ) -> TemplateString {
568+ " _ \( propertyName) = Deferred(_dataDict: _dataDict) "
536569 }
537570
538571 private func NamedFragmentAccessorTemplate(
@@ -545,13 +578,22 @@ struct SelectionSetTemplate {
545578 let isOptional =
546579 fragment. inclusionConditions != nil
547580 && !scope. matches ( fragment. inclusionConditions. unsafelyUnwrapped)
581+ let isDeferred = fragment. typeInfo. deferCondition != nil
548582
549583 return """
550- \( renderAccessControl ( ) ) var \( propertyName) : \( typeName) \
551- \( if: isOptional, " ? " ) { \
584+ \( if: isDeferred,
585+ DeferredFragmentAccessorTemplate (
586+ propertyName: fragment. definition. name. firstLowercased,
587+ typeName: fragment. definition. name. asFragmentName
588+ )
589+ , else:
590+ """
591+ \( renderAccessControl ( ) ) var \( propertyName) : \( typeName) \( if: isOptional, " ? " ) { \
592+ \( if: !isMutable && !isDeferred, " _toFragment() } " )
593+ """
594+ )
552595 \( if: isMutable,
553596 """
554-
555597 get { _toFragment() }
556598 _modify { var f = \( propertyName) ; yield &f; \(
557599 if: isOptional,
@@ -561,16 +603,15 @@ struct SelectionSetTemplate {
561603 @available(*, unavailable, message: " mutate properties of the fragment instead. " )
562604 set { preconditionFailure() }
563605 }
564- """ ,
565- else: " _toFragment() } "
566- )
606+ """ )
567607 """
568608 }
569609
570610 private func DeferredFragmentAccessorTemplate(
571- _ deferCondition: CompilationResult . DeferCondition
611+ propertyName: String ,
612+ typeName: String
572613 ) -> TemplateString {
573- " @Deferred public var \( deferCondition . label ) : \( deferCondition . renderedTypeName ) ? "
614+ " @Deferred public var \( propertyName ) : \( typeName ) ? "
574615 }
575616
576617 // MARK: - SelectionSet Initializer
@@ -1149,3 +1190,9 @@ extension OrderedDictionary<ScopeCondition, InlineFragmentSpread> {
11491190 keys. contains ( where: { $0. isDeferred } )
11501191 }
11511192}
1193+
1194+ extension OrderedDictionary < String , NamedFragmentSpread > {
1195+ fileprivate var containsDeferredFragment : Bool {
1196+ values. contains ( where: { $0. typeInfo. deferCondition != nil } )
1197+ }
1198+ }
0 commit comments