feat(linter): report export errors in javascript

This commit is contained in:
Boshen 2023-03-16 00:06:03 +08:00
parent 8d3a5c46ba
commit 164c2831e1
6 changed files with 560 additions and 30 deletions

View file

@ -1,6 +1,7 @@
#[allow(clippy::wildcard_imports)]
use oxc_ast::{
ast::*,
module_record::ExportLocalName,
syntax_directed_operations::{BoundNames, IsSimpleParameterList, PropName},
AstKind, Atom, GetSpan, ModuleKind, Span,
};
@ -17,12 +18,12 @@ use crate::{ast_util::STRICT_MODE_NAMES, context::LintContext, rule::Rule, AstNo
pub struct EarlyErrorJavaScript;
impl Rule for EarlyErrorJavaScript {
#[allow(clippy::single_match)]
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
let kind = node.get().kind();
check_function_declaration(kind, node, ctx);
match kind {
AstKind::Program(_) => check_program(node, ctx),
AstKind::BindingIdentifier(ident) => {
check_identifier(&ident.name, ident.span, node, ctx);
check_binding_identifier(ident, node, ctx);
@ -75,6 +76,62 @@ impl Rule for EarlyErrorJavaScript {
}
}
fn check_program(node: &AstNode, ctx: &LintContext) {
#[derive(Debug, Error, Diagnostic)]
#[error("Export '{0}' is not defined")]
#[diagnostic()]
struct UndefinedExport(Atom, #[label] Span);
#[derive(Debug, Error, Diagnostic)]
#[error("Duplicated export '{0}'")]
#[diagnostic()]
struct DuplicateExport(
Atom,
#[label("Export has already been declared here")] Span,
#[label("It cannot be redeclared here")] Span,
);
// Skip checkking for exports in TypeScript for now
if ctx.source_type().is_typescript() {
return;
}
let scope = ctx.scope(node);
let module_record = ctx.semantic().module_record();
// It is a Syntax Error if any element of the ExportedBindings of ModuleItemList
// does not also occur in either the VarDeclaredNames of ModuleItemList, or the LexicallyDeclaredNames of ModuleItemList.
module_record
.local_export_entries
.iter()
.filter_map(|export_entry| match &export_entry.local_name {
ExportLocalName::Name(name_span) => Some(name_span),
_ => None,
})
.filter(|name_span| scope.get_variable_symbol_id(name_span.name()).is_none())
.for_each(|name_span| {
ctx.diagnostic(UndefinedExport(name_span.name().clone(), name_span.span()));
});
// It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
for name_span in &module_record.exported_bindings_duplicated {
let old_span = module_record.exported_bindings.get(name_span.name()).unwrap();
ctx.diagnostic(DuplicateExport(name_span.name().clone(), name_span.span(), *old_span));
}
for span in &module_record.export_default_duplicated {
let old_span = module_record.export_default.unwrap();
ctx.diagnostic(DuplicateExport("default".into(), *span, old_span));
}
// `export default x;`
// `export { y as default };`
if let Some(span) = module_record.exported_bindings.get("default")
&& let Some(default_span) = &module_record.export_default {
ctx.diagnostic(DuplicateExport("default".into(), *default_span, *span));
}
}
fn check_duplicate_bound_names<T: BoundNames>(bound_names: &T, ctx: &LintContext) {
// bound_names are usually small, a simple loop should be more performant checking with a hashmap
let mut idents = bound_names.bound_names();

View file

@ -182,3 +182,17 @@ impl<'a> Binder for CatchClause<'a> {
}
}
}
impl<'a> Binder for ModuleDeclaration<'a> {
fn bind(&self, builder: &mut SemanticBuilder) {
for ident in self.bound_names() {
builder.declare_symbol(
&ident.name,
ident.span,
builder.scope.current_scope_id,
SymbolFlags::empty(),
SymbolFlags::empty(),
);
}
}
}

View file

@ -65,9 +65,12 @@ impl<'a> SemanticBuilder<'a> {
#[must_use]
pub fn build(mut self, program: &'a Program<'a>, trivias: Rc<Trivias>) -> ScopeBuilderReturn {
// AST pass
// First AST pass
self.visit_program(program);
let module_record = self.module_record_builder.build();
// Second partial AST pass on top level import / export statements
let module_record = self.module_record_builder.build(program);
let semantic = Semantic {
source_type: self.source_type,
nodes: self.nodes,
@ -180,6 +183,9 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
impl<'a> SemanticBuilder<'a> {
fn enter_kind(&mut self, kind: AstKind<'a>) {
match kind {
AstKind::ModuleDeclaration(decl) => {
decl.bind(self);
}
AstKind::VariableDeclarator(decl) => {
decl.bind(self);
}
@ -208,9 +214,6 @@ impl<'a> SemanticBuilder<'a> {
self.scope.current_scope_mut().strict_mode = true;
}
}
AstKind::ModuleDeclaration(decl) => {
self.module_record_builder.visit_module_declaration(decl);
}
_ => {}
}
}

View file

@ -11,7 +11,15 @@ pub struct ModuleRecordBuilder {
impl ModuleRecordBuilder {
#[must_use]
pub fn build(mut self) -> ModuleRecord {
pub fn build(mut self, program: &Program) -> ModuleRecord {
// This avoids additional checks on TypeScript `TsModuleBlock` which
// also has `ModuleDeclaration`s.
for stmt in &program.body {
if let Statement::ModuleDeclaration(module_decl) = stmt {
self.visit_module_declaration(module_decl);
}
}
// The `ParseModule` algorithm requires `importedBoundNames` (import entries) to be
// resolved before resovling export entries.
self.resolve_export_entries();

View file

@ -1,7 +1,7 @@
Babel Summary:
AST Parsed : 2050/2071 (98.99%)
Positive Passed: 2050/2071 (98.99%)
Negative Passed: 1321/1502 (87.95%)
Negative Passed: 1335/1502 (88.88%)
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"
@ -13,22 +13,9 @@ Expect Syntax Error: "annex-b/disabled/3.5-for-in-initializer/input.js"
Expect Syntax Error: "annex-b/enabled/3.1-sloppy-labeled-functions-if-body/input.js"
Expect Syntax Error: "core/categorized/invalid-fn-decl-labeled-inside-if/input.js"
Expect Syntax Error: "core/categorized/invalid-fn-decl-labeled-inside-loop/input.js"
Expect Syntax Error: "core/scope/undecl-export-as-default/input.js"
Expect Syntax Error: "core/scope/undecl-export-as/input.js"
Expect Syntax Error: "core/scope/undecl-export-block/input.js"
Expect Syntax Error: "core/scope/undecl-export-builtin-as/input.js"
Expect Syntax Error: "core/scope/undecl-export-builtin/input.js"
Expect Syntax Error: "core/scope/undecl-export/input.js"
Expect Syntax Error: "es2015/class-methods/direct-super-in-object-method/input.js"
Expect Syntax Error: "es2015/destructuring/error-operator-for-default/input.js"
Expect Syntax Error: "es2015/for-of/invalid-let-as-identifier/input.js"
Expect Syntax Error: "es2015/modules/duplicate-export-default-and-export-as-default/input.js"
Expect Syntax Error: "es2015/modules/duplicate-export-default/input.js"
Expect Syntax Error: "es2015/modules/duplicate-named-export-class-declaration/input.js"
Expect Syntax Error: "es2015/modules/duplicate-named-export-destructuring-assignment/input.js"
Expect Syntax Error: "es2015/modules/duplicate-named-export-function-declaration/input.js"
Expect Syntax Error: "es2015/modules/duplicate-named-export-variable-declaration/input.js"
Expect Syntax Error: "es2015/modules/duplicate-named-export/input.js"
Expect Syntax Error: "es2015/object/disallow-duplicate-method-params/input.js"
Expect Syntax Error: "es2015/uncategorised/.191/input.js"
Expect Syntax Error: "es2015/uncategorised/.335/input.js"
@ -43,7 +30,6 @@ Expect Syntax Error: "es2018/object-rest-spread/comma-after-spread-nested/input.
Expect Syntax Error: "es2018/object-rest-spread/no-pattern-in-rest-with-ts/input.js"
Expect Syntax Error: "es2018/object-rest-spread/no-pattern-in-rest/input.js"
Expect Syntax Error: "es2020/dynamic-import/invalid-trailing-comma/input.js"
Expect Syntax Error: "esprima/es2015-export-declaration/invalid-export-named-default/input.js"
Expect Syntax Error: "esprima/es2015-generator/.generator-parameter-binding-property-reserved/input.js"
Expect Syntax Error: "esprima/es2015-identifier/.invalid_function_wait/input.js"
Expect Syntax Error: "esprima/expression-primary-literal-regular-expression/.migrated_0005/input.js"
@ -1125,6 +1111,38 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │ }
╰────
× Export 'encrypt' is not defined
╭─[core/scope/undecl-export-as-default/input.js:1:1]
1 │ export { encrypt as default };
· ───────
╰────
× Export 'encrypt' is not defined
╭─[core/scope/undecl-export-as/input.js:1:1]
1 │ export { encrypt as decrypt };
· ───────
2 │ function decrypt() {}
╰────
× Export 'encrypt' is not defined
╭─[core/scope/undecl-export-block/input.js:3:1]
3 │ }
4 │ export { encrypt }
· ───────
╰────
× Export 'Object' is not defined
╭─[core/scope/undecl-export-builtin-as/input.js:1:1]
1 │ export { Object as Obj };
· ──────
╰────
× Export 'Object' is not defined
╭─[core/scope/undecl-export-builtin/input.js:1:1]
1 │ export { Object };
· ──────
╰────
× Invalid function declaration
╭─[core/scope/undecl-export-if/input.js:1:1]
1 │ export { encrypt };
@ -1133,6 +1151,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
╰────
help: In strict mode code, functions can only be declared at top level or inside a block
× Export 'encrypt' is not defined
╭─[core/scope/undecl-export/input.js:1:1]
1 │ export { encrypt };
· ───────
╰────
× A 'get' accessor must not have any formal parameters.
╭─[core/uncategorised/.542/input.js:1:1]
1 │ ({ get prop(x) {} })
@ -3036,6 +3060,63 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
╰────
help: new.target is only allowed in constructors and functions invoked using thew `new` operator
× Export 'foo' is not defined
╭─[es2015/modules/duplicate-export-default-and-export-as-default/input.js:1:1]
1 │ export default function() {};
2 │ export { foo as default };
· ───
╰────
× Duplicated export 'default'
╭─[es2015/modules/duplicate-export-default-and-export-as-default/input.js:1:1]
1 │ export default function() {};
· ───┬───
· ╰── Export has already been declared here
2 │ export { foo as default };
· ───┬───
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'default'
╭─[es2015/modules/duplicate-export-default/input.js:1:1]
1 │ export default {};
· ───┬───
· ╰── Export has already been declared here
2 │ export default function() {};
· ───┬───
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'Foo'
╭─[es2015/modules/duplicate-named-export-class-declaration/input.js:1:1]
1 │ export { Foo };
· ─┬─
· ╰── Export has already been declared here
2 │ export class Foo {};
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring-assignment/input.js:1:1]
1 │ export { foo };
· ─┬─
· ╰── Export has already been declared here
2 │ export const { foo = 1 } = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring10/input.js:1:1]
1 │ export function foo() {};
· ─┬─
· ╰── Export has already been declared here
2 │ export const { a: [{foo}] } = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring10/input.js:1:1]
1 │ export function foo() {};
@ -3046,6 +3127,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo4'
╭─[es2015/modules/duplicate-named-export-destructuring11/input.js:1:1]
1 │ export function foo4() {};
· ──┬─
· ╰── Export has already been declared here
2 │ export const [{ a: [{ foo }], b: { foo2: [{ foo3: foo4 }] } }] = bar;
· ──┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo4` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring11/input.js:1:1]
1 │ export function foo4() {};
@ -3056,6 +3147,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo4'
╭─[es2015/modules/duplicate-named-export-destructuring12/input.js:1:1]
1 │ export function foo4() {};
· ──┬─
· ╰── Export has already been declared here
2 │ export const { a: [{ foo }], b: { foo2: [{ foo3: foo4 }] } } = bar;
· ──┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo4` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring12/input.js:1:1]
1 │ export function foo4() {};
@ -3066,6 +3167,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo4'
╭─[es2015/modules/duplicate-named-export-destructuring13/input.js:1:1]
1 │ export function foo4() {};
· ──┬─
· ╰── Export has already been declared here
2 │ export const { a: [{ foo4: foo }], b, c: { foo2: [{ foo3: foo4 }] } } = bar;
· ──┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo4` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring13/input.js:1:1]
1 │ export function foo4() {};
@ -3076,6 +3187,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring14/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const { foo2: foo } = bar;
· ─┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring14/input.js:1:1]
1 │ export const foo = 1;
@ -3087,6 +3209,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'foo2'
╭─[es2015/modules/duplicate-named-export-destructuring15/input.js:1:1]
1 │ export const { foo: foo2 } = bar;
· ──┬─
· ╰── Export has already been declared here
2 │ export const foo2 = 1;
· ──┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `foo2` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring15/input.js:1:1]
1 │ export const { foo: foo2 } = bar;
@ -3098,6 +3231,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring16/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const [bar, ...foo] = baz;
· ─┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring16/input.js:1:1]
1 │ export const foo = 1;
@ -3109,6 +3253,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'bar'
╭─[es2015/modules/duplicate-named-export-destructuring17/input.js:1:1]
1 │ export const [foo, ...bar] = baz;
· ─┬─
· ╰── Export has already been declared here
2 │ export const bar = 1;
· ─┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `bar` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring17/input.js:1:1]
1 │ export const [foo, ...bar] = baz;
@ -3120,6 +3275,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring18/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const [bar, [baz, ...foo]] = qux;
· ─┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring18/input.js:1:1]
1 │ export const foo = 1;
@ -3131,6 +3297,17 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring19/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const { bar: [baz, ...foo] } = qux;
· ─┬─
· ╰── It cannot be redeclared here
3 │
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring19/input.js:1:1]
1 │ export const foo = 1;
@ -3142,6 +3319,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring2/input.js:1:1]
1 │ export function foo() {};
· ─┬─
· ╰── Export has already been declared here
2 │ export const { foo } = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring2/input.js:1:1]
1 │ export function foo() {};
@ -3152,6 +3339,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring3/input.js:1:1]
1 │ export const { foo } = bar;
· ─┬─
· ╰── Export has already been declared here
2 │ export function foo() {};
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring3/input.js:1:1]
1 │ export const { foo } = bar;
@ -3162,6 +3359,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring4/input.js:1:1]
1 │ export function foo() {};
· ─┬─
· ╰── Export has already been declared here
2 │ export const [foo] = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring4/input.js:1:1]
1 │ export function foo() {};
@ -3172,6 +3379,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring5/input.js:1:1]
1 │ export const [foo] = bar;
· ─┬─
· ╰── Export has already been declared here
2 │ export function foo() {};
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring5/input.js:1:1]
1 │ export const [foo] = bar;
@ -3182,6 +3399,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring6/input.js:1:1]
1 │ export const { foo } = bar;
· ─┬─
· ╰── Export has already been declared here
2 │ export const [foo] = bar2;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring6/input.js:1:1]
1 │ export const { foo } = bar;
@ -3192,6 +3419,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-destructuring7/input.js:1:1]
1 │ export const [foo] = bar;
· ─┬─
· ╰── Export has already been declared here
2 │ export const { foo } = bar2;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring7/input.js:1:1]
1 │ export const [foo] = bar;
@ -3202,6 +3439,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'Foo'
╭─[es2015/modules/duplicate-named-export-destructuring8/input.js:1:1]
1 │ export class Foo {};
· ─┬─
· ╰── Export has already been declared here
2 │ export const { Foo } = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `Foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring8/input.js:1:1]
1 │ export class Foo {};
@ -3212,6 +3459,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'Foo'
╭─[es2015/modules/duplicate-named-export-destructuring9/input.js:1:1]
1 │ export class Foo {};
· ─┬─
· ╰── Export has already been declared here
2 │ export const [Foo] = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `Foo` has already been declared
╭─[es2015/modules/duplicate-named-export-destructuring9/input.js:1:1]
1 │ export class Foo {};
@ -3222,6 +3479,50 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-function-declaration/input.js:1:1]
1 │ export { foo };
· ─┬─
· ╰── Export has already been declared here
2 │ export function foo() {};
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export-variable-declaration/input.js:1:1]
1 │ export { foo };
· ─┬─
· ╰── Export has already been declared here
2 │ export const foo = bar;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Export 'foo' is not defined
╭─[es2015/modules/duplicate-named-export/input.js:1:1]
1 │ export { foo };
· ───
2 │ export { bar as foo };
╰────
× Export 'bar' is not defined
╭─[es2015/modules/duplicate-named-export/input.js:1:1]
1 │ export { foo };
2 │ export { bar as foo };
· ───
╰────
× Duplicated export 'foo'
╭─[es2015/modules/duplicate-named-export/input.js:1:1]
1 │ export { foo };
· ─┬─
· ╰── Export has already been declared here
2 │ export { bar as foo };
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Unexpected token
╭─[es2015/modules/export-default-variable-declaration/input.js:1:1]
1 │ export default const Foo = () => {
@ -3257,6 +3558,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ────────
╰────
× Export 'X' is not defined
╭─[es2015/modules/invalid-escape-export-as/input.js:1:1]
1 │ export { X \u0061s Y }
· ─
╰────
× Keywords cannot contain escape characters
╭─[es2015/modules/invalid-escape-export-as/input.js:1:1]
1 │ export { X \u0061s Y }
@ -5252,6 +5559,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
3 │ }
╰────
× Duplicated export 'foo'
╭─[es2018/object-rest-spread/11/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const { bar, ...foo } = baz;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2018/object-rest-spread/11/input.js:1:1]
1 │ export const foo = 1;
@ -5262,6 +5579,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'bar'
╭─[es2018/object-rest-spread/12/input.js:1:1]
1 │ export const { foo, ...bar } = baz;
· ─┬─
· ╰── Export has already been declared here
2 │ export const bar = 1;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `bar` has already been declared
╭─[es2018/object-rest-spread/12/input.js:1:1]
1 │ export const { foo, ...bar } = baz;
@ -5272,6 +5599,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2018/object-rest-spread/13/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const { bar: { baz, ...foo } } = qux;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2018/object-rest-spread/13/input.js:1:1]
1 │ export const foo = 1;
@ -5282,6 +5619,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2018/object-rest-spread/14/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const [bar, { baz, ...foo }] = qux;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2018/object-rest-spread/14/input.js:1:1]
1 │ export const foo = 1;
@ -5292,6 +5639,16 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'foo'
╭─[es2018/object-rest-spread/15/input.js:1:1]
1 │ export const foo = 1;
· ─┬─
· ╰── Export has already been declared here
2 │ export const [bar, [{ baz, ...foo }]] = qux;
· ─┬─
· ╰── It cannot be redeclared here
╰────
× Identifier `foo` has already been declared
╭─[es2018/object-rest-spread/15/input.js:1:1]
1 │ export const foo = 1;
@ -7283,6 +7640,12 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts"
╰────
help: Try insert a semicolon here
× Export 'default' is not defined
╭─[esprima/es2015-export-declaration/invalid-export-named-default/input.js:1:1]
1 │ export {default}
· ───────
╰────
× for-of loop variable declaration may not have an initializer
╭─[esprima/es2015-for-of/invalid-const-init/input.js:1:1]
1 │ for (const x = 1 of y);

View file

@ -1,14 +1,7 @@
Test262 Summary:
AST Parsed : 44005/44024 (99.96%)
Positive Passed: 44005/44024 (99.96%)
Negative Passed: 3908/3915 (99.82%)
Expect Syntax Error: "language/module-code/early-dup-export-as-star-as.js"
Expect Syntax Error: "language/module-code/early-dup-export-dflt-id.js"
Expect Syntax Error: "language/module-code/early-dup-export-id-as.js"
Expect Syntax Error: "language/module-code/early-dup-export-id.js"
Expect Syntax Error: "language/module-code/early-dup-export-star-as-dflt.js"
Expect Syntax Error: "language/module-code/early-export-global.js"
Expect Syntax Error: "language/module-code/early-export-unresolvable.js"
Negative Passed: 3915/3915 (100.00%)
Expect to Parse: "language/block-scope/syntax/redeclaration-global/allowed-to-redeclare-function-declaration-with-var.js"
× Identifier `f` has already been declared
@ -20473,6 +20466,28 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
25 │ };
╰────
× Duplicated export 'z'
╭─[language/module-code/early-dup-export-as-star-as.js:17:1]
17 │ var x;
18 │ export { x as z };
· ┬
· ╰── Export has already been declared here
19 │ export * as z from './early-dup-export-as-star-as.js';
· ┬
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'f'
╭─[language/module-code/early-dup-export-decl.js:16:1]
16 │
17 │ export function f() {}
· ┬
· ╰── Export has already been declared here
18 │ export function *f() {}
· ┬
· ╰── It cannot be redeclared here
╰────
× Identifier `f` has already been declared
╭─[language/module-code/early-dup-export-decl.js:16:1]
16 │
@ -20484,6 +20499,17 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
· ╰── It can not be redeclared here
╰────
× Duplicated export 'default'
╭─[language/module-code/early-dup-export-dflt-id.js:17:1]
17 │ var x, y;
18 │ export default x;
· ───┬───
· ╰── Export has already been declared here
19 │ export { y as default };
· ───┬───
· ╰── It cannot be redeclared here
╰────
× Unexpected token
╭─[language/module-code/early-dup-export-dflt.js:15:1]
15 │
@ -20492,6 +20518,39 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
17 │ export default var x = null;
╰────
× Duplicated export 'z'
╭─[language/module-code/early-dup-export-id-as.js:17:1]
17 │ var x, y;
18 │ export { x as z };
· ┬
· ╰── Export has already been declared here
19 │ export { y as z };
· ┬
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'x'
╭─[language/module-code/early-dup-export-id.js:16:1]
16 │ var x;
17 │ export { x };
· ┬
· ╰── Export has already been declared here
18 │ export { x };
· ┬
· ╰── It cannot be redeclared here
╰────
× Duplicated export 'default'
╭─[language/module-code/early-dup-export-star-as-dflt.js:17:1]
17 │ var x;
18 │ export default x;
· ───┬───
· ╰── Export has already been declared here
19 │ export * as default from './early-dup-export-start-as-dflt.js';
· ───┬───
· ╰── It cannot be redeclared here
╰────
× Identifier `label` has already been declared
╭─[language/module-code/early-dup-lables.js:15:1]
15 │
@ -20559,6 +20618,25 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
· ╰── It can not be redeclared here
╰────
× Export 'Number' is not defined
╭─[language/module-code/early-export-global.js:18:1]
18 │
19 │ export { Number };
· ──────
╰────
× Duplicated export '\ud83c'
╭─[language/module-code/early-export-ill-formed-string.js:20:1]
20 │ // 🌙 is '\uD83C\uDF19'
21 │ export {Moon as "\uD83C",} from "./early-export-ill-formed-string.js";
· ────┬───
· ╰── Export has already been declared here
22 │ export {"\uD83C"} from "./early-export-ill-formed-string.js";
· ────┬───
· ╰── It cannot be redeclared here
23 │ import {'\uD83C' as Usagi} from "./early-export-ill-formed-string.js";
╰────
× An export name cannot include a unicode lone surrogate
╭─[language/module-code/early-export-ill-formed-string.js:20:1]
20 │ // 🌙 is '\uD83C\uDF19'
@ -20586,6 +20664,13 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
24 │
╰────
× Export 'unresolvable' is not defined
╭─[language/module-code/early-export-unresolvable.js:16:1]
16 │
17 │ export { unresolvable };
· ────────────
╰────
× Cannot assign to 'arguments' in strict mode
╭─[language/module-code/early-import-arguments.js:34:1]
34 │