Skip to main content

tsz_parser/parser/
node.rs

1//! Thin `Node` Architecture for Cache-Efficient AST
2//!
3//! This module implements a cache-optimized AST representation where each node
4//! is exactly 16 bytes (4 nodes per 64-byte cache line), compared to the
5//! previous 208-byte Node enum (0.31 nodes per cache line).
6//!
7//! # Architecture
8//!
9//! Instead of a single large enum, we use:
10//! 1. `Node` - A 16-byte header containing kind, flags, position, and a data index
11//! 2. Typed storage pools - Separate Vec<T> for each node category
12//!
13//! The `data_index` field points into the appropriate pool based on `kind`.
14//!
15//! # Performance Impact
16//!
17//! - **Before**: 208 bytes/node = 0.31 nodes/cache-line
18//! - **After**: 16 bytes/node = 4 nodes/cache-line
19//! - **Improvement**: 13x better cache locality for AST traversal
20//!
21//! # Design Principles
22//!
23//! 1. **Common data inline**: kind, flags, pos, end are accessed constantly
24//! 2. **Rare data indirect**: modifiers, type parameters, etc. via index
25//! 3. **No heap allocation per node**: All storage in arena vectors
26//! 4. **O(1) node access**: Direct index into typed pool
27
28use super::base::{NodeIndex, NodeList};
29use serde::{Deserialize, Serialize};
30use std::sync::Arc;
31use tsz_common::interner::{Atom, Interner};
32
33/// A thin 16-byte node header for cache-efficient AST storage.
34///
35/// Layout (16 bytes total):
36/// - `kind`: 2 bytes (`SyntaxKind` value, supports 0-65535)
37/// - `flags`: 2 bytes (packed `NodeFlags`)
38/// - `pos`: 4 bytes (start position in source)
39/// - `end`: 4 bytes (end position in source)
40/// - `data_index`: 4 bytes (index into type-specific pool, `u32::MAX` = no data)
41#[repr(C)]
42#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
43pub struct Node {
44    /// `SyntaxKind` value (u16 to support extended kinds up to 400+)
45    pub kind: u16,
46    /// Packed node flags (subset of `NodeFlags` that fits in u16)
47    pub flags: u16,
48    /// Start position in source (character index)
49    pub pos: u32,
50    /// End position in source (character index)
51    pub end: u32,
52    /// Index into the type-specific storage pool (`u32::MAX` = no data)
53    pub data_index: u32,
54}
55
56impl Node {
57    pub const NO_DATA: u32 = u32::MAX;
58
59    /// Create a new thin node with no associated data
60    #[inline]
61    #[must_use]
62    pub const fn new(kind: u16, pos: u32, end: u32) -> Self {
63        Self {
64            kind,
65            flags: 0,
66            pos,
67            end,
68            data_index: Self::NO_DATA,
69        }
70    }
71
72    /// Create a new thin node with data index
73    #[inline]
74    #[must_use]
75    pub const fn with_data(kind: u16, pos: u32, end: u32, data_index: u32) -> Self {
76        Self {
77            kind,
78            flags: 0,
79            pos,
80            end,
81            data_index,
82        }
83    }
84
85    /// Create a new thin node with data index and flags
86    #[inline]
87    #[must_use]
88    pub const fn with_data_and_flags(
89        kind: u16,
90        pos: u32,
91        end: u32,
92        data_index: u32,
93        flags: u16,
94    ) -> Self {
95        Self {
96            kind,
97            flags,
98            pos,
99            end,
100            data_index,
101        }
102    }
103
104    /// Check if this node has associated data
105    #[inline]
106    #[must_use]
107    pub const fn has_data(&self) -> bool {
108        self.data_index != Self::NO_DATA
109    }
110}
111
112// =============================================================================
113// Node Category Classification
114// =============================================================================
115
116/// Categories of nodes that share storage pools.
117/// Nodes in the same category have similar data layouts.
118#[derive(Clone, Copy, Debug, PartialEq, Eq)]
119pub enum NodeCategory {
120    /// Simple tokens with no additional data (keywords, operators, etc.)
121    Token,
122    /// Identifiers with text data
123    Identifier,
124    /// String/numeric/regex literals with text
125    Literal,
126    /// Binary, unary, conditional expressions
127    Expression,
128    /// Function declarations and expressions
129    Function,
130    /// Class declarations
131    Class,
132    /// Statements (if, for, while, etc.)
133    Statement,
134    /// Type nodes (`TypeReference`, `UnionType`, etc.)
135    TypeNode,
136    /// Import/export declarations
137    Module,
138    /// JSX elements
139    Jsx,
140    /// Source file (only one per parse)
141    SourceFile,
142}
143
144// =============================================================================
145// Typed Data Pools
146// =============================================================================
147
148/// Data for identifier nodes (`Identifier`, `PrivateIdentifier`)
149#[derive(Clone, Debug, Serialize, Deserialize)]
150pub struct IdentifierData {
151    /// Interned atom for O(1) comparison (`OPTIMIZATION`: use this instead of `escaped_text`)
152    #[serde(skip, default = "Atom::none")]
153    pub atom: Atom,
154    /// The identifier text (DEPRECATED: kept for backward compatibility during migration)
155    pub escaped_text: String,
156    pub original_text: Option<String>,
157    pub type_arguments: Option<NodeList>,
158}
159
160/// Data for string literals (`StringLiteral`, template parts)
161#[derive(Clone, Debug, Serialize, Deserialize)]
162pub struct LiteralData {
163    pub text: String,
164    pub raw_text: Option<String>,
165    /// For numeric literals only
166    pub value: Option<f64>,
167}
168
169/// Data for binary expressions
170#[derive(Clone, Debug, Serialize, Deserialize)]
171pub struct BinaryExprData {
172    pub left: NodeIndex,
173    pub operator_token: u16, // SyntaxKind
174    pub right: NodeIndex,
175}
176
177/// Data for unary expressions (prefix/postfix)
178#[derive(Clone, Debug, Serialize, Deserialize)]
179pub struct UnaryExprData {
180    pub operator: u16, // SyntaxKind
181    pub operand: NodeIndex,
182}
183
184/// Data for call/new expressions
185#[derive(Clone, Debug, Serialize, Deserialize)]
186pub struct CallExprData {
187    pub expression: NodeIndex,
188    pub type_arguments: Option<NodeList>,
189    pub arguments: Option<NodeList>,
190}
191
192/// Data for property/element access
193#[derive(Clone, Debug, Serialize, Deserialize)]
194pub struct AccessExprData {
195    pub expression: NodeIndex,
196    pub name_or_argument: NodeIndex,
197    pub question_dot_token: bool,
198}
199
200/// Data for function declarations/expressions/arrows
201#[derive(Clone, Debug, Serialize, Deserialize)]
202pub struct FunctionData {
203    pub modifiers: Option<NodeList>,
204    pub is_async: bool,       // Async function
205    pub asterisk_token: bool, // Generator function
206    pub name: NodeIndex,
207    pub type_parameters: Option<NodeList>,
208    pub parameters: NodeList,
209    pub type_annotation: NodeIndex,
210    pub body: NodeIndex,
211    pub equals_greater_than_token: bool, // For arrows
212}
213
214/// Data for class declarations
215#[derive(Clone, Debug, Serialize, Deserialize)]
216pub struct ClassData {
217    pub modifiers: Option<NodeList>,
218    pub name: NodeIndex,
219    pub type_parameters: Option<NodeList>,
220    pub heritage_clauses: Option<NodeList>,
221    pub members: NodeList,
222}
223
224/// Data for if statements
225#[derive(Clone, Debug, Serialize, Deserialize)]
226pub struct IfStatementData {
227    pub expression: NodeIndex,
228    pub then_statement: NodeIndex,
229    pub else_statement: NodeIndex,
230}
231
232/// Data for for/while/do loops
233#[derive(Clone, Debug, Serialize, Deserialize)]
234pub struct LoopData {
235    pub initializer: NodeIndex,
236    pub condition: NodeIndex,
237    pub incrementor: NodeIndex,
238    pub statement: NodeIndex,
239}
240
241/// Data for block statements
242#[derive(Clone, Debug, Serialize, Deserialize)]
243pub struct BlockData {
244    pub statements: NodeList,
245    pub multi_line: bool,
246}
247
248/// Data for expression statements
249#[derive(Clone, Copy, Debug)]
250pub struct ExpressionStatementData {
251    pub expression: NodeIndex,
252}
253
254/// Data for variable declarations
255#[derive(Clone, Debug, Serialize, Deserialize)]
256pub struct VariableData {
257    pub modifiers: Option<NodeList>,
258    pub declarations: NodeList,
259}
260
261/// Data for type references
262#[derive(Clone, Debug, Serialize, Deserialize)]
263pub struct TypeRefData {
264    pub type_name: NodeIndex,
265    pub type_arguments: Option<NodeList>,
266}
267
268/// Data for union/intersection types
269#[derive(Clone, Debug, Serialize, Deserialize)]
270pub struct CompositeTypeData {
271    pub types: NodeList,
272}
273
274/// Data for conditional expressions (a ? b : c)
275#[derive(Clone, Debug, Serialize, Deserialize)]
276pub struct ConditionalExprData {
277    pub condition: NodeIndex,
278    pub when_true: NodeIndex,
279    pub when_false: NodeIndex,
280}
281
282/// Data for object/array literals
283#[derive(Clone, Debug, Serialize, Deserialize)]
284pub struct LiteralExprData {
285    pub elements: NodeList,
286    pub multi_line: bool,
287}
288
289/// Data for parenthesized expressions
290#[derive(Clone, Debug, Serialize, Deserialize)]
291pub struct ParenthesizedData {
292    pub expression: NodeIndex,
293}
294
295/// Data for spread/await/yield expressions
296#[derive(Clone, Debug, Serialize, Deserialize)]
297pub struct UnaryExprDataEx {
298    pub expression: NodeIndex,
299    pub asterisk_token: bool, // For yield*
300}
301
302/// Data for as/satisfies/type assertion expressions
303#[derive(Clone, Debug, Serialize, Deserialize)]
304pub struct TypeAssertionData {
305    pub expression: NodeIndex,
306    pub type_node: NodeIndex,
307}
308
309/// Data for return/throw statements
310#[derive(Clone, Debug, Serialize, Deserialize)]
311pub struct ReturnData {
312    pub expression: NodeIndex,
313}
314
315/// Data for expression statements
316#[derive(Clone, Debug, Serialize, Deserialize)]
317pub struct ExprStatementData {
318    pub expression: NodeIndex,
319}
320
321/// Data for switch statements
322#[derive(Clone, Debug, Serialize, Deserialize)]
323pub struct SwitchData {
324    pub expression: NodeIndex,
325    pub case_block: NodeIndex,
326}
327
328/// Data for case/default clauses
329#[derive(Clone, Debug, Serialize, Deserialize)]
330pub struct CaseClauseData {
331    pub expression: NodeIndex, // NONE for default clause
332    pub statements: NodeList,
333}
334
335/// Data for try statements
336#[derive(Clone, Debug, Serialize, Deserialize)]
337pub struct TryData {
338    pub try_block: NodeIndex,
339    pub catch_clause: NodeIndex,
340    pub finally_block: NodeIndex,
341}
342
343/// Data for catch clauses
344#[derive(Clone, Debug, Serialize, Deserialize)]
345pub struct CatchClauseData {
346    pub variable_declaration: NodeIndex,
347    pub block: NodeIndex,
348}
349
350/// Data for labeled statements
351#[derive(Clone, Debug, Serialize, Deserialize)]
352pub struct LabeledData {
353    pub label: NodeIndex,
354    pub statement: NodeIndex,
355}
356
357/// Data for break/continue statements
358#[derive(Clone, Debug, Serialize, Deserialize)]
359pub struct JumpData {
360    pub label: NodeIndex,
361}
362
363/// Data for with statements
364#[derive(Clone, Debug, Serialize, Deserialize)]
365pub struct WithData {
366    pub expression: NodeIndex,
367    pub statement: NodeIndex,
368}
369
370/// Data for interface declarations
371#[derive(Clone, Debug, Serialize, Deserialize)]
372pub struct InterfaceData {
373    pub modifiers: Option<NodeList>,
374    pub name: NodeIndex,
375    pub type_parameters: Option<NodeList>,
376    pub heritage_clauses: Option<NodeList>,
377    pub members: NodeList,
378}
379
380/// Data for type alias declarations
381#[derive(Clone, Debug, Serialize, Deserialize)]
382pub struct TypeAliasData {
383    pub modifiers: Option<NodeList>,
384    pub name: NodeIndex,
385    pub type_parameters: Option<NodeList>,
386    pub type_node: NodeIndex,
387}
388
389/// Data for enum declarations
390#[derive(Clone, Debug, Serialize, Deserialize)]
391pub struct EnumData {
392    pub modifiers: Option<NodeList>,
393    pub name: NodeIndex,
394    pub members: NodeList,
395}
396
397/// Data for enum members
398#[derive(Clone, Debug, Serialize, Deserialize)]
399pub struct EnumMemberData {
400    pub name: NodeIndex,
401    pub initializer: NodeIndex,
402}
403
404/// Data for module/namespace declarations
405#[derive(Clone, Debug, Serialize, Deserialize)]
406pub struct ModuleData {
407    pub modifiers: Option<NodeList>,
408    pub name: NodeIndex,
409    pub body: NodeIndex,
410}
411
412/// Data for module blocks: { statements }
413#[derive(Clone, Debug, Serialize, Deserialize)]
414pub struct ModuleBlockData {
415    pub statements: Option<NodeList>,
416}
417
418/// Data for property/method signatures
419#[derive(Clone, Debug, Serialize, Deserialize)]
420pub struct SignatureData {
421    pub modifiers: Option<NodeList>,
422    pub name: NodeIndex,
423    pub question_token: bool,
424    pub type_parameters: Option<NodeList>,
425    pub parameters: Option<NodeList>,
426    pub type_annotation: NodeIndex,
427}
428
429/// Data for index signatures
430#[derive(Clone, Debug, Serialize, Deserialize)]
431pub struct IndexSignatureData {
432    pub modifiers: Option<NodeList>,
433    pub parameters: NodeList,
434    pub type_annotation: NodeIndex,
435}
436
437/// Data for property declarations
438#[derive(Clone, Debug, Serialize, Deserialize)]
439pub struct PropertyDeclData {
440    pub modifiers: Option<NodeList>,
441    pub name: NodeIndex,
442    pub question_token: bool,
443    pub exclamation_token: bool,
444    pub type_annotation: NodeIndex,
445    pub initializer: NodeIndex,
446}
447
448/// Data for method declarations (class methods)
449#[derive(Clone, Debug, Serialize, Deserialize)]
450pub struct MethodDeclData {
451    pub modifiers: Option<NodeList>,
452    pub asterisk_token: bool,
453    pub name: NodeIndex,
454    pub question_token: bool,
455    pub type_parameters: Option<NodeList>,
456    pub parameters: NodeList,
457    pub type_annotation: NodeIndex,
458    pub body: NodeIndex,
459}
460
461/// Data for constructor declarations
462#[derive(Clone, Debug, Serialize, Deserialize)]
463pub struct ConstructorData {
464    pub modifiers: Option<NodeList>,
465    pub type_parameters: Option<NodeList>,
466    pub parameters: NodeList,
467    pub body: NodeIndex,
468}
469
470/// Data for accessor declarations (get/set)
471#[derive(Clone, Debug, Serialize, Deserialize)]
472pub struct AccessorData {
473    pub modifiers: Option<NodeList>,
474    pub name: NodeIndex,
475    pub type_parameters: Option<NodeList>,
476    pub parameters: NodeList,
477    pub type_annotation: NodeIndex,
478    pub body: NodeIndex,
479}
480
481/// Data for parameter declarations
482#[derive(Clone, Debug, Serialize, Deserialize)]
483pub struct ParameterData {
484    pub modifiers: Option<NodeList>,
485    pub dot_dot_dot_token: bool,
486    pub name: NodeIndex,
487    pub question_token: bool,
488    pub type_annotation: NodeIndex,
489    pub initializer: NodeIndex,
490}
491
492/// Data for type parameter declarations
493#[derive(Clone, Debug, Serialize, Deserialize)]
494pub struct TypeParameterData {
495    pub modifiers: Option<NodeList>,
496    pub name: NodeIndex,
497    pub constraint: NodeIndex,
498    pub default: NodeIndex,
499}
500
501/// Data for decorator nodes
502#[derive(Clone, Debug, Serialize, Deserialize)]
503pub struct DecoratorData {
504    pub expression: NodeIndex,
505}
506
507/// Data for heritage clauses
508#[derive(Clone, Debug, Serialize, Deserialize)]
509pub struct HeritageData {
510    pub token: u16, // ExtendsKeyword or ImplementsKeyword
511    pub types: NodeList,
512}
513
514/// Data for expression with type arguments
515#[derive(Clone, Debug, Serialize, Deserialize)]
516pub struct ExprWithTypeArgsData {
517    pub expression: NodeIndex,
518    pub type_arguments: Option<NodeList>,
519}
520
521/// Data for import declarations
522#[derive(Clone, Debug, Serialize, Deserialize)]
523pub struct ImportDeclData {
524    pub modifiers: Option<NodeList>,
525    pub import_clause: NodeIndex,
526    pub module_specifier: NodeIndex,
527    pub attributes: NodeIndex,
528}
529
530/// Data for import clauses
531#[derive(Clone, Debug, Serialize, Deserialize)]
532pub struct ImportClauseData {
533    pub is_type_only: bool,
534    pub is_deferred: bool,
535    pub name: NodeIndex,
536    pub named_bindings: NodeIndex,
537}
538
539/// Data for namespace/named imports
540#[derive(Clone, Debug, Serialize, Deserialize)]
541pub struct NamedImportsData {
542    pub name: NodeIndex,    // For namespace import
543    pub elements: NodeList, // For named imports
544}
545
546/// Data for import/export specifiers
547#[derive(Clone, Debug, Serialize, Deserialize)]
548pub struct SpecifierData {
549    pub is_type_only: bool,
550    pub property_name: NodeIndex,
551    pub name: NodeIndex,
552}
553
554/// Data for export declarations
555#[derive(Clone, Debug, Serialize, Deserialize)]
556pub struct ExportDeclData {
557    pub modifiers: Option<NodeList>,
558    pub is_type_only: bool,
559    /// True if this is `export default ...`
560    pub is_default_export: bool,
561    pub export_clause: NodeIndex,
562    pub module_specifier: NodeIndex,
563    pub attributes: NodeIndex,
564}
565
566/// Data for export assignments
567#[derive(Clone, Debug, Serialize, Deserialize)]
568pub struct ExportAssignmentData {
569    pub modifiers: Option<NodeList>,
570    pub is_export_equals: bool,
571    pub expression: NodeIndex,
572}
573
574/// Data for import attributes
575#[derive(Clone, Debug, Serialize, Deserialize)]
576pub struct ImportAttributesData {
577    pub token: u16,
578    pub elements: NodeList,
579    pub multi_line: bool,
580}
581
582/// Data for import attribute
583#[derive(Clone, Debug, Serialize, Deserialize)]
584pub struct ImportAttributeData {
585    pub name: NodeIndex,
586    pub value: NodeIndex,
587}
588
589/// Data for binding patterns
590#[derive(Clone, Debug, Serialize, Deserialize)]
591pub struct BindingPatternData {
592    pub elements: NodeList,
593}
594
595/// Data for binding elements
596#[derive(Clone, Debug, Serialize, Deserialize)]
597pub struct BindingElementData {
598    pub dot_dot_dot_token: bool,
599    pub property_name: NodeIndex,
600    pub name: NodeIndex,
601    pub initializer: NodeIndex,
602}
603
604/// Data for property assignments
605#[derive(Clone, Debug, Serialize, Deserialize)]
606pub struct PropertyAssignmentData {
607    pub modifiers: Option<NodeList>,
608    pub name: NodeIndex,
609    pub initializer: NodeIndex,
610}
611
612/// Data for shorthand property assignments
613#[derive(Clone, Debug, Serialize, Deserialize)]
614pub struct ShorthandPropertyData {
615    pub modifiers: Option<NodeList>,
616    pub name: NodeIndex,
617    pub equals_token: bool,
618    pub object_assignment_initializer: NodeIndex,
619}
620
621/// Data for spread assignments
622#[derive(Clone, Debug, Serialize, Deserialize)]
623pub struct SpreadData {
624    pub expression: NodeIndex,
625}
626
627/// Data for variable declarations (individual)
628#[derive(Clone, Debug, Serialize, Deserialize)]
629pub struct VariableDeclarationData {
630    pub name: NodeIndex,            // Identifier or BindingPattern
631    pub exclamation_token: bool,    // Definite assignment assertion
632    pub type_annotation: NodeIndex, // TypeNode (optional)
633    pub initializer: NodeIndex,     // Expression (optional)
634}
635
636/// Data for for-in/for-of statements
637#[derive(Clone, Debug, Serialize, Deserialize)]
638pub struct ForInOfData {
639    pub await_modifier: bool,   // For for-await-of
640    pub initializer: NodeIndex, // Variable declaration or expression
641    pub expression: NodeIndex,  // The iterable expression
642    pub statement: NodeIndex,   // The loop body
643}
644
645/// Data for debugger/empty statements (no data needed, use token)
646///
647/// Data for template expressions
648#[derive(Clone, Debug, Serialize, Deserialize)]
649pub struct TemplateExprData {
650    pub head: NodeIndex,
651    pub template_spans: NodeList,
652}
653
654/// Data for template spans
655#[derive(Clone, Debug, Serialize, Deserialize)]
656pub struct TemplateSpanData {
657    pub expression: NodeIndex,
658    pub literal: NodeIndex,
659}
660
661/// Data for tagged template expressions
662#[derive(Clone, Debug, Serialize, Deserialize)]
663pub struct TaggedTemplateData {
664    pub tag: NodeIndex,
665    pub type_arguments: Option<NodeList>,
666    pub template: NodeIndex,
667}
668
669/// Data for qualified names
670#[derive(Clone, Debug, Serialize, Deserialize)]
671pub struct QualifiedNameData {
672    pub left: NodeIndex,
673    pub right: NodeIndex,
674}
675
676/// Data for computed property names
677#[derive(Clone, Debug, Serialize, Deserialize)]
678pub struct ComputedPropertyData {
679    pub expression: NodeIndex,
680}
681
682/// Data for type nodes (function type, constructor type)
683#[derive(Clone, Debug, Serialize, Deserialize)]
684pub struct FunctionTypeData {
685    pub type_parameters: Option<NodeList>,
686    pub parameters: NodeList,
687    pub type_annotation: NodeIndex,
688    /// True if this is an abstract constructor type: `abstract new () => T`
689    #[serde(skip_serializing_if = "std::ops::Not::not")]
690    pub is_abstract: bool,
691}
692
693/// Data for type query (typeof)
694#[derive(Clone, Debug, Serialize, Deserialize)]
695pub struct TypeQueryData {
696    pub expr_name: NodeIndex,
697    pub type_arguments: Option<NodeList>,
698}
699
700/// Data for type literal
701#[derive(Clone, Debug, Serialize, Deserialize)]
702pub struct TypeLiteralData {
703    pub members: NodeList,
704}
705
706/// Data for array type
707#[derive(Clone, Debug, Serialize, Deserialize)]
708pub struct ArrayTypeData {
709    pub element_type: NodeIndex,
710}
711
712/// Data for tuple type
713#[derive(Clone, Debug, Serialize, Deserialize)]
714pub struct TupleTypeData {
715    pub elements: NodeList,
716}
717
718/// Data for optional/rest types
719#[derive(Clone, Debug, Serialize, Deserialize)]
720pub struct WrappedTypeData {
721    pub type_node: NodeIndex,
722}
723
724/// Data for conditional types
725#[derive(Clone, Debug, Serialize, Deserialize)]
726pub struct ConditionalTypeData {
727    pub check_type: NodeIndex,
728    pub extends_type: NodeIndex,
729    pub true_type: NodeIndex,
730    pub false_type: NodeIndex,
731}
732
733/// Data for infer type
734#[derive(Clone, Debug, Serialize, Deserialize)]
735pub struct InferTypeData {
736    pub type_parameter: NodeIndex,
737}
738
739/// Data for type operator (keyof, unique, readonly)
740#[derive(Clone, Debug, Serialize, Deserialize)]
741pub struct TypeOperatorData {
742    pub operator: u16,
743    pub type_node: NodeIndex,
744}
745
746/// Data for indexed access type
747#[derive(Clone, Debug, Serialize, Deserialize)]
748pub struct IndexedAccessTypeData {
749    pub object_type: NodeIndex,
750    pub index_type: NodeIndex,
751}
752
753/// Data for mapped type
754#[derive(Clone, Debug, Serialize, Deserialize)]
755pub struct MappedTypeData {
756    pub readonly_token: NodeIndex,
757    pub type_parameter: NodeIndex,
758    pub name_type: NodeIndex,
759    pub question_token: NodeIndex,
760    pub type_node: NodeIndex,
761    pub members: Option<NodeList>,
762}
763
764/// Data for literal types
765#[derive(Clone, Debug, Serialize, Deserialize)]
766pub struct LiteralTypeData {
767    pub literal: NodeIndex,
768}
769
770/// Data for template literal types
771#[derive(Clone, Debug, Serialize, Deserialize)]
772pub struct TemplateLiteralTypeData {
773    pub head: NodeIndex,
774    pub template_spans: NodeList,
775}
776
777/// Data for named tuple member
778#[derive(Clone, Debug, Serialize, Deserialize)]
779pub struct NamedTupleMemberData {
780    pub dot_dot_dot_token: bool,
781    pub name: NodeIndex,
782    pub question_token: bool,
783    pub type_node: NodeIndex,
784}
785
786/// Data for type predicate
787#[derive(Clone, Debug, Serialize, Deserialize)]
788pub struct TypePredicateData {
789    pub asserts_modifier: bool,
790    pub parameter_name: NodeIndex,
791    pub type_node: NodeIndex,
792}
793
794/// Data for JSX elements
795#[derive(Clone, Debug, Serialize, Deserialize)]
796pub struct JsxElementData {
797    pub opening_element: NodeIndex,
798    pub children: NodeList,
799    pub closing_element: NodeIndex,
800}
801
802/// Data for JSX self-closing/opening elements
803#[derive(Clone, Debug, Serialize, Deserialize)]
804pub struct JsxOpeningData {
805    pub tag_name: NodeIndex,
806    pub type_arguments: Option<NodeList>,
807    pub attributes: NodeIndex,
808}
809
810/// Data for JSX closing elements
811#[derive(Clone, Debug, Serialize, Deserialize)]
812pub struct JsxClosingData {
813    pub tag_name: NodeIndex,
814}
815
816/// Data for JSX fragments
817#[derive(Clone, Debug, Serialize, Deserialize)]
818pub struct JsxFragmentData {
819    pub opening_fragment: NodeIndex,
820    pub children: NodeList,
821    pub closing_fragment: NodeIndex,
822}
823
824/// Data for JSX attributes
825#[derive(Clone, Debug, Serialize, Deserialize)]
826pub struct JsxAttributesData {
827    pub properties: NodeList,
828}
829
830/// Data for JSX attribute
831#[derive(Clone, Debug, Serialize, Deserialize)]
832pub struct JsxAttributeData {
833    pub name: NodeIndex,
834    pub initializer: NodeIndex,
835}
836
837/// Data for JSX spread attribute
838#[derive(Clone, Debug, Serialize, Deserialize)]
839pub struct JsxSpreadAttributeData {
840    pub expression: NodeIndex,
841}
842
843/// Data for JSX expression
844#[derive(Clone, Debug, Serialize, Deserialize)]
845pub struct JsxExpressionData {
846    pub dot_dot_dot_token: bool,
847    pub expression: NodeIndex,
848}
849
850/// Data for JSX text
851#[derive(Clone, Debug, Serialize, Deserialize)]
852pub struct JsxTextData {
853    pub text: String,
854    pub contains_only_trivia_white_spaces: bool,
855}
856
857/// Data for JSX namespaced name
858#[derive(Clone, Debug, Serialize, Deserialize)]
859pub struct JsxNamespacedNameData {
860    pub namespace: NodeIndex,
861    pub name: NodeIndex,
862}
863
864/// Data for source files
865#[derive(Clone, Debug, Serialize, Deserialize)]
866pub struct SourceFileData {
867    pub statements: NodeList,
868    pub end_of_file_token: NodeIndex,
869    pub file_name: String,
870    /// Source text. Uses custom serialization to handle Arc<str> properly.
871    #[serde(
872        serialize_with = "serialize_arc_str",
873        deserialize_with = "deserialize_arc_str"
874    )]
875    pub text: Arc<str>,
876    pub language_version: u32,
877    pub language_variant: u32,
878    pub script_kind: u32,
879    pub is_declaration_file: bool,
880    pub has_no_default_lib: bool,
881    /// Cached comment ranges for the entire file (computed once during parsing).
882    /// This avoids O(N) rescanning on every hover/documentation request.
883    pub comments: Vec<tsz_common::comments::CommentRange>,
884    // Extended node info (parent, id, modifiers, transform_flags)
885    pub parent: NodeIndex,
886    pub id: u32,
887    pub modifier_flags: u32,
888    pub transform_flags: u32,
889}
890
891/// Serialize Arc<str> as a regular string
892fn serialize_arc_str<S>(arc: &Arc<str>, serializer: S) -> Result<S::Ok, S::Error>
893where
894    S: serde::Serializer,
895{
896    serializer.serialize_str(arc)
897}
898
899/// Deserialize Arc<str> from a string
900fn deserialize_arc_str<'de, D>(deserializer: D) -> Result<Arc<str>, D::Error>
901where
902    D: serde::Deserializer<'de>,
903{
904    use serde::Deserialize;
905    let s = String::deserialize(deserializer)?;
906    Ok(Arc::from(s))
907}
908
909// =============================================================================
910// Thin Node Arena
911// =============================================================================
912
913/// Arena for thin nodes with typed data pools.
914/// Provides O(1) allocation and cache-efficient storage.
915#[derive(Clone, Debug, Default, Serialize, Deserialize)]
916pub struct NodeArena {
917    /// The thin node headers (16 bytes each)
918    pub nodes: Vec<Node>,
919
920    /// String interner for resolving identifier atoms
921    /// This is populated from the scanner after parsing completes
922    #[serde(skip)]
923    pub interner: Interner,
924
925    // ==========================================================================
926    // Typed data pools - organized by category
927    // ==========================================================================
928
929    // Names and identifiers
930    pub identifiers: Vec<IdentifierData>,
931    pub qualified_names: Vec<QualifiedNameData>,
932    pub computed_properties: Vec<ComputedPropertyData>,
933
934    // Literals
935    pub literals: Vec<LiteralData>,
936
937    // Expressions
938    pub binary_exprs: Vec<BinaryExprData>,
939    pub unary_exprs: Vec<UnaryExprData>,
940    pub call_exprs: Vec<CallExprData>,
941    pub access_exprs: Vec<AccessExprData>,
942    pub conditional_exprs: Vec<ConditionalExprData>,
943    pub literal_exprs: Vec<LiteralExprData>,
944    pub parenthesized: Vec<ParenthesizedData>,
945    pub unary_exprs_ex: Vec<UnaryExprDataEx>,
946    pub type_assertions: Vec<TypeAssertionData>,
947    pub template_exprs: Vec<TemplateExprData>,
948    pub template_spans: Vec<TemplateSpanData>,
949    pub tagged_templates: Vec<TaggedTemplateData>,
950
951    // Functions and classes
952    pub functions: Vec<FunctionData>,
953    pub classes: Vec<ClassData>,
954    pub interfaces: Vec<InterfaceData>,
955    pub type_aliases: Vec<TypeAliasData>,
956    pub enums: Vec<EnumData>,
957    pub enum_members: Vec<EnumMemberData>,
958    pub modules: Vec<ModuleData>,
959    pub module_blocks: Vec<ModuleBlockData>,
960
961    // Signatures and members
962    pub signatures: Vec<SignatureData>,
963    pub index_signatures: Vec<IndexSignatureData>,
964    pub property_decls: Vec<PropertyDeclData>,
965    pub method_decls: Vec<MethodDeclData>,
966    pub constructors: Vec<ConstructorData>,
967    pub accessors: Vec<AccessorData>,
968    pub parameters: Vec<ParameterData>,
969    pub type_parameters: Vec<TypeParameterData>,
970    pub decorators: Vec<DecoratorData>,
971    pub heritage_clauses: Vec<HeritageData>,
972    pub expr_with_type_args: Vec<ExprWithTypeArgsData>,
973
974    // Statements
975    pub if_statements: Vec<IfStatementData>,
976    pub loops: Vec<LoopData>,
977    pub blocks: Vec<BlockData>,
978    pub variables: Vec<VariableData>,
979    pub return_data: Vec<ReturnData>,
980    pub expr_statements: Vec<ExprStatementData>,
981    pub switch_data: Vec<SwitchData>,
982    pub case_clauses: Vec<CaseClauseData>,
983    pub try_data: Vec<TryData>,
984    pub catch_clauses: Vec<CatchClauseData>,
985    pub labeled_data: Vec<LabeledData>,
986    pub jump_data: Vec<JumpData>,
987    pub with_data: Vec<WithData>,
988
989    // Types
990    pub type_refs: Vec<TypeRefData>,
991    pub composite_types: Vec<CompositeTypeData>,
992    pub function_types: Vec<FunctionTypeData>,
993    pub type_queries: Vec<TypeQueryData>,
994    pub type_literals: Vec<TypeLiteralData>,
995    pub array_types: Vec<ArrayTypeData>,
996    pub tuple_types: Vec<TupleTypeData>,
997    pub wrapped_types: Vec<WrappedTypeData>,
998    pub conditional_types: Vec<ConditionalTypeData>,
999    pub infer_types: Vec<InferTypeData>,
1000    pub type_operators: Vec<TypeOperatorData>,
1001    pub indexed_access_types: Vec<IndexedAccessTypeData>,
1002    pub mapped_types: Vec<MappedTypeData>,
1003    pub literal_types: Vec<LiteralTypeData>,
1004    pub template_literal_types: Vec<TemplateLiteralTypeData>,
1005    pub named_tuple_members: Vec<NamedTupleMemberData>,
1006    pub type_predicates: Vec<TypePredicateData>,
1007
1008    // Import/export
1009    pub import_decls: Vec<ImportDeclData>,
1010    pub import_clauses: Vec<ImportClauseData>,
1011    pub named_imports: Vec<NamedImportsData>,
1012    pub specifiers: Vec<SpecifierData>,
1013    pub export_decls: Vec<ExportDeclData>,
1014    pub export_assignments: Vec<ExportAssignmentData>,
1015    pub import_attributes: Vec<ImportAttributesData>,
1016    pub import_attribute: Vec<ImportAttributeData>,
1017
1018    // Binding patterns
1019    pub binding_patterns: Vec<BindingPatternData>,
1020    pub binding_elements: Vec<BindingElementData>,
1021
1022    // Object literal members
1023    pub property_assignments: Vec<PropertyAssignmentData>,
1024    pub shorthand_properties: Vec<ShorthandPropertyData>,
1025    pub spread_data: Vec<SpreadData>,
1026
1027    // Variable declarations (individual)
1028    pub variable_declarations: Vec<VariableDeclarationData>,
1029
1030    // For-in/for-of
1031    pub for_in_of: Vec<ForInOfData>,
1032
1033    // JSX
1034    pub jsx_elements: Vec<JsxElementData>,
1035    pub jsx_opening: Vec<JsxOpeningData>,
1036    pub jsx_closing: Vec<JsxClosingData>,
1037    pub jsx_fragments: Vec<JsxFragmentData>,
1038    pub jsx_attributes: Vec<JsxAttributesData>,
1039    pub jsx_attribute: Vec<JsxAttributeData>,
1040    pub jsx_spread_attributes: Vec<JsxSpreadAttributeData>,
1041    pub jsx_expressions: Vec<JsxExpressionData>,
1042    pub jsx_text: Vec<JsxTextData>,
1043    pub jsx_namespaced_names: Vec<JsxNamespacedNameData>,
1044
1045    // Source file
1046    pub source_files: Vec<SourceFileData>,
1047
1048    // Extended node info (for nodes that need parent, id, full flags)
1049    pub extended_info: Vec<ExtendedNodeInfo>,
1050}
1051
1052/// Extended node info for nodes that need more than what fits in Node
1053#[derive(Clone, Debug, Serialize, Deserialize)]
1054pub struct ExtendedNodeInfo {
1055    pub parent: NodeIndex,
1056    pub id: u32,
1057    pub modifier_flags: u32,
1058    pub transform_flags: u32,
1059}
1060
1061impl Default for ExtendedNodeInfo {
1062    fn default() -> Self {
1063        Self {
1064            parent: NodeIndex::NONE,
1065            id: 0,
1066            modifier_flags: 0,
1067            transform_flags: 0,
1068        }
1069    }
1070}
1071
1072// Re-export types from node_access module for backward compatibility
1073pub use super::node_access::{NodeAccess, NodeInfo, NodeView};
1074
1075#[cfg(test)]
1076#[path = "../../tests/node_tests.rs"]
1077mod node_tests;