Skip to content

Auto-import should respect std/extern/crate order #3301

New issue

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

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

Already on GitHub? # to your account

Closed
matklad opened this issue Feb 25, 2020 · 10 comments
Closed

Auto-import should respect std/extern/crate order #3301

matklad opened this issue Feb 25, 2020 · 10 comments
Labels

Comments

@matklad
Copy link
Member

matklad commented Feb 25, 2020

image

TraitId is misplaced, it should have been added to the second group. Before we fix import insertion infra to do this, it maybe make sense to move it to a separate module inside utils and in general to refactor code. I think it was introduced before we even had the modern make/edit APIs?

cc @SomeoneToIgnore

@matklad matklad added E-medium E-unknown It's unclear if the issue is E-hard or E-easy without digging in labels Feb 25, 2020
@SomeoneToIgnore
Copy link
Contributor

SomeoneToIgnore commented Feb 25, 2020

Does that get fixed by the cargo fmt?
I'm not entirely sure that we need to dive that deep into determining the specific place for an import if it's possible to reformat it after importing.

@matklad
Copy link
Member Author

matklad commented Feb 25, 2020

Does that get fixed by the cargo fmt?

I don't think so. And, anyway, we should eventually subsume rustfmt, so this functionality needs to be implemented anyway ^^

@flodiebold
Copy link
Member

cargo fmt just reorders imports within groups (i.e. where there's not a blank line in between), and only by ordering alphabetically, as far as I know.

@matklad
Copy link
Member Author

matklad commented Feb 29, 2020

I've moved code for inserting uses to the utils module. I haven't refactored it yet. But I've scetched an interface we want in the end:

pub fn insert_use(where_: SyntaxNode, path: ModPath) -> SyntaxNode {
    let use_item = make::use_item(path);

    let use_scope: UseScope = UseScope::cast(where_).unwrap();
    for existing_use in use_scope.imports() {
        if let Some(merged) = try_merge_two_imports(existing_use, &use_item) {
            return algo::replace_children(where_, existing_use, merged);
        }
    }

    let group: ImportGroup = ImportGroup::new(path);
    let insert_position: InsertPosition<SyntaxElement> = find_insert_position(&use_scope, group);

    algo::insert_children(&where_, insert_position, vec![use_item].into_iter())
}

enum UseScope {
    SourceFile(ast::SourceFile),
    ItemList(ast::ItemList),
}

impl UseScope {
    fn imports(&self) -> AstChildren<ast::UseItem> {
        todo!()
    }
}

fn try_merge_two_imports(lhs: &ast::UseItem, rhs: &ast::UseItem) -> Option<ast::UseItem> {
    todo!()
}

enum ImportGroup {
    Std,
    ExternCrate,
    ThisCrate,
    ThisModule,
    SuperModule,
}

fn find_insert_position(scope: &UseScope, group: ImportGroup) -> InsertPosition<SyntaxElement> {
    todo!()
}

try_merge_two_imports should also allow us to implement the eponymous assist.

@matklad
Copy link
Member Author

matklad commented Mar 5, 2020

in general to refactor code.

This is super hard actually!

@matklad matklad added E-hard and removed E-medium E-unknown It's unclear if the issue is E-hard or E-easy without digging in labels Mar 5, 2020
@SomeoneToIgnore
Copy link
Contributor

I suspected that :(

@matklad
Copy link
Member Author

matklad commented Mar 6, 2020

Some minimal groundwork in #3487

bors bot added a commit that referenced this issue Sep 4, 2020
5935: Rewrite import insertion r=matklad a=Veykril

This is my attempt at refactoring the import insertion #3947. I hope what I created here is somewhat in line with what was requested, it wouldn't surprise me .

`common_prefix` is a copy from `merge_imports.rs` so those should be unified somewhere, `try_merge_trees` is also copied from there but slighly modified to take the `MergeBehaviour` enum into account.
`MergeBehaviour` should in the end become a configuration option, and the order if `ImportGroup` probably as well?

I'm not too familiar with the assist stuff and the like which is why I dont know what i have to do with `insert_use_statement` and `find_insert_use_container` for now.

I will most likely add more test cases in the end as well as I currently only tried to hit every path in `find_insert_position`. 
Some of the merge tests also fail atm due to them not sorting what they insert. There is also this test case I'm not sure if we want to support it. I would assume we want to? https://github.com/rust-analyzer/rust-analyzer/pull/5935/files#diff-6923916dd8bdd2f1ab4b984adacd265fR540-R547

The entire module was rewritten so looking at the the file itself is probably better than looking at the diff.

Regarding the sub issues of #3947:
- #3301: This is fixed with the rewrite, what this implementation does is that it scans through the first occurence of groupings and picks the appropriate one out. This means the user can actually rearrange the groupings on a per file basis to their liking. If a group isnt being found it is inserted according to the `ImportGroup` variant order(Would be nice if this was configurable I imagine).
- #3831: This should be fixed with the introduced `MergeBehaviour` enum and it's `Last` variant.
- #3946: This should also be [fixed](https://github.com/rust-analyzer/rust-analyzer/pull/5935/files#diff-6923916dd8bdd2f1ab4b984adacd265fR87)
- #5795: This is fixed in the sense that the grouping search picks the first group that is of the same kind as the import that is being added. So if  there is a random import in the middle of the program it should only be considered if there is no group of the same kind in the file already present.
- the last point in the list I havent checked yet, tho I got the feeling that it's not gonna be too simple as that will require knowledge of whether in this example `ast` is a crate or the module that is already imported.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
@Veykril
Copy link
Member

Veykril commented Oct 7, 2020

I think this issue can be closed, this was fixed in #5935.

@lnicola lnicola closed this as completed Oct 7, 2020
@asv7c2
Copy link
Contributor

asv7c2 commented Mar 4, 2021

Is auto-import order configurable? Can ordering be disabled?

@Veykril
Copy link
Member

Veykril commented Mar 4, 2021

It is currently fixed and cannot be disabled no, though PRs to change this are welcome

lnicola pushed a commit to lnicola/rust-analyzer that referenced this issue Apr 7, 2024
RalfJung pushed a commit to RalfJung/rust-analyzer that referenced this issue Apr 27, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants