in compiler/crates/relay-lsp/src/completion/mod.rs [790:881]
fn resolve_completion_items_from_fields<T: TypeWithFields + Named>(
type_: &T,
schema: &SDLSchema,
schema_documentation: impl SchemaDocumentation,
existing_linked_field: bool,
) -> Vec<CompletionItem> {
type_
.fields()
.iter()
.map(|field_id| {
let field = schema.field(*field_id);
let field_name = field.name.item.to_string();
let deprecated = field.deprecated();
let is_deprecated = deprecated.is_some();
let deprecated_reason = deprecated
.and_then(|deprecated| deprecated.reason)
.map(|reason| format!("Deprecated: {}", reason));
let args = create_arguments_snippets(field.arguments.iter(), schema);
let insert_text = match (
existing_linked_field
|| matches!(field.type_.inner(), Type::Scalar(_) | Type::Enum(_)), // don't insert { }
args.is_empty(), // don't insert arguments
) {
(true, true) => None,
(true, false) => Some(format!("{}({})", field_name, args.join(", "))),
(false, true) => Some(format!("{} {{\n\t$1\n}}", field_name)),
(false, false) => Some(format!(
"{}({}) {{\n\t${}\n}}",
field_name,
args.join(", "),
args.len() + 1
)),
};
let (insert_text_format, command) = if insert_text.is_some() {
(
Some(lsp_types::InsertTextFormat::Snippet),
Some(lsp_types::Command::new(
"Suggest".into(),
"editor.action.triggerSuggest".into(),
None,
)),
)
} else {
(None, None)
};
let type_description = schema_documentation
.get_type_description(schema.get_type_name(field.type_.inner()).lookup());
let field_description = schema_documentation
.get_field_description(type_.name().lookup(), field.name.item.lookup());
let type_name = schema.get_type_string(&field.type_);
let documentation = make_markdown_table_documentation(
field.name.item.lookup(),
&type_name,
field_description.unwrap_or(""),
type_description.unwrap_or(""),
);
let kind = match field.type_.inner() {
Type::Enum(_) => Some(CompletionItemKind::Enum),
Type::Interface(_) => Some(CompletionItemKind::Interface),
// There is no Kind for union, so we'll use interface
Type::Union(_) => Some(CompletionItemKind::Interface),
Type::Object(_) => Some(CompletionItemKind::Struct),
Type::InputObject(_) => Some(CompletionItemKind::Struct),
type_ if schema.is_string(type_) => Some(CompletionItemKind::Text),
_ => Some(CompletionItemKind::Value),
};
CompletionItem {
label: field_name,
kind,
detail: deprecated_reason.or(Some(type_name)),
documentation: Some(documentation),
deprecated: Some(is_deprecated),
preselect: None,
sort_text: None,
filter_text: None,
insert_text,
insert_text_format,
text_edit: None,
additional_text_edits: None,
command,
data: None,
tags: None,
..Default::default()
}
})
.collect()
}