Skip to content

Commit e6db30b

Browse files
leaysgurCopilot
authored andcommitted
test(formatter/sort-imports): Update comments and tests (#15896)
Follow up of #15831
1 parent 6ddf297 commit e6db30b

File tree

4 files changed

+124
-87
lines changed

4 files changed

+124
-87
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
//! This module contains all IR transforms for sorting and aesthetically features.
2+
//! Currently, it only includes the `SortImportsTransform`.
3+
//!
4+
//! There were several approaches to achieve sorting.
5+
//! - 1. Sort at the AST level.
6+
//! - 2. Sort after converting AST to IR (current approach).
7+
//!
8+
//! At first glance, the former seems simpler and faster, but in practice, there are inconvenient aspects.
9+
//!
10+
//! Sorting requires referencing comments and blank lines while traversing the AST.
11+
//! Frequent lookups are necessary, and there wasn't a dramatic improvement in speed.
12+
//!
13+
//! Additionally, comments are printed in a top-down manner,
14+
//! and sorting that disrupts this order would complicate the code.
15+
//!
16+
//! Despite some overhead, sorting the IR allows us to avoid impacting the existing complex code that converts AST to IR.
17+
//!
18+
//! For more details, refer to the experimental PR below.
19+
//! - <https://github.com/oxc-project/oxc/pull/14647>
20+
//! - <https://github.com/oxc-project/oxc/pull/14651>
21+
122
mod sort_imports;
223

324
pub use sort_imports::SortImportsTransform;

crates/oxc_formatter/src/ir_transform/sort_imports/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use crate::{
1616
options,
1717
};
1818

19+
/// An IR transform that sorts import statements according to specified options.
20+
/// Heavily inspired by ESLint's `@perfectionist/sort-imports` rule.
21+
/// <https://perfectionist.dev/rules/sort-imports>
1922
pub struct SortImportsTransform {
2023
options: options::SortImports,
2124
groups: Vec<Vec<GroupName>>,

crates/oxc_formatter/tests/ir_transform/_sort-imports-tests.ref.snap

Lines changed: 0 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2,93 +2,6 @@
22
// vim: set filetype=typescript:
33

44
describe("misc", () => {
5-
it("recognizes Node.js built-in modules with node: prefix", async () => {
6-
await valid({
7-
code: dedent`
8-
import { writeFile } from 'node:fs/promises'
9-
10-
import { useEffect } from 'react'
11-
`,
12-
options: [
13-
{
14-
groups: ["builtin", "external"],
15-
},
16-
],
17-
});
18-
19-
await invalid({
20-
output: dedent`
21-
import { writeFile } from 'node:fs/promises'
22-
23-
import { useEffect } from 'react'
24-
`,
25-
code: dedent`
26-
import { writeFile } from 'node:fs/promises'
27-
import { useEffect } from 'react'
28-
`,
29-
options: [
30-
{
31-
groups: ["builtin", "external"],
32-
},
33-
],
34-
});
35-
});
36-
37-
it("classifies internal pattern side-effects correctly by group priority", async () => {
38-
await valid({
39-
code: dedent`
40-
import { useClient } from '~/hooks/useClient'
41-
42-
import '~/css/globals.css'
43-
44-
import '~/data'
45-
`,
46-
options: [
47-
{
48-
groups: ["internal", "side-effect-style", "side-effect"],
49-
},
50-
],
51-
});
52-
53-
await invalid({
54-
output: dedent`
55-
import { useClient } from '~/hooks/useClient'
56-
57-
import '~/css/globals.css'
58-
59-
import '~/data'
60-
`,
61-
code: dedent`
62-
import { useClient } from '~/hooks/useClient'
63-
import '~/data'
64-
import '~/css/globals.css'
65-
`,
66-
options: [
67-
{
68-
groups: ["internal", "side-effect-style", "side-effect"],
69-
},
70-
],
71-
});
72-
});
73-
74-
it("treats empty named imports as regular imports not side-effects", async () => {
75-
await valid({
76-
code: dedent`
77-
import {} from 'node:os'
78-
import sqlite from 'node:sqlite'
79-
import { describe, test } from 'node:test'
80-
import { c } from 'c'
81-
import 'node:os'
82-
`,
83-
options: [
84-
{
85-
groups: ["builtin", "external", "side-effect"],
86-
},
87-
],
88-
});
89-
});
90-
91-
925
describe("validates compatibility between sortSideEffects and groups configuration", () => {
936
function createRule(
947
groups: Options[0]["groups"],

crates/oxc_formatter/tests/ir_transform/sort_imports.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,4 +1613,104 @@ import d from "d";
16131613
import e from "timers";
16141614
"##,
16151615
);
1616+
// Empty groups
1617+
assert_format(
1618+
r#"
1619+
import d from "d";
1620+
import a from "a";
1621+
import * as c from "c";
1622+
import { b1, type b2, b3 as b33 } from "b";
1623+
"#,
1624+
r#"{
1625+
"experimentalSortImports": {
1626+
"groups": []
1627+
}
1628+
}"#,
1629+
r#"
1630+
import a from "a";
1631+
import { b1, type b2, b3 as b33 } from "b";
1632+
import * as c from "c";
1633+
import d from "d";
1634+
"#,
1635+
);
1636+
assert_format(
1637+
r#"
1638+
import d from "d";
1639+
import a from "a";
1640+
import * as c from "c";
1641+
import { b1, type b2, b3 as b33 } from "b";
1642+
"#,
1643+
r#"{
1644+
"experimentalSortImports": {
1645+
"groups": [[], []]
1646+
}
1647+
}"#,
1648+
r#"
1649+
import a from "a";
1650+
import { b1, type b2, b3 as b33 } from "b";
1651+
import * as c from "c";
1652+
import d from "d";
1653+
"#,
1654+
);
1655+
// Node.js built-in modules with node: prefix are classified as builtin group
1656+
assert_format(
1657+
r#"
1658+
import { writeFile } from "node:fs/promises";
1659+
import { useEffect } from "react";
1660+
"#,
1661+
r#"{
1662+
"experimentalSortImports": {
1663+
"groups": ["builtin", "external"]
1664+
}
1665+
}"#,
1666+
r#"
1667+
import { writeFile } from "node:fs/promises";
1668+
1669+
import { useEffect } from "react";
1670+
"#,
1671+
);
1672+
// Internal pattern side-effects are correctly classified by group priority
1673+
assert_format(
1674+
r#"
1675+
import { useClient } from "~/hooks/useClient";
1676+
import "~/data";
1677+
import "~/css/globals.css";
1678+
"#,
1679+
r#"{
1680+
"experimentalSortImports": {
1681+
"groups": ["internal", "side-effect-style", "side-effect"]
1682+
}
1683+
}"#,
1684+
r#"
1685+
import { useClient } from "~/hooks/useClient";
1686+
1687+
import "~/css/globals.css";
1688+
1689+
import "~/data";
1690+
"#,
1691+
);
1692+
// Empty named imports are treated as regular imports not side-effects
1693+
assert_format(
1694+
r#"
1695+
import {} from "node:os";
1696+
import sqlite from "node:sqlite";
1697+
import { describe, test } from "node:test";
1698+
import { c } from "c";
1699+
import "node:os";
1700+
"#,
1701+
r#"{
1702+
"experimentalSortImports": {
1703+
"groups": ["builtin", "external", "side-effect"]
1704+
}
1705+
}"#,
1706+
r#"
1707+
import {} from "node:os";
1708+
import sqlite from "node:sqlite";
1709+
import { describe, test } from "node:test";
1710+
1711+
import { c } from "c";
1712+
1713+
import "node:os";
1714+
"#,
1715+
);
16161716
}

0 commit comments

Comments
 (0)