Skip to content

Commit

Permalink
feat(ast): serialize identifiers to ESTree (#2521)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudBarre authored Mar 4, 2024
1 parent e2d2ce3 commit f6709e4
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 14 deletions.
28 changes: 16 additions & 12 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ use serde::Serialize;
#[allow(clippy::wildcard_imports)]
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)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type", rename_all = "camelCase"))]
#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))]
Expand Down Expand Up @@ -298,11 +310,9 @@ impl<'a> Expression<'a> {
}

/// Identifier Name
// See serializer in serialize.rs
#[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> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span,
pub name: Atom<'a>,
}
Expand All @@ -314,11 +324,9 @@ impl<'a> IdentifierName<'a> {
}

/// Identifier Reference
// See serializer in serialize.rs
#[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> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span,
pub name: Atom<'a>,
pub reference_id: Cell<Option<ReferenceId>>,
Expand All @@ -339,11 +347,9 @@ impl<'a> IdentifierReference<'a> {
}

/// Binding Identifier
// See serializer in serialize.rs
#[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> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span,
pub name: Atom<'a>,
pub symbol_id: Cell<Option<SymbolId>>,
Expand All @@ -363,11 +369,9 @@ impl<'a> BindingIdentifier<'a> {
}

/// Label Identifier
// See serializer in serialize.rs
#[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> {
#[cfg_attr(feature = "serde", serde(flatten))]
pub span: Span,
pub name: Atom<'a>,
}
Expand Down
62 changes: 60 additions & 2 deletions crates/oxc_ast/src/serialize.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -34,3 +40,55 @@ impl Serialize for RegExpFlags {
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)
}
}

0 comments on commit f6709e4

Please sign in to comment.