fn completion_items_for_request()

in compiler/crates/relay-lsp/src/completion/mod.rs [510:631]


fn completion_items_for_request(
    request: CompletionRequest,
    schema: &SDLSchema,
    schema_documentation: impl SchemaDocumentation,
    program: &Program,
) -> Option<Vec<CompletionItem>> {
    let kind = request.kind;
    debug!("completion_items_for_request: {:?}", kind);
    match kind {
        CompletionKind::FragmentSpread => {
            let leaf_type = request.type_path.resolve_leaf_type(schema)?;

            debug!("has source program");
            let items = resolve_completion_items_for_fragment_spread(leaf_type, program, schema);
            Some(items)
        }
        CompletionKind::FieldName {
            existing_linked_field,
        } => match request.type_path.resolve_leaf_type(schema)? {
            Type::Interface(interface_id) => {
                let interface = schema.interface(interface_id);
                let items = resolve_completion_items_from_fields(
                    interface,
                    schema,
                    schema_documentation,
                    existing_linked_field,
                );
                Some(items)
            }
            Type::Object(object_id) => {
                let object = schema.object(object_id);
                let items = resolve_completion_items_from_fields(
                    object,
                    schema,
                    schema_documentation,
                    existing_linked_field,
                );
                Some(items)
            }
            Type::Enum(_) | Type::InputObject(_) | Type::Scalar(_) | Type::Union(_) => None,
        },
        CompletionKind::DirectiveName { location } => {
            let directives = schema.directives_for_location(location);
            let items = directives
                .iter()
                .map(|directive| completion_item_from_directive(directive, schema))
                .collect();
            Some(items)
        }
        CompletionKind::ArgumentName {
            has_colon,
            existing_names,
            kind,
        } => match kind {
            ArgumentKind::Field => {
                let (_, field) = request.type_path.resolve_current_field(schema)?;
                Some(resolve_completion_items_for_argument_name(
                    field.arguments.iter(),
                    schema,
                    existing_names,
                    has_colon,
                ))
            }
            ArgumentKind::ArgumentsDirective(fragment_spread_name) => {
                let fragment = program.fragment(fragment_spread_name)?;
                Some(resolve_completion_items_for_argument_name(
                    fragment.variable_definitions.iter(),
                    schema,
                    existing_names,
                    has_colon,
                ))
            }
            ArgumentKind::Directive(directive_name) => {
                Some(resolve_completion_items_for_argument_name(
                    schema.get_directive(directive_name)?.arguments.iter(),
                    schema,
                    existing_names,
                    has_colon,
                ))
            }
        },
        CompletionKind::ArgumentValue {
            executable_name,
            argument_name,
            kind,
        } => {
            let argument_type = match kind {
                ArgumentKind::Field => {
                    let (_, field) = request.type_path.resolve_current_field(schema)?;
                    &field.arguments.named(argument_name)?.type_
                }
                ArgumentKind::ArgumentsDirective(fragment_spread_name) => {
                    let fragment = program.fragment(fragment_spread_name)?;
                    &fragment.variable_definitions.named(argument_name)?.type_
                }
                ArgumentKind::Directive(directive_name) => {
                    &schema
                        .get_directive(directive_name)?
                        .arguments
                        .named(argument_name)?
                        .type_
                }
            };
            Some(resolve_completion_items_for_argument_value(
                schema,
                argument_type,
                program,
                executable_name,
            ))
        }
        CompletionKind::InlineFragmentType {
            existing_inline_fragment,
        } => {
            let type_ = request.type_path.resolve_leaf_type(schema)?;
            Some(resolve_completion_items_for_inline_fragment_type(
                type_,
                schema,
                existing_inline_fragment,
            ))
        }
    }
}