in compiler/crates/relay-transforms/src/generate_data_driven_dependency_metadata.rs [39:141]
fn generate_data_driven_dependency_for_selections(
&mut self,
type_: TypeReference,
selections: &[Selection],
) -> Option<Directive> {
let mut processing_queue: Vec<ProcessingItem<'_>> = vec![ProcessingItem {
plural: false,
parent_type: type_,
selections,
}];
let mut module_entries: ModuleEntries = Default::default();
while let Some(processing_item) = processing_queue.pop() {
for selection in processing_item.selections {
match selection {
Selection::ScalarField(_) | Selection::FragmentSpread(_) => {}
Selection::LinkedField(linked_filed) => {
let field_type = &self
.program
.schema
.field(linked_filed.definition.item)
.type_;
processing_queue.push(ProcessingItem {
plural: processing_item.plural || field_type.is_list(),
parent_type: field_type.clone(),
selections: &linked_filed.selections,
});
}
Selection::InlineFragment(inline_fragment) => {
let parent_type = match inline_fragment.type_condition {
Some(type_) => TypeReference::Named(type_),
None => processing_item.parent_type.clone(),
};
if let Some(module_metadata) =
ModuleMetadata::find(&inline_fragment.directives)
{
let id = module_metadata.module_id;
let component = module_metadata.module_name;
let fragment_spread = inline_fragment
.selections
.iter()
.find(|item| matches!(item, Selection::FragmentSpread(_)));
// This is expected to be a fragment spread
let fragment_name = match fragment_spread {
Some(Selection::FragmentSpread(spread)) => spread.fragment.item,
_ => panic!("Expected to have a fragment spread"),
};
let type_name = self
.program
.schema
.get_type_name(processing_item.parent_type.inner());
module_entries
.entry(id)
.and_modify(|module_entry| {
module_entry.branches.insert(
type_name,
Branch {
component,
fragment: get_fragment_filename(fragment_name),
},
);
})
.or_insert(ModuleEntry {
branches: {
let mut map = StringKeyMap::default();
map.insert(
type_name,
Branch {
component,
fragment: get_fragment_filename(fragment_name),
},
);
map
},
plural: processing_item.plural,
});
}
processing_queue.push(ProcessingItem {
plural: processing_item.plural,
parent_type,
selections: &inline_fragment.selections,
});
}
Selection::Condition(condition) => {
processing_queue.push(ProcessingItem {
plural: processing_item.plural,
parent_type: processing_item.parent_type.clone(),
selections: &condition.selections,
});
}
}
}
}
if !module_entries.is_empty() {
Some(create_metadata_directive(module_entries))
} else {
None
}
}