Skip to main content

oxc_graphql_parser/
ast.rs

1use crate::Error;
2use crate::LimitTracker;
3use std::fmt;
4use std::slice::Iter;
5
6pub use oxc_allocator::{Box as AstBox, Vec as AstVec};
7
8/// A half-open byte range into the source text.
9///
10/// Offsets are `u32`: source texts are limited to 4 GiB (asserted by
11/// [`crate::Parser::new`]), which halves the size of every AST node that
12/// carries a span.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
14pub struct Span {
15    pub start: u32,
16    pub end: u32,
17}
18
19impl Span {
20    pub fn new(start: u32, end: u32) -> Self {
21        Self { start, end }
22    }
23}
24
25#[derive(Debug)]
26pub struct Ast<'a, T> {
27    source: &'a str,
28    root: T,
29    errors: Vec<Error>,
30    comments: Vec<Span>,
31    recursion_limit: LimitTracker,
32    token_limit: LimitTracker,
33}
34
35impl<'a, T> Ast<'a, T> {
36    pub(crate) fn new(
37        source: &'a str,
38        root: T,
39        errors: Vec<Error>,
40        comments: Vec<Span>,
41        recursion_limit: LimitTracker,
42        token_limit: LimitTracker,
43    ) -> Self {
44        Self { source, root, errors, comments, recursion_limit, token_limit }
45    }
46
47    pub fn root(&self) -> &T {
48        &self.root
49    }
50
51    pub fn into_root(self) -> T {
52        self.root
53    }
54
55    pub fn source(&self) -> &str {
56        self.source
57    }
58
59    pub fn errors(&self) -> Iter<'_, Error> {
60        self.errors.iter()
61    }
62
63    /// Comment token spans in document order.
64    ///
65    /// GraphQL comments are always line comments: each span covers `#` through
66    /// the end of the line (excluding the line terminator).
67    ///
68    /// NOTE: Only comments consumed while parsing are recorded.
69    /// [`Parser::parse`] reads to the end of input, so it collects every comment in the source.
70    /// Partial roots ([`Parser::parse_selection_set`], [`Parser::parse_type`])
71    /// stop at the end of the root, so comments past it are not included.
72    ///
73    /// [`Parser::parse`]: crate::Parser::parse
74    /// [`Parser::parse_selection_set`]: crate::Parser::parse_selection_set
75    /// [`Parser::parse_type`]: crate::Parser::parse_type
76    pub fn comments(&self) -> &[Span] {
77        &self.comments
78    }
79
80    pub fn recursion_limit(&self) -> LimitTracker {
81        self.recursion_limit
82    }
83
84    pub fn token_limit(&self) -> LimitTracker {
85        self.token_limit
86    }
87}
88
89impl<'a> Ast<'a, Document<'a>> {
90    pub fn document(&self) -> &Document<'a> {
91        self.root()
92    }
93}
94
95impl<'a> Ast<'a, SelectionSet<'a>> {
96    pub fn field_set(&self) -> &SelectionSet<'a> {
97        self.root()
98    }
99}
100
101impl<'a> Ast<'a, Type<'a>> {
102    pub fn ty(&self) -> &Type<'a> {
103        self.root()
104    }
105}
106
107#[derive(Debug)]
108pub struct Document<'a> {
109    pub definitions: AstVec<'a, Definition<'a>>,
110    pub span: Span,
111}
112
113#[derive(Debug)]
114pub enum Definition<'a> {
115    Operation(AstBox<'a, OperationDefinition<'a>>),
116    Fragment(AstBox<'a, FragmentDefinition<'a>>),
117    Directive(AstBox<'a, DirectiveDefinition<'a>>),
118    DirectiveExtension(AstBox<'a, DirectiveExtension<'a>>),
119    Schema(AstBox<'a, SchemaDefinition<'a>>),
120    SchemaExtension(AstBox<'a, SchemaExtension<'a>>),
121    ScalarType(AstBox<'a, ScalarTypeDefinition<'a>>),
122    ScalarTypeExtension(AstBox<'a, ScalarTypeExtension<'a>>),
123    ObjectType(AstBox<'a, ObjectTypeDefinition<'a>>),
124    ObjectTypeExtension(AstBox<'a, ObjectTypeExtension<'a>>),
125    InterfaceType(AstBox<'a, InterfaceTypeDefinition<'a>>),
126    InterfaceTypeExtension(AstBox<'a, InterfaceTypeExtension<'a>>),
127    UnionType(AstBox<'a, UnionTypeDefinition<'a>>),
128    UnionTypeExtension(AstBox<'a, UnionTypeExtension<'a>>),
129    EnumType(AstBox<'a, EnumTypeDefinition<'a>>),
130    EnumTypeExtension(AstBox<'a, EnumTypeExtension<'a>>),
131    InputObjectType(AstBox<'a, InputObjectTypeDefinition<'a>>),
132    InputObjectTypeExtension(AstBox<'a, InputObjectTypeExtension<'a>>),
133}
134
135impl<'a> Definition<'a> {
136    pub fn name(&self) -> Option<&Name<'a>> {
137        match self {
138            Self::Operation(definition) => definition.name.as_ref(),
139            Self::Fragment(definition) => Some(&definition.name),
140            Self::Directive(definition) => Some(&definition.name),
141            Self::DirectiveExtension(definition) => Some(&definition.name),
142            Self::Schema(_) | Self::SchemaExtension(_) => None,
143            Self::ScalarType(definition) => Some(&definition.name),
144            Self::ScalarTypeExtension(definition) => Some(&definition.name),
145            Self::ObjectType(definition) => Some(&definition.name),
146            Self::ObjectTypeExtension(definition) => Some(&definition.name),
147            Self::InterfaceType(definition) => Some(&definition.name),
148            Self::InterfaceTypeExtension(definition) => Some(&definition.name),
149            Self::UnionType(definition) => Some(&definition.name),
150            Self::UnionTypeExtension(definition) => Some(&definition.name),
151            Self::EnumType(definition) => Some(&definition.name),
152            Self::EnumTypeExtension(definition) => Some(&definition.name),
153            Self::InputObjectType(definition) => Some(&definition.name),
154            Self::InputObjectTypeExtension(definition) => Some(&definition.name),
155        }
156    }
157
158    /// The source span of the definition, whichever variant it is.
159    ///
160    /// When adding a new variant, remember to extend this match as well.
161    pub fn span(&self) -> Span {
162        match self {
163            Self::Operation(definition) => definition.span,
164            Self::Fragment(definition) => definition.span,
165            Self::Directive(definition) => definition.span,
166            Self::DirectiveExtension(definition) => definition.span,
167            Self::Schema(definition) => definition.span,
168            Self::SchemaExtension(definition) => definition.span,
169            Self::ScalarType(definition) => definition.span,
170            Self::ScalarTypeExtension(definition) => definition.span,
171            Self::ObjectType(definition) => definition.span,
172            Self::ObjectTypeExtension(definition) => definition.span,
173            Self::InterfaceType(definition) => definition.span,
174            Self::InterfaceTypeExtension(definition) => definition.span,
175            Self::UnionType(definition) => definition.span,
176            Self::UnionTypeExtension(definition) => definition.span,
177            Self::EnumType(definition) => definition.span,
178            Self::EnumTypeExtension(definition) => definition.span,
179            Self::InputObjectType(definition) => definition.span,
180            Self::InputObjectTypeExtension(definition) => definition.span,
181        }
182    }
183}
184
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct Name<'a> {
187    pub value: &'a str,
188    pub span: Span,
189}
190
191impl Name<'_> {
192    pub fn as_str(&self) -> &str {
193        self.value
194    }
195}
196
197impl fmt::Display for Name<'_> {
198    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199        f.write_str(self.value)
200    }
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
204pub struct StringValue<'a> {
205    pub raw: &'a str,
206    pub value: &'a str,
207    pub block: bool,
208    pub span: Span,
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
212pub enum OperationType {
213    Query,
214    Mutation,
215    Subscription,
216}
217
218#[derive(Debug)]
219pub struct OperationDefinition<'a> {
220    pub description: Option<AstBox<'a, StringValue<'a>>>,
221    pub operation_type: OperationType,
222    pub name: Option<Name<'a>>,
223    pub variable_definitions: Option<VariableDefinitions<'a>>,
224    pub directives: AstVec<'a, Directive<'a>>,
225    pub selection_set: Option<AstBox<'a, SelectionSet<'a>>>,
226    pub span: Span,
227}
228
229#[derive(Debug)]
230pub struct FragmentDefinition<'a> {
231    pub description: Option<AstBox<'a, StringValue<'a>>>,
232    pub name: Name<'a>,
233    pub variable_definitions: Option<VariableDefinitions<'a>>,
234    pub type_condition: TypeCondition<'a>,
235    pub directives: AstVec<'a, Directive<'a>>,
236    pub selection_set: Option<AstBox<'a, SelectionSet<'a>>>,
237    pub span: Span,
238}
239
240#[derive(Debug)]
241pub struct SelectionSet<'a> {
242    pub selections: AstVec<'a, Selection<'a>>,
243    pub span: Span,
244}
245
246#[derive(Debug)]
247pub enum Selection<'a> {
248    Field(AstBox<'a, Field<'a>>),
249    FragmentSpread(AstBox<'a, FragmentSpread<'a>>),
250    InlineFragment(AstBox<'a, InlineFragment<'a>>),
251}
252
253impl Selection<'_> {
254    /// The source span of the selection, whichever variant it is.
255    ///
256    /// When adding a new variant, remember to extend this match as well.
257    pub fn span(&self) -> Span {
258        match self {
259            Self::Field(selection) => selection.span,
260            Self::FragmentSpread(selection) => selection.span,
261            Self::InlineFragment(selection) => selection.span,
262        }
263    }
264}
265
266#[derive(Debug)]
267pub struct Field<'a> {
268    pub alias: Option<Name<'a>>,
269    pub name: Name<'a>,
270    pub arguments: Option<Arguments<'a>>,
271    pub directives: AstVec<'a, Directive<'a>>,
272    pub selection_set: Option<AstBox<'a, SelectionSet<'a>>>,
273    pub span: Span,
274}
275
276#[derive(Debug)]
277pub struct FragmentSpread<'a> {
278    pub name: Name<'a>,
279    pub arguments: Option<Arguments<'a>>,
280    pub directives: AstVec<'a, Directive<'a>>,
281    pub span: Span,
282}
283
284#[derive(Debug)]
285pub struct InlineFragment<'a> {
286    pub type_condition: Option<TypeCondition<'a>>,
287    pub directives: AstVec<'a, Directive<'a>>,
288    pub selection_set: Option<AstBox<'a, SelectionSet<'a>>>,
289    pub span: Span,
290}
291
292#[derive(Debug)]
293pub struct VariableDefinition<'a> {
294    pub description: Option<AstBox<'a, StringValue<'a>>>,
295    pub variable: Variable<'a>,
296    pub ty: Option<Type<'a>>,
297    pub default_value: Option<DefaultValue<'a>>,
298    pub directives: AstVec<'a, Directive<'a>>,
299    pub span: Span,
300}
301
302#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
303pub struct Variable<'a> {
304    pub name: Name<'a>,
305    pub span: Span,
306}
307
308#[derive(Debug)]
309pub struct Argument<'a> {
310    pub name: Name<'a>,
311    pub value: Option<Value<'a>>,
312    pub span: Span,
313}
314
315#[derive(Debug)]
316pub struct Directive<'a> {
317    pub name: Name<'a>,
318    pub arguments: Option<Arguments<'a>>,
319    pub span: Span,
320}
321
322#[derive(Debug)]
323pub enum Value<'a> {
324    Variable(AstBox<'a, Variable<'a>>),
325    Int(AstBox<'a, IntValue<'a>>),
326    Float(AstBox<'a, FloatValue<'a>>),
327    String(AstBox<'a, StringValue<'a>>),
328    Boolean(AstBox<'a, BooleanValue>),
329    Null(AstBox<'a, NullValue>),
330    Enum(AstBox<'a, EnumValue<'a>>),
331    List(AstBox<'a, ListValue<'a>>),
332    Object(AstBox<'a, ObjectValue<'a>>),
333    Missing(Span),
334}
335
336impl Value<'_> {
337    pub fn span(&self) -> Span {
338        match self {
339            Self::Variable(value) => value.span,
340            Self::Int(value) => value.span,
341            Self::Float(value) => value.span,
342            Self::String(value) => value.span,
343            Self::Boolean(value) => value.span,
344            Self::Null(value) => value.span,
345            Self::Enum(value) => value.name.span,
346            Self::List(value) => value.span,
347            Self::Object(value) => value.span,
348            Self::Missing(span) => *span,
349        }
350    }
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
354pub struct IntValue<'a> {
355    pub raw: &'a str,
356    pub span: Span,
357}
358
359#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
360pub struct FloatValue<'a> {
361    pub raw: &'a str,
362    pub span: Span,
363}
364
365#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
366pub struct BooleanValue {
367    pub value: bool,
368    pub span: Span,
369}
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
372pub struct NullValue {
373    pub span: Span,
374}
375
376#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
377pub struct EnumValue<'a> {
378    pub name: Name<'a>,
379}
380
381#[derive(Debug)]
382pub struct ListValue<'a> {
383    pub values: AstVec<'a, Value<'a>>,
384    pub span: Span,
385}
386
387#[derive(Debug)]
388pub struct ObjectValue<'a> {
389    pub fields: AstVec<'a, ObjectField<'a>>,
390    pub span: Span,
391}
392
393#[derive(Debug)]
394pub struct ObjectField<'a> {
395    pub name: Name<'a>,
396    pub value: Option<Value<'a>>,
397    pub span: Span,
398}
399
400#[derive(Debug)]
401pub enum Type<'a> {
402    Named(AstBox<'a, NamedType<'a>>),
403    List(AstBox<'a, ListType<'a>>),
404    NonNull(AstBox<'a, NonNullType<'a>>),
405    Missing(Span),
406}
407
408impl Type<'_> {
409    pub fn span(&self) -> Span {
410        match self {
411            Self::Named(value) => value.name.span,
412            Self::List(value) => value.span,
413            Self::NonNull(value) => value.span,
414            Self::Missing(span) => *span,
415        }
416    }
417}
418
419#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
420pub struct NamedType<'a> {
421    pub name: Name<'a>,
422}
423
424#[derive(Debug)]
425pub struct ListType<'a> {
426    pub ty: Type<'a>,
427    pub span: Span,
428}
429
430#[derive(Debug)]
431pub struct NonNullType<'a> {
432    pub ty: Type<'a>,
433    pub span: Span,
434}
435
436#[derive(Debug)]
437pub struct SchemaDefinition<'a> {
438    pub description: Option<AstBox<'a, StringValue<'a>>>,
439    pub directives: AstVec<'a, Directive<'a>>,
440    /// No wrapper node: the spec inlines the `{`..`}` in the SchemaDefinition
441    /// production itself (no named production to mirror).
442    pub root_operations: AstVec<'a, RootOperationTypeDefinition<'a>>,
443    pub span: Span,
444}
445
446#[derive(Debug)]
447pub struct SchemaExtension<'a> {
448    pub directives: AstVec<'a, Directive<'a>>,
449    /// No wrapper node: see [`SchemaDefinition::root_operations`].
450    pub root_operations: AstVec<'a, RootOperationTypeDefinition<'a>>,
451    pub span: Span,
452}
453
454#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
455pub struct RootOperationTypeDefinition<'a> {
456    pub operation_type: OperationType,
457    pub named_type: NamedType<'a>,
458    pub span: Span,
459}
460
461#[derive(Debug)]
462pub struct DirectiveExtension<'a> {
463    pub name: Name<'a>,
464    pub directives: AstVec<'a, Directive<'a>>,
465    pub span: Span,
466}
467
468#[derive(Debug)]
469pub struct DirectiveDefinition<'a> {
470    pub description: Option<AstBox<'a, StringValue<'a>>>,
471    pub name: Name<'a>,
472    pub arguments: Option<ArgumentsDefinition<'a>>,
473    pub directives: AstVec<'a, Directive<'a>>,
474    pub repeatable: bool,
475    pub locations: AstVec<'a, DirectiveLocation<'a>>,
476    pub span: Span,
477}
478
479#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
480pub struct DirectiveLocation<'a> {
481    pub name: &'a str,
482    pub span: Span,
483}
484
485#[derive(Debug)]
486pub struct ScalarTypeDefinition<'a> {
487    pub description: Option<AstBox<'a, StringValue<'a>>>,
488    pub name: Name<'a>,
489    pub directives: AstVec<'a, Directive<'a>>,
490    pub span: Span,
491}
492
493#[derive(Debug)]
494pub struct ScalarTypeExtension<'a> {
495    pub name: Name<'a>,
496    pub directives: AstVec<'a, Directive<'a>>,
497    pub span: Span,
498}
499
500#[derive(Debug)]
501pub struct ObjectTypeDefinition<'a> {
502    pub description: Option<AstBox<'a, StringValue<'a>>>,
503    pub name: Name<'a>,
504    pub implements: Option<ImplementsInterfaces<'a>>,
505    pub directives: AstVec<'a, Directive<'a>>,
506    pub fields: Option<FieldsDefinition<'a>>,
507    pub span: Span,
508}
509
510#[derive(Debug)]
511pub struct ObjectTypeExtension<'a> {
512    pub name: Name<'a>,
513    pub implements: Option<ImplementsInterfaces<'a>>,
514    pub directives: AstVec<'a, Directive<'a>>,
515    pub fields: Option<FieldsDefinition<'a>>,
516    pub span: Span,
517}
518
519#[derive(Debug)]
520pub struct InterfaceTypeDefinition<'a> {
521    pub description: Option<AstBox<'a, StringValue<'a>>>,
522    pub name: Name<'a>,
523    pub implements: Option<ImplementsInterfaces<'a>>,
524    pub directives: AstVec<'a, Directive<'a>>,
525    pub fields: Option<FieldsDefinition<'a>>,
526    pub span: Span,
527}
528
529#[derive(Debug)]
530pub struct InterfaceTypeExtension<'a> {
531    pub name: Name<'a>,
532    pub implements: Option<ImplementsInterfaces<'a>>,
533    pub directives: AstVec<'a, Directive<'a>>,
534    pub fields: Option<FieldsDefinition<'a>>,
535    pub span: Span,
536}
537
538#[derive(Debug)]
539pub struct UnionTypeDefinition<'a> {
540    pub description: Option<AstBox<'a, StringValue<'a>>>,
541    pub name: Name<'a>,
542    pub directives: AstVec<'a, Directive<'a>>,
543    pub members: Option<UnionMemberTypes<'a>>,
544    pub span: Span,
545}
546
547#[derive(Debug)]
548pub struct UnionTypeExtension<'a> {
549    pub name: Name<'a>,
550    pub directives: AstVec<'a, Directive<'a>>,
551    pub members: Option<UnionMemberTypes<'a>>,
552    pub span: Span,
553}
554
555#[derive(Debug)]
556pub struct EnumTypeDefinition<'a> {
557    pub description: Option<AstBox<'a, StringValue<'a>>>,
558    pub name: Name<'a>,
559    pub directives: AstVec<'a, Directive<'a>>,
560    pub values: Option<EnumValuesDefinition<'a>>,
561    pub span: Span,
562}
563
564#[derive(Debug)]
565pub struct EnumTypeExtension<'a> {
566    pub name: Name<'a>,
567    pub directives: AstVec<'a, Directive<'a>>,
568    pub values: Option<EnumValuesDefinition<'a>>,
569    pub span: Span,
570}
571
572#[derive(Debug)]
573pub struct EnumValueDefinition<'a> {
574    pub description: Option<AstBox<'a, StringValue<'a>>>,
575    pub value: EnumValue<'a>,
576    pub directives: AstVec<'a, Directive<'a>>,
577    pub span: Span,
578}
579
580#[derive(Debug)]
581pub struct InputObjectTypeDefinition<'a> {
582    pub description: Option<AstBox<'a, StringValue<'a>>>,
583    pub name: Name<'a>,
584    pub directives: AstVec<'a, Directive<'a>>,
585    pub fields: Option<InputFieldsDefinition<'a>>,
586    pub span: Span,
587}
588
589#[derive(Debug)]
590pub struct InputObjectTypeExtension<'a> {
591    pub name: Name<'a>,
592    pub directives: AstVec<'a, Directive<'a>>,
593    pub fields: Option<InputFieldsDefinition<'a>>,
594    pub span: Span,
595}
596
597#[derive(Debug)]
598pub struct FieldDefinition<'a> {
599    pub description: Option<AstBox<'a, StringValue<'a>>>,
600    pub name: Name<'a>,
601    pub arguments: Option<ArgumentsDefinition<'a>>,
602    pub ty: Option<Type<'a>>,
603    pub directives: AstVec<'a, Directive<'a>>,
604    pub span: Span,
605}
606
607#[derive(Debug)]
608pub struct InputValueDefinition<'a> {
609    pub description: Option<AstBox<'a, StringValue<'a>>>,
610    pub name: Name<'a>,
611    pub ty: Option<Type<'a>>,
612    pub default_value: Option<DefaultValue<'a>>,
613    pub directives: AstVec<'a, Directive<'a>>,
614    pub span: Span,
615}
616
617/// `( Argument+ )`
618#[derive(Debug)]
619pub struct Arguments<'a> {
620    pub items: AstVec<'a, Argument<'a>>,
621    /// Covers `(`..`)`.
622    pub span: Span,
623}
624
625/// `( InputValueDefinition+ )` on field and directive definitions.
626#[derive(Debug)]
627pub struct ArgumentsDefinition<'a> {
628    pub items: AstVec<'a, InputValueDefinition<'a>>,
629    /// Covers `(`..`)`.
630    pub span: Span,
631}
632
633/// `( VariableDefinition+ )` on operations and fragments.
634#[derive(Debug)]
635pub struct VariableDefinitions<'a> {
636    pub items: AstVec<'a, VariableDefinition<'a>>,
637    /// Covers `(`..`)`.
638    pub span: Span,
639}
640
641/// `implements &? NamedType (& NamedType)*`
642#[derive(Debug)]
643pub struct ImplementsInterfaces<'a> {
644    pub interfaces: AstVec<'a, NamedType<'a>>,
645    /// Starts at the `implements` keyword.
646    pub span: Span,
647}
648
649/// `= Value`
650#[derive(Debug)]
651pub struct DefaultValue<'a> {
652    pub value: Value<'a>,
653    /// Starts at the `=` token.
654    pub span: Span,
655}
656
657/// `on NamedType`
658#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
659pub struct TypeCondition<'a> {
660    pub named_type: NamedType<'a>,
661    /// Starts at the `on` keyword.
662    pub span: Span,
663}
664
665/// `= |? NamedType (| NamedType)*`
666#[derive(Debug)]
667pub struct UnionMemberTypes<'a> {
668    pub members: AstVec<'a, NamedType<'a>>,
669    /// Starts at the `=` token.
670    pub span: Span,
671}
672
673/// `{ FieldDefinition+ }`
674#[derive(Debug)]
675pub struct FieldsDefinition<'a> {
676    pub fields: AstVec<'a, FieldDefinition<'a>>,
677    /// Covers `{`..`}`.
678    pub span: Span,
679}
680
681/// `{ EnumValueDefinition+ }`
682#[derive(Debug)]
683pub struct EnumValuesDefinition<'a> {
684    pub values: AstVec<'a, EnumValueDefinition<'a>>,
685    /// Covers `{`..`}`.
686    pub span: Span,
687}
688
689/// `{ InputValueDefinition+ }`
690#[derive(Debug)]
691pub struct InputFieldsDefinition<'a> {
692    pub fields: AstVec<'a, InputValueDefinition<'a>>,
693    /// Covers `{`..`}`.
694    pub span: Span,
695}
696
697/// Compile-time size gates for the memory-sensitive AST nodes, in the style
698/// of `oxc_ast`'s `assert_layouts.rs`.
699///
700/// AST nodes are bulk data: parsers allocate thousands of them per document,
701/// so a size regression here is a memory and cache regression everywhere.
702/// If an intentional layout change trips these, update the constants.
703#[cfg(target_pointer_width = "64")]
704const _: () = {
705    use std::mem::size_of;
706
707    assert!(size_of::<Span>() == 8);
708    assert!(size_of::<Name>() == 24);
709    assert!(size_of::<StringValue>() == 48);
710
711    assert!(size_of::<Definition>() == 16);
712    assert!(size_of::<OperationDefinition>() == 112);
713    assert!(size_of::<FragmentDefinition>() == 136);
714
715    assert!(size_of::<SelectionSet>() == 32);
716    assert!(size_of::<Selection>() == 16);
717    assert!(size_of::<Field>() == 120);
718    assert!(size_of::<InlineFragment>() == 72);
719
720    assert!(size_of::<Value>() == 16);
721    assert!(size_of::<Argument>() == 48);
722    assert!(size_of::<ObjectField>() == 48);
723    assert!(size_of::<Directive>() == 64);
724    assert!(size_of::<Type>() == 16);
725
726    assert!(size_of::<FieldDefinition>() == 112);
727    assert!(size_of::<InputValueDefinition>() == 104);
728    assert!(size_of::<VariableDefinition>() == 112);
729    assert!(size_of::<EnumValueDefinition>() == 64);
730};