feat(organize_import): utilities for ordering import sources #4313
+693
−68
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implements #4239.
In the RFC (#3015), I proposed to parse import sources in order to compare them in a structural way.
At the time of writing the RFC it took a lot of time trying to decide which structure to parse.
I left the RFC a bit loose because I couldn't find a satisfactory structure.
I fell into the same problem again. I am not 100% happy with the result and I am open to suggestions.
However, the current implementation should be good enough, and we can improve it later.
The implementation is in
biome_js_analyze/src/assists/source/organize_imports/util.rs
andbiome_string_case/src/lib.rs
.In contrast to the spec, I decided to avoid a parsing phase (except for paths).
Instead, we just look at the first bytes of an import source to determine its kind.
An import source can be one of the following kind:
https://example.org
node:test
,npm:@scope/package
package
This corresponds to import sources that start with
@/
,#
,~
, or%
/// Import sources that start with
/
,./
, or../
/
,./
, or../
Import paths are first ordered according to their kind (order of kind is reflected by their position in the previous list).
Note that unrecognized import source kinds are placed first.
I am unsure if we should keep or remove
Unknown
and choose a kind instead (probably Alias).Two import sources with identical kind are then ordered by a custom order:
../../
<../
<./
)ImportSourceAsciiCollator
) tailored for paths and URIs.The collation is case-insensitive (
A
<a
<B
<b
), compares numbers in a human-friendly way (9
<10
).Special characters such as
/
and@
are carefully ordered to yield a more natural ordering for import sources.I added the base of the collation algorithm in
biome_string_case
because it is kind of related to character case.Another option is to create a dedicated crate
biome_string_collator
or a cratebiome_str_utils
.Note: This PR can be merged into
main
as the utilities introduced are not yet in use.Alternative design
Instead of creating a custom collation, we could use the conventional Unicode Collation reduced to the ASCII set (
biome_string_case::CldrAsciiCollator
) and to parse import sources in a more advanced structure. I started with this design in mind and find it a bit too complex. However, I am still open to revisiting it if you think it could be better.Test Plan
I added tests in the source code.