mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(linter) eslint: no-new-wrappers (#2413)
Part of: #479 docs: https://eslint.org/docs/latest/rules/no-new-wrappers I am unsure of what do do with 2 of the eslint tests that use `languageOptions: { globals: { String: "off" } }` and `/* global Boolean:off */`. I've commented them out as of now. --------- Co-authored-by: Boshen <boshenc@gmail.com>
This commit is contained in:
parent
6b3b260dcc
commit
9d69167d96
3 changed files with 144 additions and 0 deletions
|
|
@ -72,6 +72,7 @@ mod eslint {
|
|||
pub mod no_loss_of_precision;
|
||||
pub mod no_mixed_operators;
|
||||
pub mod no_new_symbol;
|
||||
pub mod no_new_wrappers;
|
||||
pub mod no_obj_calls;
|
||||
pub mod no_prototype_builtins;
|
||||
pub mod no_redeclare;
|
||||
|
|
@ -370,6 +371,7 @@ oxc_macros::declare_all_lint_rules! {
|
|||
eslint::no_loss_of_precision,
|
||||
eslint::no_mixed_operators,
|
||||
eslint::no_new_symbol,
|
||||
eslint::no_new_wrappers,
|
||||
eslint::no_obj_calls,
|
||||
eslint::no_prototype_builtins,
|
||||
eslint::no_redeclare,
|
||||
|
|
|
|||
98
crates/oxc_linter/src/rules/eslint/no_new_wrappers.rs
Normal file
98
crates/oxc_linter/src/rules/eslint/no_new_wrappers.rs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
use oxc_ast::{ast::Expression, AstKind};
|
||||
use oxc_diagnostics::{
|
||||
miette::{self, Diagnostic},
|
||||
thiserror::Error,
|
||||
};
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::{Atom, Span};
|
||||
|
||||
use crate::{context::LintContext, rule::Rule, AstNode};
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error(
|
||||
"eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects"
|
||||
)]
|
||||
#[diagnostic(
|
||||
severity(warning),
|
||||
help("do not use {0} as a constructor, consider removing the new operator.")
|
||||
)]
|
||||
struct NoNewWrappersDiagnostic(Atom, #[label] pub Span);
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct NoNewWrappers;
|
||||
|
||||
declare_oxc_lint!(
|
||||
/// ### What it does
|
||||
///
|
||||
/// Disallow new operators with the String, Number, and Boolean objects
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
///
|
||||
/// The first problem is that primitive wrapper objects are, in fact, objects. That means typeof will return "object" instead of "string", "number", or "boolean".
|
||||
/// The second problem comes with boolean objects. Every object is truthy, that means an instance of Boolean always resolves to true even when its actual value is false.
|
||||
/// https://eslint.org/docs/latest/rules/no-new-wrappers
|
||||
///
|
||||
/// ### Example
|
||||
/// ```javascript
|
||||
/// var stringObject = new String('Hello world');
|
||||
/// ```
|
||||
NoNewWrappers,
|
||||
pedantic
|
||||
);
|
||||
|
||||
impl Rule for NoNewWrappers {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
let AstKind::NewExpression(expr) = node.kind() else { return };
|
||||
let Expression::Identifier(ident) = &expr.callee else { return };
|
||||
if (ident.name == "String" || ident.name == "Number" || ident.name == "Boolean")
|
||||
&& ctx.semantic().is_reference_to_global_variable(ident)
|
||||
{
|
||||
ctx.diagnostic(NoNewWrappersDiagnostic(ident.name.clone(), expr.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
||||
let pass = vec![
|
||||
"var a = new Object();",
|
||||
"var a = String('test'), b = String.fromCharCode(32);",
|
||||
"function test(Number) { return new Number; }",
|
||||
r#"
|
||||
import String from "./string";
|
||||
const str = new String(42);
|
||||
"#,
|
||||
"
|
||||
if (foo) {
|
||||
result = new Boolean(bar);
|
||||
} else {
|
||||
var Boolean = CustomBoolean;
|
||||
}
|
||||
",
|
||||
// Disabled because the eslint-test uses languageOptions: { globals: { String: "off" } }
|
||||
// "new String()",
|
||||
|
||||
// Disabled as the global option from the eslint-test does not work
|
||||
// "
|
||||
// /* global Boolean:off */
|
||||
// assert(new Boolean);
|
||||
// ",
|
||||
];
|
||||
|
||||
let fail = vec![
|
||||
"var a = new String('hello');",
|
||||
"var a = new Number(10);",
|
||||
"var a = new Boolean(false);",
|
||||
"
|
||||
const a = new String('bar');
|
||||
{
|
||||
const String = CustomString;
|
||||
const b = new String('foo');
|
||||
}
|
||||
",
|
||||
];
|
||||
|
||||
Tester::new(NoNewWrappers::NAME, pass, fail).test_and_snapshot();
|
||||
}
|
||||
44
crates/oxc_linter/src/snapshots/no_new_wrappers.snap
Normal file
44
crates/oxc_linter/src/snapshots/no_new_wrappers.snap
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
source: crates/oxc_linter/src/tester.rs
|
||||
expression: no_new_wrappers
|
||||
---
|
||||
|
||||
⚠ eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects
|
||||
╭─[no_new_wrappers.tsx:1:9]
|
||||
1 │ var a = new String('hello');
|
||||
· ───────────────────
|
||||
╰────
|
||||
help: do not use String as a constructor, consider removing the new operator.
|
||||
|
||||
⚠ eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects
|
||||
╭─[no_new_wrappers.tsx:1:9]
|
||||
1 │ var a = new Number(10);
|
||||
· ──────────────
|
||||
╰────
|
||||
help: do not use Number as a constructor, consider removing the new operator.
|
||||
|
||||
⚠ eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects
|
||||
╭─[no_new_wrappers.tsx:1:9]
|
||||
1 │ var a = new Boolean(false);
|
||||
· ──────────────────
|
||||
╰────
|
||||
help: do not use Boolean as a constructor, consider removing the new operator.
|
||||
|
||||
⚠ eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects
|
||||
╭─[no_new_wrappers.tsx:2:23]
|
||||
1 │
|
||||
2 │ const a = new String('bar');
|
||||
· ─────────────────
|
||||
3 │ {
|
||||
╰────
|
||||
help: do not use String as a constructor, consider removing the new operator.
|
||||
|
||||
⚠ eslint(no-new-wrappers): Disallow new operators with the String, Number, and Boolean objects
|
||||
╭─[no_new_wrappers.tsx:5:27]
|
||||
4 │ const String = CustomString;
|
||||
5 │ const b = new String('foo');
|
||||
· ─────────────────
|
||||
6 │ }
|
||||
╰────
|
||||
help: do not use String as a constructor, consider removing the new operator.
|
||||
|
||||
Loading…
Reference in a new issue