mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(ast)!: always return Array<ImportDeclarationSpecifier> for ImportDeclaration.specifiers (#8560)
refs https://github.com/oxc-project/oxc/issues/2854#issuecomment-2595115817
This commit is contained in:
parent
869bc73e67
commit
19d36771af
6 changed files with 34 additions and 3 deletions
|
|
@ -2196,6 +2196,7 @@ pub struct ImportExpression<'a> {
|
||||||
pub struct ImportDeclaration<'a> {
|
pub struct ImportDeclaration<'a> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
/// `None` for `import 'foo'`, `Some([])` for `import {} from 'foo'`
|
/// `None` for `import 'foo'`, `Some([])` for `import {} from 'foo'`
|
||||||
|
#[estree(with = "OptionVecDefault", type = "Array<ImportDeclarationSpecifier>")]
|
||||||
pub specifiers: Option<Vec<'a, ImportDeclarationSpecifier<'a>>>,
|
pub specifiers: Option<Vec<'a, ImportDeclarationSpecifier<'a>>>,
|
||||||
pub source: StringLiteral<'a>,
|
pub source: StringLiteral<'a>,
|
||||||
pub phase: Option<ImportPhase>,
|
pub phase: Option<ImportPhase>,
|
||||||
|
|
|
||||||
|
|
@ -1696,7 +1696,7 @@ impl Serialize for ImportDeclaration<'_> {
|
||||||
let mut map = serializer.serialize_map(None)?;
|
let mut map = serializer.serialize_map(None)?;
|
||||||
map.serialize_entry("type", "ImportDeclaration")?;
|
map.serialize_entry("type", "ImportDeclaration")?;
|
||||||
self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?;
|
self.span.serialize(serde::__private::ser::FlatMapSerializer(&mut map))?;
|
||||||
map.serialize_entry("specifiers", &self.specifiers)?;
|
map.serialize_entry("specifiers", &crate::serialize::OptionVecDefault(&self.specifiers))?;
|
||||||
map.serialize_entry("source", &self.source)?;
|
map.serialize_entry("source", &self.source)?;
|
||||||
map.serialize_entry("phase", &self.phase)?;
|
map.serialize_entry("phase", &self.phase)?;
|
||||||
map.serialize_entry("withClause", &self.with_clause)?;
|
map.serialize_entry("withClause", &self.with_clause)?;
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,18 @@ impl<E: Serialize, R: Serialize> Serialize for ElementsAndRest<'_, E, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct OptionVecDefault<'a, 'b, T: Serialize>(pub &'a Option<oxc_allocator::Vec<'b, T>>);
|
||||||
|
|
||||||
|
impl<T: Serialize> Serialize for OptionVecDefault<'_, '_, T> {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||||
|
if let Some(vec) = &self.0 {
|
||||||
|
vec.serialize(serializer)
|
||||||
|
} else {
|
||||||
|
[false; 0].serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Serialize `TSModuleBlock` to be ESTree compatible, with `body` and `directives` fields combined,
|
/// Serialize `TSModuleBlock` to be ESTree compatible, with `body` and `directives` fields combined,
|
||||||
/// and directives output as `StringLiteral` expression statements
|
/// and directives output as `StringLiteral` expression statements
|
||||||
impl Serialize for TSModuleBlock<'_> {
|
impl Serialize for TSModuleBlock<'_> {
|
||||||
|
|
|
||||||
2
npm/oxc-types/types.d.ts
vendored
2
npm/oxc-types/types.d.ts
vendored
|
|
@ -911,7 +911,7 @@ export interface ImportExpression extends Span {
|
||||||
|
|
||||||
export interface ImportDeclaration extends Span {
|
export interface ImportDeclaration extends Span {
|
||||||
type: 'ImportDeclaration';
|
type: 'ImportDeclaration';
|
||||||
specifiers: Array<ImportDeclarationSpecifier> | null;
|
specifiers: Array<ImportDeclarationSpecifier>;
|
||||||
source: StringLiteral;
|
source: StringLiteral;
|
||||||
phase: ImportPhase | null;
|
phase: ImportPhase | null;
|
||||||
withClause: WithClause | null;
|
withClause: WithClause | null;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
serialize::{enum_variant_name, get_always_flatten_structs, get_type_tag},
|
serialize::{enum_variant_name, get_always_flatten_structs, get_type_tag},
|
||||||
EnumDef, FieldDef, GetGenerics, GetIdent, Schema, StructDef, TypeDef,
|
EnumDef, FieldDef, GetGenerics, GetIdent, Schema, StructDef, TypeDef,
|
||||||
},
|
},
|
||||||
|
util::ToIdent,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{define_derive, Derive};
|
use super::{define_derive, Derive};
|
||||||
|
|
@ -141,6 +142,14 @@ fn serialize_struct(def: &StructDef, schema: &Schema) -> TokenStream {
|
||||||
}
|
}
|
||||||
)?;
|
)?;
|
||||||
});
|
});
|
||||||
|
} else if let Some(with) = &field.markers.derive_attributes.estree.with {
|
||||||
|
let with_ident = with.to_ident();
|
||||||
|
fields.push(quote! {
|
||||||
|
map.serialize_entry(
|
||||||
|
#name,
|
||||||
|
&crate::serialize::#with_ident(&self.#ident)
|
||||||
|
)?;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
fields.push(quote! {
|
fields.push(quote! {
|
||||||
map.serialize_entry(#name, &self.#ident)?;
|
map.serialize_entry(#name, &self.#ident)?;
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ pub struct ESTreeFieldAttribute {
|
||||||
pub rename: Option<String>,
|
pub rename: Option<String>,
|
||||||
pub typescript_type: Option<String>,
|
pub typescript_type: Option<String>,
|
||||||
pub append_to: Option<String>,
|
pub append_to: Option<String>,
|
||||||
|
pub with: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for ESTreeFieldAttribute {
|
impl Parse for ESTreeFieldAttribute {
|
||||||
|
|
@ -236,6 +237,7 @@ impl Parse for ESTreeFieldAttribute {
|
||||||
let mut rename = None;
|
let mut rename = None;
|
||||||
let mut typescript_type = None;
|
let mut typescript_type = None;
|
||||||
let mut append_to = None;
|
let mut append_to = None;
|
||||||
|
let mut with = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let is_type = input.peek(Token![type]);
|
let is_type = input.peek(Token![type]);
|
||||||
|
|
@ -281,6 +283,13 @@ impl Parse for ESTreeFieldAttribute {
|
||||||
"Duplicate estree(append_to)"
|
"Duplicate estree(append_to)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"with" => {
|
||||||
|
input.parse::<Token![=]>()?;
|
||||||
|
assert!(
|
||||||
|
with.replace(input.parse::<LitStr>()?.value()).is_none(),
|
||||||
|
"Duplicate estree(with)"
|
||||||
|
);
|
||||||
|
}
|
||||||
arg => panic!("Unsupported #[estree(...)] argument: {arg}"),
|
arg => panic!("Unsupported #[estree(...)] argument: {arg}"),
|
||||||
}
|
}
|
||||||
let comma = input.peek(Token![,]);
|
let comma = input.peek(Token![,]);
|
||||||
|
|
@ -290,7 +299,7 @@ impl Parse for ESTreeFieldAttribute {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Self { flatten, skip, rename, typescript_type, append_to })
|
Ok(Self { flatten, skip, rename, typescript_type, append_to, with })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue