0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-21 21:03:16 -05:00
denoland-deno/cli/tools/lint/ast.rs

3076 lines
81 KiB
Rust
Raw Normal View History

2024-12-04 16:21:17 +01:00
use deno_ast::{
swc::{
ast::{
2024-12-12 01:35:57 +01:00
AssignTarget, AssignTargetPat, BlockStmtOrExpr, Callee, ClassMember,
Decl, ExportSpecifier, Expr, ExprOrSpread, FnExpr, ForHead, Function,
Ident, IdentName, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement,
2024-12-11 17:41:33 +01:00
JSXElementChild, JSXElementName, JSXEmptyExpr, JSXExpr, JSXExprContainer,
JSXFragment, JSXMemberExpr, JSXNamespacedName, JSXObject,
2024-12-12 15:20:36 +01:00
JSXOpeningElement, Lit, MemberExpr, MemberProp, ModuleDecl,
ModuleExportName, ModuleItem, ObjectPatProp, OptChainBase, Param,
ParamOrTsParamProp, Pat, PrivateName, Program, Prop, PropName,
PropOrSpread, SimpleAssignTarget, Stmt, SuperProp, Tpl, TsEntityName,
TsEnumMemberId, TsFnOrConstructorType, TsFnParam, TsLit, TsType,
TsTypeAnn, TsTypeElement, TsTypeParam, TsTypeParamDecl, TsTypeQueryExpr,
TsUnionOrIntersectionType, VarDeclOrExpr,
2024-12-04 16:21:17 +01:00
},
2024-12-10 21:17:02 +01:00
common::{Span, Spanned, SyntaxContext, DUMMY_SP},
2024-12-04 16:21:17 +01:00
},
2024-12-12 13:28:35 +01:00
view::{
Accessibility, AssignOp, BinaryOp, TruePlusMinus, TsKeywordTypeKind,
UnaryOp, UpdateOp, VarDeclKind,
},
2024-12-04 16:21:17 +01:00
ParsedSource,
};
2024-12-05 11:21:34 +01:00
use indexmap::IndexMap;
2024-12-04 16:21:17 +01:00
2024-12-05 01:18:08 +01:00
// Keep in sync with JS
2024-12-04 16:21:17 +01:00
enum AstNode {
Invalid,
//
Program,
// Module declarations
Import,
ImportDecl,
ExportDecl,
2024-12-10 22:48:54 +01:00
ExportNamedDeclaration,
2024-12-04 16:21:17 +01:00
ExportDefaultDecl,
ExportDefaultExpr,
ExportAll,
TsImportEquals,
TsExportAssignment,
TsNamespaceExport,
// Decls
2024-12-12 01:35:57 +01:00
ClassDeclaration,
2024-12-04 16:21:17 +01:00
Fn,
Var,
Using,
2024-12-12 13:28:35 +01:00
TSInterface,
2024-12-04 16:21:17 +01:00
TsTypeAlias,
2024-12-12 13:28:35 +01:00
TSEnumDeclaration,
2024-12-04 16:21:17 +01:00
TsModule,
// Statements
Block,
Empty,
Debugger,
With,
Return,
Labeled,
Break,
Continue,
2024-12-12 04:19:11 +01:00
IfStatement,
2024-12-04 16:21:17 +01:00
Switch,
SwitchCase,
Throw,
2024-12-11 17:10:05 +01:00
TryStatement,
2024-12-04 16:21:17 +01:00
While,
2024-12-12 01:35:57 +01:00
DoWhileStatement,
2024-12-12 04:19:11 +01:00
ForStatement,
2024-12-11 17:10:05 +01:00
ForInStatement,
2024-12-12 04:19:11 +01:00
ForOfStatement,
2024-12-04 16:21:17 +01:00
Decl,
Expr,
// Expressions
This,
Array,
Object,
2024-12-12 01:35:57 +01:00
FunctionExpression,
2024-12-04 16:21:17 +01:00
Unary,
2024-12-11 17:41:33 +01:00
UpdateExpression,
2024-12-11 17:10:05 +01:00
BinaryExpression,
2024-12-04 16:21:17 +01:00
Assign,
2024-12-11 11:02:21 +01:00
MemberExpression,
Super,
2024-12-04 16:21:17 +01:00
Cond,
2024-12-12 15:20:36 +01:00
CallExpression,
2024-12-04 16:21:17 +01:00
New,
2024-12-10 04:33:33 +01:00
Paren,
2024-12-04 16:21:17 +01:00
Seq,
2024-12-11 11:02:21 +01:00
Identifier,
2024-12-10 22:48:54 +01:00
TemplateLiteral,
2024-12-12 20:53:08 +01:00
TaggedTemplateExpression,
2024-12-11 17:10:05 +01:00
ArrowFunctionExpression,
2024-12-04 16:21:17 +01:00
ClassExpr,
2024-12-11 17:47:46 +01:00
YieldExpression,
2024-12-04 16:21:17 +01:00
MetaProp,
2024-12-11 17:10:05 +01:00
AwaitExpression,
2024-12-10 04:33:33 +01:00
LogicalExpression,
2024-12-12 13:28:35 +01:00
TSTypeAssertion,
2024-12-04 16:21:17 +01:00
TsConstAssertion,
2024-12-12 13:28:35 +01:00
TSNonNullExpression,
TSAsExpression,
2024-12-04 16:21:17 +01:00
TsInstantiation,
TsSatisfies,
2024-12-10 04:33:33 +01:00
PrivateIdentifier,
2024-12-12 15:20:36 +01:00
ChainExpression,
2024-12-04 16:21:17 +01:00
// Literals
StringLiteral,
Bool,
Null,
2024-12-10 22:48:54 +01:00
NumericLiteral,
BigIntLiteral,
RegExpLiteral,
2024-12-04 16:21:17 +01:00
// Custom
EmptyExpr,
Spread,
2024-12-10 04:33:33 +01:00
Property,
2024-12-10 21:17:02 +01:00
VariableDeclarator,
2024-12-05 02:24:26 +01:00
CatchClause,
2024-12-10 21:17:02 +01:00
RestElement,
2024-12-10 22:48:54 +01:00
ExportSpecifier,
TemplateElement,
2024-12-12 01:35:57 +01:00
MethodDefinition,
2024-12-10 04:33:33 +01:00
// Patterns
ArrayPattern,
AssignmentPattern,
ObjectPattern,
2024-12-11 12:47:45 +01:00
// JSX
JSXAttribute,
JSXClosingElement,
JSXClosingFragment,
JSXElement,
JSXEmptyExpression,
JSXExpressionContainer,
JSXFragment,
JSXIdentifier,
JSXMemberExpression,
JSXNamespacedName,
JSXOpeningElement,
JSXOpeningFragment,
JSXSpreadAttribute,
JSXSpreadChild,
JSXText,
2024-12-12 13:28:35 +01:00
TSTypeAnnotation,
TSTypeParameterDeclaration,
TSTypeParameter,
TSEnumMember,
TSInterfaceBody,
TSInterfaceHeritage,
TSTypeReference,
TSThisType,
TSLiteralType,
TSInferType,
TSConditionalType,
TSUnionType,
TSIntersectionType,
TSMappedType,
2024-12-12 15:20:36 +01:00
TSTypeQuery,
TSTupleType,
TSFunctionType,
TsCallSignatureDeclaration,
2024-12-12 13:28:35 +01:00
TSAnyKeyword,
TSBigIntKeyword,
TSBooleanKeyword,
TSIntrinsicKeyword,
TSNeverKeyword,
TSNullKeyword,
TSNumberKeyword,
TSObjectKeyword,
TSStringKeyword,
TSSymbolKeyword,
TSUndefinedKeyword,
TSUnknownKeyword,
TSVoidKeyword,
2024-12-04 16:21:17 +01:00
}
impl From<AstNode> for u8 {
fn from(m: AstNode) -> u8 {
m as u8
}
}
2024-12-10 04:33:33 +01:00
const MASK_U32_1: u32 = 0b11111111_00000000_00000000_00000000;
const MASK_U32_2: u32 = 0b00000000_11111111_00000000_00000000;
const MASK_U32_3: u32 = 0b00000000_00000000_11111111_00000000;
const MASK_U32_4: u32 = 0b00000000_00000000_00000000_11111111;
fn append_u32(result: &mut Vec<u8>, value: u32) {
let v1: u8 = ((value & MASK_U32_1) >> 24) as u8;
let v2: u8 = ((value & MASK_U32_2) >> 16) as u8;
let v3: u8 = ((value & MASK_U32_3) >> 8) as u8;
let v4: u8 = (value & MASK_U32_4) as u8;
result.push(v1);
result.push(v2);
result.push(v3);
result.push(v4);
}
fn append_usize(result: &mut Vec<u8>, value: usize) {
let raw = u32::try_from(value).unwrap();
append_u32(result, raw);
}
2024-12-12 10:53:12 +01:00
fn write_usize(result: &mut [u8], value: usize, idx: usize) {
2024-12-10 04:33:33 +01:00
let raw = u32::try_from(value).unwrap();
let v1: u8 = ((raw & MASK_U32_1) >> 24) as u8;
let v2: u8 = ((raw & MASK_U32_2) >> 16) as u8;
let v3: u8 = ((raw & MASK_U32_3) >> 8) as u8;
let v4: u8 = (raw & MASK_U32_4) as u8;
result[idx] = v1;
result[idx + 1] = v2;
result[idx + 2] = v3;
result[idx + 3] = v4;
}
enum Flag {
2024-12-05 11:21:34 +01:00
ProgramModule,
2024-12-10 04:33:33 +01:00
FnAsync,
FnGenerator,
2024-12-10 21:17:02 +01:00
FnDeclare,
2024-12-12 15:20:36 +01:00
FnOptional,
2024-12-10 04:33:33 +01:00
MemberComputed,
2024-12-12 15:20:36 +01:00
MemberOptional,
2024-12-10 04:33:33 +01:00
PropShorthand,
PropComputed,
PropGetter,
PropSetter,
2024-12-10 21:17:02 +01:00
PropMethod,
VarVar,
VarConst,
VarLet,
VarDeclare,
2024-12-10 22:48:54 +01:00
ExportType,
TplTail,
2024-12-10 23:05:38 +01:00
ForAwait,
LogicalOr,
LogicalAnd,
LogicalNullishCoalescin,
2024-12-11 12:47:45 +01:00
JSXSelfClosing,
2024-12-11 17:10:05 +01:00
BinEqEq,
BinNotEq,
BinEqEqEq,
BinNotEqEq,
BinLt,
BinLtEq,
BinGt,
BinGtEq,
BinLShift,
BinRShift,
BinZeroFillRShift,
BinAdd,
BinSub,
BinMul,
BinDiv,
BinMod,
BinBitOr,
BinBitXor,
BinBitAnd,
BinIn,
BinInstanceOf,
BinExp,
UnaryMinus,
UnaryPlus,
UnaryBang,
UnaryTilde,
UnaryTypeOf,
UnaryVoid,
UnaryDelete,
2024-12-11 17:41:33 +01:00
UpdatePrefix,
UpdatePlusPlus,
UpdateMinusMinus,
2024-12-11 17:47:46 +01:00
YieldDelegate,
2024-12-12 01:35:57 +01:00
ParamOptional,
ClassDeclare,
ClassAbstract,
ClassConstructor,
ClassMethod,
ClassPublic,
ClassProtected,
ClassPrivate,
2024-12-12 13:28:35 +01:00
TsDeclare,
TsConst,
TsTrue,
TsPlus,
TsMinus,
TsReadonly,
2024-12-05 01:18:08 +01:00
}
2024-12-10 05:34:12 +01:00
fn assign_op_to_flag(m: AssignOp) -> u8 {
match m {
AssignOp::Assign => 0,
AssignOp::AddAssign => 1,
AssignOp::SubAssign => 2,
AssignOp::MulAssign => 3,
AssignOp::DivAssign => 4,
AssignOp::ModAssign => 5,
AssignOp::LShiftAssign => 6,
AssignOp::RShiftAssign => 7,
AssignOp::ZeroFillRShiftAssign => 8,
AssignOp::BitOrAssign => 9,
AssignOp::BitXorAssign => 10,
AssignOp::BitAndAssign => 11,
AssignOp::ExpAssign => 12,
AssignOp::AndAssign => 13,
AssignOp::OrAssign => 14,
AssignOp::NullishAssign => 15,
}
}
2024-12-10 04:33:33 +01:00
impl From<Flag> for u8 {
fn from(m: Flag) -> u8 {
2024-12-05 11:21:34 +01:00
match m {
2024-12-10 04:33:33 +01:00
Flag::ProgramModule => 0b00000001,
Flag::FnAsync => 0b00000001,
Flag::FnGenerator => 0b00000010,
2024-12-10 21:17:02 +01:00
Flag::FnDeclare => 0b00000100,
2024-12-12 15:20:36 +01:00
Flag::FnOptional => 0b00001000,
2024-12-10 04:33:33 +01:00
Flag::MemberComputed => 0b00000001,
2024-12-12 15:20:36 +01:00
Flag::MemberOptional => 0b00000010,
2024-12-10 04:33:33 +01:00
Flag::PropShorthand => 0b00000001,
Flag::PropComputed => 0b00000010,
Flag::PropGetter => 0b00000100,
Flag::PropSetter => 0b00001000,
2024-12-10 21:17:02 +01:00
Flag::PropMethod => 0b00010000,
Flag::VarVar => 0b00000001,
Flag::VarConst => 0b00000010,
Flag::VarLet => 0b00000100,
Flag::VarDeclare => 0b00001000,
2024-12-10 22:48:54 +01:00
Flag::ExportType => 0b000000001,
Flag::TplTail => 0b000000001,
2024-12-10 23:05:38 +01:00
Flag::ForAwait => 0b000000001,
Flag::LogicalOr => 0b000000001,
Flag::LogicalAnd => 0b000000010,
Flag::LogicalNullishCoalescin => 0b000000100,
2024-12-11 12:47:45 +01:00
Flag::JSXSelfClosing => 0b000000001,
2024-12-11 17:10:05 +01:00
Flag::BinEqEq => 1,
Flag::BinNotEq => 2,
Flag::BinEqEqEq => 3,
Flag::BinNotEqEq => 4,
Flag::BinLt => 5,
Flag::BinLtEq => 6,
Flag::BinGt => 7,
Flag::BinGtEq => 8,
Flag::BinLShift => 9,
Flag::BinRShift => 10,
Flag::BinZeroFillRShift => 11,
Flag::BinAdd => 12,
Flag::BinSub => 13,
Flag::BinMul => 14,
Flag::BinDiv => 15,
Flag::BinMod => 16,
Flag::BinBitOr => 17,
Flag::BinBitXor => 18,
Flag::BinBitAnd => 19,
Flag::BinIn => 20,
Flag::BinInstanceOf => 21,
Flag::BinExp => 22,
Flag::UnaryMinus => 1,
Flag::UnaryPlus => 2,
Flag::UnaryBang => 3,
Flag::UnaryTilde => 4,
Flag::UnaryTypeOf => 5,
Flag::UnaryVoid => 6,
Flag::UnaryDelete => 7,
2024-12-11 17:41:33 +01:00
Flag::UpdatePrefix => 0b000000001,
Flag::UpdatePlusPlus => 0b000000010,
Flag::UpdateMinusMinus => 0b000000100,
2024-12-11 17:47:46 +01:00
Flag::YieldDelegate => 1,
2024-12-12 01:35:57 +01:00
Flag::ParamOptional => 1,
Flag::ClassDeclare => 0b000000001,
Flag::ClassAbstract => 0b000000010,
Flag::ClassConstructor => 0b000000100,
Flag::ClassMethod => 0b000001000,
Flag::ClassPublic => 0b001000000,
Flag::ClassProtected => 0b010000000,
Flag::ClassPrivate => 0b10000000,
2024-12-12 13:28:35 +01:00
Flag::TsDeclare => 0b000000001,
Flag::TsConst => 0b000000010,
Flag::TsTrue => 0b000000100,
Flag::TsPlus => 0b000001000,
Flag::TsMinus => 0b000010000,
Flag::TsReadonly => 0b000100000,
2024-12-05 11:21:34 +01:00
}
}
}
2024-12-10 04:33:33 +01:00
#[derive(Debug, Clone)]
struct FlagValue(u8);
impl FlagValue {
fn new() -> Self {
Self(0)
}
fn set(&mut self, flag: Flag) {
let value: u8 = flag.into();
self.0 |= value;
}
}
#[derive(Debug)]
2024-12-05 11:21:34 +01:00
struct StringTable {
2024-12-10 04:33:33 +01:00
id: usize,
table: IndexMap<String, usize>,
2024-12-05 11:21:34 +01:00
}
impl StringTable {
fn new() -> Self {
Self {
id: 0,
table: IndexMap::new(),
}
}
2024-12-10 04:33:33 +01:00
fn insert(&mut self, s: &str) -> usize {
2024-12-05 11:21:34 +01:00
if let Some(id) = self.table.get(s) {
2024-12-12 10:53:12 +01:00
return *id;
2024-12-05 11:21:34 +01:00
}
let id = self.id;
self.id += 1;
self.table.insert(s.to_string(), id);
id
}
fn serialize(&mut self) -> Vec<u8> {
let mut result: Vec<u8> = vec![];
append_u32(&mut result, self.table.len() as u32);
// Assume that it's sorted by id
for (s, _id) in &self.table {
let bytes = s.as_bytes();
append_u32(&mut result, bytes.len() as u32);
result.append(&mut bytes.to_vec());
}
2024-12-10 21:17:02 +01:00
// eprintln!("Serialized string table: {:#?}", result);
2024-12-10 04:33:33 +01:00
2024-12-05 11:21:34 +01:00
result
2024-12-05 01:18:08 +01:00
}
}
2024-12-05 11:21:34 +01:00
struct SerializeCtx {
2024-12-10 04:33:33 +01:00
id: usize,
id_to_offset: IndexMap<usize, usize>,
2024-12-05 11:21:34 +01:00
result: Vec<u8>,
str_table: StringTable,
}
2024-12-10 04:33:33 +01:00
impl SerializeCtx {
fn new() -> Self {
let mut ctx = Self {
id: 0,
id_to_offset: IndexMap::new(),
result: vec![],
str_table: StringTable::new(),
};
2024-12-10 22:48:54 +01:00
ctx.str_table.insert("");
2024-12-12 20:53:08 +01:00
// Placeholder node
ctx.push_node(AstNode::Invalid, 0, &DUMMY_SP);
2024-12-10 04:33:33 +01:00
ctx
}
2024-12-12 04:19:11 +01:00
fn next_id(&mut self) -> usize {
let id = self.id;
self.id += 1;
id
}
fn write_u8(&mut self, value: u8) {
self.result.push(value);
}
fn write_node(
&mut self,
id: usize,
kind: AstNode,
parent_id: usize,
span: &Span,
) {
self.id_to_offset.insert(id, self.result.len());
let kind_value: u8 = kind.into();
self.result.push(kind_value);
append_usize(&mut self.result, parent_id);
// Span
append_u32(&mut self.result, span.lo.0);
append_u32(&mut self.result, span.hi.0);
}
fn write_ids<I>(&mut self, ids: I)
where
I: IntoIterator<Item = usize>,
{
let mut count = 0;
let idx = self.result.len();
append_usize(&mut self.result, 0);
for id in ids {
append_usize(&mut self.result, id);
count += 1;
}
write_usize(&mut self.result, count, idx);
}
fn write_id(&mut self, id: usize) {
append_usize(&mut self.result, id);
}
fn write_flags(&mut self, flags: &FlagValue) {
self.result.push(flags.0)
}
2024-12-10 04:33:33 +01:00
fn push_node(
&mut self,
kind: AstNode,
parent_id: usize,
span: &Span,
) -> usize {
let id = self.id;
self.id_to_offset.insert(id, self.result.len());
self.id += 1;
2024-12-12 20:53:08 +01:00
self.write_node(id, kind, parent_id, span);
2024-12-10 04:33:33 +01:00
id
}
2024-12-12 11:34:45 +01:00
}
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
pub fn serialize_ast_bin(parsed_source: &ParsedSource) -> Vec<u8> {
let mut ctx = SerializeCtx::new();
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
let parent_id = 0;
2024-12-12 10:22:21 +01:00
2024-12-12 11:34:45 +01:00
let program = &parsed_source.program();
let mut flags = FlagValue::new();
2024-12-12 10:22:21 +01:00
2024-12-12 11:34:45 +01:00
// eprintln!("SWC {:#?}", program);
2024-12-12 10:22:21 +01:00
2024-12-12 20:53:08 +01:00
let root_id = ctx.next_id();
2024-12-12 11:34:45 +01:00
match program.as_ref() {
Program::Module(module) => {
flags.set(Flag::ProgramModule);
2024-12-12 10:22:21 +01:00
2024-12-12 11:34:45 +01:00
let child_ids = module
.body
.iter()
.map(|item| match item {
ModuleItem::ModuleDecl(module_decl) => {
serialize_module_decl(&mut ctx, module_decl, parent_id)
}
2024-12-12 20:53:08 +01:00
ModuleItem::Stmt(stmt) => serialize_stmt(&mut ctx, stmt, root_id),
2024-12-12 11:34:45 +01:00
})
.collect::<Vec<_>>();
2024-12-12 20:53:08 +01:00
ctx.write_node(root_id, AstNode::Program, parent_id, &module.span);
2024-12-12 11:34:45 +01:00
ctx.write_flags(&flags);
ctx.write_ids(child_ids);
}
Program::Script(script) => {
let child_ids = script
.body
.iter()
2024-12-12 20:53:08 +01:00
.map(|stmt| serialize_stmt(&mut ctx, stmt, root_id))
2024-12-12 11:34:45 +01:00
.collect::<Vec<_>>();
2024-12-12 20:53:08 +01:00
ctx.write_node(root_id, AstNode::Program, parent_id, &script.span);
2024-12-12 11:34:45 +01:00
ctx.write_flags(&flags);
ctx.write_ids(child_ids);
2024-12-12 10:22:21 +01:00
}
}
2024-12-12 20:53:08 +01:00
let mut buf: Vec<u8> = vec![];
// Append serialized AST
buf.append(&mut ctx.result);
let offset_str_table = buf.len();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
// Serialize string table
// eprintln!("STRING {:#?}", ctx.str_table);
2024-12-12 20:53:08 +01:00
buf.append(&mut ctx.str_table.serialize());
2024-12-10 04:33:33 +01:00
2024-12-12 20:53:08 +01:00
let offset_id_table = buf.len();
2024-12-04 16:21:17 +01:00
2024-12-12 20:53:08 +01:00
// Serialize ids
append_usize(&mut buf, ctx.id_to_offset.len());
2024-12-10 04:33:33 +01:00
2024-12-12 20:53:08 +01:00
let mut ids = ctx.id_to_offset.keys().collect::<Vec<_>>();
ids.sort();
for id in ids {
let offset = ctx.id_to_offset.get(id).unwrap();
append_usize(&mut buf, *offset);
2024-12-12 11:34:45 +01:00
}
2024-12-10 05:34:12 +01:00
2024-12-12 20:53:08 +01:00
append_usize(&mut buf, offset_str_table);
append_usize(&mut buf, offset_id_table);
append_usize(&mut buf, root_id);
buf
2024-12-12 11:34:45 +01:00
}
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
fn serialize_module_decl(
ctx: &mut SerializeCtx,
module_decl: &ModuleDecl,
parent_id: usize,
) -> usize {
match module_decl {
ModuleDecl::Import(node) => {
ctx.push_node(AstNode::Import, parent_id, &node.span)
}
ModuleDecl::ExportDecl(node) => {
ctx.push_node(AstNode::ExportDecl, parent_id, &node.span)
}
ModuleDecl::ExportNamed(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::ExportType);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let src_id = node
.src
.as_ref()
.map_or(0, |src| serialize_lit(ctx, &Lit::Str(*src.clone()), id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
// FIXME: I don't think these are valid
let attr_id = node.with.as_ref().map_or(0, |attributes| {
serialize_expr(ctx, &Expr::Object(*attributes.clone()), id)
});
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let spec_ids = node
.specifiers
.iter()
.map(|spec| {
match spec {
ExportSpecifier::Named(child) => {
let spec_id = ctx.next_id();
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::ExportType);
2024-12-05 11:21:34 +01:00
2024-12-12 11:34:45 +01:00
let org_id =
serialize_module_exported_name(ctx, &child.orig, spec_id);
2024-12-05 11:21:34 +01:00
2024-12-12 11:34:45 +01:00
let exported_id = child.exported.as_ref().map_or(0, |exported| {
serialize_module_exported_name(ctx, exported, spec_id)
});
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(
spec_id,
AstNode::ExportSpecifier,
id,
&child.span,
);
ctx.write_flags(&flags);
ctx.write_id(org_id);
ctx.write_id(exported_id);
2024-12-05 11:21:34 +01:00
2024-12-12 11:34:45 +01:00
spec_id
}
2024-12-05 11:21:34 +01:00
2024-12-12 11:34:45 +01:00
// These two aren't syntactically valid
ExportSpecifier::Namespace(_) => todo!(),
ExportSpecifier::Default(_) => todo!(),
}
})
.collect::<Vec<_>>();
2024-12-05 11:21:34 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(
id,
AstNode::ExportNamedDeclaration,
parent_id,
&node.span,
);
ctx.write_flags(&flags);
ctx.write_id(src_id);
ctx.write_id(attr_id);
ctx.write_ids(spec_ids);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
id
}
ModuleDecl::ExportDefaultDecl(node) => {
ctx.push_node(AstNode::ExportDefaultDecl, parent_id, &node.span)
}
ModuleDecl::ExportDefaultExpr(node) => {
ctx.push_node(AstNode::ExportDefaultExpr, parent_id, &node.span)
}
ModuleDecl::ExportAll(node) => {
ctx.push_node(AstNode::ExportAll, parent_id, &node.span)
}
ModuleDecl::TsImportEquals(node) => {
ctx.push_node(AstNode::TsImportEquals, parent_id, &node.span)
}
ModuleDecl::TsExportAssignment(node) => {
ctx.push_node(AstNode::TsExportAssignment, parent_id, &node.span)
}
ModuleDecl::TsNamespaceExport(node) => {
ctx.push_node(AstNode::TsNamespaceExport, parent_id, &node.span)
}
}
}
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
fn serialize_stmt(
ctx: &mut SerializeCtx,
stmt: &Stmt,
parent_id: usize,
) -> usize {
match stmt {
Stmt::Block(node) => {
let id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let children = node
.stmts
.iter()
.map(|stmt| serialize_stmt(ctx, stmt, parent_id))
.collect::<Vec<_>>();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Block, parent_id, &node.span);
ctx.write_ids(children);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Empty(_) => 0,
Stmt::Debugger(node) => {
ctx.push_node(AstNode::Debugger, parent_id, &node.span)
}
Stmt::With(_) => todo!(),
Stmt::Return(node) => {
let id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let arg_id = node
.arg
.as_ref()
.map_or(0, |arg| serialize_expr(ctx, arg, id));
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Return, parent_id, &node.span);
ctx.write_id(arg_id);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Labeled(node) => {
let id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let ident_id = serialize_ident(ctx, &node.label, id);
let stmt_id = serialize_stmt(ctx, &node.body, id);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Labeled, parent_id, &node.span);
ctx.write_id(ident_id);
ctx.write_id(stmt_id);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Break(node) => {
let id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let arg_id = node
.label
.as_ref()
.map_or(0, |label| serialize_ident(ctx, label, id));
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Break, parent_id, &node.span);
ctx.write_id(arg_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Continue(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let arg_id = node
.label
.as_ref()
.map_or(0, |label| serialize_ident(ctx, label, id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Continue, parent_id, &node.span);
ctx.write_id(arg_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::If(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let test_id = serialize_expr(ctx, node.test.as_ref(), id);
let cons_id = serialize_stmt(ctx, node.cons.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let alt_id = node
.alt
.as_ref()
.map_or(0, |alt| serialize_stmt(ctx, alt, id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::IfStatement, parent_id, &node.span);
ctx.write_id(test_id);
ctx.write_id(cons_id);
ctx.write_id(alt_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Switch(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, &node.discriminant, id);
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let case_ids = node
.cases
.iter()
.map(|case| {
let child_id = ctx.next_id();
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let test_id = case
.test
.as_ref()
.map_or(0, |test| serialize_expr(ctx, test, child_id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let cons = case
.cons
.iter()
.map(|cons| serialize_stmt(ctx, cons, child_id))
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(child_id, AstNode::SwitchCase, id, &case.span);
ctx.write_id(test_id);
ctx.write_ids(cons);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
child_id
})
.collect::<Vec<_>>();
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Switch, parent_id, &node.span);
ctx.write_id(expr_id);
ctx.write_ids(case_ids);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Throw(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, &node.arg, id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Throw, parent_id, &node.span);
ctx.write_id(expr_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Try(node) => {
let id = ctx.next_id();
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let block_id = serialize_stmt(ctx, &Stmt::Block(node.block.clone()), id);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let catch_id = node.handler.as_ref().map_or(0, |catch| {
let clause_id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
let param_id = catch
.param
.as_ref()
.map_or(0, |param| serialize_pat(ctx, param, clause_id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let body_id = serialize_stmt(ctx, &Stmt::Block(catch.body.clone()), id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(clause_id, AstNode::CatchClause, id, &catch.span);
ctx.write_id(param_id);
ctx.write_id(body_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
clause_id
});
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let final_id = node.finalizer.as_ref().map_or(0, |finalizer| {
serialize_stmt(ctx, &Stmt::Block(finalizer.clone()), id)
});
2024-12-05 02:24:26 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::TryStatement, parent_id, &node.span);
ctx.write_id(block_id);
ctx.write_id(catch_id);
ctx.write_id(final_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
2024-12-12 04:19:11 +01:00
}
2024-12-12 11:34:45 +01:00
Stmt::While(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let test_id = serialize_expr(ctx, node.test.as_ref(), id);
let stmt_id = serialize_stmt(ctx, node.body.as_ref(), id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::While, parent_id, &node.span);
ctx.write_id(test_id);
ctx.write_id(stmt_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::DoWhile(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, node.test.as_ref(), id);
let stmt_id = serialize_stmt(ctx, node.body.as_ref(), id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::DoWhileStatement, parent_id, &node.span);
ctx.write_id(expr_id);
ctx.write_id(stmt_id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::For(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let init_id = node.init.as_ref().map_or(0, |init| match init {
VarDeclOrExpr::VarDecl(var_decl) => {
serialize_stmt(ctx, &Stmt::Decl(Decl::Var(var_decl.clone())), id)
}
VarDeclOrExpr::Expr(expr) => serialize_expr(ctx, expr, id),
});
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let test_id = node
.test
.as_ref()
.map_or(0, |expr| serialize_expr(ctx, expr, id));
let update_id = node
.update
.as_ref()
.map_or(0, |expr| serialize_expr(ctx, expr, id));
let body_id = serialize_stmt(ctx, node.body.as_ref(), id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::ForStatement, parent_id, &node.span);
ctx.write_id(init_id);
ctx.write_id(test_id);
ctx.write_id(update_id);
ctx.write_id(body_id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::ForIn(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let left_id = serialize_for_head(ctx, &node.left, id);
let right_id = serialize_expr(ctx, node.right.as_ref(), id);
let body_id = serialize_stmt(ctx, node.body.as_ref(), id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::ForInStatement, parent_id, &node.span);
ctx.write_id(left_id);
ctx.write_id(right_id);
ctx.write_id(body_id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::ForOf(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::ForAwait);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let left_id = serialize_for_head(ctx, &node.left, id);
let right_id = serialize_expr(ctx, node.right.as_ref(), id);
let body_id = serialize_stmt(ctx, node.body.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::ForOfStatement, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(left_id);
ctx.write_id(right_id);
ctx.write_id(body_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Stmt::Decl(node) => serialize_decl(ctx, node, parent_id),
Stmt::Expr(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let child_id = serialize_expr(ctx, node.expr.as_ref(), id);
ctx.write_node(id, AstNode::Expr, parent_id, &node.span);
ctx.write_id(child_id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
}
}
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
fn serialize_expr(
ctx: &mut SerializeCtx,
expr: &Expr,
parent_id: usize,
) -> usize {
match expr {
Expr::This(node) => ctx.push_node(AstNode::This, parent_id, &node.span),
Expr::Array(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let elem_ids = node
.elems
.iter()
.map(|item| {
item
.as_ref()
.map_or(0, |item| serialize_expr_or_spread(ctx, item, id))
})
.collect::<Vec<_>>();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Array, parent_id, &node.span);
ctx.write_ids(elem_ids);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Object(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let prop_ids = node
.props
.iter()
.map(|prop| {
match prop {
PropOrSpread::Spread(spread_element) => serialize_spread(
ctx,
spread_element.expr.as_ref(),
&spread_element.dot3_token,
parent_id,
),
PropOrSpread::Prop(prop) => {
let mut flags = FlagValue::new();
let prop_id = ctx.next_id();
// FIXME: optional
let (key_id, value_id) = match prop.as_ref() {
Prop::Shorthand(ident) => {
flags.set(Flag::PropShorthand);
let child_id = serialize_ident(ctx, ident, prop_id);
(child_id, child_id)
}
Prop::KeyValue(key_value_prop) => {
if let PropName::Computed(_) = key_value_prop.key {
flags.set(Flag::PropComputed)
}
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let key_id =
serialize_prop_name(ctx, &key_value_prop.key, prop_id);
let value_id =
serialize_expr(ctx, key_value_prop.value.as_ref(), prop_id);
(key_id, value_id)
}
Prop::Assign(assign_prop) => {
let child_id = ctx.next_id();
let key_id = serialize_ident(ctx, &assign_prop.key, prop_id);
let value_id =
serialize_expr(ctx, assign_prop.value.as_ref(), prop_id);
ctx.write_node(
child_id,
AstNode::AssignmentPattern,
prop_id,
&assign_prop.span,
);
ctx.write_id(key_id);
ctx.write_id(value_id);
(key_id, value_id)
}
Prop::Getter(getter_prop) => {
flags.set(Flag::PropGetter);
let key_id =
serialize_prop_name(ctx, &getter_prop.key, prop_id);
let value_id = serialize_expr(
ctx,
&Expr::Fn(FnExpr {
ident: None,
function: Box::new(Function {
params: vec![],
decorators: vec![],
span: getter_prop.span,
ctxt: SyntaxContext::empty(),
body: getter_prop.body.clone(),
is_generator: false,
is_async: false,
type_params: None, // FIXME
return_type: None,
}),
}),
prop_id,
);
(key_id, value_id)
}
Prop::Setter(setter_prop) => {
flags.set(Flag::PropSetter);
let key_id =
serialize_prop_name(ctx, &setter_prop.key, prop_id);
let param = Param::from(*setter_prop.param.clone());
let value_id = serialize_expr(
ctx,
&Expr::Fn(FnExpr {
ident: None,
function: Box::new(Function {
params: vec![param],
decorators: vec![],
span: setter_prop.span,
ctxt: SyntaxContext::empty(),
body: setter_prop.body.clone(),
is_generator: false,
is_async: false,
type_params: None,
return_type: None,
}),
}),
prop_id,
);
(key_id, value_id)
}
Prop::Method(method_prop) => {
flags.set(Flag::PropMethod);
let key_id =
serialize_prop_name(ctx, &method_prop.key, prop_id);
let value_id = serialize_expr(
ctx,
&Expr::Fn(FnExpr {
ident: None,
function: method_prop.function.clone(),
}),
prop_id,
);
(key_id, value_id)
}
};
ctx.write_node(prop_id, AstNode::Property, id, &prop.span());
ctx.write_flags(&flags);
ctx.write_id(key_id);
ctx.write_id(value_id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
prop_id
}
}
})
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Object, parent_id, &node.span);
ctx.write_ids(prop_ids);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Fn(node) => {
let id = ctx.next_id();
let fn_obj = node.function.as_ref();
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
if fn_obj.is_async {
flags.set(Flag::FnAsync)
}
if fn_obj.is_generator {
flags.set(Flag::FnGenerator)
2024-12-04 16:21:17 +01:00
}
2024-12-12 11:34:45 +01:00
let ident_id = node
.ident
.as_ref()
.map_or(0, |ident| serialize_ident(ctx, ident, id));
2024-12-04 16:21:17 +01:00
2024-12-12 13:28:35 +01:00
let type_param_id =
maybe_serialize_ts_type_param(ctx, &fn_obj.type_params, id);
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let param_ids = fn_obj
.params
.iter()
.map(|param| serialize_pat(ctx, &param.pat, id))
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let return_id = maybe_serialize_ts_type_ann(ctx, &fn_obj.return_type, id);
2024-12-12 11:34:45 +01:00
let block_id = fn_obj.body.as_ref().map_or(0, |block| {
serialize_stmt(ctx, &Stmt::Block(block.clone()), id)
});
ctx.write_node(id, AstNode::FunctionExpression, parent_id, &fn_obj.span);
ctx.write_flags(&flags);
ctx.write_id(ident_id);
ctx.write_id(type_param_id);
ctx.write_ids(param_ids);
ctx.write_id(return_id);
ctx.write_id(block_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Unary(node) => {
let id = ctx.next_id();
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(match node.op {
UnaryOp::Minus => Flag::UnaryMinus,
UnaryOp::Plus => Flag::UnaryPlus,
UnaryOp::Bang => Flag::UnaryBang,
UnaryOp::Tilde => Flag::UnaryTilde,
UnaryOp::TypeOf => Flag::UnaryTypeOf,
UnaryOp::Void => Flag::UnaryVoid,
UnaryOp::Delete => Flag::UnaryDelete,
});
let child_id = serialize_expr(ctx, &node.arg, id);
ctx.write_node(id, AstNode::Unary, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(child_id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Update(node) => {
let id = ctx.next_id();
let mut flags = FlagValue::new();
if node.prefix {
flags.set(Flag::UpdatePrefix);
2024-12-12 04:19:11 +01:00
}
2024-12-12 11:34:45 +01:00
flags.set(match node.op {
UpdateOp::PlusPlus => Flag::UpdatePlusPlus,
UpdateOp::MinusMinus => Flag::UpdateMinusMinus,
});
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let child_id = serialize_expr(ctx, node.arg.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::UpdateExpression, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(child_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Bin(node) => {
let (node_type, flag) = match node.op {
BinaryOp::LogicalOr => (AstNode::LogicalExpression, Flag::LogicalOr),
BinaryOp::LogicalAnd => (AstNode::LogicalExpression, Flag::LogicalAnd),
BinaryOp::NullishCoalescing => {
(AstNode::LogicalExpression, Flag::LogicalNullishCoalescin)
}
BinaryOp::EqEq => (AstNode::BinaryExpression, Flag::BinEqEq),
BinaryOp::NotEq => (AstNode::BinaryExpression, Flag::BinNotEq),
BinaryOp::EqEqEq => (AstNode::BinaryExpression, Flag::BinEqEqEq),
BinaryOp::NotEqEq => (AstNode::BinaryExpression, Flag::BinNotEqEq),
BinaryOp::Lt => (AstNode::BinaryExpression, Flag::BinLt),
BinaryOp::LtEq => (AstNode::BinaryExpression, Flag::BinLtEq),
BinaryOp::Gt => (AstNode::BinaryExpression, Flag::BinGt),
BinaryOp::GtEq => (AstNode::BinaryExpression, Flag::BinGtEq),
BinaryOp::LShift => (AstNode::BinaryExpression, Flag::BinLShift),
BinaryOp::RShift => (AstNode::BinaryExpression, Flag::BinRShift),
BinaryOp::ZeroFillRShift => {
(AstNode::BinaryExpression, Flag::BinZeroFillRShift)
}
BinaryOp::Add => (AstNode::BinaryExpression, Flag::BinAdd),
BinaryOp::Sub => (AstNode::BinaryExpression, Flag::BinSub),
BinaryOp::Mul => (AstNode::BinaryExpression, Flag::BinMul),
BinaryOp::Div => (AstNode::BinaryExpression, Flag::BinDiv),
BinaryOp::Mod => (AstNode::BinaryExpression, Flag::BinMod),
BinaryOp::BitOr => (AstNode::BinaryExpression, Flag::BinBitOr),
BinaryOp::BitXor => (AstNode::BinaryExpression, Flag::BinBitXor),
BinaryOp::BitAnd => (AstNode::BinaryExpression, Flag::BinBitAnd),
BinaryOp::In => (AstNode::BinaryExpression, Flag::BinIn),
BinaryOp::InstanceOf => {
(AstNode::BinaryExpression, Flag::BinInstanceOf)
}
BinaryOp::Exp => (AstNode::BinaryExpression, Flag::BinExp),
};
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(flag);
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let left_id = serialize_expr(ctx, node.left.as_ref(), id);
let right_id = serialize_expr(ctx, node.right.as_ref(), id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, node_type, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(left_id);
ctx.write_id(right_id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Assign(node) => {
let id = ctx.next_id();
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let left_id = match &node.left {
AssignTarget::Simple(simple_assign_target) => {
match simple_assign_target {
2024-12-12 15:20:36 +01:00
SimpleAssignTarget::Ident(target) => {
serialize_ident(ctx, &target.id, id)
2024-12-12 11:34:45 +01:00
}
2024-12-12 15:20:36 +01:00
SimpleAssignTarget::Member(target) => {
serialize_expr(ctx, &Expr::Member(target.clone()), id)
2024-12-12 11:34:45 +01:00
}
2024-12-12 15:20:36 +01:00
SimpleAssignTarget::SuperProp(target) => todo!(),
2024-12-12 11:34:45 +01:00
SimpleAssignTarget::Paren(paren_expr) => todo!(),
2024-12-12 15:20:36 +01:00
SimpleAssignTarget::OptChain(target) => {
serialize_expr(ctx, &Expr::OptChain(target.clone()), id)
}
2024-12-12 11:34:45 +01:00
SimpleAssignTarget::TsAs(ts_as_expr) => todo!(),
SimpleAssignTarget::TsSatisfies(ts_satisfies_expr) => todo!(),
SimpleAssignTarget::TsNonNull(ts_non_null_expr) => todo!(),
SimpleAssignTarget::TsTypeAssertion(ts_type_assertion) => todo!(),
SimpleAssignTarget::TsInstantiation(ts_instantiation) => todo!(),
2024-12-12 15:20:36 +01:00
SimpleAssignTarget::Invalid(_) => unreachable!(),
2024-12-12 04:19:11 +01:00
}
2024-12-12 11:34:45 +01:00
}
AssignTarget::Pat(target) => match target {
AssignTargetPat::Array(array_pat) => {
serialize_pat(ctx, &Pat::Array(array_pat.clone()), id)
}
AssignTargetPat::Object(object_pat) => {
serialize_pat(ctx, &Pat::Object(object_pat.clone()), id)
}
2024-12-12 15:20:36 +01:00
AssignTargetPat::Invalid(_) => unreachable!(),
2024-12-12 11:34:45 +01:00
},
};
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let right_id = serialize_expr(ctx, node.right.as_ref(), id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Assign, parent_id, &node.span);
ctx.write_u8(assign_op_to_flag(node.op));
ctx.write_id(left_id);
ctx.write_id(right_id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
2024-12-12 15:20:36 +01:00
Expr::Member(node) => serialize_member_expr(ctx, node, parent_id, false),
2024-12-12 11:34:45 +01:00
Expr::SuperProp(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
if let SuperProp::Computed(_) = node.prop {
flags.set(Flag::MemberComputed)
2024-12-12 01:35:57 +01:00
}
2024-12-12 11:34:45 +01:00
let super_id = ctx.push_node(AstNode::Super, id, &node.obj.span);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let child_id = match &node.prop {
SuperProp::Ident(ident_name) => {
serialize_ident_name(ctx, ident_name, id)
}
SuperProp::Computed(prop) => serialize_expr(ctx, &prop.expr, id),
};
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(super_id);
ctx.write_id(child_id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Cond(node) => {
let id = ctx.next_id();
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let test_id = serialize_expr(ctx, node.test.as_ref(), id);
let cons_id = serialize_expr(ctx, node.cons.as_ref(), id);
let alt_id = serialize_expr(ctx, node.alt.as_ref(), id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Cond, parent_id, &node.span);
ctx.write_id(test_id);
ctx.write_id(cons_id);
ctx.write_id(alt_id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Call(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let callee_id = match &node.callee {
Callee::Super(super_node) => {
ctx.push_node(AstNode::Super, id, &super_node.span)
}
Callee::Import(import) => todo!(),
Callee::Expr(expr) => serialize_expr(ctx, expr, id),
};
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let type_id = node.type_args.as_ref().map_or(0, |type_arg| {
todo!() // FIXME
});
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let arg_ids = node
.args
.iter()
.map(|arg| serialize_expr_or_spread(ctx, arg, id))
.collect::<Vec<_>>();
2024-12-12 01:35:57 +01:00
2024-12-12 15:20:36 +01:00
ctx.write_node(id, AstNode::CallExpression, parent_id, &node.span);
ctx.write_flags(&FlagValue::new());
2024-12-12 11:34:45 +01:00
ctx.write_id(callee_id);
ctx.write_id(type_id);
ctx.write_ids(arg_ids);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::New(node) => {
let id = ctx.next_id();
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let callee_id = serialize_expr(ctx, node.callee.as_ref(), id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let arg_ids: Vec<usize> = node.args.as_ref().map_or(vec![], |args| {
args
2024-12-12 04:19:11 +01:00
.iter()
2024-12-12 11:34:45 +01:00
.map(|arg| serialize_expr_or_spread(ctx, arg, id))
.collect::<Vec<_>>()
});
2024-12-12 01:35:57 +01:00
2024-12-12 13:28:35 +01:00
// let type_arg_id = maybe_serialize_ts_type_param(ctx, &node.type_args, id);
// FIXME
let type_arg_id = 0;
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::New, parent_id, &node.span);
ctx.write_id(callee_id);
ctx.write_id(type_arg_id);
ctx.write_ids(arg_ids);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Seq(node) => {
let id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let children = node
.exprs
.iter()
.map(|expr| serialize_expr(ctx, expr, id))
.collect::<Vec<_>>();
2024-12-11 17:41:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Seq, parent_id, &node.span);
ctx.write_ids(children);
2024-12-11 17:41:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Ident(node) => serialize_ident(ctx, node, parent_id),
Expr::Lit(node) => serialize_lit(ctx, node, parent_id),
Expr::Tpl(node) => {
let id = ctx.next_id();
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
let quasi_ids = node
.quasis
.iter()
.map(|quasi| {
let tpl_id = ctx.next_id();
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::TplTail);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let raw_str_id = ctx.str_table.insert(quasi.raw.as_str());
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
let cooked_str_id = quasi
.cooked
.as_ref()
.map_or(0, |cooked| ctx.str_table.insert(cooked.as_str()));
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(tpl_id, AstNode::TemplateElement, id, &quasi.span);
ctx.write_flags(&flags);
append_usize(&mut ctx.result, raw_str_id);
append_usize(&mut ctx.result, cooked_str_id);
2024-12-11 17:41:33 +01:00
2024-12-12 11:34:45 +01:00
tpl_id
})
.collect::<Vec<_>>();
2024-12-11 17:41:33 +01:00
2024-12-12 11:34:45 +01:00
let expr_ids = node
.exprs
.iter()
.map(|expr| serialize_expr(ctx, expr, id))
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::TemplateLiteral, parent_id, &node.span);
ctx.write_ids(quasi_ids);
ctx.write_ids(expr_ids);
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
id
}
2024-12-12 20:53:08 +01:00
Expr::TaggedTpl(node) => {
let id = ctx.next_id();
let tag_id = serialize_expr(ctx, &node.tag, id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
// FIXME
2024-12-12 20:53:08 +01:00
let type_param_id = 0;
let quasi_id = serialize_expr(ctx, &Expr::Tpl(*node.tpl.clone()), id);
ctx.write_node(
id,
AstNode::TaggedTemplateExpression,
parent_id,
&node.span,
);
ctx.write_id(tag_id);
ctx.write_id(type_param_id);
ctx.write_id(quasi_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Arrow(node) => {
let id = ctx.next_id();
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
if node.is_async {
flags.set(Flag::FnAsync);
2024-12-12 04:19:11 +01:00
}
2024-12-12 11:34:45 +01:00
if node.is_generator {
flags.set(Flag::FnGenerator);
2024-12-12 04:19:11 +01:00
}
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let type_param_id =
maybe_serialize_ts_type_param(ctx, &node.type_params, id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
let param_ids = node
.params
.iter()
.map(|param| serialize_pat(ctx, param, id))
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let body_id = match node.body.as_ref() {
BlockStmtOrExpr::BlockStmt(block_stmt) => {
serialize_stmt(ctx, &Stmt::Block(block_stmt.clone()), id)
}
BlockStmtOrExpr::Expr(expr) => serialize_expr(ctx, expr.as_ref(), id),
};
2024-12-05 01:18:08 +01:00
2024-12-12 13:28:35 +01:00
let return_type_id =
maybe_serialize_ts_type_ann(ctx, &node.return_type, id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(
id,
AstNode::ArrowFunctionExpression,
parent_id,
&node.span,
);
ctx.write_flags(&flags);
ctx.write_id(type_param_id);
ctx.write_ids(param_ids);
ctx.write_id(body_id);
ctx.write_id(return_type_id);
2024-12-05 01:18:08 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Class(node) => {
let id = ctx.push_node(AstNode::ClassExpr, parent_id, &node.class.span);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
// FIXME
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Yield(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let mut flags = FlagValue::new();
if node.delegate {
flags.set(Flag::YieldDelegate)
2024-12-12 04:19:11 +01:00
}
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let arg_id = node
.arg
.as_ref()
.map_or(0, |arg| serialize_expr(ctx, arg.as_ref(), id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::YieldExpression, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(arg_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::MetaProp(node) => {
ctx.push_node(AstNode::MetaProp, parent_id, &node.span)
}
Expr::Await(node) => {
let id = ctx.next_id();
let arg_id = serialize_expr(ctx, node.arg.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::AwaitExpression, parent_id, &node.span);
ctx.write_id(arg_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::Paren(node) => {
// Paren nodes are treated as a syntax only thing in TSEStree
// and are never materialized to actual AST nodes.
serialize_expr(ctx, &node.expr, parent_id)
}
Expr::JSXMember(node) => serialize_jsx_member_expr(ctx, node, parent_id),
Expr::JSXNamespacedName(node) => {
serialize_jsx_namespaced_name(ctx, node, parent_id)
}
Expr::JSXEmpty(node) => serialize_jsx_empty_expr(ctx, node, parent_id),
Expr::JSXElement(node) => serialize_jsx_element(ctx, node, parent_id),
Expr::JSXFragment(node) => serialize_jsx_fragment(ctx, node, parent_id),
Expr::TsTypeAssertion(node) => {
2024-12-12 13:28:35 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let expr_id = serialize_expr(ctx, &node.expr, parent_id);
let type_ann_id = serialize_ts_type(ctx, &node.type_ann, id);
ctx.write_node(id, AstNode::TSTypeAssertion, parent_id, &node.span);
ctx.write_id(expr_id);
ctx.write_id(type_ann_id);
2024-12-12 04:19:11 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::TsConstAssertion(node) => {
let id = ctx.next_id();
let expr_id = serialize_expr(ctx, node.expr.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::TsConstAssertion, parent_id, &node.span);
ctx.write_id(expr_id);
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
id
2024-12-04 16:21:17 +01:00
}
2024-12-12 11:34:45 +01:00
Expr::TsNonNull(node) => {
let id = ctx.next_id();
let expr_id = serialize_expr(ctx, node.expr.as_ref(), id);
2024-12-04 16:21:17 +01:00
2024-12-12 13:28:35 +01:00
ctx.write_node(id, AstNode::TSNonNullExpression, parent_id, &node.span);
2024-12-12 11:34:45 +01:00
ctx.write_id(expr_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::TsAs(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, node.expr.as_ref(), id);
2024-12-12 13:28:35 +01:00
let type_ann_id = serialize_ts_type(ctx, node.type_ann.as_ref(), id);
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
ctx.write_node(id, AstNode::TSAsExpression, parent_id, &node.span);
2024-12-12 11:34:45 +01:00
ctx.write_id(expr_id);
2024-12-12 13:28:35 +01:00
ctx.write_id(type_ann_id);
2024-12-12 10:22:21 +01:00
2024-12-12 11:34:45 +01:00
id
2024-12-12 10:22:21 +01:00
}
2024-12-12 11:34:45 +01:00
Expr::TsInstantiation(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, node.expr.as_ref(), id);
// FIXME
// let expr_id = serialize_expr(ctx, ts_instantiation.type_args.as_ref(), id);
ctx.write_node(id, AstNode::TsInstantiation, parent_id, &node.span);
ctx.write_id(expr_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
Expr::TsSatisfies(node) => {
let id = ctx.next_id();
2024-12-10 05:34:12 +01:00
2024-12-12 11:34:45 +01:00
let expr_id = serialize_expr(ctx, node.expr.as_ref(), id);
let type_id = serialize_ts_type(ctx, node.type_ann.as_ref(), id);
2024-12-10 05:34:12 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::TsSatisfies, parent_id, &node.span);
ctx.write_id(expr_id);
ctx.write_id(type_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
2024-12-12 15:20:36 +01:00
Expr::PrivateName(node) => serialize_private_name(ctx, node, parent_id),
Expr::OptChain(node) => {
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 15:20:36 +01:00
let arg_id = match node.base.as_ref() {
OptChainBase::Member(member_expr) => {
serialize_member_expr(ctx, member_expr, id, true)
}
OptChainBase::Call(opt_call) => {
let call_id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 15:20:36 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::FnOptional);
2024-12-10 04:33:33 +01:00
2024-12-12 15:20:36 +01:00
let callee_id = serialize_expr(ctx, &opt_call.callee, id);
let type_id = opt_call.type_args.as_ref().map_or(0, |type_arg| {
todo!() // FIXME
});
let arg_ids = opt_call
.args
.iter()
.map(|arg| serialize_expr_or_spread(ctx, arg, id))
.collect::<Vec<_>>();
ctx.write_node(call_id, AstNode::CallExpression, id, &opt_call.span);
ctx.write_flags(&flags);
ctx.write_id(callee_id);
ctx.write_id(type_id);
ctx.write_ids(arg_ids);
call_id
}
};
ctx.write_node(id, AstNode::ChainExpression, parent_id, &node.span);
ctx.write_id(arg_id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
id
}
2024-12-12 15:20:36 +01:00
Expr::Invalid(_) => {
unreachable!()
2024-12-12 04:19:11 +01:00
}
}
2024-12-12 11:34:45 +01:00
}
2024-12-10 21:17:02 +01:00
2024-12-12 15:20:36 +01:00
fn serialize_member_expr(
ctx: &mut SerializeCtx,
node: &MemberExpr,
parent_id: usize,
optional: bool,
) -> usize {
let id = ctx.next_id();
let mut flags = FlagValue::new();
if optional {
flags.set(Flag::MemberOptional)
}
let obj_id = serialize_expr(ctx, node.obj.as_ref(), id);
let prop_id = match &node.prop {
MemberProp::Ident(ident_name) => serialize_ident_name(ctx, ident_name, id),
MemberProp::PrivateName(private_name) => {
serialize_private_name(ctx, private_name, id)
}
MemberProp::Computed(computed_prop_name) => {
flags.set(Flag::MemberComputed);
serialize_expr(ctx, computed_prop_name.expr.as_ref(), id)
}
};
ctx.write_node(id, AstNode::MemberExpression, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(obj_id);
ctx.write_id(prop_id);
id
}
2024-12-12 11:34:45 +01:00
fn serialize_expr_or_spread(
ctx: &mut SerializeCtx,
arg: &ExprOrSpread,
parent_id: usize,
) -> usize {
if let Some(spread) = &arg.spread {
serialize_spread(ctx, &arg.expr, spread, parent_id)
} else {
serialize_expr(ctx, arg.expr.as_ref(), parent_id)
}
}
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
fn serialize_ident(
ctx: &mut SerializeCtx,
ident: &Ident,
parent_id: usize,
) -> usize {
let id = ctx.push_node(AstNode::Identifier, parent_id, &ident.span);
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
let str_id = ctx.str_table.insert(ident.sym.as_str());
append_usize(&mut ctx.result, str_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
id
}
2024-12-11 17:10:05 +01:00
2024-12-12 11:34:45 +01:00
fn serialize_module_exported_name(
ctx: &mut SerializeCtx,
name: &ModuleExportName,
parent_id: usize,
) -> usize {
match &name {
ModuleExportName::Ident(ident) => serialize_ident(ctx, ident, parent_id),
ModuleExportName::Str(lit) => {
serialize_lit(ctx, &Lit::Str(lit.clone()), parent_id)
}
2024-12-12 04:19:11 +01:00
}
}
2024-12-10 04:33:33 +01:00
2024-12-12 04:19:11 +01:00
fn serialize_decl(
ctx: &mut SerializeCtx,
decl: &Decl,
parent_id: usize,
) -> usize {
match decl {
Decl::Class(node) => {
2024-12-12 10:42:38 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-11 11:02:21 +01:00
let mut flags = FlagValue::new();
2024-12-12 04:19:11 +01:00
if node.declare {
flags.set(Flag::ClassDeclare)
}
if node.class.is_abstract {
flags.set(Flag::ClassAbstract)
2024-12-11 11:02:21 +01:00
}
2024-12-05 02:24:26 +01:00
2024-12-12 11:34:45 +01:00
let ident_id = serialize_ident(ctx, &node.ident, id);
2024-12-12 10:42:38 +01:00
let type_param_id =
2024-12-12 13:28:35 +01:00
maybe_serialize_ts_type_param(ctx, &node.class.type_params, id);
2024-12-10 04:33:33 +01:00
2024-12-12 10:42:38 +01:00
let super_class_id = node
.class
.super_class
.as_ref()
2024-12-12 11:34:45 +01:00
.map_or(0, |super_class| serialize_expr(ctx, super_class, id));
2024-12-10 04:33:33 +01:00
2024-12-12 10:42:38 +01:00
let super_type_params =
node
.class
.super_type_params
.as_ref()
.map_or(0, |super_params| {
// FIXME
todo!()
});
let implement_ids = node
.class
.implements
.iter()
.map(|implements| {
// FIXME
todo!()
})
.collect::<Vec<_>>();
2024-12-12 04:19:11 +01:00
2024-12-12 10:42:38 +01:00
let member_ids = node
.class
.body
.iter()
.map(|member| {
match member {
ClassMember::Constructor(constructor) => {
let member_id = ctx.next_id();
let mut flags = FlagValue::new();
flags.set(Flag::ClassConstructor);
accessibility_to_flag(&mut flags, constructor.accessibility);
let key_id =
serialize_prop_name(ctx, &constructor.key, member_id);
let body_id = constructor.body.as_ref().map_or(0, |body| {
2024-12-12 11:34:45 +01:00
serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id)
2024-12-12 10:42:38 +01:00
});
let params = constructor
.params
.iter()
.map(|param| match param {
ParamOrTsParamProp::TsParamProp(ts_param_prop) => todo!(),
ParamOrTsParamProp::Param(param) => {
serialize_pat(ctx, &param.pat, member_id)
}
})
.collect::<Vec<_>>();
ctx.write_node(
member_id,
AstNode::MethodDefinition,
id,
&constructor.span,
);
ctx.write_flags(&flags);
ctx.write_id(key_id);
ctx.write_id(body_id);
ctx.write_ids(params);
member_id
2024-12-12 04:19:11 +01:00
}
2024-12-12 10:42:38 +01:00
ClassMember::Method(method) => {
let member_id = ctx.next_id();
2024-12-10 22:48:54 +01:00
2024-12-12 10:42:38 +01:00
let mut flags = FlagValue::new();
flags.set(Flag::ClassMethod);
if method.function.is_async {
// FIXME
}
2024-12-10 22:48:54 +01:00
2024-12-12 10:42:38 +01:00
accessibility_to_flag(&mut flags, method.accessibility);
let key_id = serialize_prop_name(ctx, &method.key, member_id);
let body_id = method.function.body.as_ref().map_or(0, |body| {
2024-12-12 11:34:45 +01:00
serialize_stmt(ctx, &Stmt::Block(body.clone()), member_id)
2024-12-12 10:42:38 +01:00
});
let params = method
.function
.params
.iter()
.map(|param| serialize_pat(ctx, &param.pat, member_id))
.collect::<Vec<_>>();
ctx.write_node(
member_id,
AstNode::MethodDefinition,
id,
&method.span,
);
ctx.write_flags(&flags);
ctx.write_id(key_id);
ctx.write_id(body_id);
ctx.write_ids(params);
member_id
2024-12-12 04:19:11 +01:00
}
2024-12-12 10:42:38 +01:00
ClassMember::PrivateMethod(private_method) => todo!(),
ClassMember::ClassProp(class_prop) => todo!(),
ClassMember::PrivateProp(private_prop) => todo!(),
ClassMember::TsIndexSignature(ts_index_signature) => todo!(),
ClassMember::Empty(_) => unreachable!(),
ClassMember::StaticBlock(static_block) => todo!(),
ClassMember::AutoAccessor(auto_accessor) => todo!(),
2024-12-12 04:19:11 +01:00
}
2024-12-12 10:42:38 +01:00
})
.collect::<Vec<_>>();
2024-12-10 22:48:54 +01:00
2024-12-12 10:42:38 +01:00
ctx.write_node(
id,
AstNode::ClassDeclaration,
parent_id,
&node.class.span,
);
ctx.write_flags(&flags);
ctx.write_id(ident_id);
ctx.write_id(type_param_id);
ctx.write_id(super_class_id);
ctx.write_id(super_type_params);
ctx.write_ids(implement_ids);
ctx.write_ids(member_ids);
2024-12-10 04:33:33 +01:00
id
2024-12-04 16:21:17 +01:00
}
2024-12-12 04:19:11 +01:00
Decl::Fn(node) => {
2024-12-12 10:42:38 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
let mut flags = FlagValue::new();
2024-12-12 04:19:11 +01:00
if node.declare {
flags.set(Flag::FnDeclare)
}
if node.function.is_async {
flags.set(Flag::FnAsync)
2024-12-05 01:18:08 +01:00
}
2024-12-12 04:19:11 +01:00
if node.function.is_generator {
flags.set(Flag::FnGenerator)
2024-12-05 01:18:08 +01:00
}
2024-12-11 17:10:05 +01:00
2024-12-12 11:34:45 +01:00
let ident_id = serialize_ident(ctx, &node.ident, parent_id);
2024-12-12 10:42:38 +01:00
let type_param_id =
2024-12-12 13:28:35 +01:00
maybe_serialize_ts_type_param(ctx, &node.function.type_params, id);
2024-12-12 10:42:38 +01:00
let return_type =
2024-12-12 13:28:35 +01:00
maybe_serialize_ts_type_ann(ctx, &node.function.return_type, id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let body_id = node.function.body.as_ref().map_or(0, |body| {
serialize_stmt(ctx, &Stmt::Block(body.clone()), id)
});
2024-12-10 04:33:33 +01:00
2024-12-12 10:42:38 +01:00
let params = node
.function
.params
.iter()
.map(|param| serialize_pat(ctx, &param.pat, id))
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::Fn, parent_id, &node.function.span);
ctx.write_flags(&flags);
ctx.write_id(ident_id);
ctx.write_id(type_param_id);
ctx.write_id(return_type);
ctx.write_id(body_id);
ctx.write_ids(params);
2024-12-10 04:33:33 +01:00
id
}
2024-12-12 04:19:11 +01:00
Decl::Var(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 17:47:46 +01:00
let mut flags = FlagValue::new();
2024-12-12 04:19:11 +01:00
if node.declare {
flags.set(Flag::VarDeclare)
}
2024-12-12 11:34:45 +01:00
flags.set(match node.kind {
VarDeclKind::Var => Flag::VarVar,
VarDeclKind::Let => Flag::VarLet,
VarDeclKind::Const => Flag::VarConst,
});
2024-12-11 17:47:46 +01:00
2024-12-12 11:34:45 +01:00
let children = node
.decls
.iter()
.map(|decl| {
let child_id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
// FIXME: Definite?
2024-12-04 16:21:17 +01:00
2024-12-12 11:34:45 +01:00
let decl_id = serialize_pat(ctx, &decl.name, child_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
let init_id = decl
.init
.as_ref()
.map_or(0, |init| serialize_expr(ctx, init.as_ref(), child_id));
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(child_id, AstNode::VariableDeclarator, id, &decl.span);
ctx.write_id(decl_id);
ctx.write_id(init_id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
child_id
})
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::Var, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_ids(children);
2024-12-10 04:33:33 +01:00
id
}
2024-12-12 04:19:11 +01:00
Decl::Using(node) => {
let id = ctx.push_node(AstNode::Using, parent_id, &node.span);
2024-12-10 04:33:33 +01:00
2024-12-12 04:19:11 +01:00
for (i, decl) in node.decls.iter().enumerate() {
// FIXME
}
2024-12-10 04:33:33 +01:00
id
}
2024-12-12 04:19:11 +01:00
Decl::TsInterface(node) => {
2024-12-12 13:28:35 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let mut flags = FlagValue::new();
if node.declare {
flags.set(Flag::TsDeclare);
}
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let ident_id = serialize_ident(ctx, &node.id, id);
let type_param =
maybe_serialize_ts_type_param(ctx, &node.type_params, id);
let extend_ids = node
.extends
.iter()
.map(|item| {
let child_id = ctx.next_id();
let expr_id = serialize_expr(ctx, &item.expr, child_id);
ctx.write_node(
child_id,
AstNode::TSInterfaceHeritage,
id,
&item.span,
);
ctx.write_id(expr_id);
child_id
})
.collect::<Vec<_>>();
let body_elem_ids = node
.body
.body
.iter()
.map(|item| match item {
2024-12-12 15:20:36 +01:00
TsTypeElement::TsCallSignatureDecl(ts_call) => {
let item_id = ctx.next_id();
let type_param_id =
maybe_serialize_ts_type_param(ctx, &ts_call.type_params, id);
let return_type_id =
maybe_serialize_ts_type_ann(ctx, &ts_call.type_ann, id);
let param_ids = ts_call
.params
.iter()
.map(|param| serialize_ts_fn_param(ctx, param, id))
.collect::<Vec<_>>();
ctx.write_node(
item_id,
AstNode::TsCallSignatureDeclaration,
id,
&ts_call.span,
);
ctx.write_id(type_param_id);
ctx.write_ids(param_ids);
ctx.write_id(return_type_id);
item_id
}
2024-12-12 13:28:35 +01:00
TsTypeElement::TsConstructSignatureDecl(
ts_construct_signature_decl,
) => todo!(),
TsTypeElement::TsPropertySignature(ts_property_signature) => todo!(),
TsTypeElement::TsGetterSignature(ts_getter_signature) => todo!(),
TsTypeElement::TsSetterSignature(ts_setter_signature) => todo!(),
TsTypeElement::TsMethodSignature(ts_method_signature) => todo!(),
TsTypeElement::TsIndexSignature(ts_index_signature) => todo!(),
})
.collect::<Vec<_>>();
let body_id = ctx.next_id();
ctx.write_node(body_id, AstNode::TSInterfaceBody, id, &node.body.span);
ctx.write_ids(body_elem_ids);
ctx.write_node(id, AstNode::TSInterface, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(ident_id);
ctx.write_id(type_param);
ctx.write_ids(extend_ids);
2024-12-10 04:33:33 +01:00
id
}
2024-12-12 04:19:11 +01:00
Decl::TsTypeAlias(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-05 01:18:08 +01:00
2024-12-12 13:28:35 +01:00
let mut flags = FlagValue::new();
if node.declare {
flags.set(Flag::TsDeclare);
}
2024-12-12 11:34:45 +01:00
let ident_id = serialize_ident(ctx, &node.id, id);
2024-12-12 13:28:35 +01:00
let ts_type_id = serialize_ts_type(ctx, &node.type_ann, id);
let type_param_id =
maybe_serialize_ts_type_param(ctx, &node.type_params, id);
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::TsTypeAlias, parent_id, &node.span);
2024-12-12 13:28:35 +01:00
ctx.write_flags(&flags);
2024-12-12 11:34:45 +01:00
ctx.write_id(ident_id);
2024-12-12 13:28:35 +01:00
ctx.write_id(type_param_id);
ctx.write_id(ts_type_id);
2024-12-10 04:33:33 +01:00
id
2024-12-04 16:21:17 +01:00
}
2024-12-12 04:19:11 +01:00
Decl::TsEnum(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 13:28:35 +01:00
let mut flags = FlagValue::new();
if node.declare {
flags.set(Flag::TsDeclare);
}
if node.is_const {
flags.set(Flag::TsConst);
}
2024-12-12 11:34:45 +01:00
let ident_id = serialize_ident(ctx, &node.id, parent_id);
2024-12-12 04:19:11 +01:00
2024-12-12 13:28:35 +01:00
let member_ids = node
2024-12-12 11:34:45 +01:00
.members
.iter()
.map(|member| {
2024-12-12 13:28:35 +01:00
let member_id = ctx.next_id();
let ident_id = match &member.id {
TsEnumMemberId::Ident(ident) => {
serialize_ident(ctx, &ident, member_id)
}
TsEnumMemberId::Str(lit_str) => {
serialize_lit(ctx, &Lit::Str(lit_str.clone()), member_id)
}
};
let init_id = member
.init
.as_ref()
.map_or(0, |init| serialize_expr(ctx, init, member_id));
ctx.write_node(member_id, AstNode::TSEnumMember, id, &member.span);
ctx.write_id(ident_id);
ctx.write_id(init_id);
member_id
2024-12-12 11:34:45 +01:00
})
.collect::<Vec<_>>();
2024-12-12 04:19:11 +01:00
2024-12-12 13:28:35 +01:00
ctx.write_node(id, AstNode::TSEnumDeclaration, parent_id, &node.span);
ctx.write_flags(&flags);
2024-12-12 11:34:45 +01:00
ctx.write_id(ident_id);
2024-12-12 13:28:35 +01:00
ctx.write_ids(member_ids);
2024-12-10 04:33:33 +01:00
id
2024-12-04 16:21:17 +01:00
}
2024-12-12 04:19:11 +01:00
Decl::TsModule(ts_module_decl) => {
ctx.push_node(AstNode::TsModule, parent_id, &ts_module_decl.span)
2024-12-04 16:21:17 +01:00
}
}
}
2024-12-12 01:35:57 +01:00
fn accessibility_to_flag(
flags: &mut FlagValue,
accessibility: Option<Accessibility>,
) {
if let Some(accessibility) = &accessibility {
let value = match accessibility {
Accessibility::Public => Flag::ClassPublic,
Accessibility::Protected => Flag::ClassProtected,
Accessibility::Private => Flag::ClassPrivate,
};
flags.set(value);
}
}
2024-12-12 15:20:36 +01:00
fn serialize_private_name(
ctx: &mut SerializeCtx,
node: &PrivateName,
parent_id: usize,
) -> usize {
let id = ctx.push_node(AstNode::PrivateIdentifier, parent_id, &node.span);
let str_id = ctx.str_table.insert(node.name.as_str());
append_usize(&mut ctx.result, str_id);
id
}
2024-12-11 12:47:45 +01:00
fn serialize_jsx_element(
ctx: &mut SerializeCtx,
node: &JSXElement,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 12:47:45 +01:00
let opening_id = serialize_jsx_opening_element(ctx, &node.opening, id);
2024-12-12 11:34:45 +01:00
let closing_id = node.closing.as_ref().map_or(0, |closing| {
let closing_id = ctx.next_id();
2024-12-11 17:10:05 +01:00
let child_id = serialize_jsx_element_name(ctx, &closing.name, id);
2024-12-12 11:34:45 +01:00
ctx.write_node(closing_id, AstNode::JSXClosingElement, id, &closing.span);
ctx.write_id(child_id);
closing_id
});
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
let children = serialize_jsx_children(ctx, &node.children, id);
ctx.write_node(id, AstNode::JSXElement, parent_id, &node.span);
ctx.write_id(opening_id);
ctx.write_id(closing_id);
ctx.write_ids(children);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_jsx_fragment(
ctx: &mut SerializeCtx,
node: &JSXFragment,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 17:10:05 +01:00
2024-12-11 12:47:45 +01:00
let opening_id =
ctx.push_node(AstNode::JSXOpeningFragment, id, &node.opening.span);
let closing_id =
ctx.push_node(AstNode::JSXClosingFragment, id, &node.closing.span);
2024-12-12 11:34:45 +01:00
let children = serialize_jsx_children(ctx, &node.children, id);
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::JSXFragment, parent_id, &node.span);
ctx.write_id(opening_id);
ctx.write_id(closing_id);
ctx.write_ids(children);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_jsx_children(
ctx: &mut SerializeCtx,
2024-12-12 10:53:12 +01:00
children: &[JSXElementChild],
2024-12-11 12:47:45 +01:00
parent_id: usize,
2024-12-12 11:34:45 +01:00
) -> Vec<usize> {
children
.iter()
.map(|child| {
match child {
JSXElementChild::JSXText(text) => {
let id = ctx.push_node(AstNode::JSXText, parent_id, &text.span);
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
let raw_id = ctx.str_table.insert(text.raw.as_str());
let value_id = ctx.str_table.insert(text.value.as_str());
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
append_usize(&mut ctx.result, raw_id);
append_usize(&mut ctx.result, value_id);
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
id
}
JSXElementChild::JSXExprContainer(container) => {
serialize_jsx_container_expr(ctx, container, parent_id)
}
JSXElementChild::JSXElement(el) => {
serialize_jsx_element(ctx, el, parent_id)
}
JSXElementChild::JSXFragment(frag) => {
serialize_jsx_fragment(ctx, frag, parent_id)
}
// No parser supports this
JSXElementChild::JSXSpreadChild(_) => unreachable!(),
2024-12-11 12:47:45 +01:00
}
2024-12-12 11:34:45 +01:00
})
.collect::<Vec<_>>()
2024-12-11 12:47:45 +01:00
}
fn serialize_jsx_member_expr(
ctx: &mut SerializeCtx,
node: &JSXMemberExpr,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 12:47:45 +01:00
let obj_id = match &node.obj {
JSXObject::JSXMemberExpr(member) => {
serialize_jsx_member_expr(ctx, member, id)
}
2024-12-12 10:53:12 +01:00
JSXObject::Ident(ident) => serialize_jsx_identifier(ctx, ident, parent_id),
2024-12-11 12:47:45 +01:00
};
let prop_id = serialize_ident_name_as_jsx_identifier(ctx, &node.prop, id);
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::JSXMemberExpression, parent_id, &node.span);
ctx.write_id(obj_id);
ctx.write_id(prop_id);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_jsx_element_name(
ctx: &mut SerializeCtx,
node: &JSXElementName,
parent_id: usize,
) -> usize {
match &node {
JSXElementName::Ident(ident) => {
2024-12-12 10:53:12 +01:00
serialize_jsx_identifier(ctx, ident, parent_id)
2024-12-11 12:47:45 +01:00
}
JSXElementName::JSXMemberExpr(member) => {
2024-12-12 10:53:12 +01:00
serialize_jsx_member_expr(ctx, member, parent_id)
2024-12-11 12:47:45 +01:00
}
JSXElementName::JSXNamespacedName(ns) => {
2024-12-12 10:53:12 +01:00
serialize_jsx_namespaced_name(ctx, ns, parent_id)
2024-12-11 12:47:45 +01:00
}
}
}
fn serialize_jsx_opening_element(
ctx: &mut SerializeCtx,
node: &JSXOpeningElement,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 12:47:45 +01:00
2024-12-11 17:10:05 +01:00
let mut flags = FlagValue::new();
2024-12-11 12:47:45 +01:00
if node.self_closing {
2024-12-11 17:10:05 +01:00
flags.set(Flag::JSXSelfClosing);
2024-12-11 12:47:45 +01:00
}
let name_id = serialize_jsx_element_name(ctx, &node.name, id);
// FIXME: type args
2024-12-12 11:34:45 +01:00
let attr_ids = node
.attrs
.iter()
.map(|attr| match attr {
2024-12-11 12:47:45 +01:00
JSXAttrOrSpread::JSXAttr(jsxattr) => {
2024-12-12 11:34:45 +01:00
let attr_id = ctx.next_id();
2024-12-11 12:47:45 +01:00
let name_id = match &jsxattr.name {
JSXAttrName::Ident(name) => {
2024-12-12 10:53:12 +01:00
serialize_ident_name_as_jsx_identifier(ctx, name, attr_id)
2024-12-11 12:47:45 +01:00
}
JSXAttrName::JSXNamespacedName(node) => {
serialize_jsx_namespaced_name(ctx, node, attr_id)
}
};
2024-12-12 11:34:45 +01:00
let value_id = jsxattr.value.as_ref().map_or(0, |value| match value {
JSXAttrValue::Lit(lit) => serialize_lit(ctx, lit, attr_id),
JSXAttrValue::JSXExprContainer(container) => {
serialize_jsx_container_expr(ctx, container, attr_id)
}
JSXAttrValue::JSXElement(el) => {
serialize_jsx_element(ctx, el, attr_id)
}
JSXAttrValue::JSXFragment(frag) => {
serialize_jsx_fragment(ctx, frag, attr_id)
}
});
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(attr_id, AstNode::JSXAttribute, id, &jsxattr.span);
ctx.write_id(name_id);
ctx.write_id(value_id);
2024-12-11 12:47:45 +01:00
attr_id
}
JSXAttrOrSpread::SpreadElement(spread) => {
2024-12-12 11:34:45 +01:00
let attr_id = ctx.next_id();
let child_id = serialize_expr(ctx, &spread.expr, attr_id);
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(attr_id, AstNode::JSXAttribute, id, &spread.span());
ctx.write_id(child_id);
2024-12-11 12:47:45 +01:00
attr_id
}
2024-12-12 11:34:45 +01:00
})
.collect::<Vec<_>>();
2024-12-11 12:47:45 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::JSXOpeningElement, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(name_id);
ctx.write_ids(attr_ids);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_jsx_container_expr(
ctx: &mut SerializeCtx,
node: &JSXExprContainer,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 12:47:45 +01:00
let child_id = match &node.expr {
JSXExpr::JSXEmptyExpr(expr) => serialize_jsx_empty_expr(ctx, expr, id),
2024-12-12 11:34:45 +01:00
JSXExpr::Expr(expr) => serialize_expr(ctx, expr, id),
2024-12-11 12:47:45 +01:00
};
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::JSXExpressionContainer, parent_id, &node.span);
ctx.write_id(child_id);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_jsx_empty_expr(
ctx: &mut SerializeCtx,
node: &JSXEmptyExpr,
parent_id: usize,
) -> usize {
2024-12-11 17:10:05 +01:00
ctx.push_node(AstNode::JSXEmptyExpression, parent_id, &node.span)
2024-12-11 12:47:45 +01:00
}
fn serialize_jsx_namespaced_name(
ctx: &mut SerializeCtx,
node: &JSXNamespacedName,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-11 12:47:45 +01:00
let ns_id = serialize_ident_name_as_jsx_identifier(ctx, &node.ns, id);
let name_id = serialize_ident_name_as_jsx_identifier(ctx, &node.name, id);
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::JSXNamespacedName, parent_id, &node.span);
ctx.write_id(ns_id);
ctx.write_id(name_id);
2024-12-11 12:47:45 +01:00
id
}
fn serialize_ident_name_as_jsx_identifier(
ctx: &mut SerializeCtx,
node: &IdentName,
parent_id: usize,
) -> usize {
let id = ctx.push_node(AstNode::JSXIdentifier, parent_id, &node.span);
let str_id = ctx.str_table.insert(node.sym.as_str());
append_usize(&mut ctx.result, str_id);
id
}
fn serialize_jsx_identifier(
ctx: &mut SerializeCtx,
node: &Ident,
parent_id: usize,
) -> usize {
let id = ctx.push_node(AstNode::JSXIdentifier, parent_id, &node.span);
let str_id = ctx.str_table.insert(node.sym.as_str());
append_usize(&mut ctx.result, str_id);
id
}
2024-12-10 04:33:33 +01:00
fn serialize_pat(ctx: &mut SerializeCtx, pat: &Pat, parent_id: usize) -> usize {
match pat {
2024-12-12 11:34:45 +01:00
Pat::Ident(node) => serialize_ident(ctx, &node.id, parent_id),
2024-12-10 04:33:33 +01:00
Pat::Array(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-10 04:33:33 +01:00
2024-12-12 01:35:57 +01:00
let mut flags = FlagValue::new();
if node.optional {
flags.set(Flag::ParamOptional);
}
2024-12-12 13:28:35 +01:00
let type_ann_id = maybe_serialize_ts_type_ann(ctx, &node.type_ann, id);
2024-12-12 01:35:57 +01:00
2024-12-12 11:34:45 +01:00
let children = node
.elems
.iter()
.map(|pat| pat.as_ref().map_or(0, |v| serialize_pat(ctx, &v, id)))
.collect::<Vec<_>>();
2024-12-10 04:33:33 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::ArrayPattern, parent_id, &node.span);
ctx.write_flags(&flags);
2024-12-12 13:28:35 +01:00
ctx.write_id(type_ann_id);
2024-12-12 11:34:45 +01:00
ctx.write_ids(children);
2024-12-10 04:33:33 +01:00
id
}
2024-12-10 21:17:02 +01:00
Pat::Rest(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-10 21:17:02 +01:00
2024-12-12 13:28:35 +01:00
let type_ann_id = maybe_serialize_ts_type_ann(ctx, &node.type_ann, id);
2024-12-10 21:17:02 +01:00
let arg_id = serialize_pat(ctx, &node.arg, parent_id);
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::RestElement, parent_id, &node.span);
2024-12-12 13:28:35 +01:00
ctx.write_id(type_ann_id);
2024-12-12 11:34:45 +01:00
ctx.write_id(arg_id);
2024-12-10 21:17:02 +01:00
id
}
Pat::Object(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-10 21:17:02 +01:00
2024-12-12 01:35:57 +01:00
let mut flags = FlagValue::new();
if node.optional {
flags.set(Flag::ParamOptional);
}
2024-12-10 21:17:02 +01:00
// FIXME: Type Ann
2024-12-12 11:34:45 +01:00
if let Some(type_ann) = &node.type_ann {}
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
let children = node
.props
.iter()
.map(|prop| match prop {
2024-12-10 21:17:02 +01:00
ObjectPatProp::KeyValue(key_value_prop) => {
2024-12-12 11:34:45 +01:00
let child_id = ctx.next_id();
2024-12-10 21:17:02 +01:00
let mut flags = FlagValue::new();
if let PropName::Computed(_) = key_value_prop.key {
flags.set(Flag::PropComputed)
}
let key_id =
serialize_prop_name(ctx, &key_value_prop.key, child_id);
let value_id =
serialize_pat(ctx, key_value_prop.value.as_ref(), child_id);
2024-12-12 11:34:45 +01:00
ctx.write_node(
child_id,
AstNode::Property,
id,
&key_value_prop.span(),
);
ctx.write_flags(&flags);
ctx.write_id(key_id);
ctx.write_id(value_id);
2024-12-10 21:17:02 +01:00
child_id
}
ObjectPatProp::Assign(assign_pat_prop) => {
2024-12-12 11:34:45 +01:00
let child_id = ctx.next_id();
2024-12-10 21:17:02 +01:00
let ident_id =
2024-12-12 11:34:45 +01:00
serialize_ident(ctx, &assign_pat_prop.key.id, parent_id);
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
let value_id = assign_pat_prop
.value
.as_ref()
.map_or(0, |value| serialize_expr(ctx, value, child_id));
ctx.write_node(
child_id,
AstNode::Property,
id,
&assign_pat_prop.span,
);
ctx.write_flags(&FlagValue::new());
ctx.write_id(ident_id);
ctx.write_id(value_id);
2024-12-10 21:17:02 +01:00
child_id
}
ObjectPatProp::Rest(rest_pat) => {
serialize_pat(ctx, &Pat::Rest(rest_pat.clone()), parent_id)
}
2024-12-12 11:34:45 +01:00
})
.collect::<Vec<_>>();
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::ObjectPattern, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_ids(children);
2024-12-10 21:17:02 +01:00
id
}
Pat::Assign(node) => {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
2024-12-10 21:17:02 +01:00
let left_id = serialize_pat(ctx, &node.left, id);
2024-12-12 11:34:45 +01:00
let right_id = serialize_expr(ctx, &node.right, id);
2024-12-10 21:17:02 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::AssignmentPattern, parent_id, &node.span);
ctx.write_id(left_id);
ctx.write_id(right_id);
2024-12-10 21:17:02 +01:00
id
}
2024-12-12 15:20:36 +01:00
Pat::Invalid(_) => unreachable!(),
2024-12-12 11:34:45 +01:00
Pat::Expr(node) => serialize_expr(ctx, node, parent_id),
2024-12-10 04:33:33 +01:00
}
}
2024-12-10 22:48:54 +01:00
fn serialize_for_head(
ctx: &mut SerializeCtx,
for_head: &ForHead,
parent_id: usize,
) -> usize {
match for_head {
ForHead::VarDecl(var_decl) => {
serialize_decl(ctx, &Decl::Var(var_decl.clone()), parent_id)
}
2024-12-12 15:20:36 +01:00
ForHead::UsingDecl(using_decl) => {
serialize_decl(ctx, &Decl::Using(using_decl.clone()), parent_id)
}
2024-12-10 22:48:54 +01:00
ForHead::Pat(pat) => serialize_pat(ctx, pat, parent_id),
}
}
fn serialize_spread(
ctx: &mut SerializeCtx,
expr: &Expr,
span: &Span,
parent_id: usize,
) -> usize {
2024-12-12 11:34:45 +01:00
let id = ctx.next_id();
let expr_id = serialize_expr(ctx, expr, id);
2024-12-10 22:48:54 +01:00
2024-12-12 11:34:45 +01:00
ctx.write_node(id, AstNode::Spread, parent_id, span);
ctx.write_id(expr_id);
2024-12-10 22:48:54 +01:00
id
}
2024-12-11 11:02:21 +01:00
fn serialize_ident_name(
ctx: &mut SerializeCtx,
ident_name: &IdentName,
parent_id: usize,
) -> usize {
let id = ctx.push_node(AstNode::Identifier, parent_id, &ident_name.span);
let str_id = ctx.str_table.insert(ident_name.sym.as_str());
append_usize(&mut ctx.result, str_id);
id
}
2024-12-10 04:33:33 +01:00
fn serialize_prop_name(
ctx: &mut SerializeCtx,
prop_name: &PropName,
parent_id: usize,
) -> usize {
match prop_name {
PropName::Ident(ident_name) => {
2024-12-11 11:02:21 +01:00
serialize_ident_name(ctx, ident_name, parent_id)
2024-12-10 04:33:33 +01:00
}
PropName::Str(str_prop) => {
let child_id =
ctx.push_node(AstNode::StringLiteral, parent_id, &str_prop.span);
2024-12-12 10:42:38 +01:00
let str_id = ctx.str_table.insert(str_prop.value.as_str());
2024-12-10 04:33:33 +01:00
append_usize(&mut ctx.result, str_id);
child_id
}
PropName::Num(number) => {
serialize_lit(ctx, &Lit::Num(number.clone()), parent_id)
}
2024-12-12 11:34:45 +01:00
PropName::Computed(node) => serialize_expr(ctx, &node.expr, parent_id),
2024-12-10 04:33:33 +01:00
PropName::BigInt(big_int) => {
serialize_lit(ctx, &Lit::BigInt(big_int.clone()), parent_id)
}
}
2024-12-05 11:21:34 +01:00
}
2024-12-10 04:33:33 +01:00
fn serialize_lit(ctx: &mut SerializeCtx, lit: &Lit, parent_id: usize) -> usize {
2024-12-04 16:21:17 +01:00
match lit {
2024-12-10 04:33:33 +01:00
Lit::Str(node) => {
let id = ctx.push_node(AstNode::StringLiteral, parent_id, &node.span);
2024-12-12 10:42:38 +01:00
let str_id = ctx.str_table.insert(node.value.as_str());
2024-12-10 04:33:33 +01:00
append_usize(&mut ctx.result, str_id);
id
}
2024-12-05 11:21:34 +01:00
Lit::Bool(lit_bool) => {
2024-12-10 04:33:33 +01:00
let id = ctx.push_node(AstNode::Bool, parent_id, &lit_bool.span);
let value: u8 = if lit_bool.value { 1 } else { 0 };
ctx.result.push(value);
id
}
Lit::Null(node) => ctx.push_node(AstNode::Null, parent_id, &node.span),
Lit::Num(node) => {
2024-12-10 22:48:54 +01:00
let id = ctx.push_node(AstNode::NumericLiteral, parent_id, &node.span);
2024-12-10 04:33:33 +01:00
let value = node.raw.as_ref().unwrap();
2024-12-12 10:42:38 +01:00
let str_id = ctx.str_table.insert(value.as_str());
2024-12-10 04:33:33 +01:00
append_usize(&mut ctx.result, str_id);
id
}
Lit::BigInt(node) => {
2024-12-10 22:48:54 +01:00
let id = ctx.push_node(AstNode::BigIntLiteral, parent_id, &node.span);
2024-12-10 04:33:33 +01:00
2024-12-12 10:53:12 +01:00
let str_id = ctx.str_table.insert(&node.value.to_string());
2024-12-10 04:33:33 +01:00
append_usize(&mut ctx.result, str_id);
id
}
Lit::Regex(node) => {
2024-12-10 22:48:54 +01:00
let id = ctx.push_node(AstNode::RegExpLiteral, parent_id, &node.span);
2024-12-10 04:33:33 +01:00
2024-12-12 10:42:38 +01:00
let pattern_id = ctx.str_table.insert(node.exp.as_str());
let flag_id = ctx.str_table.insert(node.flags.as_str());
2024-12-10 04:33:33 +01:00
append_usize(&mut ctx.result, pattern_id);
append_usize(&mut ctx.result, flag_id);
id
}
Lit::JSXText(jsxtext) => {
ctx.push_node(AstNode::JSXText, parent_id, &jsxtext.span)
}
2024-12-05 01:18:08 +01:00
}
}
2024-12-10 04:33:33 +01:00
fn serialize_ts_type(
ctx: &mut SerializeCtx,
2024-12-12 13:28:35 +01:00
node: &TsType,
parent_id: usize,
) -> usize {
match node {
TsType::TsKeywordType(node) => {
let kind = match node.kind {
TsKeywordTypeKind::TsAnyKeyword => AstNode::TSAnyKeyword,
TsKeywordTypeKind::TsUnknownKeyword => AstNode::TSUnknownKeyword,
TsKeywordTypeKind::TsNumberKeyword => AstNode::TSNumberKeyword,
TsKeywordTypeKind::TsObjectKeyword => AstNode::TSObjectKeyword,
TsKeywordTypeKind::TsBooleanKeyword => AstNode::TSBooleanKeyword,
TsKeywordTypeKind::TsBigIntKeyword => AstNode::TSBigIntKeyword,
TsKeywordTypeKind::TsStringKeyword => AstNode::TSStringKeyword,
TsKeywordTypeKind::TsSymbolKeyword => AstNode::TSSymbolKeyword,
TsKeywordTypeKind::TsVoidKeyword => AstNode::TSVoidKeyword,
TsKeywordTypeKind::TsUndefinedKeyword => AstNode::TSUndefinedKeyword,
TsKeywordTypeKind::TsNullKeyword => AstNode::TSNullKeyword,
TsKeywordTypeKind::TsNeverKeyword => AstNode::TSNeverKeyword,
TsKeywordTypeKind::TsIntrinsicKeyword => AstNode::TSIntrinsicKeyword,
};
ctx.push_node(kind, parent_id, &node.span)
}
TsType::TsThisType(node) => {
ctx.push_node(AstNode::TSThisType, parent_id, &node.span)
}
2024-12-12 15:20:36 +01:00
TsType::TsFnOrConstructorType(node) => {
match node {
TsFnOrConstructorType::TsFnType(node) => {
let id = ctx.next_id();
let param_ids = node
.params
.iter()
.map(|param| serialize_ts_fn_param(ctx, param, id))
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::TSFunctionType, parent_id, &node.span);
ctx.write_ids(param_ids);
//
id
}
TsFnOrConstructorType::TsConstructorType(ts_constructor_type) => {
todo!()
}
}
}
2024-12-12 13:28:35 +01:00
TsType::TsTypeRef(node) => {
let id = ctx.next_id();
2024-12-12 15:20:36 +01:00
let name_id = serialize_ts_entity_name(ctx, &node.type_name, id);
2024-12-12 13:28:35 +01:00
// FIXME params
ctx.write_node(id, AstNode::TSTypeReference, parent_id, &node.span);
ctx.write_id(name_id);
id
}
2024-12-12 15:20:36 +01:00
TsType::TsTypeQuery(node) => {
let id = ctx.next_id();
let name_id = match &node.expr_name {
TsTypeQueryExpr::TsEntityName(entity) => {
serialize_ts_entity_name(ctx, entity, id)
}
TsTypeQueryExpr::Import(ts_import_type) => todo!(),
};
// FIXME: params
ctx.write_node(id, AstNode::TSTypeQuery, parent_id, &node.span);
ctx.write_id(name_id);
id
}
2024-12-12 13:28:35 +01:00
TsType::TsTypeLit(ts_type_lit) => todo!(),
TsType::TsArrayType(ts_array_type) => todo!(),
2024-12-12 15:20:36 +01:00
TsType::TsTupleType(node) => {
let id = ctx.next_id();
let children = node
.elem_types
.iter()
.map(|elem| todo!())
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::TSTupleType, parent_id, &node.span);
ctx.write_ids(children);
id
}
2024-12-12 13:28:35 +01:00
TsType::TsOptionalType(ts_optional_type) => todo!(),
TsType::TsRestType(ts_rest_type) => todo!(),
TsType::TsUnionOrIntersectionType(node) => match node {
TsUnionOrIntersectionType::TsUnionType(node) => {
let id = ctx.next_id();
let children = node
.types
.iter()
.map(|item| serialize_ts_type(ctx, item, id))
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::TSUnionType, parent_id, &node.span);
ctx.write_ids(children);
id
}
TsUnionOrIntersectionType::TsIntersectionType(node) => {
let id = ctx.next_id();
let children = node
.types
.iter()
.map(|item| serialize_ts_type(ctx, item, id))
.collect::<Vec<_>>();
ctx.write_node(id, AstNode::TSIntersectionType, parent_id, &node.span);
ctx.write_ids(children);
id
}
},
TsType::TsConditionalType(node) => {
let id = ctx.next_id();
let check_id = serialize_ts_type(ctx, &node.check_type, id);
let extends_id = serialize_ts_type(ctx, &node.extends_type, id);
let true_id = serialize_ts_type(ctx, &node.true_type, id);
let false_id = serialize_ts_type(ctx, &node.false_type, id);
ctx.write_node(id, AstNode::TSConditionalType, parent_id, &node.span);
ctx.write_id(check_id);
ctx.write_id(extends_id);
ctx.write_id(true_id);
ctx.write_id(false_id);
id
}
TsType::TsInferType(node) => {
let id = ctx.next_id();
let param_id = serialize_ts_type_param(ctx, &node.type_param, parent_id);
ctx.write_node(id, AstNode::TSInferType, parent_id, &node.span);
ctx.write_id(param_id);
id
}
TsType::TsParenthesizedType(ts_parenthesized_type) => todo!(),
TsType::TsTypeOperator(ts_type_operator) => todo!(),
TsType::TsIndexedAccessType(ts_indexed_access_type) => todo!(),
TsType::TsMappedType(node) => {
let id = ctx.next_id();
let mut optional_flags = FlagValue::new();
let mut readonly_flags = FlagValue::new();
if let Some(optional) = node.optional {
optional_flags.set(match optional {
TruePlusMinus::True => Flag::TsTrue,
TruePlusMinus::Plus => Flag::TsPlus,
TruePlusMinus::Minus => Flag::TsMinus,
});
}
if let Some(readonly) = node.readonly {
readonly_flags.set(match readonly {
TruePlusMinus::True => Flag::TsTrue,
TruePlusMinus::Plus => Flag::TsPlus,
TruePlusMinus::Minus => Flag::TsMinus,
});
}
let name_id = maybe_serialize_ts_type(ctx, &node.name_type, id);
let type_ann_id = maybe_serialize_ts_type(ctx, &node.type_ann, id);
// FIXME
ctx.write_node(id, AstNode::TSMappedType, parent_id, &node.span);
ctx.write_flags(&optional_flags);
ctx.write_flags(&readonly_flags);
ctx.write_id(name_id);
ctx.write_id(type_ann_id);
id
}
TsType::TsLitType(node) => {
let id = ctx.next_id();
let child_id = match &node.lit {
TsLit::Number(lit) => serialize_lit(ctx, &Lit::Num(lit.clone()), id),
TsLit::Str(lit) => serialize_lit(ctx, &Lit::Str(lit.clone()), id),
TsLit::Bool(lit) => serialize_lit(ctx, &Lit::Bool(lit.clone()), id),
TsLit::BigInt(lit) => serialize_lit(ctx, &Lit::BigInt(lit.clone()), id),
TsLit::Tpl(lit) => serialize_expr(
ctx,
&Expr::Tpl(Tpl {
span: lit.span,
exprs: vec![],
quasis: lit.quasis.clone(),
}),
id,
),
};
ctx.write_node(id, AstNode::TSLiteralType, parent_id, &node.span);
ctx.write_id(child_id);
id
}
TsType::TsTypePredicate(ts_type_predicate) => todo!(),
TsType::TsImportType(ts_import_type) => todo!(),
}
}
2024-12-12 15:20:36 +01:00
fn serialize_ts_entity_name(
ctx: &mut SerializeCtx,
node: &TsEntityName,
parent_id: usize,
) -> usize {
match &node {
TsEntityName::TsQualifiedName(ts_qualified_name) => todo!(),
TsEntityName::Ident(ident) => serialize_ident(ctx, ident, parent_id),
}
}
2024-12-12 13:28:35 +01:00
fn maybe_serialize_ts_type_ann(
ctx: &mut SerializeCtx,
node: &Option<Box<TsTypeAnn>>,
parent_id: usize,
) -> usize {
node.as_ref().map_or(0, |type_ann| {
serialize_ts_type_ann(ctx, type_ann, parent_id)
})
}
fn serialize_ts_type_ann(
ctx: &mut SerializeCtx,
node: &TsTypeAnn,
2024-12-10 04:33:33 +01:00
parent_id: usize,
) -> usize {
2024-12-12 13:28:35 +01:00
let id = ctx.next_id();
let type_ann_id = serialize_ts_type(ctx, &node.type_ann, id);
ctx.write_node(id, AstNode::TSTypeAnnotation, parent_id, &node.span);
ctx.write_id(type_ann_id);
id
}
fn maybe_serialize_ts_type(
ctx: &mut SerializeCtx,
node: &Option<Box<TsType>>,
parent_id: usize,
) -> usize {
node
.as_ref()
.map_or(0, |item| serialize_ts_type(ctx, item, parent_id))
}
fn serialize_ts_type_param(
ctx: &mut SerializeCtx,
node: &TsTypeParam,
parent_id: usize,
) -> usize {
let id = ctx.next_id();
let mut flags = FlagValue::new();
// FIXME: flags
let name_id = serialize_ident(ctx, &node.name, id);
let constraint_id = maybe_serialize_ts_type(ctx, &node.constraint, id);
let default_id = maybe_serialize_ts_type(ctx, &node.default, id);
ctx.write_node(id, AstNode::TSTypeParameter, parent_id, &node.span);
ctx.write_flags(&flags);
ctx.write_id(name_id);
ctx.write_id(constraint_id);
ctx.write_id(default_id);
id
}
fn maybe_serialize_ts_type_param(
ctx: &mut SerializeCtx,
node: &Option<Box<TsTypeParamDecl>>,
parent_id: usize,
) -> usize {
node.as_ref().map_or(0, |node| {
let id = ctx.next_id();
let children = node
.params
.iter()
.map(|param| serialize_ts_type_param(ctx, param, id))
.collect::<Vec<_>>();
ctx.write_node(
id,
AstNode::TSTypeParameterDeclaration,
parent_id,
&node.span,
);
ctx.write_ids(children);
id
})
2024-12-04 16:21:17 +01:00
}
2024-12-12 15:20:36 +01:00
fn serialize_ts_fn_param(
ctx: &mut SerializeCtx,
node: &TsFnParam,
parent_id: usize,
) -> usize {
match node {
TsFnParam::Ident(ident) => serialize_ident(ctx, ident, parent_id),
TsFnParam::Array(pat) => {
serialize_pat(ctx, &Pat::Array(pat.clone()), parent_id)
}
TsFnParam::Rest(pat) => {
serialize_pat(ctx, &Pat::Rest(pat.clone()), parent_id)
}
TsFnParam::Object(pat) => {
serialize_pat(ctx, &Pat::Object(pat.clone()), parent_id)
}
}
}