feat(linter): eslint/no-proto (#2760)

Rule detail: https://eslint.org/docs/latest/rules/no-proto

---------

Co-authored-by: j.buendia <j.buendia>
This commit is contained in:
Jose 2024-03-19 13:01:15 +01:00 committed by GitHub
parent 39b98badca
commit 134e15e657
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 110 additions and 0 deletions

View file

@ -86,6 +86,7 @@ mod eslint {
pub mod no_new_wrappers;
pub mod no_nonoctal_decimal_escape;
pub mod no_obj_calls;
pub mod no_proto;
pub mod no_prototype_builtins;
pub mod no_redeclare;
pub mod no_regex_spaces;
@ -408,6 +409,7 @@ oxc_macros::declare_all_lint_rules! {
eslint::no_new_wrappers,
eslint::no_nonoctal_decimal_escape,
eslint::no_obj_calls,
eslint::no_proto,
eslint::no_prototype_builtins,
eslint::no_redeclare,
eslint::no_regex_spaces,

View file

@ -0,0 +1,77 @@
use oxc_ast::AstKind;
use oxc_diagnostics::{
miette::{self, Diagnostic},
thiserror::Error,
};
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{context::LintContext, rule::Rule, AstNode};
#[derive(Debug, Error, Diagnostic)]
#[error("eslint(no-proto): The '__proto__' property is deprecated")]
#[diagnostic(severity(warning), help("Disallow the use of the `__proto__` property."))]
struct NoProtoDiagnostic(#[label] pub Span);
#[derive(Debug, Default, Clone)]
pub struct NoProto;
declare_oxc_lint!(
/// ### What it does
/// Disallow the use of the __proto__ property
///
/// ### Why is this bad?
/// __proto__ property has been deprecated as of ECMAScript 3.1 and shouldnt be used in the code. Use Object.getPrototypeOf and Object.setPrototypeOf instead.
///
/// ### Example
/// ```javascript
/// /*eslint no-proto: "error"*/
///
/// var a = obj.__proto__;
///
/// var a = obj["__proto__"];
///
/// obj.__proto__ = b;
///
/// obj["__proto__"] = b;
/// ```
NoProto,
correctness
);
impl Rule for NoProto {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let AstKind::MemberExpression(member_expression) = node.kind() else { return };
if let Some(static_property_name) = member_expression.static_property_name() {
if static_property_name == "__proto__" {
ctx.diagnostic(NoProtoDiagnostic(Span::new(
member_expression.span().start,
member_expression.span().end,
)));
}
}
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
"var a = test[__proto__];",
"var __proto__ = null;",
"foo[`__proto`] = null;",
"foo[`__proto__
`] = null;",
"class C { #__proto__; foo() { this.#__proto__; } }",
];
let fail = vec![
"var a = test.__proto__;",
"var a = test['__proto__'];",
"var a = test[`__proto__`];",
"test[`__proto__`] = function () {};",
];
Tester::new(NoProto::NAME, pass, fail).test_and_snapshot();
}

View file

@ -0,0 +1,31 @@
---
source: crates/oxc_linter/src/tester.rs
expression: no_proto
---
⚠ eslint(no-proto): The '__proto__' property is deprecated
╭─[no_proto.tsx:1:9]
1 │ var a = test.__proto__;
· ──────────────
╰────
help: Disallow the use of the `__proto__` property.
⚠ eslint(no-proto): The '__proto__' property is deprecated
╭─[no_proto.tsx:1:9]
1 │ var a = test['__proto__'];
· ─────────────────
╰────
help: Disallow the use of the `__proto__` property.
⚠ eslint(no-proto): The '__proto__' property is deprecated
╭─[no_proto.tsx:1:9]
1 │ var a = test[`__proto__`];
· ─────────────────
╰────
help: Disallow the use of the `__proto__` property.
⚠ eslint(no-proto): The '__proto__' property is deprecated
╭─[no_proto.tsx:1:1]
1 │ test[`__proto__`] = function () {};
· ─────────────────
╰────
help: Disallow the use of the `__proto__` property.