in compiler/crates/relay-transforms/src/validations/validate_selection_conflict.rs [136:278]
fn validate_and_insert_field_selection(
&self,
fields: &mut Fields<'s>,
field: Field<'s>,
parent_fields_mutually_exclusive: bool,
) -> DiagnosticsResult<()> {
let key = field.get_response_key(&self.program.schema);
let mut errors = vec![];
for existing_field in fields
.iter_mut()
.filter(|field| key == field.get_response_key(&self.program.schema))
{
if &field == existing_field {
return if errors.is_empty() {
Ok(())
} else {
Err(errors)
};
}
let l_definition = existing_field.get_field_definition(&self.program.schema);
let r_definition = field.get_field_definition(&self.program.schema);
let is_parent_fields_mutually_exclusive = || {
parent_fields_mutually_exclusive
|| l_definition.parent_type != r_definition.parent_type
&& matches!(
(l_definition.parent_type, r_definition.parent_type),
(Some(Type::Object(_)), Some(Type::Object(_)))
)
};
match (existing_field, &field) {
(Field::LinkedField(l), Field::LinkedField(r)) => {
let fields_mutually_exclusive = is_parent_fields_mutually_exclusive();
if !fields_mutually_exclusive {
if let Err(err) = self.validate_same_field(
key,
l_definition.name.item,
r_definition.name.item,
*l,
*r,
) {
errors.push(err)
};
}
if has_same_type_reference_wrapping(&l_definition.type_, &r_definition.type_) {
let mut l_fields = self.validate_linked_field_selections(l)?;
let r_fields = self.validate_linked_field_selections(r)?;
if let Err(errs) = self.validate_and_merge_fields(
Arc::make_mut(&mut l_fields),
r_fields.to_vec(),
fields_mutually_exclusive,
) {
errors.extend(errs);
}
} else {
errors.push(
Diagnostic::error(
ValidationMessage::AmbiguousFieldType {
response_key: key,
l_name: l_definition.name.item,
r_name: r_definition.name.item,
l_type_string: self
.program
.schema
.get_type_string(&l_definition.type_),
r_type_string: self
.program
.schema
.get_type_string(&r_definition.type_),
},
l.definition.location,
)
.annotate("the other field", r.definition.location),
);
}
}
(Field::ScalarFeild(l), Field::ScalarFeild(r)) => {
if !is_parent_fields_mutually_exclusive() {
if let Err(err) = self.validate_same_field(
key,
l_definition.name.item,
r_definition.name.item,
*l,
*r,
) {
errors.push(err)
};
} else if l_definition.type_ != r_definition.type_ {
errors.push(
Diagnostic::error(
ValidationMessage::AmbiguousFieldType {
response_key: key,
l_name: l_definition.name.item,
r_name: r_definition.name.item,
l_type_string: self
.program
.schema
.get_type_string(&l_definition.type_),
r_type_string: self
.program
.schema
.get_type_string(&r_definition.type_),
},
l.definition.location,
)
.annotate("the other field", r.definition.location),
);
}
}
(existing_field, _) => {
errors.push(
Diagnostic::error(
ValidationMessage::AmbiguousFieldType {
response_key: key,
l_name: l_definition.name.item,
r_name: r_definition.name.item,
l_type_string: self
.program
.schema
.get_type_string(&l_definition.type_),
r_type_string: self
.program
.schema
.get_type_string(&r_definition.type_),
},
existing_field.loc(),
)
.annotate("the other field", field.loc()),
);
}
}
}
if errors.is_empty() {
fields.push(field);
Ok(())
} else {
Err(errors)
}
}