Merge #5753
5753: Remove Hygiene from completion
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
9930ef2536
@ -10,30 +10,21 @@
|
|||||||
pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
// complete keyword "crate" in use stmt
|
// complete keyword "crate" in use stmt
|
||||||
let source_range = ctx.source_range();
|
let source_range = ctx.source_range();
|
||||||
match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) {
|
|
||||||
(Some(_), None) => {
|
if ctx.use_item_syntax.is_some() {
|
||||||
|
if ctx.path_qual.is_none() {
|
||||||
CompletionItem::new(CompletionKind::Keyword, source_range, "crate::")
|
CompletionItem::new(CompletionKind::Keyword, source_range, "crate::")
|
||||||
.kind(CompletionItemKind::Keyword)
|
.kind(CompletionItemKind::Keyword)
|
||||||
.insert_text("crate::")
|
.insert_text("crate::")
|
||||||
.add_to(acc);
|
.add_to(acc);
|
||||||
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
|
|
||||||
.kind(CompletionItemKind::Keyword)
|
|
||||||
.add_to(acc);
|
|
||||||
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
|
|
||||||
.kind(CompletionItemKind::Keyword)
|
|
||||||
.insert_text("super::")
|
|
||||||
.add_to(acc);
|
|
||||||
}
|
}
|
||||||
(Some(_), Some(_)) => {
|
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
|
||||||
CompletionItem::new(CompletionKind::Keyword, source_range, "self")
|
.kind(CompletionItemKind::Keyword)
|
||||||
.kind(CompletionItemKind::Keyword)
|
.add_to(acc);
|
||||||
.add_to(acc);
|
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
|
||||||
CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
|
.kind(CompletionItemKind::Keyword)
|
||||||
.kind(CompletionItemKind::Keyword)
|
.insert_text("super::")
|
||||||
.insert_text("super::")
|
.add_to(acc);
|
||||||
.add_to(acc);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suggest .await syntax for types that implement Future trait
|
// Suggest .await syntax for types that implement Future trait
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
use crate::completion::{CompletionContext, Completions};
|
use crate::completion::{CompletionContext, Completions};
|
||||||
|
|
||||||
pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
let path = match &ctx.path_prefix {
|
let path = match &ctx.path_qual {
|
||||||
Some(path) => path.clone(),
|
Some(path) => path.clone(),
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -19,7 +19,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
|
|||||||
|
|
||||||
let context_module = ctx.scope.module();
|
let context_module = ctx.scope.module();
|
||||||
|
|
||||||
let resolution = match ctx.scope.resolve_hir_path_qualifier(&path) {
|
let resolution = match ctx.sema.resolve_path(&path) {
|
||||||
Some(res) => res,
|
Some(res) => res,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
@ -56,7 +56,7 @@ pub(crate) struct CompletionContext<'a> {
|
|||||||
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
|
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
|
||||||
pub(super) is_trivial_path: bool,
|
pub(super) is_trivial_path: bool,
|
||||||
/// If not a trivial path, the prefix (qualifier).
|
/// If not a trivial path, the prefix (qualifier).
|
||||||
pub(super) path_prefix: Option<hir::Path>,
|
pub(super) path_qual: Option<ast::Path>,
|
||||||
pub(super) after_if: bool,
|
pub(super) after_if: bool,
|
||||||
/// `true` if we are a statement or a last expr in the block.
|
/// `true` if we are a statement or a last expr in the block.
|
||||||
pub(super) can_be_stmt: bool,
|
pub(super) can_be_stmt: bool,
|
||||||
@ -137,7 +137,7 @@ pub(super) fn new(
|
|||||||
is_param: false,
|
is_param: false,
|
||||||
is_pat_binding_or_const: false,
|
is_pat_binding_or_const: false,
|
||||||
is_trivial_path: false,
|
is_trivial_path: false,
|
||||||
path_prefix: None,
|
path_qual: None,
|
||||||
after_if: false,
|
after_if: false,
|
||||||
can_be_stmt: false,
|
can_be_stmt: false,
|
||||||
is_expr: false,
|
is_expr: false,
|
||||||
@ -385,48 +385,54 @@ fn classify_name_ref(
|
|||||||
self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
|
self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
|
||||||
self.has_type_args = segment.generic_arg_list().is_some();
|
self.has_type_args = segment.generic_arg_list().is_some();
|
||||||
|
|
||||||
let hygiene = hir::Hygiene::new(self.db, self.position.file_id.into());
|
if let Some(path) = path_or_use_tree_qualifier(&path) {
|
||||||
if let Some(path) = hir::Path::from_src(path.clone(), &hygiene) {
|
self.path_qual = path
|
||||||
if let Some(path_prefix) = path.qualifier() {
|
.segment()
|
||||||
self.path_prefix = Some(path_prefix);
|
.and_then(|it| {
|
||||||
|
find_node_with_range::<ast::PathSegment>(
|
||||||
|
original_file,
|
||||||
|
it.syntax().text_range(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(|it| it.parent_path());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(segment) = path.segment() {
|
||||||
|
if segment.coloncolon_token().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if path.qualifier().is_none() {
|
self.is_trivial_path = true;
|
||||||
self.is_trivial_path = true;
|
|
||||||
|
|
||||||
// Find either enclosing expr statement (thing with `;`) or a
|
// Find either enclosing expr statement (thing with `;`) or a
|
||||||
// block. If block, check that we are the last expr.
|
// block. If block, check that we are the last expr.
|
||||||
self.can_be_stmt = name_ref
|
self.can_be_stmt = name_ref
|
||||||
.syntax()
|
.syntax()
|
||||||
.ancestors()
|
.ancestors()
|
||||||
.find_map(|node| {
|
.find_map(|node| {
|
||||||
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
|
if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
|
||||||
return Some(
|
return Some(stmt.syntax().text_range() == name_ref.syntax().text_range());
|
||||||
stmt.syntax().text_range() == name_ref.syntax().text_range(),
|
}
|
||||||
);
|
if let Some(block) = ast::BlockExpr::cast(node) {
|
||||||
}
|
return Some(
|
||||||
if let Some(block) = ast::BlockExpr::cast(node) {
|
block.expr().map(|e| e.syntax().text_range())
|
||||||
return Some(
|
== Some(name_ref.syntax().text_range()),
|
||||||
block.expr().map(|e| e.syntax().text_range())
|
);
|
||||||
== Some(name_ref.syntax().text_range()),
|
}
|
||||||
);
|
None
|
||||||
}
|
})
|
||||||
None
|
.unwrap_or(false);
|
||||||
})
|
self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
|
||||||
.unwrap_or(false);
|
|
||||||
self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
|
|
||||||
|
|
||||||
if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
|
if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
|
||||||
if let Some(if_expr) =
|
if let Some(if_expr) =
|
||||||
self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
|
self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
|
||||||
|
{
|
||||||
|
if if_expr.syntax().text_range().end() < name_ref.syntax().text_range().start()
|
||||||
{
|
{
|
||||||
if if_expr.syntax().text_range().end()
|
self.after_if = true;
|
||||||
< name_ref.syntax().text_range().start()
|
|
||||||
{
|
|
||||||
self.after_if = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -469,3 +475,12 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
|
|||||||
Some(n) => n.syntax().text_range() == node.text_range(),
|
Some(n) => n.syntax().text_range() == node.text_range(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<ast::Path> {
|
||||||
|
if let Some(qual) = path.qualifier() {
|
||||||
|
return Some(qual);
|
||||||
|
}
|
||||||
|
let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
|
||||||
|
let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
|
||||||
|
use_tree.path()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user