Skip to content

Commit 50eafd4

Browse files
Don't pass entire completer to completion
1 parent afc57b3 commit 50eafd4

File tree

1 file changed

+42
-37
lines changed

1 file changed

+42
-37
lines changed

compiler-core/src/language_server/completer.rs

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -128,31 +128,6 @@ impl<'a, IO> Completer<'a, IO> {
128128
}
129129
}
130130

131-
fn match_type(&self, type_: &Type) -> TypeMatch {
132-
if let Some(expected_type) = &self.expected_type {
133-
// If the type of the value we are completing is unbound, that
134-
// technically means that all types match, which doesn't give us
135-
// any useful information so we treat it as not knowing what the
136-
// type is, which generally is the case.
137-
if expected_type.is_unbound() {
138-
TypeMatch::Unknown
139-
}
140-
// We also want to prioritise functions which return the desired type,
141-
// as often the user's intention will be to write a function call.
142-
else if let Some((_, return_)) = type_.fn_types()
143-
&& expected_type.same_as(&return_)
144-
{
145-
TypeMatch::Matching
146-
} else if expected_type.same_as(type_) {
147-
TypeMatch::Matching
148-
} else {
149-
TypeMatch::Incompatible
150-
}
151-
} else {
152-
TypeMatch::Unknown
153-
}
154-
}
155-
156131
// Gets the current range around the cursor to place a completion
157132
// and the phrase surrounding the cursor to use for completion.
158133
// This method takes in a helper to determine what qualifies as
@@ -611,8 +586,13 @@ impl<'a, IO> Completer<'a, IO> {
611586
.peek()
612587
{
613588
completions.extend(
614-
LocalCompletion::new(mod_name, insert_range, cursor, self)
615-
.fn_completions(function),
589+
LocalCompletion::new(
590+
mod_name,
591+
insert_range,
592+
cursor,
593+
self.expected_type.clone(),
594+
)
595+
.fn_completions(function),
616596
);
617597
}
618598

@@ -635,7 +615,7 @@ impl<'a, IO> Completer<'a, IO> {
635615
let sort_text = Some(sort_text(
636616
CompletionKind::Prelude,
637617
&label,
638-
self.match_type(&type_),
618+
match_type(&self.expected_type, &type_),
639619
));
640620
completions.push(CompletionItem {
641621
label,
@@ -923,7 +903,7 @@ impl<'a, IO> Completer<'a, IO> {
923903
insert_range: Range,
924904
priority: CompletionKind,
925905
) -> CompletionItem {
926-
let type_match = self.match_type(&value.type_);
906+
let type_match = match_type(&self.expected_type, &value.type_);
927907
let label = match module_qualifier {
928908
Some(module) => format!("{module}.{name}"),
929909
None => name.to_string(),
@@ -966,7 +946,7 @@ impl<'a, IO> Completer<'a, IO> {
966946
}
967947

968948
fn field_completion(&self, label: &str, type_: Arc<Type>) -> CompletionItem {
969-
let type_match = self.match_type(&type_);
949+
let type_match = match_type(&self.expected_type, &type_);
970950
let type_ = Printer::new().pretty_print(&type_, 0);
971951

972952
CompletionItem {
@@ -1028,27 +1008,52 @@ fn type_completion(
10281008
}
10291009
}
10301010

1031-
pub struct LocalCompletion<'a, IO> {
1011+
fn match_type(expected_type: &Option<Arc<Type>>, type_: &Type) -> TypeMatch {
1012+
if let Some(expected_type) = expected_type {
1013+
// If the type of the value we are completing is unbound, that
1014+
// technically means that all types match, which doesn't give us
1015+
// any useful information so we treat it as not knowing what the
1016+
// type is, which generally is the case.
1017+
if expected_type.is_unbound() {
1018+
TypeMatch::Unknown
1019+
}
1020+
// We also want to prioritise functions which return the desired type,
1021+
// as often the user's intention will be to write a function call.
1022+
else if let Some((_, return_)) = type_.fn_types()
1023+
&& expected_type.same_as(&return_)
1024+
{
1025+
TypeMatch::Matching
1026+
} else if expected_type.same_as(type_) {
1027+
TypeMatch::Matching
1028+
} else {
1029+
TypeMatch::Incompatible
1030+
}
1031+
} else {
1032+
TypeMatch::Unknown
1033+
}
1034+
}
1035+
1036+
pub struct LocalCompletion<'a> {
10321037
mod_name: &'a str,
10331038
insert_range: Range,
10341039
cursor: u32,
10351040
completions: HashMap<EcoString, CompletionItem>,
1036-
completer: &'a Completer<'a, IO>,
1041+
expected_type: Option<Arc<Type>>,
10371042
}
10381043

1039-
impl<'a, IO> LocalCompletion<'a, IO> {
1044+
impl<'a> LocalCompletion<'a> {
10401045
pub fn new(
10411046
mod_name: &'a str,
10421047
insert_range: Range,
10431048
cursor: u32,
1044-
completer: &'a Completer<'a, IO>,
1049+
expected_type: Option<Arc<Type>>,
10451050
) -> Self {
10461051
Self {
10471052
mod_name,
10481053
insert_range,
10491054
cursor,
10501055
completions: HashMap::new(),
1051-
completer,
1056+
expected_type,
10521057
}
10531058
}
10541059

@@ -1096,7 +1101,7 @@ impl<'a, IO> LocalCompletion<'a, IO> {
10961101
type_: Arc<Type>,
10971102
insert_range: Range,
10981103
) -> CompletionItem {
1099-
let type_match = self.completer.match_type(&type_);
1104+
let type_match = match_type(&self.expected_type, &type_);
11001105

11011106
let label = name.to_string();
11021107
let type_ = Printer::new().pretty_print(&type_, 0);
@@ -1129,7 +1134,7 @@ impl<'a, IO> LocalCompletion<'a, IO> {
11291134
}
11301135
}
11311136

1132-
impl<'ast, IO> Visit<'ast> for LocalCompletion<'_, IO> {
1137+
impl<'ast> Visit<'ast> for LocalCompletion<'_> {
11331138
fn visit_typed_statement(&mut self, statement: &'ast ast::TypedStatement) {
11341139
// We only want to suggest local variables that are defined before
11351140
// the cursor

0 commit comments

Comments
 (0)