Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement extern crate completion #15374

Merged
merged 1 commit into from Aug 21, 2023
Merged

Conversation

jmintb
Copy link
Contributor

@jmintb jmintb commented Aug 2, 2023

Hi, this is a draft PR for #13002.

I have basic completion working as well as a filter for existing extern crate imports in the same file. This is based on the tests, I have not actually tried this in an editor. Before going further I think this is a good point to stop and get feedback on the
structure and approach I have taken so far. Let me know what you think :)

I will make sure to add more tests, rebase commits and align with the code style guidelines before submitting a final version.

A few specific questions :

  1. Is there a better way to check for matching suggestions? right now I just test if an extern crate name starts with the current
    user input.
  2. Am I creating the CompletionItem correctly? I noticed that use_.rs invokes a builder where as I do not.
  3. When checking for existing extern crate imports the current implementation only looks at the current source file, is that sufficient?

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 2, 2023
@jmintb jmintb force-pushed the extern_crate branch 2 times, most recently from 38f2010 to b56c5a2 Compare August 2, 2023 07:16
Comment on lines 482 to 494
pub fn extern_crates_in_scope(&self) -> Vec<Name> {
self.module_scope.def_map.extern_prelude().map(|(name, _)| name.clone()).collect()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be no need to collect here and we are also interested in the module here

Suggested change
pub fn extern_crates_in_scope(&self) -> Vec<Name> {
self.module_scope.def_map.extern_prelude().map(|(name, _)| name.clone()).collect()
pub fn extern_crates_in_scope(&self) -> impl Iterator<Item = (Name, ModuleId)> {
self.module_scope.def_map.extern_prelude().map(|(name, mid)| (name.clone(), mid))


use crate::{context::CompletionContext, CompletionItem, CompletionItemKind};

use super::Completions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, we prefer not to use super imports, I assume this was copied from another file (we have a few rogue super imports lying around still)

Comment on lines 34 to 35
let current_txt =
name_ref.as_ref().map(|name_ref| name_ref.to_string()).unwrap_or(String::new());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to filter the names ourselves, that's something the clients (text editors) are doing for us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that makes a lot of sense.

Comment on lines 18 to 32
let imported_extern_crates: FxHashSet<String> = ctx
.token
.parent_ancestors()
.find_map(ast::SourceFile::cast)
.map(|src_file| {
src_file
.syntax()
.children()
.into_iter()
.filter_map(ast::ExternCrate::cast)
.filter_map(|node| node.name_ref())
.map(|name| name.to_string())
.collect()
})
.unwrap_or_default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going via syntax is pretty messy and error prone (given macros could create these as well), but we can't go the HIR route here right now as we don't record extern_crate decls in the HIR yet. Can you put a FIXME above this something like FIXME: Collect extern crate names via HIR when possible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually with #15377 we can make this work on the HIR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice it felt like a hack haha.

I made a quick implementation using the resolver to perform external crate decl queries here. Am I on the right track or should I be finding the information somewhere else? I suspect a bit of adjustment somewhere might remove the need for querying extern crate decl data 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, using the query is the correct approach

Comment on lines 1706 to 1728
pub fn extern_crates(&self) -> Vec<Name> {
self.resolver.extern_crates_in_scope()
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar stuff here, but map from ModuleId to Module

Suggested change
pub fn extern_crates(&self) -> Vec<Name> {
self.resolver.extern_crates_in_scope()
}
pub fn extern_crates(&self) -> impl Iterator<Item = (Name, Module)> {
self.resolver.extern_crates_in_scope().map(...)
}

Comment on lines 44 to 31
CompletionItem::new(
CompletionItemKind::SymbolKind(SymbolKind::Module),
ctx.source_range(),
name.to_smol_str(),
)
.add_to(acc, ctx.db);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the scope.extern_crates() changes above giving us the module as well we can add the module docs via .set_documentation(module.docs(db)

Comment on lines 53 to 71
#[cfg(test)]
mod test {
use crate::tests::completion_list_no_kw;

#[test]
fn can_complete_extern_crate() {
let case = r#"
//- /lib.rs crate:other_crate_a
// nothing here
//- /other_crate_b.rs crate:other_crate_b
pub mod good_mod{}
//- /lib.rs crate:crate_c
// nothing here
//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a,crate_c
extern crate crate_c;
extern crate oth$0
mod other_mod {}
"#;

let completion_list = completion_list_no_kw(case);

assert_eq!("md other_crate_a\n".to_string(), completion_list);
}

#[test]
fn will_not_complete_existing_import() {
let case = r#"
//- /lib.rs crate:other_crate_a
// nothing here
//- /lib.rs crate:crate_c
// nothing here
//- /lib.rs crate:other_crate_b
//
//- /lib.rs crate:lib deps:other_crate_a,other_crate_b,crate_c extern-prelude:other_crate_a,other_crate_b,crate_c
extern crate other_crate_b;
extern crate oth$0
mod other_mod {}
"#;

let completion_list = completion_list_no_kw(case);

assert_eq!("md other_crate_a\n".to_string(), completion_list);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create a new module in the ide-completion/src/tests folder instead, you can also check how a completion test is structured for this usually by taking a look at the use_tree module in there for example.

@jmintb jmintb force-pushed the extern_crate branch 2 times, most recently from e4ace6e to 4764447 Compare August 7, 2023 07:20
@Veykril
Copy link
Member

Veykril commented Aug 8, 2023

Thanks!
@bors r+

@bors
Copy link
Collaborator

bors commented Aug 8, 2023

📌 Commit 4764447 has been approved by Veykril

It is now in the queue for this repository.

@Veykril Veykril changed the title Draft: Implement extern crate completion feat: Implement extern crate completion Aug 8, 2023
@jmintb
Copy link
Contributor Author

jmintb commented Aug 8, 2023

Thanks! @bors r+

I wasn't quite finished but I guess it was good enough haha. Thanks for the insightful feedback!

@Veykril
Copy link
Member

Veykril commented Aug 8, 2023

Oh were you not? It looked fine to me 😅

@bors
Copy link
Collaborator

bors commented Aug 8, 2023

⌛ Testing commit 4764447 with merge b4759fd...

bors added a commit that referenced this pull request Aug 8, 2023
feat: Implement extern crate completion

Hi, this is a draft PR for #13002.

I have basic completion working as well as a filter for existing extern crate imports in the same file. This is based on the tests, I have not actually tried this in an editor. Before going further I think this is a good point to stop and get feedback on the
structure and approach I have taken so far. Let me know what you think :)

I will make sure to add more tests, rebase commits and align with the code style guidelines before submitting a final version.

A few specific questions :
1. Is there a better way to check for matching suggestions? right now I just test if an extern crate name starts with the current
user input.
2. Am I creating the `CompletionItem` correctly? I noticed that `use_.rs` invokes a builder where as I do not.
3. When checking for existing extern crate imports the current implementation only looks at the current source file, is that sufficient?
@jmintb
Copy link
Contributor Author

jmintb commented Aug 8, 2023

Oh were you not? It looked fine to me 😅

I had not addressed this:

Let's create a new module in the ide-completion/src/tests folder instead, you can also check how a completion test is structured for this usually by taking a look at the use_tree module in there for example.

But if you think it looks fine then that is good enough for me 👍

@bors
Copy link
Collaborator

bors commented Aug 8, 2023

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing b4759fd to master...

@bors
Copy link
Collaborator

bors commented Aug 8, 2023

👀 Test was successful, but fast-forwarding failed: 422 Update is not a fast forward

@jmintb
Copy link
Contributor Author

jmintb commented Aug 8, 2023

Should be fast forward-able now.

@Veykril
Copy link
Member

Veykril commented Aug 15, 2023

@bors r+

@bors
Copy link
Collaborator

bors commented Aug 15, 2023

📌 Commit d070aea has been approved by Veykril

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Aug 15, 2023

⌛ Testing commit d070aea with merge ebbcf58...

bors added a commit that referenced this pull request Aug 15, 2023
feat: Implement extern crate completion

Hi, this is a draft PR for #13002.

I have basic completion working as well as a filter for existing extern crate imports in the same file. This is based on the tests, I have not actually tried this in an editor. Before going further I think this is a good point to stop and get feedback on the
structure and approach I have taken so far. Let me know what you think :)

I will make sure to add more tests, rebase commits and align with the code style guidelines before submitting a final version.

A few specific questions :
1. Is there a better way to check for matching suggestions? right now I just test if an extern crate name starts with the current
user input.
2. Am I creating the `CompletionItem` correctly? I noticed that `use_.rs` invokes a builder where as I do not.
3. When checking for existing extern crate imports the current implementation only looks at the current source file, is that sufficient?
@bors
Copy link
Collaborator

bors commented Aug 15, 2023

💔 Test failed - checks-actions

@Veykril Veykril added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 15, 2023
@Veykril
Copy link
Member

Veykril commented Aug 15, 2023

Ah, there is a semantic conflict now when merging onto master. Could you rebase?

@bors delegate+

@bors
Copy link
Collaborator

bors commented Aug 15, 2023

✌️ @jmintb, you can now approve this pull request!

If @Veykril told you to "r=me" after making some further change, please make that change, then do @bors r=@Veykril

@jmintb
Copy link
Contributor Author

jmintb commented Aug 21, 2023

@bors r=Veykril

@bors
Copy link
Collaborator

bors commented Aug 21, 2023

📌 Commit 37e0e8a has been approved by Veykril

It is now in the queue for this repository.

@bors
Copy link
Collaborator

bors commented Aug 21, 2023

⌛ Testing commit 37e0e8a with merge a3892f0...

@bors
Copy link
Collaborator

bors commented Aug 21, 2023

☀️ Test successful - checks-actions
Approved by: Veykril
Pushing a3892f0 to master...

@bors bors merged commit a3892f0 into rust-lang:master Aug 21, 2023
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants