mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 12:51:57 +00:00
feat(linter): check BindingIdentifier in javascript
This commit is contained in:
parent
4ea7ac373d
commit
185acc49bd
4 changed files with 157 additions and 24 deletions
|
|
@ -15,10 +15,11 @@ impl Rule for EarlyErrorJavaScript {
|
|||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
match node.get().kind() {
|
||||
AstKind::BindingIdentifier(ident) => {
|
||||
check_identifier(&ident.name, ident.span, node, ctx)
|
||||
check_identifier(&ident.name, ident.span, node, ctx);
|
||||
check_binding_identifier(ident, node, ctx);
|
||||
}
|
||||
AstKind::IdentifierReference(ident) => {
|
||||
check_identifier(&ident.name, ident.span, node, ctx)
|
||||
check_identifier(&ident.name, ident.span, node, ctx);
|
||||
}
|
||||
AstKind::LabelIdentifier(ident) => check_identifier(&ident.name, ident.span, node, ctx),
|
||||
AstKind::PrivateIdentifier(ident) => check_private_identifier(ident, node, ctx),
|
||||
|
|
@ -70,7 +71,42 @@ fn check_identifier<'a>(name: &Atom, span: Span, node: &AstNode<'a>, ctx: &LintC
|
|||
|
||||
// It is a Syntax Error if this phrase is contained in strict mode code and the StringValue of IdentifierName is: "implements", "interface", "let", "package", "private", "protected", "public", "static", or "yield".
|
||||
if ctx.strict_mode(node) && STRICT_MODE_NAMES.contains(name.as_str()) {
|
||||
return ctx.diagnostic(ReservedKeyword(name.clone(), span));
|
||||
ctx.diagnostic(ReservedKeyword(name.clone(), span));
|
||||
}
|
||||
}
|
||||
|
||||
fn check_binding_identifier<'a>(
|
||||
ident: &BindingIdentifier,
|
||||
node: &AstNode<'a>,
|
||||
ctx: &LintContext<'a>,
|
||||
) {
|
||||
let strict_mode = ctx.strict_mode(node);
|
||||
// It is a Diagnostic if the StringValue of a BindingIdentifier is "eval" or "arguments" within strict mode code.
|
||||
// if strict_mode && !span.ctx.has_ambient() && matches!(name.as_str(), "eval" | "arguments") {
|
||||
// return Some(Diagnostic::UnexpectedIdentifierAssign(name.clone(), span.range()));
|
||||
// }
|
||||
|
||||
// LexicalDeclaration : LetOrConst BindingList ;
|
||||
// * It is a Syntax Error if the BoundNames of BindingList contains "let".
|
||||
if !strict_mode && ident.name == "let" {
|
||||
for node_id in ctx.ancestors(node).skip(1) {
|
||||
match ctx.kind(node_id) {
|
||||
AstKind::VariableDeclaration(decl) if decl.kind.is_lexical() => {
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error(
|
||||
"`let` cannot be declared as a variable name inside of a `{0:?}` declaration"
|
||||
)]
|
||||
#[diagnostic()]
|
||||
struct InvalidLetDeclaration(String, #[label] Span);
|
||||
return ctx
|
||||
.diagnostic(InvalidLetDeclaration(decl.kind.to_string(), ident.span));
|
||||
}
|
||||
AstKind::VariableDeclaration(_) | AstKind::Function(_) | AstKind::Program(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Babel Summary:
|
||||
AST Parsed : 2056/2069 (99.37%)
|
||||
Positive Passed: 2056/2069 (99.37%)
|
||||
Negative Passed: 922/1502 (61.38%)
|
||||
Negative Passed: 935/1502 (62.25%)
|
||||
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
|
||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
|
||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-multiple-labels/input.js"
|
||||
|
|
@ -135,19 +135,6 @@ Expect Syntax Error: "es2015/for-in/var-arraybindingpattern-initializer/input.js
|
|||
Expect Syntax Error: "es2015/for-in/var-objectbindingpattern-initializer/input.js"
|
||||
Expect Syntax Error: "es2015/for-of/invalid-let-as-identifier/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-as-identifier-strict-fail/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-1/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-10/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-11/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-12/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-2/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-3/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-4/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-5/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-6/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-7/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-8/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-binding-list-fail-9/input.js"
|
||||
Expect Syntax Error: "es2015/let/let-at-catch-block/input.js"
|
||||
Expect Syntax Error: "es2015/meta-properties/invalid-arrow-function/input.js"
|
||||
Expect Syntax Error: "es2015/meta-properties/new-invalid-prop/input.js"
|
||||
Expect Syntax Error: "es2015/meta-properties/new-target-invalid/input.js"
|
||||
|
|
@ -2203,6 +2190,86 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
|
|||
╰────
|
||||
help: Wrap this declaration in a block statement
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-1/input.js:1:1]
|
||||
1 │ let { let } = {};
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-10/input.js:1:1]
|
||||
1 │ const [let = 10] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-11/input.js:1:1]
|
||||
1 │ let [...let] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-12/input.js:1:1]
|
||||
1 │ const [...let] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-2/input.js:1:1]
|
||||
1 │ const { let } = {};
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-3/input.js:1:1]
|
||||
1 │ let [let] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-4/input.js:1:1]
|
||||
1 │ const [let] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-5/input.js:1:1]
|
||||
1 │ let let
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-6/input.js:1:1]
|
||||
1 │ const let = ''
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-7/input.js:1:1]
|
||||
1 │ let { let = 10 } = {};
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-8/input.js:1:1]
|
||||
1 │ const { let = 10 } = {};
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-binding-list-fail-9/input.js:1:1]
|
||||
1 │ let [let = 10] = [];
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es2015/let/let-at-catch-block/input.js:1:1]
|
||||
1 │ try {} catch (err) {
|
||||
2 │ let let;
|
||||
· ───
|
||||
3 │ }
|
||||
╰────
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[es2015/meta-properties/new-target-invalid-escaped-new/input.js:1:1]
|
||||
1 │ function f() { n\u0065w.target; }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Test262 Summary:
|
||||
AST Parsed : 43997/44009 (99.97%)
|
||||
Positive Passed: 43997/44009 (99.97%)
|
||||
Negative Passed: 2505/3917 (63.95%)
|
||||
Negative Passed: 2509/3917 (64.05%)
|
||||
Expect Syntax Error: "annexB/language/statements/for-in/const-initializer.js"
|
||||
Expect Syntax Error: "annexB/language/statements/for-in/let-initializer.js"
|
||||
Expect Syntax Error: "annexB/language/statements/for-in/strict-initializer.js"
|
||||
|
|
@ -1155,10 +1155,8 @@ Expect Syntax Error: "language/statements/for-in/dstr/obj-id-init-simple-strict.
|
|||
Expect Syntax Error: "language/statements/for-in/dstr/obj-id-simple-strict.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-const-bound-names-dup.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-const-bound-names-in-stmt.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-const-bound-names-let.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-let-bound-names-dup.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-let-bound-names-in-stmt.js"
|
||||
Expect Syntax Error: "language/statements/for-in/head-let-bound-names-let.js"
|
||||
Expect Syntax Error: "language/statements/for-in/labelled-fn-stmt-const.js"
|
||||
Expect Syntax Error: "language/statements/for-in/labelled-fn-stmt-let.js"
|
||||
Expect Syntax Error: "language/statements/for-in/labelled-fn-stmt-lhs.js"
|
||||
|
|
@ -1191,11 +1189,9 @@ Expect Syntax Error: "language/statements/for-of/dstr/var-ary-ptrn-rest-init-obj
|
|||
Expect Syntax Error: "language/statements/for-of/dstr/var-obj-ptrn-init-err.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-const-bound-names-dup.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-const-bound-names-in-stmt.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-const-bound-names-let.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-const-init.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-let-bound-names-dup.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-let-bound-names-in-stmt.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-let-bound-names-let.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-let-init.js"
|
||||
Expect Syntax Error: "language/statements/for-of/head-var-init.js"
|
||||
Expect Syntax Error: "language/statements/for-of/labelled-fn-stmt-const.js"
|
||||
|
|
@ -21128,6 +21124,20 @@ Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-par
|
|||
34 │ ]) ;
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[language/statements/for-in/head-const-bound-names-let.js:16:1]
|
||||
16 │
|
||||
17 │ for (const let in {}) {}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[language/statements/for-in/head-let-bound-names-let.js:16:1]
|
||||
16 │
|
||||
17 │ for (let let in {}) {}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× Unexpected token
|
||||
╭─[language/statements/for-in/head-lhs-cover-non-asnmt-trgt.js:23:1]
|
||||
23 │
|
||||
|
|
@ -21520,6 +21530,13 @@ Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-par
|
|||
· ╰── keyword cannot contain escape characters
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"const"` declaration
|
||||
╭─[language/statements/for-of/head-const-bound-names-let.js:16:1]
|
||||
16 │
|
||||
17 │ for (const let of []) {}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× Expect token
|
||||
╭─[language/statements/for-of/head-decl-no-expr.js:16:1]
|
||||
16 │
|
||||
|
|
@ -21536,6 +21553,13 @@ Expect to Parse: "language/statements/class/decorator/syntax/valid/decorator-par
|
|||
· ╰── Expect `)` here, but found `,`
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[language/statements/for-of/head-let-bound-names-let.js:16:1]
|
||||
16 │
|
||||
17 │ for (let let of []) {}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× The left-hand side of a `for...of` statement may not be `async`
|
||||
╭─[language/statements/for-of/head-lhs-async-invalid.js:16:1]
|
||||
16 │ var async;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
TypeScript Summary:
|
||||
AST Parsed : 2308/2338 (98.72%)
|
||||
Positive Passed: 2308/2338 (98.72%)
|
||||
Negative Passed: 576/2531 (22.76%)
|
||||
Negative Passed: 577/2531 (22.80%)
|
||||
Expect Syntax Error: "Symbols/ES5SymbolProperty2.ts"
|
||||
Expect Syntax Error: "Symbols/ES5SymbolProperty6.ts"
|
||||
Expect Syntax Error: "additionalChecks/noPropertyAccessFromIndexSignature1.ts"
|
||||
|
|
@ -572,7 +572,6 @@ Expect Syntax Error: "es6/for-ofStatements/for-of39.ts"
|
|||
Expect Syntax Error: "es6/for-ofStatements/for-of46.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of47.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of48.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of51.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of52.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of54.ts"
|
||||
Expect Syntax Error: "es6/for-ofStatements/for-of55.ts"
|
||||
|
|
@ -4644,6 +4643,13 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts"
|
|||
· ───
|
||||
╰────
|
||||
|
||||
× `let` cannot be declared as a variable name inside of a `"let"` declaration
|
||||
╭─[es6/for-ofStatements/for-of51.ts:1:1]
|
||||
1 │ //@target: ES6
|
||||
2 │ for (let let of []) {}
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× Unexpected token
|
||||
╭─[es6/functionPropertyAssignments/FunctionPropertyAssignments2_es6.ts:1:1]
|
||||
1 │ // @target: es6
|
||||
|
|
|
|||
Loading…
Reference in a new issue