Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/context/analysis.rs')
-rw-r--r--crates/ide-completion/src/context/analysis.rs95
1 files changed, 45 insertions, 50 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index 1f691f3baf..7e6c842b1e 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -11,23 +11,23 @@ use syntax::{
};
use crate::context::{
- AttrCtx, CompletionContext, DotAccess, DotAccessKind, ExprCtx, IdentContext, ItemListKind,
- LifetimeContext, LifetimeKind, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind,
- PathCompletionCtx, PathKind, PatternContext, PatternRefutability, Qualified, QualifierCtx,
- TypeAscriptionTarget, TypeLocation, COMPLETION_MARKER,
+ AttrCtx, CompletionAnalysis, CompletionContext, DotAccess, DotAccessKind, ExprCtx,
+ ItemListKind, LifetimeContext, LifetimeKind, NameContext, NameKind, NameRefContext,
+ NameRefKind, ParamKind, PathCompletionCtx, PathKind, PatternContext, PatternRefutability,
+ Qualified, QualifierCtx, TypeAscriptionTarget, TypeLocation, COMPLETION_MARKER,
};
impl<'a> CompletionContext<'a> {
/// Expand attributes and macro calls at the current cursor position for both the original file
/// and fake file repeatedly. As soon as one of the two expansions fail we stop so the original
/// and speculative states stay in sync.
- pub(super) fn expand_and_fill(
+ pub(super) fn expand_and_analyze(
&mut self,
mut original_file: SyntaxNode,
mut speculative_file: SyntaxNode,
mut offset: TextSize,
mut fake_ident_token: SyntaxToken,
- ) -> Option<()> {
+ ) -> Option<CompletionAnalysis> {
let _p = profile::span("CompletionContext::expand_and_fill");
let mut derive_ctx = None;
@@ -157,7 +157,7 @@ impl<'a> CompletionContext<'a> {
break 'expansion;
}
- self.fill(&original_file, speculative_file, offset, derive_ctx)
+ self.analyze(&original_file, speculative_file, offset, derive_ctx)
}
/// Calculate the expected type and name of the cursor position.
@@ -311,13 +311,13 @@ impl<'a> CompletionContext<'a> {
/// Fill the completion context, this is what does semantic reasoning about the surrounding context
/// of the completion location.
- fn fill(
+ fn analyze(
&mut self,
original_file: &SyntaxNode,
file_with_fake_ident: SyntaxNode,
offset: TextSize,
derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>,
- ) -> Option<()> {
+ ) -> Option<CompletionAnalysis> {
let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased()?;
let syntax_element = NodeOrToken::Token(fake_ident_token);
if is_in_token_of_for_loop(syntax_element.clone()) {
@@ -350,8 +350,7 @@ impl<'a> CompletionContext<'a> {
.collect(),
};
}
- self.ident_ctx = IdentContext::NameRef(nameref_ctx);
- return Some(());
+ return Some(CompletionAnalysis::NameRef(nameref_ctx));
}
return None;
}
@@ -359,58 +358,54 @@ impl<'a> CompletionContext<'a> {
let name_like = match find_node_at_offset(&file_with_fake_ident, offset) {
Some(it) => it,
None => {
- if let Some(original) = ast::String::cast(self.original_token.clone()) {
- self.ident_ctx = IdentContext::String {
- original,
- expanded: ast::String::cast(self.token.clone()),
- };
- } else {
- // Fix up trailing whitespace problem
- // #[attr(foo = $0
- let token =
- syntax::algo::skip_trivia_token(self.token.clone(), Direction::Prev)?;
- let p = token.parent()?;
- if p.kind() == SyntaxKind::TOKEN_TREE
- && p.ancestors().any(|it| it.kind() == SyntaxKind::META)
- {
- let colon_prefix = previous_non_trivia_token(self.token.clone())
- .map_or(false, |it| T![:] == it.kind());
- self.ident_ctx = IdentContext::UnexpandedAttrTT {
- fake_attribute_under_caret: syntax_element
- .ancestors()
- .find_map(ast::Attr::cast),
- colon_prefix,
- };
+ let analysis =
+ if let Some(original) = ast::String::cast(self.original_token.clone()) {
+ CompletionAnalysis::String {
+ original,
+ expanded: ast::String::cast(self.token.clone()),
+ }
} else {
- return None;
- }
- }
- return Some(());
+ // Fix up trailing whitespace problem
+ // #[attr(foo = $0
+ let token =
+ syntax::algo::skip_trivia_token(self.token.clone(), Direction::Prev)?;
+ let p = token.parent()?;
+ if p.kind() == SyntaxKind::TOKEN_TREE
+ && p.ancestors().any(|it| it.kind() == SyntaxKind::META)
+ {
+ let colon_prefix = previous_non_trivia_token(self.token.clone())
+ .map_or(false, |it| T![:] == it.kind());
+ CompletionAnalysis::UnexpandedAttrTT {
+ fake_attribute_under_caret: syntax_element
+ .ancestors()
+ .find_map(ast::Attr::cast),
+ colon_prefix,
+ }
+ } else {
+ return None;
+ }
+ };
+ return Some(analysis);
}
};
-
- match name_like {
- ast::NameLike::Lifetime(lifetime) => {
- self.ident_ctx = IdentContext::Lifetime(Self::classify_lifetime(
- &self.sema,
- original_file,
- lifetime,
- )?);
- }
+ let analysis = match name_like {
+ ast::NameLike::Lifetime(lifetime) => CompletionAnalysis::Lifetime(
+ Self::classify_lifetime(&self.sema, original_file, lifetime)?,
+ ),
ast::NameLike::NameRef(name_ref) => {
let parent = name_ref.syntax().parent()?;
let (nameref_ctx, qualifier_ctx) =
Self::classify_name_ref(&self.sema, &original_file, name_ref, parent.clone())?;
self.qualifier_ctx = qualifier_ctx;
- self.ident_ctx = IdentContext::NameRef(nameref_ctx);
+ CompletionAnalysis::NameRef(nameref_ctx)
}
ast::NameLike::Name(name) => {
let name_ctx = Self::classify_name(&self.sema, original_file, name)?;
- self.ident_ctx = IdentContext::Name(name_ctx);
+ CompletionAnalysis::Name(name_ctx)
}
- }
- Some(())
+ };
+ Some(analysis)
}
fn classify_lifetime(