diff --git a/crates/oxc_linter/src/rules/early_error/javascript.rs b/crates/oxc_linter/src/rules/early_error/javascript.rs index 4c8bd1cf7..4112856d4 100644 --- a/crates/oxc_linter/src/rules/early_error/javascript.rs +++ b/crates/oxc_linter/src/rules/early_error/javascript.rs @@ -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(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(); diff --git a/crates/oxc_semantic/src/binder.rs b/crates/oxc_semantic/src/binder.rs index d475b4367..0fab93931 100644 --- a/crates/oxc_semantic/src/binder.rs +++ b/crates/oxc_semantic/src/binder.rs @@ -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(), + ); + } + } +} diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index d55f8722e..dd2c82627 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -65,9 +65,12 @@ impl<'a> SemanticBuilder<'a> { #[must_use] pub fn build(mut self, program: &'a Program<'a>, trivias: Rc) -> 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); - } _ => {} } } diff --git a/crates/oxc_semantic/src/module_record/builder.rs b/crates/oxc_semantic/src/module_record/builder.rs index c11d67009..d1ab6d629 100644 --- a/crates/oxc_semantic/src/module_record/builder.rs +++ b/crates/oxc_semantic/src/module_record/builder.rs @@ -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(); diff --git a/tasks/coverage/babel.snap b/tasks/coverage/babel.snap index 0b4dd6842..168ce5a8b 100644 --- a/tasks/coverage/babel.snap +++ b/tasks/coverage/babel.snap @@ -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); diff --git a/tasks/coverage/test262.snap b/tasks/coverage/test262.snap index f407b8e9f..2eb0b20b0 100644 --- a/tasks/coverage/test262.snap +++ b/tasks/coverage/test262.snap @@ -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 │