feat(ast): serialize identifiers to ESTree (#2521)

This commit is contained in:
Arnaud Barré 2024-03-04 15:53:33 +01:00 committed by GitHub
parent e2d2ce3369
commit f6709e4737
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 76 additions and 14 deletions

View file

@ -15,6 +15,18 @@ use serde::Serialize;
#[allow(clippy::wildcard_imports)] #[allow(clippy::wildcard_imports)]
use crate::ast::*; use crate::ast::*;
#[cfg_attr(
all(feature = "serde", feature = "wasm"),
wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)
)]
#[allow(dead_code)]
const TS_APPEND_CONTENT: &'static str = r#"
export interface BindingIdentifier extends Span { type: "Identifier", name: Atom }
export interface IdentifierReference extends Span { type: "Identifier", name: Atom }
export interface IdentifierName extends Span { type: "Identifier", name: Atom }
export interface LabelIdentifier extends Span { type: "Identifier", name: Atom }
"#;
#[derive(Debug, Hash)] #[derive(Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))] #[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
@ -298,11 +310,9 @@ impl<'a> Expression<'a> {
} }
/// Identifier Name /// Identifier Name
// See serializer in serialize.rs
#[derive(Debug, Clone, Hash)] #[derive(Debug, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
pub struct IdentifierName<'a> { pub struct IdentifierName<'a> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span, pub span: Span,
pub name: Atom<'a>, pub name: Atom<'a>,
} }
@ -314,11 +324,9 @@ impl<'a> IdentifierName<'a> {
} }
/// Identifier Reference /// Identifier Reference
// See serializer in serialize.rs
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
pub struct IdentifierReference<'a> { pub struct IdentifierReference<'a> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span, pub span: Span,
pub name: Atom<'a>, pub name: Atom<'a>,
pub reference_id: Cell<Option<ReferenceId>>, pub reference_id: Cell<Option<ReferenceId>>,
@ -339,11 +347,9 @@ impl<'a> IdentifierReference<'a> {
} }
/// Binding Identifier /// Binding Identifier
// See serializer in serialize.rs
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
pub struct BindingIdentifier<'a> { pub struct BindingIdentifier<'a> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span, pub span: Span,
pub name: Atom<'a>, pub name: Atom<'a>,
pub symbol_id: Cell<Option<SymbolId>>, pub symbol_id: Cell<Option<SymbolId>>,
@ -363,11 +369,9 @@ impl<'a> BindingIdentifier<'a> {
} }
/// Label Identifier /// Label Identifier
// See serializer in serialize.rs
#[derive(Debug, Clone, Hash)] #[derive(Debug, Clone, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
pub struct LabelIdentifier<'a> { pub struct LabelIdentifier<'a> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span, pub span: Span,
pub name: Atom<'a>, pub name: Atom<'a>,
} }

View file

@ -1,6 +1,12 @@
use serde::{ser::Serializer, Serialize}; use serde::{
ser::{SerializeStruct, Serializer},
Serialize,
};
use crate::ast::{Program, RegExpFlags}; use crate::ast::{
BindingIdentifier, IdentifierName, IdentifierReference, LabelIdentifier, Program, RegExpFlags,
};
use oxc_span::{Atom, Span};
pub struct EcmaFormatter; pub struct EcmaFormatter;
@ -34,3 +40,55 @@ impl Serialize for RegExpFlags {
serializer.serialize_str(&self.to_string()) serializer.serialize_str(&self.to_string())
} }
} }
/// Serialize `BindingIdentifier`, `IdentifierReference`, `IdentifierName` and `LabelIdentifier`
/// to be estree compatible with the `type` set to "Identifier".
fn serialize_identifier<S: Serializer>(
serializer: S,
struct_name: &'static str,
span: Span,
name: &Atom,
) -> Result<S::Ok, S::Error> {
let mut state = serializer.serialize_struct(struct_name, 4)?;
state.serialize_field("type", "Identifier")?;
state.serialize_field("start", &span.start)?;
state.serialize_field("end", &span.end)?;
state.serialize_field("name", name)?;
state.end()
}
impl<'a> Serialize for BindingIdentifier<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_identifier(serializer, "BindingIdentifier", self.span, &self.name)
}
}
impl<'a> Serialize for IdentifierReference<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_identifier(serializer, "IdentifierReference", self.span, &self.name)
}
}
impl<'a> Serialize for IdentifierName<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_identifier(serializer, "IdentifierName", self.span, &self.name)
}
}
impl<'a> Serialize for LabelIdentifier<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_identifier(serializer, "LabelIdentifier", self.span, &self.name)
}
}