Skip to content

Commit

Permalink
feat(linter): add fixer for prefer-node-protocol (#4129)
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Jul 9, 2024
1 parent 2334515 commit c5b4be0
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
39 changes: 36 additions & 3 deletions crates/oxc_linter/src/rules/unicorn/prefer_node_protocol.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use oxc_ast::{
ast::{Expression, ModuleDeclaration},
ast::{Expression, ModuleDeclaration, TSModuleReference},
AstKind,
};
use oxc_diagnostics::OxcDiagnostic;
Expand Down Expand Up @@ -43,6 +43,12 @@ impl Rule for PreferNodeProtocol {
}
_ => None,
},
AstKind::TSImportEqualsDeclaration(import) => match &import.module_reference {
TSModuleReference::ExternalModuleReference(external) => {
Some((external.expression.value.clone(), external.expression.span))
}
_ => None,
},
AstKind::CallExpression(call) if !call.optional => {
call.common_js_require().map(|s| (s.value.clone(), s.span))
}
Expand Down Expand Up @@ -73,7 +79,19 @@ impl Rule for PreferNodeProtocol {
return;
}

ctx.diagnostic(prefer_node_protocol_diagnostic(span, &string_lit_value));
ctx.diagnostic_with_fix(
prefer_node_protocol_diagnostic(span, &string_lit_value),
|fixer| {
// Smallest module name is 2 chars, plus 2 for quotes = 4.
debug_assert!(
span.size() >= 4,
"node stdlib module name should be at least 4 chars long"
);
// We're replacing inside the string literal, shift to account for quotes.
let span = span.shrink_left(1).shrink_right(1);
fixer.replace(span, format!("node:{string_lit_value}"))
},
);
}
}

Expand All @@ -86,7 +104,10 @@ fn test() {
r#"import fs from "./fs";"#,
r#"import fs from "unknown-builtin-module";"#,
r#"import fs from "node:fs";"#,
r#"import * as fs from "node:fs";"#,
r#"import "punycode / ";"#,
r#"import fs = require("node:fs");"#,
r#"import type fs = require("node:fs");"#,
r#"const fs = require("node:fs");"#,
r#"const fs = require("node:fs/promises");"#,
r"const fs = require(fs);",
Expand All @@ -103,6 +124,8 @@ fn test() {

let fail = vec![
r#"import fs from "fs";"#,
r#"import * as fs from "fs";"#,
r#"import fs = require("fs");"#,
r#"export {promises} from "fs";"#,
r#"import fs from "fs/promises";"#,
r#"export {default} from "fs/promises";"#,
Expand All @@ -118,5 +141,15 @@ fn test() {
r"await import('assert/strict')",
];

Tester::new(PreferNodeProtocol::NAME, pass, fail).test_and_snapshot();
let fix = vec![
(r#"import fs from "fs";"#, r#"import fs from "node:fs";"#, None),
(r#"import * as fs from "fs";"#, r#"import * as fs from "node:fs";"#, None),
(r"import fs from 'fs';", r"import fs from 'node:fs';", None),
(r"const fs = require('fs');", r"const fs = require('node:fs');", None),
(r"import fs = require('fs');", r"import fs = require('node:fs');", None),
(r#"import "child_process";"#, r#"import "node:child_process";"#, None),
(r#"import fs from "fs/promises";"#, r#"import fs from "node:fs/promises";"#, None),
];

Tester::new(PreferNodeProtocol::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
}
14 changes: 14 additions & 0 deletions crates/oxc_linter/src/snapshots/prefer_node_protocol.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@ source: crates/oxc_linter/src/tester.rs
╰────
help: Prefer `node:fs` over `fs`.

eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules.
╭─[prefer_node_protocol.tsx:1:21]
1import * as fs from "fs";
· ────
╰────
help: Prefer `node:fs` over `fs`.

eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules.
╭─[prefer_node_protocol.tsx:1:21]
1import fs = require("fs");
· ────
╰────
help: Prefer `node:fs` over `fs`.

eslint-plugin-unicorn(prefer-node-protocol): Prefer using the `node:` protocol when importing Node.js builtin modules.
╭─[prefer_node_protocol.tsx:1:24]
1export {promises} from "fs";
Expand Down

0 comments on commit c5b4be0

Please sign in to comment.