1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct Program {
3 pub line: usize,
4 pub source_file: Option<String>,
5 pub statements: Vec<Statement>,
6}
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum Statement {
10 Block(BlockStatement),
11 VariableDeclaration(VariableDeclaration),
12 VariableUnpackDeclaration(VariableUnpackDeclaration),
13 FunctionDeclaration(FunctionDeclaration),
14 ClassDeclaration(ClassDeclaration),
15 TraitDeclaration(TraitDeclaration),
16 ImportDeclaration(ImportDeclaration),
17 IfStatement(IfStatement),
18 WhileStatement(WhileStatement),
19 ForStatement(ForStatement),
20 SwitchStatement(SwitchStatement),
21 TryStatement(TryStatement),
22 ReturnStatement(ReturnStatement),
23 LoopControlStatement(LoopControlStatement),
24 ThrowStatement(ThrowStatement),
25 DieStatement(DieStatement),
26 PostfixConditionalStatement(PostfixConditionalStatement),
27 KeywordStatement(KeywordStatement),
28 ExpressionStatement(ExpressionStatement),
29}
30
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct BlockStatement {
33 pub line: usize,
34 pub source_file: Option<String>,
35 pub statements: Vec<Statement>,
36 pub needs_lexical_scope: bool,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct VariableDeclaration {
41 pub line: usize,
42 pub source_file: Option<String>,
43 pub kind: String,
44 pub declared_type: Option<String>,
45 pub name: String,
46 pub init: Option<Expression>,
47 pub is_weak_storage: bool,
48 pub runtime_typecheck_required: Option<bool>,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct VariableUnpackDeclaration {
53 pub line: usize,
54 pub source_file: Option<String>,
55 pub kind: String,
56 pub pattern: DeclarationBindingPattern,
57 pub init: Expression,
58}
59
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum DeclarationBindingPattern {
62 Keyed {
63 line: usize,
64 source_file: Option<String>,
65 entries: Vec<DeclarationBindingEntry>,
66 },
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct DeclarationBindingEntry {
71 pub line: usize,
72 pub source_file: Option<String>,
73 pub key: DictKey,
74 pub declared_type: Option<String>,
75 pub name: String,
76 pub default_value: Option<Expression>,
77 pub is_weak_storage: bool,
78 pub runtime_typecheck_required: Option<bool>,
79}
80
81#[derive(Debug, Clone, PartialEq, Eq)]
82pub struct FunctionDeclaration {
83 pub line: usize,
84 pub source_file: Option<String>,
85 pub name: String,
86 pub params: Vec<Parameter>,
87 pub return_type: Option<String>,
88 pub body: BlockStatement,
89 pub is_async: bool,
90 pub is_predeclared: bool,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq)]
94pub struct ClassDeclaration {
95 pub line: usize,
96 pub source_file: Option<String>,
97 pub name: String,
98 pub base: Option<String>,
99 pub traits: Vec<String>,
100 pub body: Vec<ClassMember>,
101 pub shorthand: bool,
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
105pub struct TraitDeclaration {
106 pub line: usize,
107 pub source_file: Option<String>,
108 pub name: String,
109 pub body: Vec<ClassMember>,
110 pub shorthand: bool,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub enum ClassMember {
115 Field(FieldDeclaration),
116 Method(MethodDeclaration),
117 Class(ClassDeclaration),
118 Trait(TraitDeclaration),
119}
120
121#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct FieldDeclaration {
123 pub line: usize,
124 pub source_file: Option<String>,
125 pub kind: String,
126 pub declared_type: Option<String>,
127 pub name: String,
128 pub accessors: Vec<String>,
129 pub default_value: Option<Expression>,
130 pub is_weak_storage: bool,
131 pub runtime_typecheck_required: Option<bool>,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct MethodDeclaration {
136 pub line: usize,
137 pub source_file: Option<String>,
138 pub name: String,
139 pub params: Vec<Parameter>,
140 pub return_type: Option<String>,
141 pub body: BlockStatement,
142 pub is_static: bool,
143 pub is_async: bool,
144 pub is_predeclared: bool,
145}
146
147#[derive(Debug, Clone, PartialEq, Eq)]
148pub struct Parameter {
149 pub line: usize,
150 pub source_file: Option<String>,
151 pub declared_type: Option<String>,
152 pub name: String,
153 pub optional: bool,
154 pub variadic: bool,
155 pub default_value: Option<Expression>,
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
159pub struct ImportDeclaration {
160 pub line: usize,
161 pub source_file: Option<String>,
162 pub source: String,
163 pub try_mode: bool,
164 pub import_all: bool,
165 pub specifiers: Vec<ImportSpecifier>,
166 pub condition: Option<PostfixCondition>,
167}
168
169#[derive(Debug, Clone, PartialEq, Eq)]
170pub struct ImportSpecifier {
171 pub line: usize,
172 pub source_file: Option<String>,
173 pub imported: String,
174 pub local: String,
175}
176
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct PostfixCondition {
179 pub line: usize,
180 pub source_file: Option<String>,
181 pub keyword: String,
182 pub test: Expression,
183}
184
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub struct IfStatement {
187 pub line: usize,
188 pub source_file: Option<String>,
189 pub test: Expression,
190 pub consequent: BlockStatement,
191 pub alternate: Option<Box<Statement>>,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct WhileStatement {
196 pub line: usize,
197 pub source_file: Option<String>,
198 pub test: Expression,
199 pub body: BlockStatement,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub struct ForStatement {
204 pub line: usize,
205 pub source_file: Option<String>,
206 pub binding_kind: Option<String>,
207 pub variable: String,
208 pub iterable: Expression,
209 pub body: BlockStatement,
210 pub else_block: Option<BlockStatement>,
211}
212
213#[derive(Debug, Clone, PartialEq, Eq)]
214pub struct SwitchStatement {
215 pub line: usize,
216 pub source_file: Option<String>,
217 pub discriminant: Expression,
218 pub comparator: Option<String>,
219 pub cases: Vec<SwitchCase>,
220 pub default: Option<Vec<Statement>>,
221 pub index: Option<Vec<SwitchIndexEntry>>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq)]
225pub struct SwitchIndexEntry {
226 pub key: String,
227 pub case_index: usize,
228}
229
230#[derive(Debug, Clone, PartialEq, Eq)]
231pub struct SwitchCase {
232 pub line: usize,
233 pub source_file: Option<String>,
234 pub values: Vec<Expression>,
235 pub operators: Vec<Option<String>>,
236 pub consequent: Vec<Statement>,
237}
238
239#[derive(Debug, Clone, PartialEq, Eq)]
240pub struct TryStatement {
241 pub line: usize,
242 pub source_file: Option<String>,
243 pub body: BlockStatement,
244 pub handlers: Vec<CatchClause>,
245}
246
247#[derive(Debug, Clone, PartialEq, Eq)]
248pub struct CatchClause {
249 pub line: usize,
250 pub source_file: Option<String>,
251 pub binding: Option<CatchBinding>,
252 pub body: BlockStatement,
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
256pub struct CatchBinding {
257 pub line: usize,
258 pub source_file: Option<String>,
259 pub declared_type: Option<String>,
260 pub name: Option<String>,
261}
262
263#[derive(Debug, Clone, PartialEq, Eq)]
264pub struct ReturnStatement {
265 pub line: usize,
266 pub source_file: Option<String>,
267 pub argument: Option<Expression>,
268 pub runtime_typecheck_required: Option<bool>,
269}
270
271#[derive(Debug, Clone, PartialEq, Eq)]
272pub struct LoopControlStatement {
273 pub line: usize,
274 pub source_file: Option<String>,
275 pub keyword: String,
276}
277
278#[derive(Debug, Clone, PartialEq, Eq)]
279pub struct ThrowStatement {
280 pub line: usize,
281 pub source_file: Option<String>,
282 pub argument: Expression,
283}
284
285#[derive(Debug, Clone, PartialEq, Eq)]
286pub struct DieStatement {
287 pub line: usize,
288 pub source_file: Option<String>,
289 pub argument: Expression,
290}
291
292#[derive(Debug, Clone, PartialEq, Eq)]
293pub struct PostfixConditionalStatement {
294 pub line: usize,
295 pub source_file: Option<String>,
296 pub statement: Box<Statement>,
297 pub keyword: String,
298 pub test: Expression,
299}
300
301#[derive(Debug, Clone, PartialEq, Eq)]
302pub struct KeywordStatement {
303 pub line: usize,
304 pub source_file: Option<String>,
305 pub keyword: String,
306 pub arguments: Vec<Expression>,
307}
308
309#[derive(Debug, Clone, PartialEq, Eq)]
310pub struct ExpressionStatement {
311 pub line: usize,
312 pub source_file: Option<String>,
313 pub expression: Expression,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq)]
317pub enum Expression {
318 Identifier {
319 line: usize,
320 source_file: Option<String>,
321 name: String,
322 inferred_type: Option<String>,
323 binding_depth: Option<usize>,
324 },
325 NumberLiteral {
326 line: usize,
327 source_file: Option<String>,
328 value: String,
329 inferred_type: Option<String>,
330 },
331 StringLiteral {
332 line: usize,
333 source_file: Option<String>,
334 value: String,
335 inferred_type: Option<String>,
336 },
337 BinaryStringLiteral {
338 line: usize,
339 source_file: Option<String>,
340 bytes: Vec<u8>,
341 inferred_type: Option<String>,
342 },
343 RegexLiteral {
344 line: usize,
345 source_file: Option<String>,
346 pattern: String,
347 parts: Vec<TemplatePart>,
348 flags: String,
349 cache_key: Option<String>,
350 inferred_type: Option<String>,
351 },
352 BooleanLiteral {
353 line: usize,
354 source_file: Option<String>,
355 value: bool,
356 inferred_type: Option<String>,
357 },
358 NullLiteral {
359 line: usize,
360 source_file: Option<String>,
361 inferred_type: Option<String>,
362 },
363 ArrayLiteral {
364 line: usize,
365 source_file: Option<String>,
366 elements: Vec<Expression>,
367 capacity_hint: Option<usize>,
368 inferred_type: Option<String>,
369 },
370 SetLiteral {
371 line: usize,
372 source_file: Option<String>,
373 elements: Vec<Expression>,
374 capacity_hint: Option<usize>,
375 inferred_type: Option<String>,
376 },
377 BagLiteral {
378 line: usize,
379 source_file: Option<String>,
380 elements: Vec<Expression>,
381 capacity_hint: Option<usize>,
382 inferred_type: Option<String>,
383 },
384 DictLiteral {
385 line: usize,
386 source_file: Option<String>,
387 entries: Vec<DictEntry>,
388 capacity_hint: Option<usize>,
389 inferred_type: Option<String>,
390 },
391 PairListLiteral {
392 line: usize,
393 source_file: Option<String>,
394 entries: Vec<DictEntry>,
395 capacity_hint: Option<usize>,
396 inferred_type: Option<String>,
397 },
398 TemplateLiteral {
399 line: usize,
400 source_file: Option<String>,
401 parts: Vec<TemplatePart>,
402 inferred_type: Option<String>,
403 },
404 Unary {
405 line: usize,
406 source_file: Option<String>,
407 operator: String,
408 argument: Box<Expression>,
409 traits: Vec<String>,
410 inferred_type: Option<String>,
411 },
412 Binary {
413 line: usize,
414 source_file: Option<String>,
415 operator: String,
416 left: Box<Expression>,
417 right: Box<Expression>,
418 inferred_type: Option<String>,
419 },
420 Ternary {
421 line: usize,
422 source_file: Option<String>,
423 test: Box<Expression>,
424 consequent: Box<Expression>,
425 alternate: Box<Expression>,
426 inferred_type: Option<String>,
427 },
428 DefinedOr {
429 line: usize,
430 source_file: Option<String>,
431 left: Box<Expression>,
432 right: Box<Expression>,
433 inferred_type: Option<String>,
434 },
435 Assignment {
436 line: usize,
437 source_file: Option<String>,
438 operator: String,
439 left: Box<Expression>,
440 right: Box<Expression>,
441 is_weak_write: bool,
442 inferred_type: Option<String>,
443 runtime_typecheck_required: Option<bool>,
444 },
445 Call {
446 line: usize,
447 source_file: Option<String>,
448 callee: Box<Expression>,
449 arguments: Vec<CallArgument>,
450 inferred_type: Option<String>,
451 },
452 MemberAccess {
453 line: usize,
454 source_file: Option<String>,
455 object: Box<Expression>,
456 member: String,
457 inferred_type: Option<String>,
458 },
459 DynamicMemberCall {
460 line: usize,
461 source_file: Option<String>,
462 object: Box<Expression>,
463 member: Box<Expression>,
464 arguments: Vec<CallArgument>,
465 inferred_type: Option<String>,
466 },
467 Index {
468 line: usize,
469 source_file: Option<String>,
470 object: Box<Expression>,
471 index: Box<Expression>,
472 inferred_type: Option<String>,
473 },
474 Slice {
475 line: usize,
476 source_file: Option<String>,
477 object: Box<Expression>,
478 start: Option<Box<Expression>>,
479 end: Option<Box<Expression>>,
480 inferred_type: Option<String>,
481 },
482 DictAccess {
483 line: usize,
484 source_file: Option<String>,
485 object: Box<Expression>,
486 key: Box<DictKey>,
487 inferred_type: Option<String>,
488 },
489 PostfixUpdate {
490 line: usize,
491 source_file: Option<String>,
492 operator: String,
493 argument: Box<Expression>,
494 inferred_type: Option<String>,
495 },
496 Lambda {
497 line: usize,
498 source_file: Option<String>,
499 params: Vec<Parameter>,
500 body: Box<Expression>,
501 is_async: bool,
502 inferred_type: Option<String>,
503 },
504 FunctionExpression {
505 line: usize,
506 source_file: Option<String>,
507 params: Vec<Parameter>,
508 return_type: Option<String>,
509 body: BlockStatement,
510 is_async: bool,
511 inferred_type: Option<String>,
512 },
513 LetExpression {
514 line: usize,
515 source_file: Option<String>,
516 kind: String,
517 declared_type: Option<String>,
518 name: String,
519 init: Option<Box<Expression>>,
520 is_weak_storage: bool,
521 inferred_type: Option<String>,
522 runtime_typecheck_required: Option<bool>,
523 },
524 TryExpression {
525 line: usize,
526 source_file: Option<String>,
527 body: BlockStatement,
528 handlers: Vec<CatchClause>,
529 inferred_type: Option<String>,
530 },
531 DoExpression {
532 line: usize,
533 source_file: Option<String>,
534 body: BlockStatement,
535 inferred_type: Option<String>,
536 },
537 AwaitExpression {
538 line: usize,
539 source_file: Option<String>,
540 body: BlockStatement,
541 inferred_type: Option<String>,
542 },
543 SpawnExpression {
544 line: usize,
545 source_file: Option<String>,
546 body: BlockStatement,
547 inferred_type: Option<String>,
548 },
549 SuperCall {
550 line: usize,
551 source_file: Option<String>,
552 arguments: Vec<CallArgument>,
553 inferred_type: Option<String>,
554 },
555}
556
557#[derive(Debug, Clone, PartialEq, Eq)]
558pub enum TemplatePart {
559 Text {
560 line: usize,
561 source_file: Option<String>,
562 value: String,
563 },
564 Expression {
565 line: usize,
566 source_file: Option<String>,
567 expression: Box<Expression>,
568 },
569}
570
571#[derive(Debug, Clone, PartialEq, Eq)]
572pub struct DictEntry {
573 pub line: usize,
574 pub source_file: Option<String>,
575 pub key: DictKey,
576 pub value: Expression,
577}
578
579#[derive(Debug, Clone, PartialEq, Eq)]
580pub enum DictKey {
581 Identifier {
582 line: usize,
583 source_file: Option<String>,
584 name: String,
585 },
586 StringLiteral {
587 line: usize,
588 source_file: Option<String>,
589 value: String,
590 },
591 Expression {
592 line: usize,
593 source_file: Option<String>,
594 expression: Box<Expression>,
595 },
596}
597
598#[derive(Debug, Clone, PartialEq, Eq)]
599pub enum CallArgument {
600 Positional {
601 line: usize,
602 source_file: Option<String>,
603 value: Expression,
604 },
605 Spread {
606 line: usize,
607 source_file: Option<String>,
608 value: Expression,
609 },
610 Named {
611 line: usize,
612 source_file: Option<String>,
613 name: DictKey,
614 value: Expression,
615 },
616}
617
618impl Program {
619 pub fn to_json_pretty(&self) -> String {
620 let mut out = String::new();
621 self.write_json(&mut out, 0);
622 out
623 }
624
625 fn write_json(&self, out: &mut String, indent: usize) {
626 out.push_str("{\n");
627 write_string_field(out, indent + 1, "type", "Program", true);
628 write_number_field(out, indent + 1, "line", self.line, true);
629 write_field_name(out, indent + 1, "statements");
630 write_array(out, indent + 1, &self.statements, |out, indent, stmt| {
631 stmt.write_json(out, indent)
632 });
633 out.push('\n');
634 write_indent(out, indent);
635 out.push('}');
636 }
637}
638
639impl Statement {
640 pub fn line(&self) -> usize {
641 match self {
642 Statement::Block(node) => node.line,
643 Statement::VariableDeclaration(node) => node.line,
644 Statement::VariableUnpackDeclaration(node) => node.line,
645 Statement::FunctionDeclaration(node) => node.line,
646 Statement::ClassDeclaration(node) => node.line,
647 Statement::TraitDeclaration(node) => node.line,
648 Statement::ImportDeclaration(node) => node.line,
649 Statement::IfStatement(node) => node.line,
650 Statement::WhileStatement(node) => node.line,
651 Statement::ForStatement(node) => node.line,
652 Statement::SwitchStatement(node) => node.line,
653 Statement::TryStatement(node) => node.line,
654 Statement::ReturnStatement(node) => node.line,
655 Statement::LoopControlStatement(node) => node.line,
656 Statement::ThrowStatement(node) => node.line,
657 Statement::DieStatement(node) => node.line,
658 Statement::PostfixConditionalStatement(node) => node.line,
659 Statement::KeywordStatement(node) => node.line,
660 Statement::ExpressionStatement(node) => node.line,
661 }
662 }
663
664 pub fn source_file(&self) -> Option<&str> {
665 match self {
666 Statement::Block(node) => node.source_file.as_deref(),
667 Statement::VariableDeclaration(node) => node.source_file.as_deref(),
668 Statement::VariableUnpackDeclaration(node) => node.source_file.as_deref(),
669 Statement::FunctionDeclaration(node) => node.source_file.as_deref(),
670 Statement::ClassDeclaration(node) => node.source_file.as_deref(),
671 Statement::TraitDeclaration(node) => node.source_file.as_deref(),
672 Statement::ImportDeclaration(node) => node.source_file.as_deref(),
673 Statement::IfStatement(node) => node.source_file.as_deref(),
674 Statement::WhileStatement(node) => node.source_file.as_deref(),
675 Statement::ForStatement(node) => node.source_file.as_deref(),
676 Statement::SwitchStatement(node) => node.source_file.as_deref(),
677 Statement::TryStatement(node) => node.source_file.as_deref(),
678 Statement::ReturnStatement(node) => node.source_file.as_deref(),
679 Statement::LoopControlStatement(node) => node.source_file.as_deref(),
680 Statement::ThrowStatement(node) => node.source_file.as_deref(),
681 Statement::DieStatement(node) => node.source_file.as_deref(),
682 Statement::PostfixConditionalStatement(node) => node.source_file.as_deref(),
683 Statement::KeywordStatement(node) => node.source_file.as_deref(),
684 Statement::ExpressionStatement(node) => node.source_file.as_deref(),
685 }
686 }
687
688 fn write_json(&self, out: &mut String, indent: usize) {
689 match self {
690 Statement::Block(node) => node.write_json(out, indent),
691 Statement::VariableDeclaration(node) => node.write_json(out, indent),
692 Statement::VariableUnpackDeclaration(node) => node.write_json(out, indent),
693 Statement::FunctionDeclaration(node) => node.write_json(out, indent),
694 Statement::ClassDeclaration(node) => node.write_json(out, indent),
695 Statement::TraitDeclaration(node) => node.write_json(out, indent),
696 Statement::ImportDeclaration(node) => node.write_json(out, indent),
697 Statement::IfStatement(node) => node.write_json(out, indent),
698 Statement::WhileStatement(node) => node.write_json(out, indent),
699 Statement::ForStatement(node) => node.write_json(out, indent),
700 Statement::SwitchStatement(node) => node.write_json(out, indent),
701 Statement::TryStatement(node) => node.write_json(out, indent),
702 Statement::ReturnStatement(node) => node.write_json(out, indent),
703 Statement::LoopControlStatement(node) => node.write_json(out, indent),
704 Statement::ThrowStatement(node) => node.write_json(out, indent),
705 Statement::DieStatement(node) => node.write_json(out, indent),
706 Statement::PostfixConditionalStatement(node) => node.write_json(out, indent),
707 Statement::KeywordStatement(node) => node.write_json(out, indent),
708 Statement::ExpressionStatement(node) => node.write_json(out, indent),
709 }
710 }
711}
712
713impl BlockStatement {
714 fn write_json(&self, out: &mut String, indent: usize) {
715 write_object_start(out);
716 write_string_field(out, indent + 1, "type", "BlockStatement", true);
717 write_number_field(out, indent + 1, "line", self.line, true);
718 write_bool_field(
719 out,
720 indent + 1,
721 "needs_lexical_scope",
722 self.needs_lexical_scope,
723 true,
724 );
725 write_field_name(out, indent + 1, "statements");
726 write_array(out, indent + 1, &self.statements, |out, indent, stmt| {
727 stmt.write_json(out, indent)
728 });
729 out.push('\n');
730 write_object_end(out, indent);
731 }
732}
733
734impl VariableDeclaration {
735 fn write_json(&self, out: &mut String, indent: usize) {
736 write_object_start(out);
737 write_string_field(out, indent + 1, "type", "VariableDeclaration", true);
738 write_number_field(out, indent + 1, "line", self.line, true);
739 write_string_field(out, indent + 1, "kind", &self.kind, true);
740 write_optional_string_field(
741 out,
742 indent + 1,
743 "declared_type",
744 self.declared_type.as_deref(),
745 true,
746 );
747 write_string_field(out, indent + 1, "name", &self.name, true);
748 write_bool_field(
749 out,
750 indent + 1,
751 "is_weak_storage",
752 self.is_weak_storage,
753 true,
754 );
755 write_optional_bool_field(
756 out,
757 indent + 1,
758 "runtime_typecheck_required",
759 self.runtime_typecheck_required,
760 true,
761 );
762 write_optional_expr_field(out, indent + 1, "init", self.init.as_ref(), false);
763 write_object_end(out, indent);
764 }
765}
766
767impl VariableUnpackDeclaration {
768 fn write_json(&self, out: &mut String, indent: usize) {
769 write_object_start(out);
770 write_string_field(out, indent + 1, "type", "VariableUnpackDeclaration", true);
771 write_number_field(out, indent + 1, "line", self.line, true);
772 write_string_field(out, indent + 1, "kind", &self.kind, true);
773 write_field_name(out, indent + 1, "pattern");
774 self.pattern.write_json(out, indent + 1);
775 out.push_str(",\n");
776 write_field_name(out, indent + 1, "init");
777 self.init.write_json(out, indent + 1);
778 out.push('\n');
779 write_object_end(out, indent);
780 }
781}
782
783impl DeclarationBindingPattern {
784 pub fn entries(&self) -> &[DeclarationBindingEntry] {
785 match self {
786 DeclarationBindingPattern::Keyed { entries, .. } => entries,
787 }
788 }
789
790 pub fn entries_mut(&mut self) -> &mut [DeclarationBindingEntry] {
791 match self {
792 DeclarationBindingPattern::Keyed { entries, .. } => entries,
793 }
794 }
795
796 fn write_json(&self, out: &mut String, indent: usize) {
797 match self {
798 DeclarationBindingPattern::Keyed { line, entries, .. } => {
799 write_object_start(out);
800 write_string_field(out, indent + 1, "type", "KeyedBindingPattern", true);
801 write_number_field(out, indent + 1, "line", *line, true);
802 write_field_name(out, indent + 1, "entries");
803 write_array(out, indent + 1, entries, |out, indent, entry| {
804 entry.write_json(out, indent)
805 });
806 out.push('\n');
807 write_object_end(out, indent);
808 }
809 }
810 }
811}
812
813impl DeclarationBindingEntry {
814 fn write_json(&self, out: &mut String, indent: usize) {
815 write_object_start(out);
816 write_string_field(out, indent + 1, "type", "BindingEntry", true);
817 write_number_field(out, indent + 1, "line", self.line, true);
818 write_field_name(out, indent + 1, "key");
819 self.key.write_json(out, indent + 1);
820 out.push_str(",\n");
821 write_optional_string_field(
822 out,
823 indent + 1,
824 "declared_type",
825 self.declared_type.as_deref(),
826 true,
827 );
828 write_string_field(out, indent + 1, "name", &self.name, true);
829 write_bool_field(
830 out,
831 indent + 1,
832 "is_weak_storage",
833 self.is_weak_storage,
834 true,
835 );
836 write_optional_bool_field(
837 out,
838 indent + 1,
839 "runtime_typecheck_required",
840 self.runtime_typecheck_required,
841 true,
842 );
843 write_optional_expr_field(
844 out,
845 indent + 1,
846 "default_value",
847 self.default_value.as_ref(),
848 false,
849 );
850 write_object_end(out, indent);
851 }
852}
853
854impl FunctionDeclaration {
855 fn write_json(&self, out: &mut String, indent: usize) {
856 write_object_start(out);
857 write_string_field(out, indent + 1, "type", "FunctionDeclaration", true);
858 write_number_field(out, indent + 1, "line", self.line, true);
859 write_string_field(out, indent + 1, "name", &self.name, true);
860 write_bool_field(out, indent + 1, "is_async", self.is_async, true);
861 write_bool_field(out, indent + 1, "is_predeclared", self.is_predeclared, true);
862 write_optional_string_field(
863 out,
864 indent + 1,
865 "return_type",
866 self.return_type.as_deref(),
867 true,
868 );
869 write_field_name(out, indent + 1, "params");
870 write_array(out, indent + 1, &self.params, |out, indent, param| {
871 param.write_json(out, indent)
872 });
873 out.push_str(",\n");
874 write_field_name(out, indent + 1, "body");
875 self.body.write_json(out, indent + 1);
876 out.push('\n');
877 write_object_end(out, indent);
878 }
879}
880
881impl ClassDeclaration {
882 fn write_json(&self, out: &mut String, indent: usize) {
883 write_object_start(out);
884 write_string_field(out, indent + 1, "type", "ClassDeclaration", true);
885 write_number_field(out, indent + 1, "line", self.line, true);
886 write_string_field(out, indent + 1, "name", &self.name, true);
887 write_optional_string_field(out, indent + 1, "base", self.base.as_deref(), true);
888 write_field_name(out, indent + 1, "traits");
889 write_string_array(out, indent + 1, &self.traits);
890 out.push_str(",\n");
891 write_bool_field(out, indent + 1, "shorthand", self.shorthand, true);
892 write_field_name(out, indent + 1, "body");
893 write_array(out, indent + 1, &self.body, |out, indent, member| {
894 member.write_json(out, indent)
895 });
896 out.push('\n');
897 write_object_end(out, indent);
898 }
899}
900
901impl TraitDeclaration {
902 fn write_json(&self, out: &mut String, indent: usize) {
903 write_object_start(out);
904 write_string_field(out, indent + 1, "type", "TraitDeclaration", true);
905 write_number_field(out, indent + 1, "line", self.line, true);
906 write_string_field(out, indent + 1, "name", &self.name, true);
907 write_bool_field(out, indent + 1, "shorthand", self.shorthand, true);
908 write_field_name(out, indent + 1, "body");
909 write_array(out, indent + 1, &self.body, |out, indent, member| {
910 member.write_json(out, indent)
911 });
912 out.push('\n');
913 write_object_end(out, indent);
914 }
915}
916
917impl ClassMember {
918 pub fn line(&self) -> usize {
919 match self {
920 ClassMember::Field(node) => node.line,
921 ClassMember::Method(node) => node.line,
922 ClassMember::Class(node) => node.line,
923 ClassMember::Trait(node) => node.line,
924 }
925 }
926
927 fn write_json(&self, out: &mut String, indent: usize) {
928 match self {
929 ClassMember::Field(node) => node.write_json(out, indent),
930 ClassMember::Method(node) => node.write_json(out, indent),
931 ClassMember::Class(node) => node.write_json(out, indent),
932 ClassMember::Trait(node) => node.write_json(out, indent),
933 }
934 }
935}
936
937impl FieldDeclaration {
938 fn write_json(&self, out: &mut String, indent: usize) {
939 write_object_start(out);
940 write_string_field(out, indent + 1, "type", "FieldDeclaration", true);
941 write_number_field(out, indent + 1, "line", self.line, true);
942 write_string_field(out, indent + 1, "kind", &self.kind, true);
943 write_optional_string_field(
944 out,
945 indent + 1,
946 "declared_type",
947 self.declared_type.as_deref(),
948 true,
949 );
950 write_string_field(out, indent + 1, "name", &self.name, true);
951 write_field_name(out, indent + 1, "accessors");
952 write_string_array(out, indent + 1, &self.accessors);
953 out.push_str(",\n");
954 write_bool_field(
955 out,
956 indent + 1,
957 "is_weak_storage",
958 self.is_weak_storage,
959 true,
960 );
961 write_optional_bool_field(
962 out,
963 indent + 1,
964 "runtime_typecheck_required",
965 self.runtime_typecheck_required,
966 true,
967 );
968 write_optional_expr_field(
969 out,
970 indent + 1,
971 "default_value",
972 self.default_value.as_ref(),
973 false,
974 );
975 write_object_end(out, indent);
976 }
977}
978
979impl MethodDeclaration {
980 fn write_json(&self, out: &mut String, indent: usize) {
981 write_object_start(out);
982 write_string_field(out, indent + 1, "type", "MethodDeclaration", true);
983 write_number_field(out, indent + 1, "line", self.line, true);
984 write_string_field(out, indent + 1, "name", &self.name, true);
985 write_bool_field(out, indent + 1, "is_static", self.is_static, true);
986 write_bool_field(out, indent + 1, "is_async", self.is_async, true);
987 write_bool_field(out, indent + 1, "is_predeclared", self.is_predeclared, true);
988 write_optional_string_field(
989 out,
990 indent + 1,
991 "return_type",
992 self.return_type.as_deref(),
993 true,
994 );
995 write_field_name(out, indent + 1, "params");
996 write_array(out, indent + 1, &self.params, |out, indent, param| {
997 param.write_json(out, indent)
998 });
999 out.push_str(",\n");
1000 write_field_name(out, indent + 1, "body");
1001 self.body.write_json(out, indent + 1);
1002 out.push('\n');
1003 write_object_end(out, indent);
1004 }
1005}
1006
1007impl Parameter {
1008 fn write_json(&self, out: &mut String, indent: usize) {
1009 write_object_start(out);
1010 write_string_field(out, indent + 1, "type", "Parameter", true);
1011 write_number_field(out, indent + 1, "line", self.line, true);
1012 write_optional_string_field(
1013 out,
1014 indent + 1,
1015 "declared_type",
1016 self.declared_type.as_deref(),
1017 true,
1018 );
1019 write_string_field(out, indent + 1, "name", &self.name, true);
1020 write_bool_field(out, indent + 1, "optional", self.optional, true);
1021 write_bool_field(out, indent + 1, "variadic", self.variadic, true);
1022 write_optional_expr_field(
1023 out,
1024 indent + 1,
1025 "default_value",
1026 self.default_value.as_ref(),
1027 false,
1028 );
1029 write_object_end(out, indent);
1030 }
1031}
1032
1033impl ImportDeclaration {
1034 fn write_json(&self, out: &mut String, indent: usize) {
1035 write_object_start(out);
1036 write_string_field(out, indent + 1, "type", "ImportDeclaration", true);
1037 write_number_field(out, indent + 1, "line", self.line, true);
1038 write_string_field(out, indent + 1, "source", &self.source, true);
1039 write_bool_field(out, indent + 1, "try_mode", self.try_mode, true);
1040 write_bool_field(out, indent + 1, "import_all", self.import_all, true);
1041 write_field_name(out, indent + 1, "specifiers");
1042 write_array(out, indent + 1, &self.specifiers, |out, indent, spec| {
1043 spec.write_json(out, indent)
1044 });
1045 out.push_str(",\n");
1046 match &self.condition {
1047 Some(condition) => {
1048 write_field_name(out, indent + 1, "condition");
1049 condition.write_json(out, indent + 1);
1050 out.push('\n');
1051 }
1052 None => {
1053 write_null_field(out, indent + 1, "condition", false);
1054 }
1055 }
1056 write_object_end(out, indent);
1057 }
1058}
1059
1060impl ImportSpecifier {
1061 fn write_json(&self, out: &mut String, indent: usize) {
1062 write_object_start(out);
1063 write_string_field(out, indent + 1, "type", "ImportSpecifier", true);
1064 write_number_field(out, indent + 1, "line", self.line, true);
1065 write_string_field(out, indent + 1, "imported", &self.imported, true);
1066 write_string_field(out, indent + 1, "local", &self.local, false);
1067 write_object_end(out, indent);
1068 }
1069}
1070
1071impl PostfixCondition {
1072 fn write_json(&self, out: &mut String, indent: usize) {
1073 write_object_start(out);
1074 write_number_field(out, indent + 1, "line", self.line, true);
1075 write_string_field(out, indent + 1, "keyword", &self.keyword, true);
1076 write_field_name(out, indent + 1, "test");
1077 self.test.write_json(out, indent + 1);
1078 out.push('\n');
1079 write_object_end(out, indent);
1080 }
1081}
1082
1083impl IfStatement {
1084 fn write_json(&self, out: &mut String, indent: usize) {
1085 write_object_start(out);
1086 write_string_field(out, indent + 1, "type", "IfStatement", true);
1087 write_number_field(out, indent + 1, "line", self.line, true);
1088 write_field_name(out, indent + 1, "test");
1089 self.test.write_json(out, indent + 1);
1090 out.push_str(",\n");
1091 write_field_name(out, indent + 1, "consequent");
1092 self.consequent.write_json(out, indent + 1);
1093 out.push_str(",\n");
1094 match &self.alternate {
1095 Some(alternate) => {
1096 write_field_name(out, indent + 1, "alternate");
1097 alternate.write_json(out, indent + 1);
1098 out.push('\n');
1099 }
1100 None => write_null_field(out, indent + 1, "alternate", false),
1101 }
1102 write_object_end(out, indent);
1103 }
1104}
1105
1106impl WhileStatement {
1107 fn write_json(&self, out: &mut String, indent: usize) {
1108 write_object_start(out);
1109 write_string_field(out, indent + 1, "type", "WhileStatement", true);
1110 write_number_field(out, indent + 1, "line", self.line, true);
1111 write_field_name(out, indent + 1, "test");
1112 self.test.write_json(out, indent + 1);
1113 out.push_str(",\n");
1114 write_field_name(out, indent + 1, "body");
1115 self.body.write_json(out, indent + 1);
1116 out.push('\n');
1117 write_object_end(out, indent);
1118 }
1119}
1120
1121impl ForStatement {
1122 fn write_json(&self, out: &mut String, indent: usize) {
1123 write_object_start(out);
1124 write_string_field(out, indent + 1, "type", "ForStatement", true);
1125 write_number_field(out, indent + 1, "line", self.line, true);
1126 write_optional_string_field(
1127 out,
1128 indent + 1,
1129 "binding_kind",
1130 self.binding_kind.as_deref(),
1131 true,
1132 );
1133 write_string_field(out, indent + 1, "variable", &self.variable, true);
1134 write_field_name(out, indent + 1, "iterable");
1135 self.iterable.write_json(out, indent + 1);
1136 out.push_str(",\n");
1137 write_field_name(out, indent + 1, "body");
1138 self.body.write_json(out, indent + 1);
1139 out.push_str(",\n");
1140 match &self.else_block {
1141 Some(body) => {
1142 write_field_name(out, indent + 1, "else_block");
1143 body.write_json(out, indent + 1);
1144 out.push('\n');
1145 }
1146 None => write_null_field(out, indent + 1, "else_block", false),
1147 }
1148 write_object_end(out, indent);
1149 }
1150}
1151
1152impl SwitchStatement {
1153 fn write_json(&self, out: &mut String, indent: usize) {
1154 write_object_start(out);
1155 write_string_field(out, indent + 1, "type", "SwitchStatement", true);
1156 write_number_field(out, indent + 1, "line", self.line, true);
1157 write_field_name(out, indent + 1, "discriminant");
1158 self.discriminant.write_json(out, indent + 1);
1159 out.push_str(",\n");
1160 write_optional_string_field(
1161 out,
1162 indent + 1,
1163 "comparator",
1164 self.comparator.as_deref(),
1165 true,
1166 );
1167 write_field_name(out, indent + 1, "cases");
1168 write_array(out, indent + 1, &self.cases, |out, indent, case| {
1169 case.write_json(out, indent)
1170 });
1171 out.push_str(",\n");
1172 match &self.index {
1173 Some(index) => {
1174 write_field_name(out, indent + 1, "index");
1175 write_array(out, indent + 1, index, |out, indent, entry| {
1176 entry.write_json(out, indent)
1177 });
1178 out.push_str(",\n");
1179 }
1180 None => write_null_field(out, indent + 1, "index", true),
1181 }
1182 match &self.default {
1183 Some(default) => {
1184 write_field_name(out, indent + 1, "default");
1185 write_array(out, indent + 1, default, |out, indent, stmt| {
1186 stmt.write_json(out, indent)
1187 });
1188 out.push('\n');
1189 }
1190 None => write_null_field(out, indent + 1, "default", false),
1191 }
1192 write_object_end(out, indent);
1193 }
1194}
1195
1196impl SwitchCase {
1197 fn write_json(&self, out: &mut String, indent: usize) {
1198 write_object_start(out);
1199 write_string_field(out, indent + 1, "type", "SwitchCase", true);
1200 write_number_field(out, indent + 1, "line", self.line, true);
1201 write_field_name(out, indent + 1, "values");
1202 write_array(out, indent + 1, &self.values, |out, indent, expr| {
1203 expr.write_json(out, indent)
1204 });
1205 out.push_str(",\n");
1206 write_field_name(out, indent + 1, "operators");
1207 write_array(out, indent + 1, &self.operators, |out, indent, operator| {
1208 write_indent(out, indent);
1209 match operator {
1210 Some(operator) => write_json_string(out, operator),
1211 None => out.push_str("null"),
1212 }
1213 });
1214 out.push_str(",\n");
1215 write_field_name(out, indent + 1, "consequent");
1216 write_array(out, indent + 1, &self.consequent, |out, indent, stmt| {
1217 stmt.write_json(out, indent)
1218 });
1219 out.push('\n');
1220 write_object_end(out, indent);
1221 }
1222}
1223
1224impl SwitchIndexEntry {
1225 fn write_json(&self, out: &mut String, indent: usize) {
1226 write_object_start(out);
1227 write_string_field(out, indent + 1, "key", &self.key, true);
1228 write_number_field(out, indent + 1, "case_index", self.case_index, false);
1229 write_object_end(out, indent);
1230 }
1231}
1232
1233impl TryStatement {
1234 fn write_json(&self, out: &mut String, indent: usize) {
1235 write_object_start(out);
1236 write_string_field(out, indent + 1, "type", "TryStatement", true);
1237 write_number_field(out, indent + 1, "line", self.line, true);
1238 write_field_name(out, indent + 1, "body");
1239 self.body.write_json(out, indent + 1);
1240 out.push_str(",\n");
1241 write_field_name(out, indent + 1, "handlers");
1242 write_array(out, indent + 1, &self.handlers, |out, indent, handler| {
1243 handler.write_json(out, indent)
1244 });
1245 out.push('\n');
1246 write_object_end(out, indent);
1247 }
1248}
1249
1250impl CatchClause {
1251 fn write_json(&self, out: &mut String, indent: usize) {
1252 write_object_start(out);
1253 write_string_field(out, indent + 1, "type", "CatchClause", true);
1254 write_number_field(out, indent + 1, "line", self.line, true);
1255 match &self.binding {
1256 Some(binding) => {
1257 write_field_name(out, indent + 1, "binding");
1258 binding.write_json(out, indent + 1);
1259 out.push_str(",\n");
1260 }
1261 None => write_null_field(out, indent + 1, "binding", true),
1262 }
1263 write_field_name(out, indent + 1, "body");
1264 self.body.write_json(out, indent + 1);
1265 out.push('\n');
1266 write_object_end(out, indent);
1267 }
1268}
1269
1270impl CatchBinding {
1271 fn write_json(&self, out: &mut String, indent: usize) {
1272 write_object_start(out);
1273 write_number_field(out, indent + 1, "line", self.line, true);
1274 write_optional_string_field(
1275 out,
1276 indent + 1,
1277 "declared_type",
1278 self.declared_type.as_deref(),
1279 true,
1280 );
1281 write_optional_string_field(out, indent + 1, "name", self.name.as_deref(), false);
1282 write_object_end(out, indent);
1283 }
1284}
1285
1286impl ReturnStatement {
1287 fn write_json(&self, out: &mut String, indent: usize) {
1288 write_object_start(out);
1289 write_string_field(out, indent + 1, "type", "ReturnStatement", true);
1290 write_number_field(out, indent + 1, "line", self.line, true);
1291 write_optional_bool_field(
1292 out,
1293 indent + 1,
1294 "runtime_typecheck_required",
1295 self.runtime_typecheck_required,
1296 true,
1297 );
1298 write_optional_expr_field(out, indent + 1, "argument", self.argument.as_ref(), false);
1299 write_object_end(out, indent);
1300 }
1301}
1302
1303impl LoopControlStatement {
1304 fn write_json(&self, out: &mut String, indent: usize) {
1305 write_object_start(out);
1306 write_string_field(out, indent + 1, "type", "LoopControlStatement", true);
1307 write_number_field(out, indent + 1, "line", self.line, true);
1308 write_string_field(out, indent + 1, "keyword", &self.keyword, false);
1309 write_object_end(out, indent);
1310 }
1311}
1312
1313impl ThrowStatement {
1314 fn write_json(&self, out: &mut String, indent: usize) {
1315 write_object_start(out);
1316 write_string_field(out, indent + 1, "type", "ThrowStatement", true);
1317 write_number_field(out, indent + 1, "line", self.line, true);
1318 write_field_name(out, indent + 1, "argument");
1319 self.argument.write_json(out, indent + 1);
1320 out.push('\n');
1321 write_object_end(out, indent);
1322 }
1323}
1324
1325impl DieStatement {
1326 fn write_json(&self, out: &mut String, indent: usize) {
1327 write_object_start(out);
1328 write_string_field(out, indent + 1, "type", "DieStatement", true);
1329 write_number_field(out, indent + 1, "line", self.line, true);
1330 write_field_name(out, indent + 1, "argument");
1331 self.argument.write_json(out, indent + 1);
1332 out.push('\n');
1333 write_object_end(out, indent);
1334 }
1335}
1336
1337impl PostfixConditionalStatement {
1338 fn write_json(&self, out: &mut String, indent: usize) {
1339 write_object_start(out);
1340 write_string_field(out, indent + 1, "type", "PostfixConditionalStatement", true);
1341 write_number_field(out, indent + 1, "line", self.line, true);
1342 write_string_field(out, indent + 1, "keyword", &self.keyword, true);
1343 write_field_name(out, indent + 1, "statement");
1344 self.statement.write_json(out, indent + 1);
1345 out.push_str(",\n");
1346 write_field_name(out, indent + 1, "test");
1347 self.test.write_json(out, indent + 1);
1348 out.push('\n');
1349 write_object_end(out, indent);
1350 }
1351}
1352
1353impl KeywordStatement {
1354 fn write_json(&self, out: &mut String, indent: usize) {
1355 write_object_start(out);
1356 write_string_field(out, indent + 1, "type", "KeywordStatement", true);
1357 write_number_field(out, indent + 1, "line", self.line, true);
1358 write_string_field(out, indent + 1, "keyword", &self.keyword, true);
1359 write_field_name(out, indent + 1, "arguments");
1360 write_array(out, indent + 1, &self.arguments, |out, indent, expr| {
1361 expr.write_json(out, indent)
1362 });
1363 out.push('\n');
1364 write_object_end(out, indent);
1365 }
1366}
1367
1368impl ExpressionStatement {
1369 fn write_json(&self, out: &mut String, indent: usize) {
1370 write_object_start(out);
1371 write_string_field(out, indent + 1, "type", "ExpressionStatement", true);
1372 write_number_field(out, indent + 1, "line", self.line, true);
1373 write_field_name(out, indent + 1, "expression");
1374 self.expression.write_json(out, indent + 1);
1375 out.push('\n');
1376 write_object_end(out, indent);
1377 }
1378}
1379
1380impl Expression {
1381 pub fn line(&self) -> usize {
1382 match self {
1383 Expression::Identifier { line, .. } => *line,
1384 Expression::NumberLiteral { line, .. } => *line,
1385 Expression::StringLiteral { line, .. } => *line,
1386 Expression::BinaryStringLiteral { line, .. } => *line,
1387 Expression::RegexLiteral { line, .. } => *line,
1388 Expression::BooleanLiteral { line, .. } => *line,
1389 Expression::NullLiteral { line, .. } => *line,
1390 Expression::ArrayLiteral { line, .. } => *line,
1391 Expression::SetLiteral { line, .. } => *line,
1392 Expression::BagLiteral { line, .. } => *line,
1393 Expression::DictLiteral { line, .. } => *line,
1394 Expression::PairListLiteral { line, .. } => *line,
1395 Expression::TemplateLiteral { line, .. } => *line,
1396 Expression::Unary { line, .. } => *line,
1397 Expression::Binary { line, .. } => *line,
1398 Expression::Ternary { line, .. } => *line,
1399 Expression::DefinedOr { line, .. } => *line,
1400 Expression::Assignment { line, .. } => *line,
1401 Expression::Call { line, .. } => *line,
1402 Expression::MemberAccess { line, .. } => *line,
1403 Expression::DynamicMemberCall { line, .. } => *line,
1404 Expression::Index { line, .. } => *line,
1405 Expression::Slice { line, .. } => *line,
1406 Expression::DictAccess { line, .. } => *line,
1407 Expression::PostfixUpdate { line, .. } => *line,
1408 Expression::Lambda { line, .. } => *line,
1409 Expression::FunctionExpression { line, .. } => *line,
1410 Expression::LetExpression { line, .. } => *line,
1411 Expression::TryExpression { line, .. } => *line,
1412 Expression::DoExpression { line, .. } => *line,
1413 Expression::AwaitExpression { line, .. } => *line,
1414 Expression::SpawnExpression { line, .. } => *line,
1415 Expression::SuperCall { line, .. } => *line,
1416 }
1417 }
1418
1419 pub fn source_file(&self) -> Option<&str> {
1420 match self {
1421 Expression::Identifier { source_file, .. }
1422 | Expression::NumberLiteral { source_file, .. }
1423 | Expression::StringLiteral { source_file, .. }
1424 | Expression::BinaryStringLiteral { source_file, .. }
1425 | Expression::RegexLiteral { source_file, .. }
1426 | Expression::BooleanLiteral { source_file, .. }
1427 | Expression::NullLiteral { source_file, .. }
1428 | Expression::ArrayLiteral { source_file, .. }
1429 | Expression::SetLiteral { source_file, .. }
1430 | Expression::BagLiteral { source_file, .. }
1431 | Expression::DictLiteral { source_file, .. }
1432 | Expression::PairListLiteral { source_file, .. }
1433 | Expression::TemplateLiteral { source_file, .. }
1434 | Expression::Unary { source_file, .. }
1435 | Expression::Binary { source_file, .. }
1436 | Expression::Ternary { source_file, .. }
1437 | Expression::DefinedOr { source_file, .. }
1438 | Expression::Assignment { source_file, .. }
1439 | Expression::Call { source_file, .. }
1440 | Expression::MemberAccess { source_file, .. }
1441 | Expression::DynamicMemberCall { source_file, .. }
1442 | Expression::Index { source_file, .. }
1443 | Expression::Slice { source_file, .. }
1444 | Expression::DictAccess { source_file, .. }
1445 | Expression::PostfixUpdate { source_file, .. }
1446 | Expression::Lambda { source_file, .. }
1447 | Expression::FunctionExpression { source_file, .. }
1448 | Expression::LetExpression { source_file, .. }
1449 | Expression::TryExpression { source_file, .. }
1450 | Expression::DoExpression { source_file, .. }
1451 | Expression::AwaitExpression { source_file, .. }
1452 | Expression::SpawnExpression { source_file, .. }
1453 | Expression::SuperCall { source_file, .. } => source_file.as_deref(),
1454 }
1455 }
1456
1457 pub fn inferred_type(&self) -> Option<&str> {
1458 match self {
1459 Expression::Identifier { inferred_type, .. }
1460 | Expression::NumberLiteral { inferred_type, .. }
1461 | Expression::StringLiteral { inferred_type, .. }
1462 | Expression::BinaryStringLiteral { inferred_type, .. }
1463 | Expression::RegexLiteral { inferred_type, .. }
1464 | Expression::BooleanLiteral { inferred_type, .. }
1465 | Expression::NullLiteral { inferred_type, .. }
1466 | Expression::ArrayLiteral { inferred_type, .. }
1467 | Expression::SetLiteral { inferred_type, .. }
1468 | Expression::BagLiteral { inferred_type, .. }
1469 | Expression::DictLiteral { inferred_type, .. }
1470 | Expression::PairListLiteral { inferred_type, .. }
1471 | Expression::TemplateLiteral { inferred_type, .. }
1472 | Expression::Unary { inferred_type, .. }
1473 | Expression::Binary { inferred_type, .. }
1474 | Expression::Ternary { inferred_type, .. }
1475 | Expression::DefinedOr { inferred_type, .. }
1476 | Expression::Assignment { inferred_type, .. }
1477 | Expression::Call { inferred_type, .. }
1478 | Expression::MemberAccess { inferred_type, .. }
1479 | Expression::DynamicMemberCall { inferred_type, .. }
1480 | Expression::Index { inferred_type, .. }
1481 | Expression::Slice { inferred_type, .. }
1482 | Expression::DictAccess { inferred_type, .. }
1483 | Expression::PostfixUpdate { inferred_type, .. }
1484 | Expression::Lambda { inferred_type, .. }
1485 | Expression::FunctionExpression { inferred_type, .. }
1486 | Expression::LetExpression { inferred_type, .. }
1487 | Expression::TryExpression { inferred_type, .. }
1488 | Expression::DoExpression { inferred_type, .. }
1489 | Expression::AwaitExpression { inferred_type, .. }
1490 | Expression::SpawnExpression { inferred_type, .. }
1491 | Expression::SuperCall { inferred_type, .. } => inferred_type.as_deref(),
1492 }
1493 }
1494
1495 pub fn set_inferred_type(&mut self, value: Option<String>) {
1496 match self {
1497 Expression::Identifier { inferred_type, .. }
1498 | Expression::NumberLiteral { inferred_type, .. }
1499 | Expression::StringLiteral { inferred_type, .. }
1500 | Expression::BinaryStringLiteral { inferred_type, .. }
1501 | Expression::RegexLiteral { inferred_type, .. }
1502 | Expression::BooleanLiteral { inferred_type, .. }
1503 | Expression::NullLiteral { inferred_type, .. }
1504 | Expression::ArrayLiteral { inferred_type, .. }
1505 | Expression::SetLiteral { inferred_type, .. }
1506 | Expression::BagLiteral { inferred_type, .. }
1507 | Expression::DictLiteral { inferred_type, .. }
1508 | Expression::PairListLiteral { inferred_type, .. }
1509 | Expression::TemplateLiteral { inferred_type, .. }
1510 | Expression::Unary { inferred_type, .. }
1511 | Expression::Binary { inferred_type, .. }
1512 | Expression::Ternary { inferred_type, .. }
1513 | Expression::DefinedOr { inferred_type, .. }
1514 | Expression::Assignment { inferred_type, .. }
1515 | Expression::Call { inferred_type, .. }
1516 | Expression::MemberAccess { inferred_type, .. }
1517 | Expression::DynamicMemberCall { inferred_type, .. }
1518 | Expression::Index { inferred_type, .. }
1519 | Expression::Slice { inferred_type, .. }
1520 | Expression::DictAccess { inferred_type, .. }
1521 | Expression::PostfixUpdate { inferred_type, .. }
1522 | Expression::Lambda { inferred_type, .. }
1523 | Expression::FunctionExpression { inferred_type, .. }
1524 | Expression::LetExpression { inferred_type, .. }
1525 | Expression::TryExpression { inferred_type, .. }
1526 | Expression::DoExpression { inferred_type, .. }
1527 | Expression::AwaitExpression { inferred_type, .. }
1528 | Expression::SpawnExpression { inferred_type, .. }
1529 | Expression::SuperCall { inferred_type, .. } => *inferred_type = value,
1530 }
1531 }
1532
1533 pub fn runtime_typecheck_required(&self) -> Option<bool> {
1534 match self {
1535 Expression::Assignment {
1536 runtime_typecheck_required,
1537 ..
1538 }
1539 | Expression::LetExpression {
1540 runtime_typecheck_required,
1541 ..
1542 } => *runtime_typecheck_required,
1543 _ => None,
1544 }
1545 }
1546
1547 pub fn set_runtime_typecheck_required(&mut self, value: Option<bool>) {
1548 match self {
1549 Expression::Assignment {
1550 runtime_typecheck_required,
1551 ..
1552 }
1553 | Expression::LetExpression {
1554 runtime_typecheck_required,
1555 ..
1556 } => *runtime_typecheck_required = value,
1557 _ => {}
1558 }
1559 }
1560
1561 pub fn is_weak_write(&self) -> bool {
1562 match self {
1563 Expression::Assignment { is_weak_write, .. } => *is_weak_write,
1564 _ => false,
1565 }
1566 }
1567
1568 pub fn is_weak_storage(&self) -> bool {
1569 match self {
1570 Expression::LetExpression {
1571 is_weak_storage, ..
1572 } => *is_weak_storage,
1573 _ => false,
1574 }
1575 }
1576
1577 fn write_json(&self, out: &mut String, indent: usize) {
1578 let inferred_type = self.inferred_type();
1579 match self {
1580 Expression::Identifier {
1581 line,
1582 name,
1583 binding_depth,
1584 ..
1585 } => {
1586 write_object_start(out);
1587 write_string_field(out, indent + 1, "type", "Identifier", true);
1588 write_number_field(out, indent + 1, "line", *line, true);
1589 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1590 write_optional_number_field(out, indent + 1, "binding_depth", *binding_depth, true);
1591 write_string_field(out, indent + 1, "name", name, false);
1592 write_object_end(out, indent);
1593 }
1594 Expression::NumberLiteral { line, value, .. } => {
1595 write_object_start(out);
1596 write_string_field(out, indent + 1, "type", "NumberLiteral", true);
1597 write_number_field(out, indent + 1, "line", *line, true);
1598 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1599 write_string_field(out, indent + 1, "value", value, false);
1600 write_object_end(out, indent);
1601 }
1602 Expression::StringLiteral { line, value, .. } => {
1603 write_object_start(out);
1604 write_string_field(out, indent + 1, "type", "StringLiteral", true);
1605 write_number_field(out, indent + 1, "line", *line, true);
1606 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1607 write_string_field(out, indent + 1, "value", value, false);
1608 write_object_end(out, indent);
1609 }
1610 Expression::BinaryStringLiteral { line, bytes, .. } => {
1611 write_object_start(out);
1612 write_string_field(out, indent + 1, "type", "BinaryStringLiteral", true);
1613 write_number_field(out, indent + 1, "line", *line, true);
1614 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1615 write_string_field(out, indent + 1, "bytes_hex", &bytes_to_hex(bytes), false);
1616 write_object_end(out, indent);
1617 }
1618 Expression::RegexLiteral {
1619 line,
1620 pattern,
1621 parts,
1622 flags,
1623 cache_key,
1624 ..
1625 } => {
1626 write_object_start(out);
1627 write_string_field(out, indent + 1, "type", "RegexLiteral", true);
1628 write_number_field(out, indent + 1, "line", *line, true);
1629 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1630 write_string_field(out, indent + 1, "pattern", pattern, true);
1631 write_string_field(out, indent + 1, "flags", flags, true);
1632 write_field_name(out, indent + 1, "parts");
1633 write_array(out, indent + 1, parts, |out, indent, part| {
1634 part.write_json(out, indent)
1635 });
1636 out.push_str(",\n");
1637 write_optional_string_field(
1638 out,
1639 indent + 1,
1640 "regex_cache_key",
1641 cache_key.as_deref(),
1642 false,
1643 );
1644 write_object_end(out, indent);
1645 }
1646 Expression::BooleanLiteral { line, value, .. } => {
1647 write_object_start(out);
1648 write_string_field(out, indent + 1, "type", "BooleanLiteral", true);
1649 write_number_field(out, indent + 1, "line", *line, true);
1650 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1651 write_field_name(out, indent + 1, "value");
1652 out.push_str(if *value { "true" } else { "false" });
1653 out.push('\n');
1654 write_object_end(out, indent);
1655 }
1656 Expression::NullLiteral { line, .. } => {
1657 write_object_start(out);
1658 write_string_field(out, indent + 1, "type", "NullLiteral", true);
1659 write_number_field(out, indent + 1, "line", *line, true);
1660 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, false);
1661 write_object_end(out, indent);
1662 }
1663 Expression::ArrayLiteral {
1664 line,
1665 elements,
1666 capacity_hint,
1667 ..
1668 } => {
1669 write_object_start(out);
1670 write_string_field(out, indent + 1, "type", "ArrayLiteral", true);
1671 write_number_field(out, indent + 1, "line", *line, true);
1672 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1673 write_optional_number_field(out, indent + 1, "capacity_hint", *capacity_hint, true);
1674 write_field_name(out, indent + 1, "elements");
1675 write_array(out, indent + 1, elements, |out, indent, expr| {
1676 expr.write_json(out, indent)
1677 });
1678 out.push('\n');
1679 write_object_end(out, indent);
1680 }
1681 Expression::SetLiteral {
1682 line,
1683 elements,
1684 capacity_hint,
1685 ..
1686 } => {
1687 write_object_start(out);
1688 write_string_field(out, indent + 1, "type", "SetLiteral", true);
1689 write_number_field(out, indent + 1, "line", *line, true);
1690 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1691 write_optional_number_field(out, indent + 1, "capacity_hint", *capacity_hint, true);
1692 write_field_name(out, indent + 1, "elements");
1693 write_array(out, indent + 1, elements, |out, indent, expr| {
1694 expr.write_json(out, indent)
1695 });
1696 out.push('\n');
1697 write_object_end(out, indent);
1698 }
1699 Expression::BagLiteral {
1700 line,
1701 elements,
1702 capacity_hint,
1703 ..
1704 } => {
1705 write_object_start(out);
1706 write_string_field(out, indent + 1, "type", "BagLiteral", true);
1707 write_number_field(out, indent + 1, "line", *line, true);
1708 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1709 write_optional_number_field(out, indent + 1, "capacity_hint", *capacity_hint, true);
1710 write_field_name(out, indent + 1, "elements");
1711 write_array(out, indent + 1, elements, |out, indent, expr| {
1712 expr.write_json(out, indent)
1713 });
1714 out.push('\n');
1715 write_object_end(out, indent);
1716 }
1717 Expression::DictLiteral {
1718 line,
1719 entries,
1720 capacity_hint,
1721 ..
1722 } => {
1723 write_object_start(out);
1724 write_string_field(out, indent + 1, "type", "DictLiteral", true);
1725 write_number_field(out, indent + 1, "line", *line, true);
1726 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1727 write_optional_number_field(out, indent + 1, "capacity_hint", *capacity_hint, true);
1728 write_field_name(out, indent + 1, "entries");
1729 write_array(out, indent + 1, entries, |out, indent, entry| {
1730 entry.write_json(out, indent)
1731 });
1732 out.push('\n');
1733 write_object_end(out, indent);
1734 }
1735 Expression::PairListLiteral {
1736 line,
1737 entries,
1738 capacity_hint,
1739 ..
1740 } => {
1741 write_object_start(out);
1742 write_string_field(out, indent + 1, "type", "PairListLiteral", true);
1743 write_number_field(out, indent + 1, "line", *line, true);
1744 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1745 write_optional_number_field(out, indent + 1, "capacity_hint", *capacity_hint, true);
1746 write_field_name(out, indent + 1, "entries");
1747 write_array(out, indent + 1, entries, |out, indent, entry| {
1748 entry.write_json(out, indent)
1749 });
1750 out.push('\n');
1751 write_object_end(out, indent);
1752 }
1753 Expression::TemplateLiteral { line, parts, .. } => {
1754 write_object_start(out);
1755 write_string_field(out, indent + 1, "type", "TemplateLiteral", true);
1756 write_number_field(out, indent + 1, "line", *line, true);
1757 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1758 write_field_name(out, indent + 1, "parts");
1759 write_array(out, indent + 1, parts, |out, indent, part| {
1760 part.write_json(out, indent)
1761 });
1762 out.push('\n');
1763 write_object_end(out, indent);
1764 }
1765 Expression::Unary {
1766 line,
1767 operator,
1768 argument,
1769 traits,
1770 ..
1771 } => {
1772 write_object_start(out);
1773 write_string_field(out, indent + 1, "type", "UnaryExpression", true);
1774 write_number_field(out, indent + 1, "line", *line, true);
1775 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1776 write_string_field(out, indent + 1, "operator", operator, true);
1777 write_string_field(
1778 out,
1779 indent + 1,
1780 "operator_kind",
1781 operator_kind(operator),
1782 true,
1783 );
1784 if !traits.is_empty() {
1785 write_field_name(out, indent + 1, "traits");
1786 write_string_array(out, indent + 1, traits);
1787 out.push_str(",\n");
1788 }
1789 write_field_name(out, indent + 1, "argument");
1790 argument.write_json(out, indent + 1);
1791 out.push('\n');
1792 write_object_end(out, indent);
1793 }
1794 Expression::Binary {
1795 line,
1796 operator,
1797 left,
1798 right,
1799 ..
1800 } => {
1801 write_object_start(out);
1802 write_string_field(out, indent + 1, "type", "BinaryExpression", true);
1803 write_number_field(out, indent + 1, "line", *line, true);
1804 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1805 write_string_field(out, indent + 1, "operator", operator, true);
1806 write_string_field(
1807 out,
1808 indent + 1,
1809 "operator_kind",
1810 operator_kind(operator),
1811 true,
1812 );
1813 write_field_name(out, indent + 1, "left");
1814 left.write_json(out, indent + 1);
1815 out.push_str(",\n");
1816 write_field_name(out, indent + 1, "right");
1817 right.write_json(out, indent + 1);
1818 out.push('\n');
1819 write_object_end(out, indent);
1820 }
1821 Expression::Ternary {
1822 line,
1823 test,
1824 consequent,
1825 alternate,
1826 ..
1827 } => {
1828 write_object_start(out);
1829 write_string_field(out, indent + 1, "type", "TernaryExpression", true);
1830 write_number_field(out, indent + 1, "line", *line, true);
1831 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1832 write_field_name(out, indent + 1, "test");
1833 test.write_json(out, indent + 1);
1834 out.push_str(",\n");
1835 write_field_name(out, indent + 1, "consequent");
1836 consequent.write_json(out, indent + 1);
1837 out.push_str(",\n");
1838 write_field_name(out, indent + 1, "alternate");
1839 alternate.write_json(out, indent + 1);
1840 out.push('\n');
1841 write_object_end(out, indent);
1842 }
1843 Expression::DefinedOr {
1844 line, left, right, ..
1845 } => {
1846 write_object_start(out);
1847 write_string_field(out, indent + 1, "type", "DefinedOrExpression", true);
1848 write_number_field(out, indent + 1, "line", *line, true);
1849 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1850 write_field_name(out, indent + 1, "left");
1851 left.write_json(out, indent + 1);
1852 out.push_str(",\n");
1853 write_field_name(out, indent + 1, "right");
1854 right.write_json(out, indent + 1);
1855 out.push('\n');
1856 write_object_end(out, indent);
1857 }
1858 Expression::Assignment {
1859 line,
1860 operator,
1861 left,
1862 right,
1863 ..
1864 } => {
1865 write_object_start(out);
1866 write_string_field(out, indent + 1, "type", "AssignmentExpression", true);
1867 write_number_field(out, indent + 1, "line", *line, true);
1868 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1869 write_optional_bool_field(
1870 out,
1871 indent + 1,
1872 "runtime_typecheck_required",
1873 self.runtime_typecheck_required(),
1874 true,
1875 );
1876 write_bool_field(out, indent + 1, "is_weak_write", self.is_weak_write(), true);
1877 write_string_field(out, indent + 1, "operator", operator, true);
1878 write_string_field(
1879 out,
1880 indent + 1,
1881 "operator_kind",
1882 operator_kind(operator),
1883 true,
1884 );
1885 write_field_name(out, indent + 1, "left");
1886 left.write_json(out, indent + 1);
1887 out.push_str(",\n");
1888 write_field_name(out, indent + 1, "right");
1889 right.write_json(out, indent + 1);
1890 out.push('\n');
1891 write_object_end(out, indent);
1892 }
1893 Expression::Call {
1894 line,
1895 callee,
1896 arguments,
1897 ..
1898 } => {
1899 write_object_start(out);
1900 write_string_field(out, indent + 1, "type", "CallExpression", true);
1901 write_number_field(out, indent + 1, "line", *line, true);
1902 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1903 write_field_name(out, indent + 1, "callee");
1904 callee.write_json(out, indent + 1);
1905 out.push_str(",\n");
1906 write_field_name(out, indent + 1, "arguments");
1907 write_array(out, indent + 1, arguments, |out, indent, arg| {
1908 arg.write_json(out, indent)
1909 });
1910 out.push('\n');
1911 write_object_end(out, indent);
1912 }
1913 Expression::MemberAccess {
1914 line,
1915 object,
1916 member,
1917 ..
1918 } => {
1919 write_object_start(out);
1920 write_string_field(out, indent + 1, "type", "MemberCallExpression", true);
1921 write_number_field(out, indent + 1, "line", *line, true);
1922 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1923 write_field_name(out, indent + 1, "object");
1924 object.write_json(out, indent + 1);
1925 out.push_str(",\n");
1926 write_string_field(out, indent + 1, "member", member, false);
1927 write_object_end(out, indent);
1928 }
1929 Expression::DynamicMemberCall {
1930 line,
1931 object,
1932 member,
1933 arguments,
1934 ..
1935 } => {
1936 write_object_start(out);
1937 write_string_field(out, indent + 1, "type", "DynamicMemberCall", true);
1938 write_number_field(out, indent + 1, "line", *line, true);
1939 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1940 write_field_name(out, indent + 1, "object");
1941 object.write_json(out, indent + 1);
1942 out.push_str(",\n");
1943 write_field_name(out, indent + 1, "member");
1944 member.write_json(out, indent + 1);
1945 out.push_str(",\n");
1946 write_field_name(out, indent + 1, "arguments");
1947 write_array(out, indent + 1, arguments, |out, indent, arg| {
1948 arg.write_json(out, indent)
1949 });
1950 out.push('\n');
1951 write_object_end(out, indent);
1952 }
1953 Expression::Index {
1954 line,
1955 object,
1956 index,
1957 ..
1958 } => {
1959 write_object_start(out);
1960 write_string_field(out, indent + 1, "type", "IndexExpression", true);
1961 write_number_field(out, indent + 1, "line", *line, true);
1962 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1963 write_field_name(out, indent + 1, "object");
1964 object.write_json(out, indent + 1);
1965 out.push_str(",\n");
1966 write_field_name(out, indent + 1, "index");
1967 index.write_json(out, indent + 1);
1968 out.push('\n');
1969 write_object_end(out, indent);
1970 }
1971 Expression::Slice {
1972 line,
1973 object,
1974 start,
1975 end,
1976 ..
1977 } => {
1978 write_object_start(out);
1979 write_string_field(out, indent + 1, "type", "SliceExpression", true);
1980 write_number_field(out, indent + 1, "line", *line, true);
1981 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1982 write_field_name(out, indent + 1, "object");
1983 object.write_json(out, indent + 1);
1984 out.push_str(",\n");
1985 write_optional_boxed_expr_field(out, indent + 1, "start", start.as_ref(), true);
1986 write_optional_boxed_expr_field(out, indent + 1, "end", end.as_ref(), false);
1987 write_object_end(out, indent);
1988 }
1989 Expression::DictAccess {
1990 line, object, key, ..
1991 } => {
1992 write_object_start(out);
1993 write_string_field(out, indent + 1, "type", "DictAccessExpression", true);
1994 write_number_field(out, indent + 1, "line", *line, true);
1995 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
1996 write_field_name(out, indent + 1, "object");
1997 object.write_json(out, indent + 1);
1998 out.push_str(",\n");
1999 write_field_name(out, indent + 1, "key");
2000 key.write_json(out, indent + 1);
2001 out.push('\n');
2002 write_object_end(out, indent);
2003 }
2004 Expression::PostfixUpdate {
2005 line,
2006 operator,
2007 argument,
2008 ..
2009 } => {
2010 write_object_start(out);
2011 write_string_field(out, indent + 1, "type", "PostfixUpdateExpression", true);
2012 write_number_field(out, indent + 1, "line", *line, true);
2013 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2014 write_string_field(out, indent + 1, "operator", operator, true);
2015 write_string_field(
2016 out,
2017 indent + 1,
2018 "operator_kind",
2019 operator_kind(operator),
2020 true,
2021 );
2022 write_field_name(out, indent + 1, "argument");
2023 argument.write_json(out, indent + 1);
2024 out.push('\n');
2025 write_object_end(out, indent);
2026 }
2027 Expression::Lambda {
2028 line,
2029 params,
2030 body,
2031 is_async,
2032 ..
2033 } => {
2034 write_object_start(out);
2035 write_string_field(out, indent + 1, "type", "LambdaExpression", true);
2036 write_number_field(out, indent + 1, "line", *line, true);
2037 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2038 write_bool_field(out, indent + 1, "is_async", *is_async, true);
2039 write_field_name(out, indent + 1, "params");
2040 write_array(out, indent + 1, params, |out, indent, param| {
2041 param.write_json(out, indent)
2042 });
2043 out.push_str(",\n");
2044 write_field_name(out, indent + 1, "body");
2045 body.write_json(out, indent + 1);
2046 out.push('\n');
2047 write_object_end(out, indent);
2048 }
2049 Expression::FunctionExpression {
2050 line,
2051 params,
2052 return_type,
2053 body,
2054 is_async,
2055 ..
2056 } => {
2057 write_object_start(out);
2058 write_string_field(out, indent + 1, "type", "FunctionExpression", true);
2059 write_number_field(out, indent + 1, "line", *line, true);
2060 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2061 write_bool_field(out, indent + 1, "is_async", *is_async, true);
2062 write_optional_string_field(
2063 out,
2064 indent + 1,
2065 "return_type",
2066 return_type.as_deref(),
2067 true,
2068 );
2069 write_field_name(out, indent + 1, "params");
2070 write_array(out, indent + 1, params, |out, indent, param| {
2071 param.write_json(out, indent)
2072 });
2073 out.push_str(",\n");
2074 write_field_name(out, indent + 1, "body");
2075 body.write_json(out, indent + 1);
2076 out.push('\n');
2077 write_object_end(out, indent);
2078 }
2079 Expression::LetExpression {
2080 line,
2081 kind,
2082 declared_type,
2083 name,
2084 init,
2085 ..
2086 } => {
2087 write_object_start(out);
2088 write_string_field(out, indent + 1, "type", "LetExpression", true);
2089 write_number_field(out, indent + 1, "line", *line, true);
2090 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2091 write_string_field(out, indent + 1, "kind", kind, true);
2092 write_optional_string_field(
2093 out,
2094 indent + 1,
2095 "declared_type",
2096 declared_type.as_deref(),
2097 true,
2098 );
2099 write_string_field(out, indent + 1, "name", name, true);
2100 write_bool_field(
2101 out,
2102 indent + 1,
2103 "is_weak_storage",
2104 self.is_weak_storage(),
2105 true,
2106 );
2107 write_optional_bool_field(
2108 out,
2109 indent + 1,
2110 "runtime_typecheck_required",
2111 self.runtime_typecheck_required(),
2112 true,
2113 );
2114 match init {
2115 Some(init) => {
2116 write_field_name(out, indent + 1, "init");
2117 init.write_json(out, indent + 1);
2118 out.push('\n');
2119 }
2120 None => write_null_field(out, indent + 1, "init", false),
2121 }
2122 write_object_end(out, indent);
2123 }
2124 Expression::TryExpression {
2125 line,
2126 body,
2127 handlers,
2128 ..
2129 } => {
2130 write_object_start(out);
2131 write_string_field(out, indent + 1, "type", "TryExpression", true);
2132 write_number_field(out, indent + 1, "line", *line, true);
2133 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2134 write_field_name(out, indent + 1, "body");
2135 body.write_json(out, indent + 1);
2136 out.push_str(",\n");
2137 write_field_name(out, indent + 1, "handlers");
2138 write_array(out, indent + 1, handlers, |out, indent, clause| {
2139 clause.write_json(out, indent)
2140 });
2141 out.push('\n');
2142 write_object_end(out, indent);
2143 }
2144 Expression::DoExpression { line, body, .. } => {
2145 write_object_start(out);
2146 write_string_field(out, indent + 1, "type", "DoExpression", true);
2147 write_number_field(out, indent + 1, "line", *line, true);
2148 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2149 write_field_name(out, indent + 1, "body");
2150 body.write_json(out, indent + 1);
2151 out.push('\n');
2152 write_object_end(out, indent);
2153 }
2154 Expression::AwaitExpression { line, body, .. } => {
2155 write_object_start(out);
2156 write_string_field(out, indent + 1, "type", "AwaitExpression", true);
2157 write_number_field(out, indent + 1, "line", *line, true);
2158 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2159 write_field_name(out, indent + 1, "body");
2160 body.write_json(out, indent + 1);
2161 out.push('\n');
2162 write_object_end(out, indent);
2163 }
2164 Expression::SpawnExpression { line, body, .. } => {
2165 write_object_start(out);
2166 write_string_field(out, indent + 1, "type", "SpawnExpression", true);
2167 write_number_field(out, indent + 1, "line", *line, true);
2168 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2169 write_field_name(out, indent + 1, "body");
2170 body.write_json(out, indent + 1);
2171 out.push('\n');
2172 write_object_end(out, indent);
2173 }
2174 Expression::SuperCall {
2175 line, arguments, ..
2176 } => {
2177 write_object_start(out);
2178 write_string_field(out, indent + 1, "type", "SuperCallExpression", true);
2179 write_number_field(out, indent + 1, "line", *line, true);
2180 write_optional_string_field(out, indent + 1, "inferred_type", inferred_type, true);
2181 write_field_name(out, indent + 1, "arguments");
2182 write_array(out, indent + 1, arguments, |out, indent, arg| {
2183 arg.write_json(out, indent)
2184 });
2185 out.push('\n');
2186 write_object_end(out, indent);
2187 }
2188 }
2189 }
2190}
2191
2192impl TemplatePart {
2193 fn write_json(&self, out: &mut String, indent: usize) {
2194 match self {
2195 TemplatePart::Text { line, value, .. } => {
2196 write_object_start(out);
2197 write_string_field(out, indent + 1, "type", "TemplateText", true);
2198 write_number_field(out, indent + 1, "line", *line, true);
2199 write_string_field(out, indent + 1, "value", value, false);
2200 write_object_end(out, indent);
2201 }
2202 TemplatePart::Expression {
2203 line, expression, ..
2204 } => {
2205 write_object_start(out);
2206 write_string_field(out, indent + 1, "type", "TemplateExpression", true);
2207 write_number_field(out, indent + 1, "line", *line, true);
2208 write_field_name(out, indent + 1, "expression");
2209 expression.write_json(out, indent + 1);
2210 out.push('\n');
2211 write_object_end(out, indent);
2212 }
2213 }
2214 }
2215}
2216
2217impl DictEntry {
2218 fn write_json(&self, out: &mut String, indent: usize) {
2219 write_object_start(out);
2220 write_number_field(out, indent + 1, "line", self.line, true);
2221 write_field_name(out, indent + 1, "key");
2222 self.key.write_json(out, indent + 1);
2223 out.push_str(",\n");
2224 write_field_name(out, indent + 1, "value");
2225 self.value.write_json(out, indent + 1);
2226 out.push('\n');
2227 write_object_end(out, indent);
2228 }
2229}
2230
2231impl DictKey {
2232 pub fn line(&self) -> usize {
2233 match self {
2234 DictKey::Identifier { line, .. } => *line,
2235 DictKey::StringLiteral { line, .. } => *line,
2236 DictKey::Expression { line, .. } => *line,
2237 }
2238 }
2239
2240 pub fn source_file(&self) -> Option<&str> {
2241 match self {
2242 DictKey::Identifier { source_file, .. }
2243 | DictKey::StringLiteral { source_file, .. }
2244 | DictKey::Expression { source_file, .. } => source_file.as_deref(),
2245 }
2246 }
2247
2248 fn write_json(&self, out: &mut String, indent: usize) {
2249 match self {
2250 DictKey::Identifier { line, name, .. } => {
2251 write_simple_object(out, indent, "IdentifierKey", *line, "name", name)
2252 }
2253 DictKey::StringLiteral { line, value, .. } => {
2254 write_simple_object(out, indent, "StringKey", *line, "value", value)
2255 }
2256 DictKey::Expression {
2257 line, expression, ..
2258 } => {
2259 write_object_start(out);
2260 write_string_field(out, indent + 1, "type", "ExpressionKey", true);
2261 write_number_field(out, indent + 1, "line", *line, true);
2262 write_field_name(out, indent + 1, "expression");
2263 expression.write_json(out, indent + 1);
2264 out.push('\n');
2265 write_object_end(out, indent);
2266 }
2267 }
2268 }
2269}
2270
2271impl CallArgument {
2272 pub fn line(&self) -> usize {
2273 match self {
2274 CallArgument::Positional { line, .. } => *line,
2275 CallArgument::Spread { line, .. } => *line,
2276 CallArgument::Named { line, .. } => *line,
2277 }
2278 }
2279
2280 fn write_json(&self, out: &mut String, indent: usize) {
2281 match self {
2282 CallArgument::Positional { line, value, .. } => {
2283 write_object_start(out);
2284 write_string_field(out, indent + 1, "type", "PositionalArgument", true);
2285 write_number_field(out, indent + 1, "line", *line, true);
2286 write_field_name(out, indent + 1, "value");
2287 value.write_json(out, indent + 1);
2288 out.push('\n');
2289 write_object_end(out, indent);
2290 }
2291 CallArgument::Spread { line, value, .. } => {
2292 write_object_start(out);
2293 write_string_field(out, indent + 1, "type", "SpreadArgument", true);
2294 write_number_field(out, indent + 1, "line", *line, true);
2295 write_field_name(out, indent + 1, "value");
2296 value.write_json(out, indent + 1);
2297 out.push('\n');
2298 write_object_end(out, indent);
2299 }
2300 CallArgument::Named {
2301 line, name, value, ..
2302 } => {
2303 write_object_start(out);
2304 write_string_field(out, indent + 1, "type", "NamedArgument", true);
2305 write_number_field(out, indent + 1, "line", *line, true);
2306 write_field_name(out, indent + 1, "name");
2307 name.write_json(out, indent + 1);
2308 out.push_str(",\n");
2309 write_field_name(out, indent + 1, "value");
2310 value.write_json(out, indent + 1);
2311 out.push('\n');
2312 write_object_end(out, indent);
2313 }
2314 }
2315 }
2316}
2317
2318fn write_array<T>(
2319 out: &mut String,
2320 indent: usize,
2321 items: &[T],
2322 mut write_item: impl FnMut(&mut String, usize, &T),
2323) {
2324 if items.is_empty() {
2325 out.push_str("[]");
2326 return;
2327 }
2328 out.push_str("[\n");
2329 for (index, item) in items.iter().enumerate() {
2330 write_indent(out, indent + 1);
2331 write_item(out, indent + 1, item);
2332 if index + 1 != items.len() {
2333 out.push(',');
2334 }
2335 out.push('\n');
2336 }
2337 write_indent(out, indent);
2338 out.push(']');
2339}
2340
2341fn write_string_array(out: &mut String, indent: usize, items: &[String]) {
2342 write_array(out, indent, items, |out, _indent, item| {
2343 write_json_string(out, item)
2344 });
2345}
2346
2347fn operator_kind(operator: &str) -> &str {
2348 match operator {
2349 "+" => "plus",
2350 "-" => "minus",
2351 "×" | "*" => "multiply",
2352 "÷" | "/" => "divide",
2353 "mod" => "modulo",
2354 "**" => "exponent",
2355 "=" => "numeric_equal",
2356 "≠" => "numeric_not_equal",
2357 "<" => "less_than",
2358 ">" => "greater_than",
2359 "≤" | "<=" => "less_equal",
2360 "≥" | ">=" => "greater_equal",
2361 "≶" | "<=>" | "≷" => "numeric_compare",
2362 "≡" | "==" => "strict_equal",
2363 "≢" | "!=" => "strict_not_equal",
2364 "default" => "default",
2365 "⋀" | "and" => "logical_and",
2366 "⋀?" | "and?" => "logical_and_value",
2367 "⋁" | "or" => "logical_or",
2368 "⋁?" | "or?" => "logical_or_value",
2369 "⊻" | "xor" => "logical_xor",
2370 "⊻?" | "xor?" => "logical_xor_value",
2371 "⊽" | "nor" => "logical_nor",
2372 "⊽?" | "nor?" => "logical_nor_value",
2373 "↔" | "xnor" => "logical_xnor",
2374 "↔?" | "xnor?" => "logical_xnor_value",
2375 "⊼" | "nand" => "logical_nand",
2376 "⊼?" | "nand?" => "logical_nand_value",
2377 "⊨" | "onlyif" => "logical_onlyif",
2378 "⊨?" | "onlyif?" => "logical_onlyif_value",
2379 "⊭" | "butnot" => "logical_butnot",
2380 "⊭?" | "butnot?" => "logical_butnot_value",
2381 "¬" | "not" | "!" => "logical_not",
2382 "√" | "sqrt" => "sqrt",
2383 "⋃" | "union" => "set_union",
2384 "⋂" | "intersection" => "set_intersection",
2385 "∖" | "\\" => "set_difference",
2386 "∈" | "in" => "membership",
2387 "∉" => "not_membership",
2388 "⊂" | "subsetof" => "subset",
2389 "⊃" | "supersetof" => "superset",
2390 "⊂⊃" | "equivalentof" => "set_equivalent",
2391 "@" => "path_first",
2392 "@@" => "path_all",
2393 "@?" => "path_exists",
2394 ":=" => "assign",
2395 "+=" => "add_assign",
2396 "-=" => "subtract_assign",
2397 "×=" | "*=" => "multiply_assign",
2398 "÷=" | "/=" => "divide_assign",
2399 "_=" => "concat_assign",
2400 "~=" => "regex_replace_assign",
2401 "**=" => "exponent_assign",
2402 "?:=" => "defined_assign",
2403 "++" => "increment",
2404 "--" => "decrement",
2405 other => other,
2406 }
2407}
2408
2409fn write_optional_expr_field(
2410 out: &mut String,
2411 indent: usize,
2412 key: &str,
2413 expr: Option<&Expression>,
2414 trailing_comma: bool,
2415) {
2416 match expr {
2417 Some(expr) => {
2418 write_field_name(out, indent, key);
2419 expr.write_json(out, indent);
2420 if trailing_comma {
2421 out.push_str(",\n");
2422 } else {
2423 out.push('\n');
2424 }
2425 }
2426 None => write_null_field(out, indent, key, trailing_comma),
2427 }
2428}
2429
2430fn write_optional_boxed_expr_field(
2431 out: &mut String,
2432 indent: usize,
2433 key: &str,
2434 expr: Option<&Box<Expression>>,
2435 trailing_comma: bool,
2436) {
2437 write_optional_expr_field(out, indent, key, expr.map(Box::as_ref), trailing_comma);
2438}
2439
2440fn write_string_field(
2441 out: &mut String,
2442 indent: usize,
2443 key: &str,
2444 value: &str,
2445 trailing_comma: bool,
2446) {
2447 write_field_name(out, indent, key);
2448 write_json_string(out, value);
2449 if trailing_comma {
2450 out.push_str(",\n");
2451 } else {
2452 out.push('\n');
2453 }
2454}
2455
2456fn write_number_field(
2457 out: &mut String,
2458 indent: usize,
2459 key: &str,
2460 value: usize,
2461 trailing_comma: bool,
2462) {
2463 write_field_name(out, indent, key);
2464 out.push_str(&value.to_string());
2465 if trailing_comma {
2466 out.push_str(",\n");
2467 } else {
2468 out.push('\n');
2469 }
2470}
2471
2472fn write_optional_string_field(
2473 out: &mut String,
2474 indent: usize,
2475 key: &str,
2476 value: Option<&str>,
2477 trailing_comma: bool,
2478) {
2479 match value {
2480 Some(value) => write_string_field(out, indent, key, value, trailing_comma),
2481 None => write_null_field(out, indent, key, trailing_comma),
2482 }
2483}
2484
2485fn write_optional_number_field(
2486 out: &mut String,
2487 indent: usize,
2488 key: &str,
2489 value: Option<usize>,
2490 trailing_comma: bool,
2491) {
2492 write_field_name(out, indent, key);
2493 match value {
2494 Some(value) => out.push_str(&value.to_string()),
2495 None => out.push_str("null"),
2496 }
2497 if trailing_comma {
2498 out.push_str(",\n");
2499 } else {
2500 out.push('\n');
2501 }
2502}
2503
2504fn write_bool_field(out: &mut String, indent: usize, key: &str, value: bool, trailing_comma: bool) {
2505 write_field_name(out, indent, key);
2506 out.push_str(if value { "true" } else { "false" });
2507 if trailing_comma {
2508 out.push_str(",\n");
2509 } else {
2510 out.push('\n');
2511 }
2512}
2513
2514fn write_optional_bool_field(
2515 out: &mut String,
2516 indent: usize,
2517 key: &str,
2518 value: Option<bool>,
2519 trailing_comma: bool,
2520) {
2521 write_field_name(out, indent, key);
2522 match value {
2523 Some(true) => out.push_str("true"),
2524 Some(false) => out.push_str("false"),
2525 None => out.push_str("null"),
2526 }
2527 if trailing_comma {
2528 out.push_str(",\n");
2529 } else {
2530 out.push('\n');
2531 }
2532}
2533
2534fn write_null_field(out: &mut String, indent: usize, key: &str, trailing_comma: bool) {
2535 write_field_name(out, indent, key);
2536 out.push_str("null");
2537 if trailing_comma {
2538 out.push_str(",\n");
2539 } else {
2540 out.push('\n');
2541 }
2542}
2543
2544fn write_field_name(out: &mut String, indent: usize, key: &str) {
2545 write_indent(out, indent);
2546 write_json_string(out, key);
2547 out.push_str(": ");
2548}
2549
2550fn write_indent(out: &mut String, indent: usize) {
2551 for _ in 0..indent {
2552 out.push_str(" ");
2553 }
2554}
2555
2556fn write_json_string(out: &mut String, value: &str) {
2557 out.push('"');
2558 for ch in value.chars() {
2559 match ch {
2560 '"' => out.push_str("\\\""),
2561 '\\' => out.push_str("\\\\"),
2562 '\n' => out.push_str("\\n"),
2563 '\r' => out.push_str("\\r"),
2564 '\t' => out.push_str("\\t"),
2565 _ => out.push(ch),
2566 }
2567 }
2568 out.push('"');
2569}
2570
2571fn bytes_to_hex(bytes: &[u8]) -> String {
2572 const HEX: &[u8; 16] = b"0123456789abcdef";
2573 let mut out = String::with_capacity(bytes.len() * 2);
2574 for byte in bytes {
2575 out.push(HEX[(byte >> 4) as usize] as char);
2576 out.push(HEX[(byte & 0x0f) as usize] as char);
2577 }
2578 out
2579}
2580
2581fn write_object_start(out: &mut String) {
2582 out.push_str("{\n");
2583}
2584
2585fn write_object_end(out: &mut String, indent: usize) {
2586 write_indent(out, indent);
2587 out.push('}');
2588}
2589
2590fn write_simple_object(
2591 out: &mut String,
2592 indent: usize,
2593 type_name: &str,
2594 line: usize,
2595 key: &str,
2596 value: &str,
2597) {
2598 write_object_start(out);
2599 write_string_field(out, indent + 1, "type", type_name, true);
2600 write_number_field(out, indent + 1, "line", line, true);
2601 write_string_field(out, indent + 1, key, value, false);
2602 write_object_end(out, indent);
2603}