mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
feat(linter): report export errors in javascript
This commit is contained in:
parent
8d3a5c46ba
commit
164c2831e1
6 changed files with 560 additions and 30 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 │
|
||||
|
|
|
|||
Loading…
Reference in a new issue