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,
))
}
}
}