in compiler/crates/relay-transforms/src/generate_id_field.rs [181:245]
fn get_selections_with_inline_id_fragments(
&mut self,
field: &LinkedField,
selections: TransformedValue<Vec<Selection>>,
concrete_ids: &[ObjectID],
) -> TransformedValue<Vec<Selection>> {
let mut next_selections = vec![];
let mut should_generate_node = false;
let mut concrete_types_with_id = Vec::new();
for object_id in concrete_ids {
let object = self.program.schema.object(*object_id);
let implements_node = if let Some(ref node_interface) = self.node_interface {
object
.interfaces
.iter()
.any(|&interface_id| interface_id == node_interface.id)
} else {
false
};
if implements_node {
should_generate_node = true;
} else if let Some(id_field_id) =
self.get_id_field_id(Type::Object(*object_id), &object.fields)
{
concrete_types_with_id.push((*object_id, id_field_id))
}
}
if concrete_types_with_id.len() > 1 {
concrete_types_with_id.sort_unstable_by_key(|(concrete_type, _)| {
self.program.schema.object(*concrete_type).name
})
}
for (object_id, id_field_id) in concrete_types_with_id {
next_selections.push(Selection::InlineFragment(self.create_inline_id_fragment(
field.definition.location,
Type::Object(object_id),
id_field_id,
)));
}
if next_selections.is_empty() && !should_generate_node {
return selections;
}
let mut result = if let TransformedValue::Replace(selections) = selections {
selections
} else {
field.selections.clone()
};
if should_generate_node {
// This should not happen because we can only set
// `should_generate_node` to true, if this is Some.
let node_interface = self.node_interface.as_ref().unwrap();
result.push(Selection::InlineFragment(self.create_inline_id_fragment(
field.definition.location,
Type::Interface(node_interface.id),
node_interface.id_field,
)));
}
result.extend(next_selections.into_iter());
TransformedValue::Replace(result)
}