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 {
|
||||
let s = match self {
|
||||
Self::Identifier(identifier) => identifier.name.to_string(),
|
||||
Self::StringLiteral(literal) => literal.value.to_string(),
|
||||
Self::StringLiteral(literal) => format!(r#""{}""#, literal.value),
|
||||
};
|
||||
write!(f, "{s}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use oxc_diagnostics::{
|
|||
miette::{self, Diagnostic},
|
||||
thiserror::{self, Error},
|
||||
};
|
||||
use oxc_span::{Atom, Span};
|
||||
use oxc_span::Span;
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Flow is not supported")]
|
||||
|
|
@ -215,8 +215,13 @@ pub struct ExportLoneSurrogate(#[label] pub Span);
|
|||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[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'`?"))]
|
||||
pub struct ExportNamedString(pub Atom, pub Atom, #[label] pub Span);
|
||||
#[diagnostic(help("Did you mean `export {{ {0} as {1} }} from 'some-module'`?"))]
|
||||
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)]
|
||||
#[error("Bad escape sequence in untagged template literal")]
|
||||
|
|
|
|||
|
|
@ -239,15 +239,32 @@ impl<'a> Parser<'a> {
|
|||
};
|
||||
|
||||
// ExportDeclaration : export NamedExports ;
|
||||
// * It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
|
||||
if source.is_none() {
|
||||
for specifier in &specifiers {
|
||||
if let ModuleExportName::StringLiteral(literal) = &specifier.local {
|
||||
self.error(diagnostics::ExportNamedString(
|
||||
literal.value.clone(),
|
||||
specifier.local.name().clone(),
|
||||
literal.span,
|
||||
));
|
||||
match &specifier.local {
|
||||
// It is a Syntax Error if ReferencedBindings of NamedExports contains any StringLiterals.
|
||||
ModuleExportName::StringLiteral(literal) => {
|
||||
self.error(diagnostics::ExportNamedString(
|
||||
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
|
||||
╭─[esprima/es2015-export-declaration/invalid-export-default-token/input.js:1:1]
|
||||
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
|
||||
|
||||
× 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
|
||||
╭─[esprima/es2015-export-declaration/invalid-export-named-default/input.js:1:1]
|
||||
1 │ export {default}
|
||||
|
|
|
|||
|
|
@ -19729,7 +19729,7 @@ Negative Passed: 3918/3918 (100.00%)
|
|||
· ─────
|
||||
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
|
||||
╭─[language/module-code/export-expname-unpaired-surrogate.js:20:1]
|
||||
|
|
|
|||
Loading…
Reference in a new issue