fn flatten_selections()

in compiler/crates/relay-transforms/src/flatten.rs [279:393]


    fn flatten_selections(
        &self,
        flattened_selections: &mut Vec<Selection>,
        selections: &[Selection],
        parent_type: Type,
    ) -> bool {
        let mut has_changes = false;
        for selection in selections {
            if let Selection::InlineFragment(inline_fragment) = selection {
                if should_flatten_inline_fragment(inline_fragment, parent_type, self.is_for_codegen)
                {
                    has_changes = true;
                    self.flatten_selections(
                        flattened_selections,
                        &inline_fragment.selections,
                        parent_type,
                    );
                    continue;
                }
            }

            let flattened_selection = flattened_selections.iter_mut().find(|sel| {
                sel.ptr_eq(selection) || NodeIdentifier::are_equal(&self.schema, sel, selection)
            });

            match flattened_selection {
                None => {
                    flattened_selections.push(selection.clone());
                }
                Some(flattened_selection) => {
                    has_changes = true;
                    if flattened_selection.ptr_eq(selection) {
                        continue;
                    }
                    match flattened_selection {
                        Selection::InlineFragment(flattened_node) => {
                            let node = match selection {
                                Selection::InlineFragment(node) => node,
                                _ => unreachable!("FlattenTransform: Expected an InlineFragment."),
                            };

                            let type_condition =
                                flattened_node.type_condition.unwrap_or(parent_type);

                            let flattened_node_mut = Arc::make_mut(flattened_node);
                            self.flatten_selections(
                                &mut flattened_node_mut.selections,
                                &node.selections,
                                type_condition,
                            );
                        }
                        Selection::LinkedField(flattened_node) => {
                            let node = match selection {
                                Selection::LinkedField(node) => node,
                                _ => unreachable!("FlattenTransform: Expected a LinkedField."),
                            };
                            let type_ = self
                                .schema
                                .field(flattened_node.definition.item)
                                .type_
                                .inner();
                            let should_merge_handles = selection.directives().iter().any(|d| {
                                CustomMetadataDirectives::is_handle_field_directive(d.name.item)
                            });

                            let flattened_node_mut = Arc::make_mut(flattened_node);
                            if should_merge_handles {
                                flattened_node_mut.directives = merge_handle_directives(
                                    &flattened_node_mut.directives,
                                    selection.directives(),
                                )
                            };
                            self.flatten_selections(
                                &mut flattened_node_mut.selections,
                                &node.selections,
                                type_,
                            );
                        }
                        Selection::Condition(flattened_node) => {
                            let node = match selection {
                                Selection::Condition(node) => node,
                                _ => unreachable!("FlattenTransform: Expected a Condition."),
                            };

                            let flattened_node_mut = Arc::make_mut(flattened_node);
                            self.flatten_selections(
                                &mut flattened_node_mut.selections,
                                &node.selections,
                                parent_type,
                            );
                        }
                        Selection::ScalarField(flattened_node) => {
                            let node = match selection {
                                Selection::ScalarField(node) => node,
                                _ => unreachable!("FlattenTransform: Expected a ScalarField."),
                            };
                            let should_merge_handles = node.directives.iter().any(|d| {
                                CustomMetadataDirectives::is_handle_field_directive(d.name.item)
                            });
                            if should_merge_handles {
                                let flattened_node_mut = Arc::make_mut(flattened_node);
                                flattened_node_mut.directives = merge_handle_directives(
                                    &flattened_node_mut.directives,
                                    selection.directives(),
                                );
                            }
                        }
                        Selection::FragmentSpread(_) => {}
                    };
                }
            }
        }

        has_changes
    }