Skip to content

Commit 9930ef2

Browse files
bors[bot]matklad
andauthored
Merge #5753
5753: Remove Hygiene from completion r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents e5b17b6 + 86f89d9 commit 9930ef2

File tree

3 files changed

+65
-59
lines changed

3 files changed

+65
-59
lines changed

crates/ide/src/completion/complete_keyword.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,21 @@ use crate::completion::{
1010
pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
1111
// complete keyword "crate" in use stmt
1212
let source_range = ctx.source_range();
13-
match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) {
14-
(Some(_), None) => {
13+
14+
if ctx.use_item_syntax.is_some() {
15+
if ctx.path_qual.is_none() {
1516
CompletionItem::new(CompletionKind::Keyword, source_range, "crate::")
1617
.kind(CompletionItemKind::Keyword)
1718
.insert_text("crate::")
1819
.add_to(acc);
19-
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
20-
.kind(CompletionItemKind::Keyword)
21-
.add_to(acc);
22-
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
23-
.kind(CompletionItemKind::Keyword)
24-
.insert_text("super::")
25-
.add_to(acc);
26-
}
27-
(Some(_), Some(_)) => {
28-
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
29-
.kind(CompletionItemKind::Keyword)
30-
.add_to(acc);
31-
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
32-
.kind(CompletionItemKind::Keyword)
33-
.insert_text("super::")
34-
.add_to(acc);
3520
}
36-
_ => {}
21+
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
22+
.kind(CompletionItemKind::Keyword)
23+
.add_to(acc);
24+
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
25+
.kind(CompletionItemKind::Keyword)
26+
.insert_text("super::")
27+
.add_to(acc);
3728
}
3829

3930
// Suggest .await syntax for types that implement Future trait

crates/ide/src/completion/complete_qualified_path.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use test_utils::mark;
88
use crate::completion::{CompletionContext, Completions};
99

1010
pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
11-
let path = match &ctx.path_prefix {
11+
let path = match &ctx.path_qual {
1212
Some(path) => path.clone(),
1313
None => return,
1414
};
@@ -19,7 +19,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
1919

2020
let context_module = ctx.scope.module();
2121

22-
let resolution = match ctx.scope.resolve_hir_path_qualifier(&path) {
22+
let resolution = match ctx.sema.resolve_path(&path) {
2323
Some(res) => res,
2424
None => return,
2525
};

crates/ide/src/completion/completion_context.rs

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub(crate) struct CompletionContext<'a> {
5656
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
5757
pub(super) is_trivial_path: bool,
5858
/// If not a trivial path, the prefix (qualifier).
59-
pub(super) path_prefix: Option<hir::Path>,
59+
pub(super) path_qual: Option<ast::Path>,
6060
pub(super) after_if: bool,
6161
/// `true` if we are a statement or a last expr in the block.
6262
pub(super) can_be_stmt: bool,
@@ -137,7 +137,7 @@ impl<'a> CompletionContext<'a> {
137137
is_param: false,
138138
is_pat_binding_or_const: false,
139139
is_trivial_path: false,
140-
path_prefix: None,
140+
path_qual: None,
141141
after_if: false,
142142
can_be_stmt: false,
143143
is_expr: false,
@@ -385,48 +385,54 @@ impl<'a> CompletionContext<'a> {
385385
self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
386386
self.has_type_args = segment.generic_arg_list().is_some();
387387

388-
let hygiene = hir::Hygiene::new(self.db, self.position.file_id.into());
389-
if let Some(path) = hir::Path::from_src(path.clone(), &hygiene) {
390-
if let Some(path_prefix) = path.qualifier() {
391-
self.path_prefix = Some(path_prefix);
388+
if let Some(path) = path_or_use_tree_qualifier(&path) {
389+
self.path_qual = path
390+
.segment()
391+
.and_then(|it| {
392+
find_node_with_range::<ast::PathSegment>(
393+
original_file,
394+
it.syntax().text_range(),
395+
)
396+
})
397+
.map(|it| it.parent_path());
398+
return;
399+
}
400+
401+
if let Some(segment) = path.segment() {
402+
if segment.coloncolon_token().is_some() {
392403
return;
393404
}
394405
}
395406

396-
if path.qualifier().is_none() {
397-
self.is_trivial_path = true;
398-
399-
// Find either enclosing expr statement (thing with `;`) or a
400-
// block. If block, check that we are the last expr.
401-
self.can_be_stmt = name_ref
402-
.syntax()
403-
.ancestors()
404-
.find_map(|node| {
405-
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
406-
return Some(
407-
stmt.syntax().text_range() == name_ref.syntax().text_range(),
408-
);
409-
}
410-
if let Some(block) = ast::BlockExpr::cast(node) {
411-
return Some(
412-
block.expr().map(|e| e.syntax().text_range())
413-
== Some(name_ref.syntax().text_range()),
414-
);
415-
}
416-
None
417-
})
418-
.unwrap_or(false);
419-
self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
407+
self.is_trivial_path = true;
420408

421-
if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
422-
if let Some(if_expr) =
423-
self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
409+
// Find either enclosing expr statement (thing with `;`) or a
410+
// block. If block, check that we are the last expr.
411+
self.can_be_stmt = name_ref
412+
.syntax()
413+
.ancestors()
414+
.find_map(|node| {
415+
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
416+
return Some(stmt.syntax().text_range() == name_ref.syntax().text_range());
417+
}
418+
if let Some(block) = ast::BlockExpr::cast(node) {
419+
return Some(
420+
block.expr().map(|e| e.syntax().text_range())
421+
== Some(name_ref.syntax().text_range()),
422+
);
423+
}
424+
None
425+
})
426+
.unwrap_or(false);
427+
self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
428+
429+
if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
430+
if let Some(if_expr) =
431+
self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
432+
{
433+
if if_expr.syntax().text_range().end() < name_ref.syntax().text_range().start()
424434
{
425-
if if_expr.syntax().text_range().end()
426-
< name_ref.syntax().text_range().start()
427-
{
428-
self.after_if = true;
429-
}
435+
self.after_if = true;
430436
}
431437
}
432438
}
@@ -469,3 +475,12 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
469475
Some(n) => n.syntax().text_range() == node.text_range(),
470476
}
471477
}
478+
479+
fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<ast::Path> {
480+
if let Some(qual) = path.qualifier() {
481+
return Some(qual);
482+
}
483+
let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
484+
let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
485+
use_tree.path()
486+
}

0 commit comments

Comments
 (0)