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#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
9pub struct Span {
10 pub start: usize,
11 pub end: usize,
12}
13
14impl Span {
15 pub fn new(start: usize, end: usize) -> Self {
16 Self { start, end }
17 }
18}
19
20#[derive(Debug, PartialEq)]
21pub struct Ast<'a, T> {
22 source: &'a str,
23 root: T,
24 errors: Vec<Error>,
25 comments: Vec<Span>,
26 recursion_limit: LimitTracker,
27 token_limit: LimitTracker,
28}
29
30impl<'a, T> Ast<'a, T> {
31 pub(crate) fn new(
32 source: &'a str,
33 root: T,
34 errors: Vec<Error>,
35 comments: Vec<Span>,
36 recursion_limit: LimitTracker,
37 token_limit: LimitTracker,
38 ) -> Self {
39 Self { source, root, errors, comments, recursion_limit, token_limit }
40 }
41
42 pub fn root(&self) -> &T {
43 &self.root
44 }
45
46 pub fn into_root(self) -> T {
47 self.root
48 }
49
50 pub fn source(&self) -> &str {
51 self.source
52 }
53
54 pub fn errors(&self) -> Iter<'_, Error> {
55 self.errors.iter()
56 }
57
58 pub fn comments(&self) -> &[Span] {
72 &self.comments
73 }
74
75 pub fn recursion_limit(&self) -> LimitTracker {
76 self.recursion_limit
77 }
78
79 pub fn token_limit(&self) -> LimitTracker {
80 self.token_limit
81 }
82}
83
84impl<'a> Ast<'a, Document<'a>> {
85 pub fn document(&self) -> &Document<'a> {
86 self.root()
87 }
88}
89
90impl<'a> Ast<'a, SelectionSet<'a>> {
91 pub fn field_set(&self) -> &SelectionSet<'a> {
92 self.root()
93 }
94}
95
96impl<'a> Ast<'a, Type<'a>> {
97 pub fn ty(&self) -> &Type<'a> {
98 self.root()
99 }
100}
101
102#[derive(Debug, PartialEq)]
103pub struct Document<'a> {
104 pub definitions: AstVec<'a, Definition<'a>>,
105 pub span: Span,
106}
107
108#[derive(Debug, PartialEq)]
109pub enum Definition<'a> {
110 Operation(OperationDefinition<'a>),
111 Fragment(FragmentDefinition<'a>),
112 Directive(DirectiveDefinition<'a>),
113 Schema(SchemaDefinition<'a>),
114 SchemaExtension(SchemaExtension<'a>),
115 ScalarType(ScalarTypeDefinition<'a>),
116 ScalarTypeExtension(ScalarTypeExtension<'a>),
117 ObjectType(ObjectTypeDefinition<'a>),
118 ObjectTypeExtension(ObjectTypeExtension<'a>),
119 InterfaceType(InterfaceTypeDefinition<'a>),
120 InterfaceTypeExtension(InterfaceTypeExtension<'a>),
121 UnionType(UnionTypeDefinition<'a>),
122 UnionTypeExtension(UnionTypeExtension<'a>),
123 EnumType(EnumTypeDefinition<'a>),
124 EnumTypeExtension(EnumTypeExtension<'a>),
125 InputObjectType(InputObjectTypeDefinition<'a>),
126 InputObjectTypeExtension(InputObjectTypeExtension<'a>),
127}
128
129impl<'a> Definition<'a> {
130 pub fn name(&self) -> Option<&Name<'a>> {
131 match self {
132 Self::Operation(definition) => definition.name.as_ref(),
133 Self::Fragment(definition) => Some(&definition.name),
134 Self::Directive(definition) => Some(&definition.name),
135 Self::Schema(_) | Self::SchemaExtension(_) => None,
136 Self::ScalarType(definition) => Some(&definition.name),
137 Self::ScalarTypeExtension(definition) => Some(&definition.name),
138 Self::ObjectType(definition) => Some(&definition.name),
139 Self::ObjectTypeExtension(definition) => Some(&definition.name),
140 Self::InterfaceType(definition) => Some(&definition.name),
141 Self::InterfaceTypeExtension(definition) => Some(&definition.name),
142 Self::UnionType(definition) => Some(&definition.name),
143 Self::UnionTypeExtension(definition) => Some(&definition.name),
144 Self::EnumType(definition) => Some(&definition.name),
145 Self::EnumTypeExtension(definition) => Some(&definition.name),
146 Self::InputObjectType(definition) => Some(&definition.name),
147 Self::InputObjectTypeExtension(definition) => Some(&definition.name),
148 }
149 }
150
151 pub fn span(&self) -> Span {
155 match self {
156 Self::Operation(definition) => definition.span,
157 Self::Fragment(definition) => definition.span,
158 Self::Directive(definition) => definition.span,
159 Self::Schema(definition) => definition.span,
160 Self::SchemaExtension(definition) => definition.span,
161 Self::ScalarType(definition) => definition.span,
162 Self::ScalarTypeExtension(definition) => definition.span,
163 Self::ObjectType(definition) => definition.span,
164 Self::ObjectTypeExtension(definition) => definition.span,
165 Self::InterfaceType(definition) => definition.span,
166 Self::InterfaceTypeExtension(definition) => definition.span,
167 Self::UnionType(definition) => definition.span,
168 Self::UnionTypeExtension(definition) => definition.span,
169 Self::EnumType(definition) => definition.span,
170 Self::EnumTypeExtension(definition) => definition.span,
171 Self::InputObjectType(definition) => definition.span,
172 Self::InputObjectTypeExtension(definition) => definition.span,
173 }
174 }
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
178pub struct Name<'a> {
179 pub value: &'a str,
180 pub span: Span,
181}
182
183impl Name<'_> {
184 pub fn as_str(&self) -> &str {
185 self.value
186 }
187}
188
189impl fmt::Display for Name<'_> {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 f.write_str(self.value)
192 }
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
196pub struct StringValue<'a> {
197 pub raw: &'a str,
198 pub value: &'a str,
199 pub block: bool,
200 pub span: Span,
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
204pub enum OperationType {
205 Query,
206 Mutation,
207 Subscription,
208}
209
210#[derive(Debug, PartialEq)]
211pub struct OperationDefinition<'a> {
212 pub description: Option<StringValue<'a>>,
213 pub operation_type: OperationType,
214 pub name: Option<Name<'a>>,
215 pub variable_definitions: AstVec<'a, VariableDefinition<'a>>,
216 pub directives: AstVec<'a, Directive<'a>>,
217 pub selection_set: Option<SelectionSet<'a>>,
218 pub span: Span,
219}
220
221#[derive(Debug, PartialEq)]
222pub struct FragmentDefinition<'a> {
223 pub description: Option<StringValue<'a>>,
224 pub name: Name<'a>,
225 pub variable_definitions: AstVec<'a, VariableDefinition<'a>>,
226 pub type_condition: NamedType<'a>,
227 pub directives: AstVec<'a, Directive<'a>>,
228 pub selection_set: Option<SelectionSet<'a>>,
229 pub span: Span,
230}
231
232#[derive(Debug, PartialEq)]
233pub struct SelectionSet<'a> {
234 pub selections: AstVec<'a, Selection<'a>>,
235 pub span: Span,
236}
237
238#[derive(Debug, PartialEq)]
239pub enum Selection<'a> {
240 Field(Field<'a>),
241 FragmentSpread(FragmentSpread<'a>),
242 InlineFragment(InlineFragment<'a>),
243}
244
245impl Selection<'_> {
246 pub fn span(&self) -> Span {
250 match self {
251 Self::Field(selection) => selection.span,
252 Self::FragmentSpread(selection) => selection.span,
253 Self::InlineFragment(selection) => selection.span,
254 }
255 }
256}
257
258#[derive(Debug, PartialEq)]
259pub struct Field<'a> {
260 pub alias: Option<Name<'a>>,
261 pub name: Name<'a>,
262 pub arguments: AstVec<'a, Argument<'a>>,
263 pub directives: AstVec<'a, Directive<'a>>,
264 pub selection_set: Option<SelectionSet<'a>>,
265 pub span: Span,
266}
267
268#[derive(Debug, PartialEq)]
269pub struct FragmentSpread<'a> {
270 pub name: Name<'a>,
271 pub directives: AstVec<'a, Directive<'a>>,
272 pub span: Span,
273}
274
275#[derive(Debug, PartialEq)]
276pub struct InlineFragment<'a> {
277 pub type_condition: Option<NamedType<'a>>,
278 pub directives: AstVec<'a, Directive<'a>>,
279 pub selection_set: Option<SelectionSet<'a>>,
280 pub span: Span,
281}
282
283#[derive(Debug, PartialEq)]
284pub struct VariableDefinition<'a> {
285 pub description: Option<StringValue<'a>>,
286 pub variable: Variable<'a>,
287 pub ty: Option<Type<'a>>,
288 pub default_value: Option<Value<'a>>,
289 pub directives: AstVec<'a, Directive<'a>>,
290 pub span: Span,
291}
292
293#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
294pub struct Variable<'a> {
295 pub name: Name<'a>,
296 pub span: Span,
297}
298
299#[derive(Debug, PartialEq)]
300pub struct Argument<'a> {
301 pub name: Name<'a>,
302 pub value: Option<Value<'a>>,
303 pub span: Span,
304}
305
306#[derive(Debug, PartialEq)]
307pub struct Directive<'a> {
308 pub name: Name<'a>,
309 pub arguments: AstVec<'a, Argument<'a>>,
310 pub span: Span,
311}
312
313#[derive(Debug, PartialEq)]
314pub enum Value<'a> {
315 Variable(Variable<'a>),
316 Int(IntValue<'a>),
317 Float(FloatValue<'a>),
318 String(StringValue<'a>),
319 Boolean(BooleanValue),
320 Null(NullValue),
321 Enum(EnumValue<'a>),
322 List(ListValue<'a>),
323 Object(ObjectValue<'a>),
324 Missing(Span),
325}
326
327impl Value<'_> {
328 pub fn span(&self) -> Span {
329 match self {
330 Self::Variable(value) => value.span,
331 Self::Int(value) => value.span,
332 Self::Float(value) => value.span,
333 Self::String(value) => value.span,
334 Self::Boolean(value) => value.span,
335 Self::Null(value) => value.span,
336 Self::Enum(value) => value.name.span,
337 Self::List(value) => value.span,
338 Self::Object(value) => value.span,
339 Self::Missing(span) => *span,
340 }
341 }
342}
343
344#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
345pub struct IntValue<'a> {
346 pub raw: &'a str,
347 pub span: Span,
348}
349
350#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
351pub struct FloatValue<'a> {
352 pub raw: &'a str,
353 pub span: Span,
354}
355
356#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
357pub struct BooleanValue {
358 pub value: bool,
359 pub span: Span,
360}
361
362#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
363pub struct NullValue {
364 pub span: Span,
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
368pub struct EnumValue<'a> {
369 pub name: Name<'a>,
370}
371
372#[derive(Debug, PartialEq)]
373pub struct ListValue<'a> {
374 pub values: AstVec<'a, Value<'a>>,
375 pub span: Span,
376}
377
378#[derive(Debug, PartialEq)]
379pub struct ObjectValue<'a> {
380 pub fields: AstVec<'a, ObjectField<'a>>,
381 pub span: Span,
382}
383
384#[derive(Debug, PartialEq)]
385pub struct ObjectField<'a> {
386 pub name: Name<'a>,
387 pub value: Option<Value<'a>>,
388 pub span: Span,
389}
390
391#[derive(Debug, PartialEq)]
392pub enum Type<'a> {
393 Named(NamedType<'a>),
394 List(ListType<'a>),
395 NonNull(NonNullType<'a>),
396 Missing(Span),
397}
398
399impl Type<'_> {
400 pub fn span(&self) -> Span {
401 match self {
402 Self::Named(value) => value.name.span,
403 Self::List(value) => value.span,
404 Self::NonNull(value) => value.span,
405 Self::Missing(span) => *span,
406 }
407 }
408}
409
410#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
411pub struct NamedType<'a> {
412 pub name: Name<'a>,
413}
414
415#[derive(Debug)]
416pub struct ListType<'a> {
417 pub ty: AstBox<'a, Type<'a>>,
418 pub span: Span,
419}
420
421impl PartialEq for ListType<'_> {
422 fn eq(&self, other: &Self) -> bool {
423 self.ty.as_ref() == other.ty.as_ref() && self.span == other.span
424 }
425}
426
427#[derive(Debug)]
428pub struct NonNullType<'a> {
429 pub ty: AstBox<'a, Type<'a>>,
430 pub span: Span,
431}
432
433impl PartialEq for NonNullType<'_> {
434 fn eq(&self, other: &Self) -> bool {
435 self.ty.as_ref() == other.ty.as_ref() && self.span == other.span
436 }
437}
438
439#[derive(Debug, PartialEq)]
440pub struct SchemaDefinition<'a> {
441 pub description: Option<StringValue<'a>>,
442 pub directives: AstVec<'a, Directive<'a>>,
443 pub root_operations: AstVec<'a, RootOperationTypeDefinition<'a>>,
444 pub span: Span,
445}
446
447#[derive(Debug, PartialEq)]
448pub struct SchemaExtension<'a> {
449 pub directives: AstVec<'a, Directive<'a>>,
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, PartialEq)]
462pub struct DirectiveDefinition<'a> {
463 pub description: Option<StringValue<'a>>,
464 pub name: Name<'a>,
465 pub arguments: AstVec<'a, InputValueDefinition<'a>>,
466 pub repeatable: bool,
467 pub locations: AstVec<'a, DirectiveLocation<'a>>,
468 pub span: Span,
469}
470
471#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
472pub struct DirectiveLocation<'a> {
473 pub name: &'a str,
474 pub span: Span,
475}
476
477#[derive(Debug, PartialEq)]
478pub struct ScalarTypeDefinition<'a> {
479 pub description: Option<StringValue<'a>>,
480 pub name: Name<'a>,
481 pub directives: AstVec<'a, Directive<'a>>,
482 pub span: Span,
483}
484
485#[derive(Debug, PartialEq)]
486pub struct ScalarTypeExtension<'a> {
487 pub name: Name<'a>,
488 pub directives: AstVec<'a, Directive<'a>>,
489 pub span: Span,
490}
491
492#[derive(Debug, PartialEq)]
493pub struct ObjectTypeDefinition<'a> {
494 pub description: Option<StringValue<'a>>,
495 pub name: Name<'a>,
496 pub interfaces: AstVec<'a, NamedType<'a>>,
497 pub directives: AstVec<'a, Directive<'a>>,
498 pub fields: AstVec<'a, FieldDefinition<'a>>,
499 pub span: Span,
500}
501
502#[derive(Debug, PartialEq)]
503pub struct ObjectTypeExtension<'a> {
504 pub name: Name<'a>,
505 pub interfaces: AstVec<'a, NamedType<'a>>,
506 pub directives: AstVec<'a, Directive<'a>>,
507 pub fields: AstVec<'a, FieldDefinition<'a>>,
508 pub span: Span,
509}
510
511#[derive(Debug, PartialEq)]
512pub struct InterfaceTypeDefinition<'a> {
513 pub description: Option<StringValue<'a>>,
514 pub name: Name<'a>,
515 pub interfaces: AstVec<'a, NamedType<'a>>,
516 pub directives: AstVec<'a, Directive<'a>>,
517 pub fields: AstVec<'a, FieldDefinition<'a>>,
518 pub span: Span,
519}
520
521#[derive(Debug, PartialEq)]
522pub struct InterfaceTypeExtension<'a> {
523 pub name: Name<'a>,
524 pub interfaces: AstVec<'a, NamedType<'a>>,
525 pub directives: AstVec<'a, Directive<'a>>,
526 pub fields: AstVec<'a, FieldDefinition<'a>>,
527 pub span: Span,
528}
529
530#[derive(Debug, PartialEq)]
531pub struct UnionTypeDefinition<'a> {
532 pub description: Option<StringValue<'a>>,
533 pub name: Name<'a>,
534 pub directives: AstVec<'a, Directive<'a>>,
535 pub members: AstVec<'a, NamedType<'a>>,
536 pub span: Span,
537}
538
539#[derive(Debug, PartialEq)]
540pub struct UnionTypeExtension<'a> {
541 pub name: Name<'a>,
542 pub directives: AstVec<'a, Directive<'a>>,
543 pub members: AstVec<'a, NamedType<'a>>,
544 pub span: Span,
545}
546
547#[derive(Debug, PartialEq)]
548pub struct EnumTypeDefinition<'a> {
549 pub description: Option<StringValue<'a>>,
550 pub name: Name<'a>,
551 pub directives: AstVec<'a, Directive<'a>>,
552 pub values: AstVec<'a, EnumValueDefinition<'a>>,
553 pub span: Span,
554}
555
556#[derive(Debug, PartialEq)]
557pub struct EnumTypeExtension<'a> {
558 pub name: Name<'a>,
559 pub directives: AstVec<'a, Directive<'a>>,
560 pub values: AstVec<'a, EnumValueDefinition<'a>>,
561 pub span: Span,
562}
563
564#[derive(Debug, PartialEq)]
565pub struct EnumValueDefinition<'a> {
566 pub description: Option<StringValue<'a>>,
567 pub value: EnumValue<'a>,
568 pub directives: AstVec<'a, Directive<'a>>,
569 pub span: Span,
570}
571
572#[derive(Debug, PartialEq)]
573pub struct InputObjectTypeDefinition<'a> {
574 pub description: Option<StringValue<'a>>,
575 pub name: Name<'a>,
576 pub directives: AstVec<'a, Directive<'a>>,
577 pub fields: AstVec<'a, InputValueDefinition<'a>>,
578 pub span: Span,
579}
580
581#[derive(Debug, PartialEq)]
582pub struct InputObjectTypeExtension<'a> {
583 pub name: Name<'a>,
584 pub directives: AstVec<'a, Directive<'a>>,
585 pub fields: AstVec<'a, InputValueDefinition<'a>>,
586 pub span: Span,
587}
588
589#[derive(Debug, PartialEq)]
590pub struct FieldDefinition<'a> {
591 pub description: Option<StringValue<'a>>,
592 pub name: Name<'a>,
593 pub arguments: AstVec<'a, InputValueDefinition<'a>>,
594 pub ty: Option<Type<'a>>,
595 pub directives: AstVec<'a, Directive<'a>>,
596 pub span: Span,
597}
598
599#[derive(Debug, PartialEq)]
600pub struct InputValueDefinition<'a> {
601 pub description: Option<StringValue<'a>>,
602 pub name: Name<'a>,
603 pub ty: Option<Type<'a>>,
604 pub default_value: Option<Value<'a>>,
605 pub directives: AstVec<'a, Directive<'a>>,
606 pub span: Span,
607}