mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Split draft
This commit is contained in:
parent
bc71631e75
commit
d35b943520
3 changed files with 85 additions and 59 deletions
|
@ -32,6 +32,12 @@ use crate::{
|
|||
pub use crate::completion::completion_item::{
|
||||
CompletionItem, CompletionItemKind, InsertTextFormat,
|
||||
};
|
||||
use either::Either;
|
||||
use hir::{StructField, Type};
|
||||
use ra_syntax::{
|
||||
ast::{self, NameOwner},
|
||||
SmolStr,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CompletionConfig {
|
||||
|
@ -98,3 +104,57 @@ pub(crate) fn completions(
|
|||
|
||||
Some(acc)
|
||||
}
|
||||
|
||||
pub(crate) fn get_missing_fields(
|
||||
ctx: &CompletionContext,
|
||||
record: Either<&ast::RecordLit, &ast::RecordPat>,
|
||||
) -> Option<Vec<(StructField, Type)>> {
|
||||
let (ty, variant) = match record {
|
||||
Either::Left(record_lit) => (
|
||||
ctx.sema.type_of_expr(&record_lit.clone().into())?,
|
||||
ctx.sema.resolve_record_literal(record_lit)?,
|
||||
),
|
||||
Either::Right(record_pat) => (
|
||||
ctx.sema.type_of_pat(&record_pat.clone().into())?,
|
||||
ctx.sema.resolve_record_pattern(record_pat)?,
|
||||
),
|
||||
};
|
||||
|
||||
let already_present_names = get_already_present_names(record);
|
||||
Some(
|
||||
ty.variant_fields(ctx.db, variant)
|
||||
.into_iter()
|
||||
.filter(|(field, _)| {
|
||||
!already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string()))
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_already_present_names(record: Either<&ast::RecordLit, &ast::RecordPat>) -> Vec<SmolStr> {
|
||||
// TODO kb have a single match
|
||||
match record {
|
||||
Either::Left(record_lit) => record_lit
|
||||
.record_field_list()
|
||||
.map(|field_list| field_list.fields())
|
||||
.map(|fields| {
|
||||
fields
|
||||
.into_iter()
|
||||
.filter_map(|field| field.name_ref())
|
||||
.map(|name_ref| name_ref.text().clone())
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
Either::Right(record_pat) => record_pat
|
||||
.record_field_pat_list()
|
||||
.map(|pat_list| pat_list.bind_pats())
|
||||
.map(|bind_pats| {
|
||||
bind_pats
|
||||
.into_iter()
|
||||
.filter_map(|pat| pat.name())
|
||||
.map(|name| name.text().clone())
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,19 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use super::get_missing_fields;
|
||||
use crate::completion::{CompletionContext, Completions};
|
||||
use ra_syntax::SmolStr;
|
||||
use either::Either;
|
||||
|
||||
/// Complete fields in fields literals.
|
||||
pub(super) fn complete_record_literal(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (ty, variant) = match ctx.record_lit_syntax.as_ref().and_then(|it| {
|
||||
Some((ctx.sema.type_of_expr(&it.clone().into())?, ctx.sema.resolve_record_literal(it)?))
|
||||
}) {
|
||||
Some(it) => it,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let already_present_names: Vec<SmolStr> = ctx
|
||||
.record_lit_syntax
|
||||
.as_ref()
|
||||
.and_then(|record_literal| record_literal.record_field_list())
|
||||
.map(|field_list| field_list.fields())
|
||||
.map(|fields| {
|
||||
fields
|
||||
.into_iter()
|
||||
.filter_map(|field| field.name_ref())
|
||||
.map(|name_ref| name_ref.text().clone())
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
|
||||
if !already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string())) {
|
||||
acc.add_field(ctx, field, &field_ty);
|
||||
}
|
||||
pub(super) fn complete_record_literal(
|
||||
acc: &mut Completions,
|
||||
ctx: &CompletionContext,
|
||||
) -> Option<()> {
|
||||
let record_lit = ctx.record_lit_syntax.as_ref()?;
|
||||
for (field, field_ty) in get_missing_fields(ctx, Either::Left(record_lit))? {
|
||||
acc.add_field(ctx, field, &field_ty);
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,35 +1,18 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use super::get_missing_fields;
|
||||
use crate::completion::{CompletionContext, Completions};
|
||||
use ra_syntax::{ast::NameOwner, SmolStr};
|
||||
use either::Either;
|
||||
|
||||
pub(super) fn complete_record_pattern(acc: &mut Completions, ctx: &CompletionContext) {
|
||||
let (ty, variant) = match ctx.record_lit_pat.as_ref().and_then(|it| {
|
||||
Some((ctx.sema.type_of_pat(&it.clone().into())?, ctx.sema.resolve_record_pattern(it)?))
|
||||
}) {
|
||||
Some(it) => it,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let already_present_names: Vec<SmolStr> = ctx
|
||||
.record_lit_pat
|
||||
.as_ref()
|
||||
.and_then(|record_pat| record_pat.record_field_pat_list())
|
||||
.map(|pat_list| pat_list.bind_pats())
|
||||
.map(|bind_pats| {
|
||||
bind_pats
|
||||
.into_iter()
|
||||
.filter_map(|pat| pat.name())
|
||||
.map(|name| name.text().clone())
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
for (field, field_ty) in ty.variant_fields(ctx.db, variant) {
|
||||
if !already_present_names.contains(&SmolStr::from(field.name(ctx.db).to_string())) {
|
||||
acc.add_field(ctx, field, &field_ty);
|
||||
}
|
||||
pub(super) fn complete_record_pattern(
|
||||
acc: &mut Completions,
|
||||
ctx: &CompletionContext,
|
||||
) -> Option<()> {
|
||||
let record_pat = ctx.record_lit_pat.as_ref()?;
|
||||
for (field, field_ty) in get_missing_fields(ctx, Either::Right(record_pat))? {
|
||||
acc.add_field(ctx, field, &field_ty);
|
||||
}
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -151,7 +134,7 @@ mod tests {
|
|||
bar: 3,
|
||||
baz: 4,
|
||||
};
|
||||
if let S { foo1, foo2, <|> } = s {}
|
||||
if let S { foo1, foo2: a, <|> } = s {}
|
||||
}
|
||||
",
|
||||
);
|
||||
|
@ -159,16 +142,16 @@ mod tests {
|
|||
[
|
||||
CompletionItem {
|
||||
label: "bar",
|
||||
source_range: [369; 369),
|
||||
delete: [369; 369),
|
||||
source_range: [372; 372),
|
||||
delete: [372; 372),
|
||||
insert: "bar",
|
||||
kind: Field,
|
||||
detail: "u32",
|
||||
},
|
||||
CompletionItem {
|
||||
label: "baz",
|
||||
source_range: [369; 369),
|
||||
delete: [369; 369),
|
||||
source_range: [372; 372),
|
||||
delete: [372; 372),
|
||||
insert: "baz",
|
||||
kind: Field,
|
||||
detail: "u32",
|
||||
|
|
Loading…
Reference in a new issue