1use crate::error::SyntaxError;
2use crate::error::SyntaxErrorType;
3use crate::loc::Loc;
4use crate::num::JsNumber;
5use crate::operator::OperatorName;
6use ahash::AHashMap;
7use core::fmt::Debug;
8use serde::Serialize;
9use serde::Serializer;
10use std::any::Any;
11use std::any::TypeId;
12use std::fmt;
13use std::fmt::Formatter;
14
15#[derive(Default)]
16pub struct NodeAssocData {
17  map: AHashMap<TypeId, Box<dyn Any>>,
18}
19
20impl NodeAssocData {
21  pub fn get<T: Any>(&self) -> Option<&T> {
22    let t = TypeId::of::<T>();
23    self.map.get(&t).map(|v| v.downcast_ref().unwrap())
24  }
25
26  pub fn set<T: Any>(&mut self, v: T) {
27    let t = TypeId::of::<T>();
28    self.map.insert(t, Box::from(v));
29  }
30}
31
32#[cfg(test)]
33mod tests {
34  use crate::ast::NodeAssocData;
35
36  #[test]
37  fn test_node_assoc_data() {
38    struct MyType(u32);
39    let mut assoc = NodeAssocData::default();
40    assoc.set(MyType(32));
41    let v = assoc.get::<MyType>().unwrap();
42    assert_eq!(v.0, 32);
43  }
44}
45
46pub struct Node {
47  pub loc: Loc,
49  pub stx: Box<Syntax>,
50  pub assoc: NodeAssocData,
51}
52
53impl Node {
54  pub fn new(loc: Loc, stx: Syntax) -> Node {
55    Node {
56      loc,
57      stx: Box::new(stx),
58      assoc: NodeAssocData::default(),
59    }
60  }
61
62  pub fn error(&self, typ: SyntaxErrorType) -> SyntaxError {
64    self.loc.error(typ, None)
65  }
66
67  pub fn as_ident(&self) -> &str {
68    match self.stx.as_ref() {
69      Syntax::IdentifierExpr { name } => name.as_str(),
70      _ => unreachable!(),
71    }
72  }
73}
74
75impl Debug for Node {
76  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
77    self.stx.fmt(f)
78  }
79}
80
81impl Serialize for Node {
82  fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
83    self.stx.serialize(serializer)
84  }
85}
86
87type Declaration = Node;
89type Expression = Node;
90type Pattern = Node;
91type Statement = Node;
92
93#[derive(Eq, PartialEq, Clone, Copy, Debug, Serialize)]
94pub enum VarDeclMode {
95  Const,
96  Let,
97  Var,
98}
99
100#[derive(Debug, Serialize)]
101pub enum ArrayElement {
102  Single(Expression),
103  Rest(Expression),
104  Empty,
105}
106
107#[derive(Debug, Serialize)]
109pub enum ClassOrObjectMemberKey {
110  Direct(String),
113  Computed(Expression),
114}
115
116#[derive(Debug, Serialize)]
117pub enum ClassOrObjectMemberValue {
118  Getter {
119    function: Node, },
121  Method {
122    function: Node, },
124  Property {
125    initializer: Option<Expression>,
127  },
128  Setter {
129    function: Node, },
131}
132
133#[derive(Debug, Serialize)]
134pub enum ObjectMemberType {
135  Valued {
136    key: ClassOrObjectMemberKey,
137    value: ClassOrObjectMemberValue,
138  },
139  Shorthand {
140    identifier: Node, },
142  Rest {
143    value: Expression,
144  },
145}
146
147#[derive(Debug, Serialize)]
148pub struct ArrayPatternElement {
149  pub target: Pattern,
150  pub default_value: Option<Expression>,
151}
152
153#[derive(Debug, Serialize)]
154pub struct ExportName {
155  pub target: String,
157  pub alias: Pattern,
159}
160
161#[derive(Debug, Serialize)]
162pub enum ExportNames {
163  All(Option<Pattern>),
168  Specific(Vec<ExportName>),
173}
174
175#[derive(Debug, Serialize)]
176pub struct VariableDeclarator {
177  pub pattern: Pattern,
178  pub initializer: Option<Expression>,
179}
180
181#[derive(Debug, Serialize)]
182pub enum ForInit {
183  None,
184  Expression(Expression),
185  Declaration(Declaration),
186}
187
188#[derive(Debug, Serialize)]
189pub enum LiteralTemplatePart {
190  Substitution(Expression),
191  String(String),
192}
193
194#[derive(Debug, Serialize)]
195#[serde(tag = "$t")]
196pub enum Syntax {
197  IdentifierPattern {
199    name: String,
200  },
201  ArrayPattern {
203    elements: Vec<Option<ArrayPatternElement>>,
205    rest: Option<Pattern>,
206  },
207  ObjectPattern {
210    properties: Vec<Node>,
212    rest: Option<Pattern>,
214  },
215  ClassOrFunctionName {
217    name: String,
218  },
219
220  Function {
223    arrow: bool,
224    async_: bool,
225    generator: bool,
226    parameters: Vec<Declaration>, body: Node, },
229  FunctionBody {
231    body: Vec<Statement>,
232  },
233
234  ClassDecl {
236    export: bool,
237    export_default: bool,
238    name: Option<Node>, extends: Option<Expression>,
240    members: Vec<Node>, },
242  FunctionDecl {
243    export: bool,
244    export_default: bool,
245    name: Option<Node>, function: Node,     },
248  ParamDecl {
249    rest: bool,
250    pattern: Pattern,
251    default_value: Option<Expression>,
252  },
253  VarDecl {
254    export: bool,
255    mode: VarDeclMode,
256    declarators: Vec<VariableDeclarator>,
257  },
258
259  ArrowFunctionExpr {
261    parenthesised: bool,
262    function: Node, },
264  BinaryExpr {
265    parenthesised: bool,
266    operator: OperatorName,
267    left: Expression,
268    right: Expression,
269  },
270  CallExpr {
271    optional_chaining: bool,
272    parenthesised: bool,
273    callee: Expression,
274    arguments: Vec<Node>,
275  },
276  ClassExpr {
277    parenthesised: bool,
278    name: Option<Node>,
279    extends: Option<Expression>,
280    members: Vec<Node>, },
282  ConditionalExpr {
283    parenthesised: bool,
284    test: Expression,
285    consequent: Expression,
286    alternate: Expression,
287  },
288  ComputedMemberExpr {
289    optional_chaining: bool,
290    object: Expression,
291    member: Expression,
292  },
293  FunctionExpr {
294    parenthesised: bool,
295    name: Option<Node>,
296    function: Node,
297  },
298  IdentifierExpr {
299    name: String,
300  },
301  ImportExpr {
302    module: Expression,
303  },
304  ImportMeta {},
305  JsxAttribute {
306    name: Expression,          value: Option<Expression>, },
309  JsxElement {
310    name: Option<Expression>, attributes: Vec<Expression>, children: Vec<Expression>, },
317  JsxExpressionContainer {
318    value: Expression,
319  },
320  JsxMemberExpression {
321    base: Node, path: Vec<String>,
324  },
325  JsxName {
326    namespace: Option<String>,
327    name: String,
328  },
329  JsxSpreadAttribute {
330    value: Expression,
331  },
332  JsxText {
333    value: String,
334  },
335  LiteralArrayExpr {
336    elements: Vec<ArrayElement>,
337  },
338  LiteralBigIntExpr {
339    value: String,
340  },
341  LiteralBooleanExpr {
342    value: bool,
343  },
344  LiteralNull {},
345  LiteralNumberExpr {
346    value: JsNumber,
347  },
348  LiteralObjectExpr {
349    members: Vec<Node>,
351  },
352  LiteralRegexExpr {
353    value: String, },
355  LiteralStringExpr {
356    value: String,
357  },
358  LiteralTemplateExpr {
359    parts: Vec<LiteralTemplatePart>,
360  },
361  MemberExpr {
363    parenthesised: bool,
364    optional_chaining: bool,
365    left: Expression,
366    right: String,
367  },
368  SuperExpr {},
369  ThisExpr {},
370  TaggedTemplateExpr {
371    function: Expression,
372    parts: Vec<LiteralTemplatePart>,
373  },
374  UnaryExpr {
375    parenthesised: bool,
376    operator: OperatorName,
377    argument: Expression,
378  },
379  UnaryPostfixExpr {
380    parenthesised: bool,
381    operator: OperatorName,
382    argument: Expression,
383  },
384
385  BlockStmt {
387    body: Vec<Statement>,
388  },
389  BreakStmt {
390    label: Option<String>,
391  },
392  ContinueStmt {
393    label: Option<String>,
394  },
395  DebuggerStmt {},
396  DoWhileStmt {
397    condition: Expression,
398    body: Statement,
399  },
400  EmptyStmt {},
401  ExportDefaultExprStmt {
402    expression: Expression,
403  },
404  ExportListStmt {
405    names: ExportNames,
406    from: Option<String>,
407  },
408  ExpressionStmt {
409    expression: Expression,
410  },
411  IfStmt {
412    test: Expression,
413    consequent: Statement,
414    alternate: Option<Statement>,
415  },
416  ImportStmt {
417    default: Option<Pattern>,
419    names: Option<ExportNames>,
420    module: String,
421  },
422  ForStmt {
423    init: ForInit,
424    condition: Option<Expression>,
425    post: Option<Expression>,
426    body: Statement, },
428  ForInStmt {
429    decl_mode: Option<VarDeclMode>,
431    pat: Pattern,
432    rhs: Expression,
433    body: Statement, },
435  ForOfStmt {
436    await_: bool,
437    decl_mode: Option<VarDeclMode>,
439    pat: Pattern,
440    rhs: Expression,
441    body: Statement, },
443  LabelStmt {
444    name: String,
445    statement: Statement,
446  },
447  ReturnStmt {
448    value: Option<Expression>,
449  },
450  SwitchStmt {
451    test: Expression,
452    branches: Vec<Node>,
453  },
454  ThrowStmt {
455    value: Expression,
456  },
457  TryStmt {
458    wrapped: Statement,
459    catch: Option<Node>,
461    finally: Option<Statement>,
462  },
463  WhileStmt {
464    condition: Expression,
465    body: Statement,
466  },
467
468  TopLevel {
470    body: Vec<Statement>,
471  },
472  CallArg {
473    spread: bool,
474    value: Expression,
475  },
476  CatchBlock {
477    parameter: Option<Pattern>,
478    body: Vec<Statement>, },
480  ClassMember {
481    key: ClassOrObjectMemberKey,
482    static_: bool,
483    value: ClassOrObjectMemberValue,
484  },
485  ForBody {
487    body: Vec<Statement>,
488  },
489  ObjectMember {
491    typ: ObjectMemberType,
492  },
493  ObjectPatternProperty {
494    key: ClassOrObjectMemberKey,
495    target: Pattern,
497    shorthand: bool,
498    default_value: Option<Expression>,
499  },
500  SwitchBranch {
501    case: Option<Expression>,
503    body: Vec<Statement>,
504  },
505}