fn transform_fragment_spread()

in compiler/crates/relay-transforms/src/inline_data_fragment.rs [61:164]


    fn transform_fragment_spread(&mut self, spread: &FragmentSpread) -> Transformed<Selection> {
        let next_fragment_spread = self.default_transform_fragment_spread(spread);
        let fragment = self
            .program
            .fragment(spread.fragment.item)
            .unwrap_or_else(|| panic!("was expecting to find fragment `{}`", spread.fragment.item));

        if fragment.directives.named(*INLINE_DIRECTIVE_NAME).is_none() {
            next_fragment_spread
        } else {
            if !fragment.variable_definitions.is_empty()
                || !fragment.used_global_variables.is_empty()
            {
                let mut error = Diagnostic::error(
                    ValidationMessage::InlineDataFragmentArgumentsNotSupported,
                    fragment.name.location,
                );
                for var in fragment
                    .variable_definitions
                    .iter()
                    .chain(fragment.used_global_variables.iter())
                {
                    error = error.annotate("Variable used:", var.name.location);
                }
                self.errors.push(error);
            }
            match &next_fragment_spread {
                Transformed::Keep => {
                    if !spread.directives.is_empty() {
                        self.errors.push(Diagnostic::error(
                            ValidationMessage::InlineDataFragmentDirectivesNotSupported,
                            spread.fragment.location,
                        ));
                    }
                }
                Transformed::Replace(Selection::FragmentSpread(next_fragment_spread)) => {
                    if !next_fragment_spread.directives.is_empty() {
                        self.errors.push(Diagnostic::error(
                            ValidationMessage::InlineDataFragmentDirectivesNotSupported,
                            next_fragment_spread.fragment.location,
                        ));
                    }
                }
                _ => {
                    panic!(
                        "InlineDataFragmentsTransform: Unexpected deletion during fragment spread transformation."
                    );
                }
            };

            if self
                .parent_inline_fragments
                .iter()
                .any(|name| name.item == fragment.name.item)
            {
                let mut cyclic_fragments = self.parent_inline_fragments.iter();
                let first = cyclic_fragments.next().unwrap();
                let mut diagnostic = Diagnostic::error(
                    ValidationMessage::CircularFragmentReference {
                        fragment_name: first.item,
                    },
                    first.location,
                );
                for spread in cyclic_fragments {
                    diagnostic =
                        diagnostic.annotate(format!("spreading {}", spread.item), spread.location);
                }
                self.errors.push(diagnostic);
                return Transformed::Keep;
            }
            self.parent_inline_fragments.push(spread.fragment);
            let transformed_fragment = self.default_transform_fragment(fragment);
            self.parent_inline_fragments.pop();

            let (name, selections) = match transformed_fragment {
                Transformed::Keep => (fragment.name.item, fragment.selections.clone()),
                Transformed::Replace(next_fragment) => {
                    (next_fragment.name.item, next_fragment.selections)
                }
                Transformed::Delete => {
                    panic!(
                        "InlineDataFragmentsTransform: Unexpected deletion during fragment spread transformation."
                    );
                }
            };

            let inline_fragment = InlineFragment {
                type_condition: None,
                directives: vec![
                    InlineDirectiveMetadata {
                        fragment_name: name,
                    }
                    .into(),
                ],
                selections: vec![Selection::InlineFragment(Arc::new(InlineFragment {
                    type_condition: Some(fragment.type_condition),
                    directives: vec![],
                    selections,
                }))],
            };

            Transformed::Replace(Selection::InlineFragment(Arc::new(inline_fragment)))
        }
    }