mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(parser): Disallow ReservedWord in NamedExports (#1230)
- fix: #1222 --------- Co-authored-by: Boshen <boshenc@gmail.com>
This commit is contained in:
parent
f775488102
commit
9c0aafcd1c
5 changed files with 48 additions and 12 deletions
|
|
@ -2063,7 +2063,7 @@ impl fmt::Display for ModuleExportName {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let s = match self {
|
let s = match self {
|
||||||
Self::Identifier(identifier) => identifier.name.to_string(),
|
Self::Identifier(identifier) => identifier.name.to_string(),
|
||||||
Self::StringLiteral(literal) => literal.value.to_string(),
|
Self::StringLiteral(literal) => format!(r#""{}""#, literal.value),
|
||||||
};
|
};
|
||||||
write!(f, "{s}")
|
write!(f, "{s}")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use oxc_diagnostics::{
|
||||||
miette::{self, Diagnostic},
|
miette::{self, Diagnostic},
|
||||||
thiserror::{self, Error},
|
thiserror::{self, Error},
|
||||||
};
|
};
|
||||||
use oxc_span::{Atom, Span};
|
use oxc_span::Span;
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
#[error("Flow is not supported")]
|
#[error("Flow is not supported")]
|
||||||
|
|
@ -215,8 +215,13 @@ pub struct ExportLoneSurrogate(#[label] pub Span);
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
#[error("A string literal cannot be used as an exported binding without `from`")]
|
#[error("A string literal cannot be used as an exported binding without `from`")]
|
||||||
#[diagnostic(help("Did you mean `export {{ '{0}' as '{1}' }} from 'some-module'`?"))]
|
#[diagnostic(help("Did you mean `export {{ {0} as {1} }} from 'some-module'`?"))]
|
||||||
pub struct ExportNamedString(pub Atom, pub Atom, #[label] pub Span);
|
pub struct ExportNamedString(pub String, pub String, #[label] pub Span);
|
||||||
|
|
||||||
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
|
#[error("A reserved word cannot be used as an exported binding without `from`")]
|
||||||
|
#[diagnostic(help("Did you mean `export {{ {0} as {1} }} from 'some-module'`?"))]
|
||||||
|
pub struct ExportReservedWord(pub String, pub String, #[label] pub Span);
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
#[error("Bad escape sequence in untagged template literal")]
|
#[error("Bad escape sequence in untagged template literal")]
|
||||||
|
|
|
||||||
|
|
@ -239,15 +239,32 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ExportDeclaration : export NamedExports ;
|
// ExportDeclaration : export NamedExports ;
|
||||||
// * It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
|
|
||||||
if source.is_none() {
|
if source.is_none() {
|
||||||
for specifier in &specifiers {
|
for specifier in &specifiers {
|
||||||
if let ModuleExportName::StringLiteral(literal) = &specifier.local {
|
match &specifier.local {
|
||||||
self.error(diagnostics::ExportNamedString(
|
// It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
|
||||||
literal.value.clone(),
|
ModuleExportName::StringLiteral(literal) => {
|
||||||
specifier.local.name().clone(),
|
self.error(diagnostics::ExportNamedString(
|
||||||
literal.span,
|
specifier.local.to_string(),
|
||||||
));
|
specifier.exported.to_string(),
|
||||||
|
literal.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
// For each IdentifierName n in ReferencedBindings of NamedExports:
|
||||||
|
// It is a Syntax Error if StringValue of n is a ReservedWord or the StringValue of n
|
||||||
|
// is one of "implements", "interface", "let", "package", "private", "protected", "public", or "static".
|
||||||
|
ModuleExportName::Identifier(id) => {
|
||||||
|
let match_result = Kind::match_keyword(&id.name);
|
||||||
|
if match_result.is_reserved_keyword()
|
||||||
|
|| match_result.is_future_reserved_keyword()
|
||||||
|
{
|
||||||
|
self.error(diagnostics::ExportReservedWord(
|
||||||
|
specifier.local.to_string(),
|
||||||
|
specifier.exported.to_string(),
|
||||||
|
id.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6947,6 +6947,13 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts"
|
||||||
· ─
|
· ─
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× A reserved word cannot be used as an exported binding without `from`
|
||||||
|
╭─[esprima/es2015-export-declaration/invalid-export-default-token/input.js:1:1]
|
||||||
|
1 │ export {default} +
|
||||||
|
· ───────
|
||||||
|
╰────
|
||||||
|
help: Did you mean `export { default as default } from 'some-module'`?
|
||||||
|
|
||||||
× Expected a semicolon or an implicit semicolon after a statement, but found none
|
× Expected a semicolon or an implicit semicolon after a statement, but found none
|
||||||
╭─[esprima/es2015-export-declaration/invalid-export-default-token/input.js:1:1]
|
╭─[esprima/es2015-export-declaration/invalid-export-default-token/input.js:1:1]
|
||||||
1 │ export {default} +
|
1 │ export {default} +
|
||||||
|
|
@ -6954,6 +6961,13 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts"
|
||||||
╰────
|
╰────
|
||||||
help: Try insert a semicolon here
|
help: Try insert a semicolon here
|
||||||
|
|
||||||
|
× A reserved word cannot be used as an exported binding without `from`
|
||||||
|
╭─[esprima/es2015-export-declaration/invalid-export-named-default/input.js:1:1]
|
||||||
|
1 │ export {default}
|
||||||
|
· ───────
|
||||||
|
╰────
|
||||||
|
help: Did you mean `export { default as default } from 'some-module'`?
|
||||||
|
|
||||||
× Export 'default' is not defined
|
× Export 'default' is not defined
|
||||||
╭─[esprima/es2015-export-declaration/invalid-export-named-default/input.js:1:1]
|
╭─[esprima/es2015-export-declaration/invalid-export-named-default/input.js:1:1]
|
||||||
1 │ export {default}
|
1 │ export {default}
|
||||||
|
|
|
||||||
|
|
@ -19729,7 +19729,7 @@ Negative Passed: 3918/3918 (100.00%)
|
||||||
· ─────
|
· ─────
|
||||||
22 │
|
22 │
|
||||||
╰────
|
╰────
|
||||||
help: Did you mean `export { 'foo' as 'foo' } from 'some-module'`?
|
help: Did you mean `export { "foo" as "bar" } from 'some-module'`?
|
||||||
|
|
||||||
× An export name cannot include a unicode lone surrogate
|
× An export name cannot include a unicode lone surrogate
|
||||||
╭─[language/module-code/export-expname-unpaired-surrogate.js:20:1]
|
╭─[language/module-code/export-expname-unpaired-surrogate.js:20:1]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue