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