fn get_js_field_args()

in compiler/crates/relay-transforms/src/match_/match_transform.rs [151:252]


    fn get_js_field_args(
        &self,
        fragment: &FragmentDefinition,
        spread: &FragmentSpread,
    ) -> Result<
        (
            FieldID,
            bool, /* has_js_field_id_arg */
            bool, /* has_js_branch_arg */
        ),
        Diagnostic,
    > {
        match fragment.type_condition {
            Type::Object(id) => {
                let object = self.program.schema.object(id);
                let js_field_id = object.fields.iter().find(|field_id| {
                    let field = self.program.schema.field(**field_id);
                    field.name.item == MATCH_CONSTANTS.js_field_name
                });
                if let Some(js_field_id) = js_field_id {
                    let js_field_id = *js_field_id;
                    let js_field = self.program.schema.field(js_field_id);

                    let js_field_module_arg = js_field
                        .arguments
                        .named(MATCH_CONSTANTS.js_field_module_arg);
                    let is_module_valid = {
                        if let Some(js_field_module_arg) = js_field_module_arg {
                            if let Some(non_list_type) = js_field_module_arg.type_.non_list_type() {
                                self.program.schema.is_string(non_list_type)
                            } else {
                                false
                            }
                        } else {
                            false
                        }
                    };

                    let js_field_id_arg = js_field.arguments.named(MATCH_CONSTANTS.js_field_id_arg);
                    let is_id_valid = {
                        if let Some(js_field_id_arg) = js_field_id_arg {
                            if let Some(id_non_list_type) = js_field_id_arg.type_.non_list_type() {
                                self.program.schema.is_string(id_non_list_type)
                            } else {
                                false
                            }
                        } else {
                            // `id` field is optional
                            true
                        }
                    };

                    let js_field_branch_arg = js_field
                        .arguments
                        .named(MATCH_CONSTANTS.js_field_branch_arg);
                    let is_branch_valid = {
                        if let Some(js_field_branch_arg) = js_field_branch_arg {
                            if let Some(branch_non_list_type) =
                                js_field_branch_arg.type_.non_list_type()
                            {
                                self.program.schema.is_string(branch_non_list_type)
                            } else {
                                false
                            }
                        } else {
                            // `id` field is optional
                            true
                        }
                    };

                    if is_module_valid && is_id_valid && is_branch_valid {
                        return Ok((
                            js_field_id,
                            js_field_id_arg.is_some(),
                            js_field_branch_arg.is_some(),
                        ));
                    }
                }
                Err(Diagnostic::error(
                    ValidationMessage::InvalidModuleInvalidSchemaArguments {
                        spread_name: spread.fragment.item,
                        type_string: self.program.schema.get_type_name(fragment.type_condition),
                        js_field_name: MATCH_CONSTANTS.js_field_name,
                        js_field_module_arg: MATCH_CONSTANTS.js_field_module_arg,
                        js_field_id_arg: MATCH_CONSTANTS.js_field_id_arg,
                        js_field_type: MATCH_CONSTANTS.js_field_type,
                    },
                    spread.fragment.location,
                )
                .annotate("related location", fragment.name.location))
            }
            // @module should only be used on `Object`
            _ => Err(Diagnostic::error(
                ValidationMessage::InvalidModuleNotOnObject {
                    spread_name: spread.fragment.item,
                    type_string: self.program.schema.get_type_name(fragment.type_condition),
                },
                spread.fragment.location,
            )
            .annotate("related location", fragment.name.location)),
        }
    }