Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat(rome_js_analyze): implement the organizeImports code action #3818

Merged
merged 2 commits into from
Nov 25, 2022

Conversation

leops
Copy link
Contributor

@leops leops commented Nov 21, 2022

Summary

Fixes #3462

This is an initial implementation of import sorting, exposed through the source.organizeImports code action. For now, the grouping of individual imports is not configurable and the rule will only reorder imports within the same "group", blocks of adjacent import nodes separated by empty lines or non-import module items (export or statement nodes). The rule also makes no attempts at merging imports from the same source (these will be preserved as individual imports and retain their original order relative to each other).

Test Plan

I've added a few snapshot tests that should cover everything that's currently supported by this version of the rule

@netlify
Copy link

netlify bot commented Nov 21, 2022

Deploy Preview for docs-rometools ready!

Name Link
🔨 Latest commit c47907e
🔍 Latest deploy log https://app.netlify.com/sites/docs-rometools/deploys/637ce2ed3cdb210009f97425
😎 Deploy Preview https://deploy-preview-3818--docs-rometools.netlify.app/playground
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

/// ```
pub(crate) OrganizeImports {
version: "11.0.0",
name: "organizeImports",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should the name be useOrganizedImports?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ironically, we're not applying this pattern to assists, but I think we should too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently assist rules have a different naming convention from lint rules, since they're primarily about exposing an action they're using an imperative phrasing for the action they perform: "flip binary expression", "inline variable" or "organize imports"

Copy link
Contributor

@ematipico ematipico Nov 24, 2022

Choose a reason for hiding this comment

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

This is true, but this could confuse the users because they are not aware of this distinction (and we don't actually document assists yet, and I bet the majority of the users are not aware of them).

We could keep the current name, but we need to come up with:

  • a way to document assists on our website (not a big deal)
  • explain to the users why this feature is here and it's not a formatter feature
  • explain to the users and us how and when some assists can opt-in via CLI (at the moment assists are only available via LSP)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've started looking a bit into this, and I think that's probably better handled in separate PRs. Specifically:

  • An update to the documentation and website to better document the "editor actions" we currently support (I just made up that name, it includes the analyzer-based assist rules along with the unstable rename action)
  • Adding a way to generally configure import sorting in the rome.json file, and that would specifically include an option to either run the assist as part of rome check or rome format

let mut iter = (&mut items_iter).enumerate();

// Iterate other the nodes of the old list
while let Some((item_slot, item)) = iter.next() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: It could be useful to provide mutation methods on lists that replace an element by its index to avoid iterating over all elements (and having to allocate a new vec because of that)

}

#[derive(Debug)]
struct ImportKey(SyntaxTokenText);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a reason why SyntaxTokenText shouldn't implement Ord, PartialOrd. It may reduce some of the boilerplate that you had to write here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree it would make sense to have SyntaxTokenText implement Ord and PartialOrd, but I still think we could keep the ImportKey type in order to implement a specific ordering logic for imports (the many of the popular import sorting plugins for Prettier use a natural sorting algorithm instead of alphabetical)

Copy link
Contributor

Choose a reason for hiding this comment

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

Totally, I like the ImportKey, even just to have some place for documenting the ordering (and what the key is, SyntaxTokenText could be any token)

@@ -0,0 +1,331 @@
use std::{
Copy link
Contributor

@ematipico ematipico Nov 22, 2022

Choose a reason for hiding this comment

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

Even though it's not a rule but an assists, I think we should apply the same convention we do for rules. Start from the nursery group and then promote it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was actually considering a way to remove groups completely from the assists category, since they only do anything for lint rules

/// ```
pub(crate) OrganizeImports {
version: "11.0.0",
name: "organizeImports",
Copy link
Contributor

Choose a reason for hiding this comment

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

Ironically, we're not applying this pattern to assists, but I think we should too.

@leops
Copy link
Contributor Author

leops commented Nov 22, 2022

Update: I've improved the way the rule handles trivia to avoid having to create (or remove) newlines trivia pieces by recycling the trivia from existing tokens instead. I've also used this refactor to implement support for file-level comments by preserving the order of some trivia pieces that are separated from the rest of the group by an empty line, for instance:

// this comment will stay in place

// this comment will be moved with the import below
import b from 'b';
import a from 'a';

@leops leops merged commit 97af058 into main Nov 25, 2022
@leops leops deleted the feature/organize-imports branch November 25, 2022 14:54
@lcswillems lcswillems mentioned this pull request Nov 25, 2022
5 tasks
@toxeus
Copy link

toxeus commented Apr 21, 2023

@leops IIUC this patch doesn't enable users to apply sorting via CLI. Is there plans to extend the CLI to allow for that?

@Conaclos
Copy link
Contributor

@toxeus
Copy link

toxeus commented Apr 21, 2023

Thanks @Conaclos! I've tried check --apply but must have overlooked check --apply-unsafe

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

☂️ Sort imports
6 participants