Skip to content

INSP: make items from std appear first when auto import #6501

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

Merged
merged 1 commit into from
Jan 18, 2021

Conversation

gfreezy
Copy link
Contributor

@gfreezy gfreezy commented Dec 11, 2020

changelog: make items from std appear first when auto import

when have async-std as dependency, auto import Arc should use std::sync::Arc instead of async_std::sync::Arc

@gfreezy gfreezy changed the title make items from std appear first when auto import INSP: make items from std appear first when auto import Dec 11, 2020
@Undin Undin self-assigned this Dec 11, 2020
@gfreezy
Copy link
Contributor Author

gfreezy commented Dec 14, 2020

@Undin i have no idea how to fix the regressions.

Copy link
Member

@Undin Undin left a comment

Choose a reason for hiding this comment

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

It would be great to provide tests.
See org.rust.ide.inspections.import.AutoImportFixTestBase as base class for all auto import tests. I suppose org.rust.ide.inspections.import.AutoImportFixTestBase#checkAutoImportFixByTextWithMultipleChoice is most suitable to check order (but it requires to change Set to List as type of expectedElements collection)

@@ -61,6 +61,14 @@ object ImportCandidatesCollector {
// check that result after import can be resolved and resolved element is suitable
// if no, don't add it in candidate list
.filter { canBeResolvedToSuitableItem(importingPathText, importContext, it.info) }
// make std appear first
.sortedBy {
if (it.qualifiedNamedItem.containingCrate?.origin == PackageOrigin.STDLIB) {
Copy link
Member

Choose a reason for hiding this comment

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

What's about code from your workspace?
If we want to make any sorting here, we want to put items from workspace first

Comment on lines 67 to 69
"0${it.qualifiedNamedItem}"
} else {
"1${it.qualifiedNamedItem}"
Copy link
Member

Choose a reason for hiding this comment

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

The current approach creates a new string object on each comparison. Let's try to avoid it.
You can create a composite comparator to compare origin first and only after that compare qualified paths.
compareBy and thenBy should help you to create the corresponding comparator and sortedWith method to use it.
Also, I'd recommend not to use it.qualifiedNamedItem.toString() to get qualified name (currently it's used implicitly to construct "1${it.qualifiedNamedItem}" string) and use ImportInfo.usePath for it

Copy link
Member

Choose a reason for hiding this comment

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

As an alternative, I can suggest implementing Comparable for ImportCandidate class

Comment on lines 141 to 147
.sortedBy {
if (it.qualifiedNamedItem.containingCrate?.origin == PackageOrigin.STDLIB) {
"0${it.qualifiedNamedItem}"
} else {
"1${it.qualifiedNamedItem}"
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Exactly the same code as above. Let's create single comparator for ImportCandidate or implement Comparable interface for ImportCandidate

@Undin Undin added the fix Pull requests that fix some bug(s) label Jan 11, 2021
}

fn foo(t: <error descr="Unresolved reference: `AtomicUsize`">AtomicUsize/*caret*/</error>) {}
""", listOf("crate::bar::AtomicUsize", "dep_lib_target::foo::AtomicUsize", "std::sync::atomic::AtomicUsize"),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ERROR: expected:<[crate::bar::AtomicUsize, dep_lib_target::foo::AtomicUsize, std::sync::atomic::AtomicUsize]> but was:<[crate::bar::AtomicUsize, dep_lib_target::foo::AtomicUsize]>

why std is not available?

Copy link
Member

@Undin Undin Jan 13, 2021

Choose a reason for hiding this comment

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

Because all Atomic* structs are generated by macros that are not expanded in these tests. To make it work, we use ExpandMacros annotation. But I suggest not to use here because macro expansion slows down test execution without actual necessity.
Let's just use another stdlib struct, for example, std::sync::Arc

Testmarks.autoInjectedStdCrate)

@MockEdition(CargoWorkspace.Edition.EDITION_2018)
fun `test import item from std over extern crate`() = checkAutoImportFixByFileTreeWithMultipleChoice("""
Copy link
Contributor Author

Choose a reason for hiding this comment

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

failed with the same problem.

Copy link
Member

@Undin Undin left a comment

Choose a reason for hiding this comment

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

@gfreezy Could you adjust failed tests, please?. As I can see, they fail because we started to check the order of suggested items and in these tests order is wrong

@gfreezy
Copy link
Contributor Author

gfreezy commented Jan 18, 2021

image

@Undin need help to fix the regression

Copy link
Member

@Undin Undin left a comment

Choose a reason for hiding this comment

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

@Undin need help to fix the regression

Unfortunately, regression-2 is broken currently for some reason. So, just ignore it.

Could you squash commits into a single one after all necessary fixes, please?

override fun compareTo(other: ImportCandidate): Int {
val origin = qualifiedNamedItem.containingCrate?.origin
val otherOrigin = other.qualifiedNamedItem.containingCrate?.origin
val userPath = info.usePath
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
val userPath = info.usePath
val usePath = info.usePath

val origin = qualifiedNamedItem.containingCrate?.origin
val otherOrigin = other.qualifiedNamedItem.containingCrate?.origin
val userPath = info.usePath
val otherUsePath = info.usePath
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
val otherUsePath = info.usePath
val otherUsePath = other.info.usePath

It's a reason of weird candidates order in tests

@gfreezy gfreezy force-pushed the auto-import-order branch 2 times, most recently from 36664bc to 84dba6a Compare January 18, 2021 15:22
@Undin Undin added this to the v140 milestone Jan 18, 2021
Copy link
Member

@Undin Undin left a comment

Choose a reason for hiding this comment

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

Thanks!
bors r+

@bors
Copy link
Contributor

bors bot commented Jan 18, 2021

Build succeeded:

@bors bors bot merged commit 9b7f095 into intellij-rust:master Jan 18, 2021
@gfreezy gfreezy deleted the auto-import-order branch January 19, 2021 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix Pull requests that fix some bug(s)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants