mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(parser): add support for empty module declaration (#2834)
Should be merged after #2829, Tried a few times to get it done with graphite stacking but found no success. I guess it either doesn't work with forks or It is just a skill issue since I'm not familiar with it. closes: #2829 closes: #2830 --------- Co-authored-by: Dmytro Maretskyi <maretskii@gmail.com>
This commit is contained in:
parent
f6391f9b43
commit
b76b02d019
8 changed files with 38 additions and 20 deletions
|
|
@ -697,7 +697,7 @@ pub struct TSModuleDeclaration<'a> {
|
||||||
#[cfg_attr(feature = "serialize", serde(flatten))]
|
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub id: TSModuleDeclarationName<'a>,
|
pub id: TSModuleDeclarationName<'a>,
|
||||||
pub body: TSModuleDeclarationBody<'a>,
|
pub body: Option<TSModuleDeclarationBody<'a>>,
|
||||||
/// The keyword used to define this module declaration
|
/// The keyword used to define this module declaration
|
||||||
/// ```text
|
/// ```text
|
||||||
/// namespace Foo {}
|
/// namespace Foo {}
|
||||||
|
|
|
||||||
|
|
@ -1273,7 +1273,7 @@ impl<'a> AstBuilder<'a> {
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
id: TSModuleDeclarationName<'a>,
|
id: TSModuleDeclarationName<'a>,
|
||||||
body: TSModuleDeclarationBody<'a>,
|
body: Option<TSModuleDeclarationBody<'a>>,
|
||||||
kind: TSModuleDeclarationKind,
|
kind: TSModuleDeclarationKind,
|
||||||
modifiers: Modifiers<'a>,
|
modifiers: Modifiers<'a>,
|
||||||
) -> Box<'a, TSModuleDeclaration<'a>> {
|
) -> Box<'a, TSModuleDeclaration<'a>> {
|
||||||
|
|
|
||||||
|
|
@ -2493,10 +2493,13 @@ pub mod walk {
|
||||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||||
}
|
}
|
||||||
match &decl.body {
|
match &decl.body {
|
||||||
TSModuleDeclarationBody::TSModuleDeclaration(decl) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||||
visitor.visit_ts_module_declaration(decl);
|
visitor.visit_ts_module_declaration(decl);
|
||||||
}
|
}
|
||||||
TSModuleDeclarationBody::TSModuleBlock(block) => visitor.visit_ts_module_block(block),
|
Some(TSModuleDeclarationBody::TSModuleBlock(block)) => {
|
||||||
|
visitor.visit_ts_module_block(block);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
visitor.leave_node(kind);
|
visitor.leave_node(kind);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2694,10 +2694,13 @@ pub mod walk_mut {
|
||||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||||
}
|
}
|
||||||
match &mut decl.body {
|
match &mut decl.body {
|
||||||
TSModuleDeclarationBody::TSModuleDeclaration(decl) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||||
visitor.visit_ts_module_declaration(decl);
|
visitor.visit_ts_module_declaration(decl);
|
||||||
}
|
}
|
||||||
TSModuleDeclarationBody::TSModuleBlock(block) => visitor.visit_ts_module_block(block),
|
Some(TSModuleDeclarationBody::TSModuleBlock(block)) => {
|
||||||
|
visitor.visit_ts_module_block(block);
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
visitor.leave_node(kind);
|
visitor.leave_node(kind);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -539,12 +539,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSModuleDeclaration<'a> {
|
||||||
p.wrap_quote(name, |p, _| p.print_str(name.as_bytes()));
|
p.wrap_quote(name, |p, _| p.print_str(name.as_bytes()));
|
||||||
p.print_hard_space();
|
p.print_hard_space();
|
||||||
match &self.body {
|
match &self.body {
|
||||||
TSModuleDeclarationBody::TSModuleDeclaration(body) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(body)) => {
|
||||||
p.print_block_start(body.span.start);
|
p.print_block_start(body.span.start);
|
||||||
body.gen(p, ctx);
|
body.gen(p, ctx);
|
||||||
p.print_block_end(body.span.end);
|
p.print_block_end(body.span.end);
|
||||||
}
|
}
|
||||||
TSModuleDeclarationBody::TSModuleBlock(body) => {
|
Some(TSModuleDeclarationBody::TSModuleBlock(body)) => {
|
||||||
p.print_block_start(body.span.start);
|
p.print_block_start(body.span.start);
|
||||||
for item in &body.body {
|
for item in &body.body {
|
||||||
p.print_semicolon_if_needed();
|
p.print_semicolon_if_needed();
|
||||||
|
|
@ -553,6 +553,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSModuleDeclaration<'a> {
|
||||||
p.print_semicolon_if_needed();
|
p.print_semicolon_if_needed();
|
||||||
p.print_block_end(body.span.end);
|
p.print_block_end(body.span.end);
|
||||||
}
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
if MINIFY {
|
if MINIFY {
|
||||||
p.print_semicolon();
|
p.print_semicolon();
|
||||||
|
|
|
||||||
|
|
@ -406,8 +406,8 @@ impl<'a> ParserImpl<'a> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use oxc_ast::CommentKind;
|
use oxc_ast::CommentKind;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
@ -436,6 +436,15 @@ mod test {
|
||||||
assert_eq!(ret.errors.first().unwrap().to_string(), "Flow is not supported");
|
assert_eq!(ret.errors.first().unwrap().to_string(), "Flow is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ts_module_declaration() {
|
||||||
|
let allocator = Allocator::default();
|
||||||
|
let source_type = SourceType::from_path(Path::new("module.ts")).unwrap();
|
||||||
|
let source = "declare module 'test'\n";
|
||||||
|
let ret = Parser::new(&allocator, source, source_type).parse();
|
||||||
|
assert_eq!(ret.errors.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn directives() {
|
fn directives() {
|
||||||
let allocator = Allocator::default();
|
let allocator = Allocator::default();
|
||||||
|
|
|
||||||
|
|
@ -212,14 +212,12 @@ impl<'a> ParserImpl<'a> {
|
||||||
|
|
||||||
let mut statements = self.ast.new_vec();
|
let mut statements = self.ast.new_vec();
|
||||||
|
|
||||||
if self.at(Kind::LCurly) {
|
|
||||||
self.expect(Kind::LCurly)?;
|
self.expect(Kind::LCurly)?;
|
||||||
|
|
||||||
while !self.eat(Kind::RCurly) && !self.at(Kind::Eof) {
|
while !self.eat(Kind::RCurly) && !self.at(Kind::Eof) {
|
||||||
let stmt = self.parse_ts_module_item()?;
|
let stmt = self.parse_ts_module_item()?;
|
||||||
statements.push(stmt);
|
statements.push(stmt);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Ok(self.ast.ts_module_block(self.end_span(span), statements))
|
Ok(self.ast.ts_module_block(self.end_span(span), statements))
|
||||||
}
|
}
|
||||||
|
|
@ -243,11 +241,14 @@ impl<'a> ParserImpl<'a> {
|
||||||
let span = self.start_span();
|
let span = self.start_span();
|
||||||
let decl =
|
let decl =
|
||||||
self.parse_ts_namespace_or_module_declaration_body(span, kind, Modifiers::empty())?;
|
self.parse_ts_namespace_or_module_declaration_body(span, kind, Modifiers::empty())?;
|
||||||
TSModuleDeclarationBody::TSModuleDeclaration(decl)
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl))
|
||||||
} else {
|
} else if self.at(Kind::LCurly) {
|
||||||
let block = self.parse_ts_module_block()?;
|
let block = self.parse_ts_module_block()?;
|
||||||
self.asi()?;
|
self.asi()?;
|
||||||
TSModuleDeclarationBody::TSModuleBlock(block)
|
Some(TSModuleDeclarationBody::TSModuleBlock(block))
|
||||||
|
} else {
|
||||||
|
self.asi()?;
|
||||||
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(self.ast.ts_module_declaration(self.end_span(span), id, body, kind, modifiers))
|
Ok(self.ast.ts_module_declaration(self.end_span(span), id, body, kind, modifiers))
|
||||||
|
|
|
||||||
|
|
@ -661,13 +661,14 @@ impl<'a> TypeScript<'a> {
|
||||||
block: &mut Box<'a, TSModuleDeclaration<'a>>,
|
block: &mut Box<'a, TSModuleDeclaration<'a>>,
|
||||||
) -> Statement<'a> {
|
) -> Statement<'a> {
|
||||||
let body_statements = match &mut block.body {
|
let body_statements = match &mut block.body {
|
||||||
TSModuleDeclarationBody::TSModuleDeclaration(decl) => {
|
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||||
let transformed_module_block = self.transform_ts_module_block(decl);
|
let transformed_module_block = self.transform_ts_module_block(decl);
|
||||||
self.ctx.ast.new_vec_single(transformed_module_block)
|
self.ctx.ast.new_vec_single(transformed_module_block)
|
||||||
}
|
}
|
||||||
TSModuleDeclarationBody::TSModuleBlock(ts_module_block) => {
|
Some(TSModuleDeclarationBody::TSModuleBlock(ts_module_block)) => {
|
||||||
self.ctx.ast.move_statement_vec(&mut ts_module_block.body)
|
self.ctx.ast.move_statement_vec(&mut ts_module_block.body)
|
||||||
}
|
}
|
||||||
|
None => self.ctx.ast.new_vec(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = block.id.name();
|
let name = block.id.name();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue