feat(linter): eslint/no-iterator (#2758)

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

---------

Co-authored-by: j.buendia <j.buendia>
This commit is contained in:
Jose 2024-03-20 09:20:09 +01:00 committed by GitHub
parent 53ffbc6bd2
commit 451162effc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 111 additions and 0 deletions

View file

@ -81,6 +81,7 @@ mod eslint {
pub mod no_import_assign;
pub mod no_inner_declarations;
pub mod no_irregular_whitespace;
pub mod no_iterator;
pub mod no_loss_of_precision;
pub mod no_mixed_operators;
pub mod no_new_symbol;
@ -409,6 +410,7 @@ oxc_macros::declare_all_lint_rules! {
eslint::no_import_assign,
eslint::no_inner_declarations,
eslint::no_irregular_whitespace,
eslint::no_iterator,
eslint::no_loss_of_precision,
eslint::no_mixed_operators,
eslint::no_new_symbol,

View file

@ -0,0 +1,71 @@
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-iterator): Reserved name '__iterator__'")]
#[diagnostic(severity(warning), help("Disallow the use of the `__iterator__` property."))]
struct NoIteratorDiagnostic(#[label] pub Span);
#[derive(Debug, Default, Clone)]
pub struct NoIterator;
declare_oxc_lint!(
/// ### What it does
/// Disallow the use of the __iterator__ property
///
/// ### Why is this bad?
/// The __iterator__ property was a SpiderMonkey extension to JavaScript that could be used to create custom iterators that are compatible with JavaScripts for in and for each constructs. However, this property is now obsolete, so it should not be used. Heres an example of how this used to work:
///
/// ### Example
/// ```javascript
/// Foo.prototype.__iterator__ = function() {
/// return new FooIterator(this);
/// }
/// ```
NoIterator,
restriction
);
impl Rule for NoIterator {
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 == "__iterator__" {
ctx.diagnostic(NoIteratorDiagnostic(Span::new(
member_expression.span().start,
member_expression.span().end,
)));
}
}
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
"var a = test[__iterator__];",
"var __iterator__ = null;",
"foo[`__iterator`] = null;",
"foo[`__iterator__
`] = null;",
];
let fail = vec![
"var a = test.__iterator__;",
"Foo.prototype.__iterator__ = function() {};",
"var a = test['__iterator__'];",
"var a = test[`__iterator__`];",
"test[`__iterator__`] = function () {};",
];
Tester::new(NoIterator::NAME, pass, fail).test_and_snapshot();
}

View file

@ -0,0 +1,38 @@
---
source: crates/oxc_linter/src/tester.rs
expression: no_iterator
---
⚠ eslint(no-iterator): Reserved name '__iterator__'
╭─[no_iterator.tsx:1:9]
1 │ var a = test.__iterator__;
· ─────────────────
╰────
help: Disallow the use of the `__iterator__` property.
⚠ eslint(no-iterator): Reserved name '__iterator__'
╭─[no_iterator.tsx:1:1]
1 │ Foo.prototype.__iterator__ = function() {};
· ──────────────────────────
╰────
help: Disallow the use of the `__iterator__` property.
⚠ eslint(no-iterator): Reserved name '__iterator__'
╭─[no_iterator.tsx:1:9]
1 │ var a = test['__iterator__'];
· ────────────────────
╰────
help: Disallow the use of the `__iterator__` property.
⚠ eslint(no-iterator): Reserved name '__iterator__'
╭─[no_iterator.tsx:1:9]
1 │ var a = test[`__iterator__`];
· ────────────────────
╰────
help: Disallow the use of the `__iterator__` property.
⚠ eslint(no-iterator): Reserved name '__iterator__'
╭─[no_iterator.tsx:1:1]
1 │ test[`__iterator__`] = function () {};
· ────────────────────
╰────
help: Disallow the use of the `__iterator__` property.