Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/Analysis/src/AstJsonEncoder.cpp
2746 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#include "Luau/AstJsonEncoder.h"
3
4
#include "Luau/Ast.h"
5
#include "Luau/ParseResult.h"
6
#include "Luau/StringUtils.h"
7
#include "Luau/Common.h"
8
9
#include <math.h>
10
11
LUAU_FASTFLAG(LuauConst2)
12
13
namespace Luau
14
{
15
16
struct AstJsonEncoder : public AstVisitor
17
{
18
static constexpr int CHUNK_SIZE = 1024;
19
std::vector<std::string> chunks;
20
bool comma = false;
21
22
AstJsonEncoder()
23
{
24
newChunk();
25
}
26
27
std::string str()
28
{
29
return join(chunks, "");
30
}
31
32
bool pushComma()
33
{
34
bool c = comma;
35
comma = false;
36
return c;
37
}
38
39
void popComma(bool c)
40
{
41
comma = c;
42
}
43
44
void newChunk()
45
{
46
chunks.emplace_back();
47
chunks.back().reserve(CHUNK_SIZE);
48
}
49
50
void appendChunk(std::string_view sv)
51
{
52
if (sv.size() > CHUNK_SIZE)
53
{
54
chunks.emplace_back(sv);
55
newChunk();
56
return;
57
}
58
59
auto& chunk = chunks.back();
60
if (chunk.size() + sv.size() < CHUNK_SIZE)
61
{
62
chunk.append(sv.data(), sv.size());
63
return;
64
}
65
66
size_t prefix = CHUNK_SIZE - chunk.size();
67
chunk.append(sv.data(), prefix);
68
newChunk();
69
70
chunks.back().append(sv.data() + prefix, sv.size() - prefix);
71
}
72
73
void writeRaw(std::string_view sv)
74
{
75
appendChunk(sv);
76
}
77
78
void writeRaw(char c)
79
{
80
writeRaw(std::string_view{&c, 1});
81
}
82
83
void writeType(std::string_view propValue)
84
{
85
write("type", propValue);
86
}
87
88
template<typename T>
89
void write(std::string_view propName, const T& value)
90
{
91
if (comma)
92
writeRaw(",");
93
comma = true;
94
writeRaw("\"");
95
writeRaw(propName);
96
writeRaw("\":");
97
write(value);
98
}
99
100
void write(bool b)
101
{
102
if (b)
103
writeRaw("true");
104
else
105
writeRaw("false");
106
}
107
108
void write(double d)
109
{
110
switch (fpclassify(d))
111
{
112
case FP_INFINITE:
113
if (d < 0)
114
writeRaw("-Infinity");
115
else
116
writeRaw("Infinity");
117
break;
118
119
case FP_NAN:
120
writeRaw("NaN");
121
break;
122
123
case FP_NORMAL:
124
case FP_SUBNORMAL:
125
case FP_ZERO:
126
default:
127
char b[32];
128
snprintf(b, sizeof(b), "%.17g", d);
129
writeRaw(b);
130
break;
131
}
132
}
133
134
void writeString(std::string_view sv)
135
{
136
// TODO escape more accurately?
137
writeRaw("\"");
138
139
for (char c : sv)
140
{
141
if (c == '"')
142
writeRaw("\\\"");
143
else if (c == '\\')
144
writeRaw("\\\\");
145
else if (c < ' ')
146
writeRaw(format("\\u%04x", c));
147
else if (c == '\n')
148
writeRaw("\\n");
149
else
150
writeRaw(c);
151
}
152
153
writeRaw("\"");
154
}
155
156
void write(char c)
157
{
158
writeString(std::string_view(&c, 1));
159
}
160
void write(int i)
161
{
162
writeRaw(std::to_string(i));
163
}
164
void write(long i)
165
{
166
writeRaw(std::to_string(i));
167
}
168
void write(long long i)
169
{
170
writeRaw(std::to_string(i));
171
}
172
void write(unsigned int i)
173
{
174
writeRaw(std::to_string(i));
175
}
176
void write(unsigned long i)
177
{
178
writeRaw(std::to_string(i));
179
}
180
void write(unsigned long long i)
181
{
182
writeRaw(std::to_string(i));
183
}
184
void write(std::nullptr_t)
185
{
186
writeRaw("null");
187
}
188
void write(std::string_view str)
189
{
190
writeString(str);
191
}
192
void write(std::optional<AstName> name)
193
{
194
if (name)
195
write(*name);
196
else
197
writeRaw("null");
198
}
199
void write(AstName name)
200
{
201
writeString(name.value ? name.value : "");
202
}
203
void write(std::optional<AstArgumentName> name)
204
{
205
if (name)
206
write(*name);
207
else
208
writeRaw("null");
209
}
210
void write(AstArgumentName name)
211
{
212
writeRaw("{");
213
bool c = pushComma();
214
writeType("AstArgumentName");
215
write("name", name.first);
216
write("location", name.second);
217
popComma(c);
218
writeRaw("}");
219
}
220
221
void write(const Position& position)
222
{
223
write(position.line);
224
writeRaw(",");
225
write(position.column);
226
}
227
228
void write(const Location& location)
229
{
230
writeRaw("\"");
231
write(location.begin);
232
writeRaw(" - ");
233
write(location.end);
234
writeRaw("\"");
235
}
236
237
void write(AstLocal* local)
238
{
239
writeRaw("{");
240
bool c = pushComma();
241
if (local->annotation != nullptr)
242
write("luauType", local->annotation);
243
else
244
write("luauType", nullptr);
245
write("name", local->name);
246
if (FFlag::LuauConst2)
247
write("isConst", local->isConst);
248
writeType("AstLocal");
249
write("location", local->location);
250
popComma(c);
251
writeRaw("}");
252
}
253
254
void writeNode(AstNode* node)
255
{
256
write("location", node->location);
257
}
258
259
template<typename F>
260
void writeNode(AstNode* node, std::string_view name, F&& f)
261
{
262
writeRaw("{");
263
bool c = pushComma();
264
writeType(name);
265
writeNode(node);
266
f();
267
popComma(c);
268
writeRaw("}");
269
}
270
271
void write(AstNode* node)
272
{
273
node->visit(this);
274
}
275
276
void write(class AstExprGroup* node)
277
{
278
writeNode(
279
node,
280
"AstExprGroup",
281
[&]()
282
{
283
write("expr", node->expr);
284
}
285
);
286
}
287
288
void write(class AstExprConstantNil* node)
289
{
290
writeNode(node, "AstExprConstantNil", []() {});
291
}
292
293
void write(class AstExprConstantBool* node)
294
{
295
writeNode(
296
node,
297
"AstExprConstantBool",
298
[&]()
299
{
300
write("value", node->value);
301
}
302
);
303
}
304
305
void write(class AstExprConstantNumber* node)
306
{
307
writeNode(
308
node,
309
"AstExprConstantNumber",
310
[&]()
311
{
312
write("value", node->value);
313
}
314
);
315
}
316
317
void write(class AstExprConstantString* node)
318
{
319
writeNode(
320
node,
321
"AstExprConstantString",
322
[&]()
323
{
324
write("value", node->value);
325
}
326
);
327
}
328
329
void write(class AstExprLocal* node)
330
{
331
writeNode(
332
node,
333
"AstExprLocal",
334
[&]()
335
{
336
write("local", node->local);
337
}
338
);
339
}
340
341
void write(class AstExprGlobal* node)
342
{
343
writeNode(
344
node,
345
"AstExprGlobal",
346
[&]()
347
{
348
write("global", node->name);
349
}
350
);
351
}
352
353
void write(class AstExprVarargs* node)
354
{
355
writeNode(node, "AstExprVarargs", []() {});
356
}
357
358
template<typename T>
359
void write(AstArray<T> arr)
360
{
361
writeRaw("[");
362
bool comma = false;
363
for (const auto& a : arr)
364
{
365
if (comma)
366
writeRaw(",");
367
else
368
comma = true;
369
370
write(a);
371
}
372
writeRaw("]");
373
}
374
375
void write(AstArray<char> arr)
376
{
377
write(std::string_view{arr.data, arr.size});
378
}
379
380
#define PROP(prop) write(#prop, node->prop)
381
382
void write(class AstExprCall* node)
383
{
384
writeNode(
385
node,
386
"AstExprCall",
387
[&]()
388
{
389
PROP(func);
390
PROP(args);
391
PROP(self);
392
PROP(argLocation);
393
}
394
);
395
}
396
397
void write(class AstExprIndexName* node)
398
{
399
writeNode(
400
node,
401
"AstExprIndexName",
402
[&]()
403
{
404
PROP(expr);
405
PROP(index);
406
PROP(indexLocation);
407
PROP(op);
408
}
409
);
410
}
411
412
void write(class AstExprIndexExpr* node)
413
{
414
writeNode(
415
node,
416
"AstExprIndexExpr",
417
[&]()
418
{
419
PROP(expr);
420
PROP(index);
421
}
422
);
423
}
424
425
void write(class AstExprFunction* node)
426
{
427
writeNode(
428
node,
429
"AstExprFunction",
430
[&]()
431
{
432
PROP(attributes);
433
PROP(generics);
434
PROP(genericPacks);
435
if (node->self)
436
PROP(self);
437
PROP(args);
438
if (node->returnAnnotation)
439
PROP(returnAnnotation);
440
PROP(vararg);
441
PROP(varargLocation);
442
if (node->varargAnnotation)
443
PROP(varargAnnotation);
444
445
PROP(body);
446
PROP(functionDepth);
447
PROP(debugname);
448
}
449
);
450
}
451
452
void write(const std::optional<AstTypeList>& typeList)
453
{
454
if (typeList)
455
write(*typeList);
456
else
457
writeRaw("null");
458
}
459
460
void write(const AstTypeList& typeList)
461
{
462
writeRaw("{");
463
bool c = pushComma();
464
writeType("AstTypeList");
465
write("types", typeList.types);
466
if (typeList.tailType)
467
write("tailType", typeList.tailType);
468
popComma(c);
469
writeRaw("}");
470
}
471
472
void write(class AstGenericType* genericType)
473
{
474
writeRaw("{");
475
bool c = pushComma();
476
writeType("AstGenericType");
477
write("name", genericType->name);
478
if (genericType->defaultValue)
479
write("luauType", genericType->defaultValue);
480
popComma(c);
481
writeRaw("}");
482
}
483
484
void write(class AstGenericTypePack* genericTypePack)
485
{
486
writeRaw("{");
487
bool c = pushComma();
488
writeType("AstGenericTypePack");
489
write("name", genericTypePack->name);
490
if (genericTypePack->defaultValue)
491
write("luauType", genericTypePack->defaultValue);
492
popComma(c);
493
writeRaw("}");
494
}
495
496
void write(AstExprTable::Item::Kind kind)
497
{
498
switch (kind)
499
{
500
case AstExprTable::Item::List:
501
return writeString("item");
502
case AstExprTable::Item::Record:
503
return writeString("record");
504
case AstExprTable::Item::General:
505
return writeString("general");
506
}
507
}
508
509
void write(const AstExprTable::Item& item)
510
{
511
writeRaw("{");
512
bool c = pushComma();
513
writeType("AstExprTableItem");
514
write("kind", item.kind);
515
switch (item.kind)
516
{
517
case AstExprTable::Item::List:
518
write("value", item.value);
519
break;
520
default:
521
write("key", item.key);
522
write("value", item.value);
523
break;
524
}
525
popComma(c);
526
writeRaw("}");
527
}
528
529
void write(class AstExprIfElse* node)
530
{
531
writeNode(
532
node,
533
"AstExprIfElse",
534
[&]()
535
{
536
PROP(condition);
537
PROP(hasThen);
538
PROP(trueExpr);
539
PROP(hasElse);
540
PROP(falseExpr);
541
}
542
);
543
}
544
545
void write(class AstExprInterpString* node)
546
{
547
writeNode(
548
node,
549
"AstExprInterpString",
550
[&]()
551
{
552
PROP(strings);
553
PROP(expressions);
554
}
555
);
556
}
557
558
void write(class AstExprTable* node)
559
{
560
writeNode(
561
node,
562
"AstExprTable",
563
[&]()
564
{
565
PROP(items);
566
}
567
);
568
}
569
570
void write(AstExprUnary::Op op)
571
{
572
switch (op)
573
{
574
case AstExprUnary::Not:
575
return writeString("Not");
576
case AstExprUnary::Minus:
577
return writeString("Minus");
578
case AstExprUnary::Len:
579
return writeString("Len");
580
}
581
}
582
583
void write(class AstExprUnary* node)
584
{
585
writeNode(
586
node,
587
"AstExprUnary",
588
[&]()
589
{
590
PROP(op);
591
PROP(expr);
592
}
593
);
594
}
595
596
void write(AstExprBinary::Op op)
597
{
598
switch (op)
599
{
600
case AstExprBinary::Add:
601
return writeString("Add");
602
case AstExprBinary::Sub:
603
return writeString("Sub");
604
case AstExprBinary::Mul:
605
return writeString("Mul");
606
case AstExprBinary::Div:
607
return writeString("Div");
608
case AstExprBinary::FloorDiv:
609
return writeString("FloorDiv");
610
case AstExprBinary::Mod:
611
return writeString("Mod");
612
case AstExprBinary::Pow:
613
return writeString("Pow");
614
case AstExprBinary::Concat:
615
return writeString("Concat");
616
case AstExprBinary::CompareNe:
617
return writeString("CompareNe");
618
case AstExprBinary::CompareEq:
619
return writeString("CompareEq");
620
case AstExprBinary::CompareLt:
621
return writeString("CompareLt");
622
case AstExprBinary::CompareLe:
623
return writeString("CompareLe");
624
case AstExprBinary::CompareGt:
625
return writeString("CompareGt");
626
case AstExprBinary::CompareGe:
627
return writeString("CompareGe");
628
case AstExprBinary::And:
629
return writeString("And");
630
case AstExprBinary::Or:
631
return writeString("Or");
632
default:
633
LUAU_ASSERT(!"Unknown Op");
634
}
635
}
636
637
void write(class AstExprBinary* node)
638
{
639
writeNode(
640
node,
641
"AstExprBinary",
642
[&]()
643
{
644
PROP(op);
645
PROP(left);
646
PROP(right);
647
}
648
);
649
}
650
651
void write(class AstExprTypeAssertion* node)
652
{
653
writeNode(
654
node,
655
"AstExprTypeAssertion",
656
[&]()
657
{
658
PROP(expr);
659
PROP(annotation);
660
}
661
);
662
}
663
664
void write(class AstExprError* node)
665
{
666
writeNode(
667
node,
668
"AstExprError",
669
[&]()
670
{
671
PROP(expressions);
672
PROP(messageIndex);
673
}
674
);
675
}
676
677
void write(class AstStatBlock* node)
678
{
679
writeNode(
680
node,
681
"AstStatBlock",
682
[&]()
683
{
684
writeRaw(",\"hasEnd\":");
685
write(node->hasEnd);
686
writeRaw(",\"body\":[");
687
bool comma = false;
688
for (AstStat* stat : node->body)
689
{
690
if (comma)
691
writeRaw(",");
692
else
693
comma = true;
694
695
write(stat);
696
}
697
writeRaw("]");
698
}
699
);
700
}
701
702
void write(class AstStatIf* node)
703
{
704
writeNode(
705
node,
706
"AstStatIf",
707
[&]()
708
{
709
PROP(condition);
710
PROP(thenbody);
711
if (node->elsebody)
712
PROP(elsebody);
713
write("hasThen", node->thenLocation.has_value());
714
}
715
);
716
}
717
718
void write(class AstStatWhile* node)
719
{
720
writeNode(
721
node,
722
"AstStatWhile",
723
[&]()
724
{
725
PROP(condition);
726
PROP(body);
727
PROP(hasDo);
728
}
729
);
730
}
731
732
void write(class AstStatRepeat* node)
733
{
734
writeNode(
735
node,
736
"AstStatRepeat",
737
[&]()
738
{
739
PROP(condition);
740
PROP(body);
741
}
742
);
743
}
744
745
void write(class AstStatBreak* node)
746
{
747
writeNode(node, "AstStatBreak", []() {});
748
}
749
750
void write(class AstStatContinue* node)
751
{
752
writeNode(node, "AstStatContinue", []() {});
753
}
754
755
void write(class AstStatReturn* node)
756
{
757
writeNode(
758
node,
759
"AstStatReturn",
760
[&]()
761
{
762
PROP(list);
763
}
764
);
765
}
766
767
void write(class AstStatExpr* node)
768
{
769
writeNode(
770
node,
771
"AstStatExpr",
772
[&]()
773
{
774
PROP(expr);
775
}
776
);
777
}
778
779
void write(class AstStatLocal* node)
780
{
781
writeNode(
782
node,
783
"AstStatLocal",
784
[&]()
785
{
786
PROP(vars);
787
PROP(values);
788
}
789
);
790
}
791
792
void write(class AstStatFor* node)
793
{
794
writeNode(
795
node,
796
"AstStatFor",
797
[&]()
798
{
799
PROP(var);
800
PROP(from);
801
PROP(to);
802
if (node->step)
803
PROP(step);
804
PROP(body);
805
PROP(hasDo);
806
}
807
);
808
}
809
810
void write(class AstStatForIn* node)
811
{
812
writeNode(
813
node,
814
"AstStatForIn",
815
[&]()
816
{
817
PROP(vars);
818
PROP(values);
819
PROP(body);
820
PROP(hasIn);
821
PROP(hasDo);
822
}
823
);
824
}
825
826
void write(class AstStatAssign* node)
827
{
828
writeNode(
829
node,
830
"AstStatAssign",
831
[&]()
832
{
833
PROP(vars);
834
PROP(values);
835
}
836
);
837
}
838
839
void write(class AstStatCompoundAssign* node)
840
{
841
writeNode(
842
node,
843
"AstStatCompoundAssign",
844
[&]()
845
{
846
PROP(op);
847
PROP(var);
848
PROP(value);
849
}
850
);
851
}
852
853
void write(class AstStatFunction* node)
854
{
855
writeNode(
856
node,
857
"AstStatFunction",
858
[&]()
859
{
860
PROP(name);
861
PROP(func);
862
}
863
);
864
}
865
866
void write(class AstStatLocalFunction* node)
867
{
868
writeNode(
869
node,
870
"AstStatLocalFunction",
871
[&]()
872
{
873
PROP(name);
874
PROP(func);
875
}
876
);
877
}
878
879
void write(class AstStatTypeAlias* node)
880
{
881
writeNode(
882
node,
883
"AstStatTypeAlias",
884
[&]()
885
{
886
PROP(name);
887
PROP(generics);
888
PROP(genericPacks);
889
write("value", node->type);
890
PROP(exported);
891
}
892
);
893
}
894
895
void write(class AstStatDeclareFunction* node)
896
{
897
writeNode(
898
node,
899
"AstStatDeclareFunction",
900
[&]()
901
{
902
PROP(attributes);
903
PROP(name);
904
PROP(nameLocation);
905
PROP(params);
906
PROP(paramNames);
907
PROP(vararg);
908
PROP(varargLocation);
909
PROP(retTypes);
910
PROP(generics);
911
PROP(genericPacks);
912
}
913
);
914
}
915
916
void write(class AstStatDeclareGlobal* node)
917
{
918
writeNode(
919
node,
920
"AstStatDeclareGlobal",
921
[&]()
922
{
923
PROP(name);
924
PROP(nameLocation);
925
PROP(type);
926
}
927
);
928
}
929
930
void write(const AstDeclaredExternTypeProperty& prop)
931
{
932
writeRaw("{");
933
bool c = pushComma();
934
write("name", prop.name);
935
write("nameLocation", prop.nameLocation);
936
writeType("AstDeclaredClassProp");
937
write("luauType", prop.ty);
938
write("location", prop.location);
939
popComma(c);
940
writeRaw("}");
941
}
942
943
void write(class AstStatDeclareExternType* node)
944
{
945
writeNode(
946
node,
947
"AstStatDeclareClass",
948
[&]()
949
{
950
PROP(name);
951
if (node->superName)
952
write("superName", *node->superName);
953
PROP(props);
954
PROP(indexer);
955
}
956
);
957
}
958
959
void write(class AstStatError* node)
960
{
961
writeNode(
962
node,
963
"AstStatError",
964
[&]()
965
{
966
PROP(expressions);
967
PROP(statements);
968
}
969
);
970
}
971
972
void write(struct AstTypeOrPack node)
973
{
974
if (node.type)
975
write(node.type);
976
else
977
write(node.typePack);
978
}
979
980
void write(class AstTypeReference* node)
981
{
982
writeNode(
983
node,
984
"AstTypeReference",
985
[&]()
986
{
987
if (node->prefix)
988
PROP(prefix);
989
if (node->prefixLocation)
990
write("prefixLocation", *node->prefixLocation);
991
PROP(name);
992
PROP(nameLocation);
993
PROP(parameters);
994
}
995
);
996
}
997
998
void write(const AstTableProp& prop)
999
{
1000
writeRaw("{");
1001
bool c = pushComma();
1002
1003
write("name", prop.name);
1004
writeType("AstTableProp");
1005
write("location", prop.location);
1006
write("propType", prop.type);
1007
1008
popComma(c);
1009
writeRaw("}");
1010
}
1011
1012
void write(class AstTypeTable* node)
1013
{
1014
writeNode(
1015
node,
1016
"AstTypeTable",
1017
[&]()
1018
{
1019
PROP(props);
1020
PROP(indexer);
1021
}
1022
);
1023
}
1024
1025
void write(struct AstTableIndexer* indexer)
1026
{
1027
if (indexer)
1028
{
1029
writeRaw("{");
1030
bool c = pushComma();
1031
write("location", indexer->location);
1032
write("indexType", indexer->indexType);
1033
write("resultType", indexer->resultType);
1034
popComma(c);
1035
writeRaw("}");
1036
}
1037
else
1038
{
1039
writeRaw("null");
1040
}
1041
}
1042
1043
void write(class AstTypeFunction* node)
1044
{
1045
writeNode(
1046
node,
1047
"AstTypeFunction",
1048
[&]()
1049
{
1050
PROP(attributes);
1051
PROP(generics);
1052
PROP(genericPacks);
1053
PROP(argTypes);
1054
PROP(argNames);
1055
PROP(returnTypes);
1056
}
1057
);
1058
}
1059
1060
void write(class AstTypeTypeof* node)
1061
{
1062
writeNode(
1063
node,
1064
"AstTypeTypeof",
1065
[&]()
1066
{
1067
PROP(expr);
1068
}
1069
);
1070
}
1071
1072
void write(class AstTypeOptional* node)
1073
{
1074
writeNode(node, "AstTypeOptional", [&]() {});
1075
}
1076
1077
void write(class AstTypeUnion* node)
1078
{
1079
writeNode(
1080
node,
1081
"AstTypeUnion",
1082
[&]()
1083
{
1084
PROP(types);
1085
}
1086
);
1087
}
1088
1089
void write(class AstTypeIntersection* node)
1090
{
1091
writeNode(
1092
node,
1093
"AstTypeIntersection",
1094
[&]()
1095
{
1096
PROP(types);
1097
}
1098
);
1099
}
1100
1101
void write(class AstTypeError* node)
1102
{
1103
writeNode(
1104
node,
1105
"AstTypeError",
1106
[&]()
1107
{
1108
PROP(types);
1109
PROP(messageIndex);
1110
}
1111
);
1112
}
1113
1114
void write(class AstTypePackExplicit* node)
1115
{
1116
writeNode(
1117
node,
1118
"AstTypePackExplicit",
1119
[&]()
1120
{
1121
PROP(typeList);
1122
}
1123
);
1124
}
1125
1126
void write(class AstTypePackVariadic* node)
1127
{
1128
writeNode(
1129
node,
1130
"AstTypePackVariadic",
1131
[&]()
1132
{
1133
PROP(variadicType);
1134
}
1135
);
1136
}
1137
1138
void write(class AstTypePackGeneric* node)
1139
{
1140
writeNode(
1141
node,
1142
"AstTypePackGeneric",
1143
[&]()
1144
{
1145
PROP(genericName);
1146
}
1147
);
1148
}
1149
1150
void write(class AstAttr* node)
1151
{
1152
writeNode(
1153
node,
1154
"AstAttr",
1155
[&]()
1156
{
1157
write("name", node->name);
1158
}
1159
);
1160
}
1161
1162
bool visit(class AstTypeGroup* node) override
1163
{
1164
writeNode(
1165
node,
1166
"AstTypeGroup",
1167
[&]()
1168
{
1169
write("inner", node->type);
1170
}
1171
);
1172
return false;
1173
}
1174
1175
bool visit(class AstTypeSingletonBool* node) override
1176
{
1177
writeNode(
1178
node,
1179
"AstTypeSingletonBool",
1180
[&]()
1181
{
1182
write("value", node->value);
1183
}
1184
);
1185
return false;
1186
}
1187
1188
bool visit(class AstTypeSingletonString* node) override
1189
{
1190
writeNode(
1191
node,
1192
"AstTypeSingletonString",
1193
[&]()
1194
{
1195
write("value", node->value);
1196
}
1197
);
1198
return false;
1199
}
1200
1201
bool visit(class AstExprGroup* node) override
1202
{
1203
write(node);
1204
return false;
1205
}
1206
1207
bool visit(class AstExprConstantNil* node) override
1208
{
1209
write(node);
1210
return false;
1211
}
1212
1213
bool visit(class AstExprConstantBool* node) override
1214
{
1215
write(node);
1216
return false;
1217
}
1218
1219
bool visit(class AstExprConstantNumber* node) override
1220
{
1221
write(node);
1222
return false;
1223
}
1224
1225
bool visit(class AstExprConstantString* node) override
1226
{
1227
write(node);
1228
return false;
1229
}
1230
1231
bool visit(class AstExprIfElse* node) override
1232
{
1233
write(node);
1234
return false;
1235
}
1236
1237
bool visit(class AstExprInterpString* node) override
1238
{
1239
write(node);
1240
return false;
1241
}
1242
1243
bool visit(class AstExprLocal* node) override
1244
{
1245
write(node);
1246
return false;
1247
}
1248
1249
bool visit(class AstExprGlobal* node) override
1250
{
1251
write(node);
1252
return false;
1253
}
1254
1255
bool visit(class AstExprVarargs* node) override
1256
{
1257
write(node);
1258
return false;
1259
}
1260
1261
bool visit(class AstExprCall* node) override
1262
{
1263
write(node);
1264
return false;
1265
}
1266
1267
bool visit(class AstExprIndexName* node) override
1268
{
1269
write(node);
1270
return false;
1271
}
1272
1273
bool visit(class AstExprIndexExpr* node) override
1274
{
1275
write(node);
1276
return false;
1277
}
1278
1279
bool visit(class AstExprFunction* node) override
1280
{
1281
write(node);
1282
return false;
1283
}
1284
1285
bool visit(class AstExprTable* node) override
1286
{
1287
write(node);
1288
return false;
1289
}
1290
1291
bool visit(class AstExprUnary* node) override
1292
{
1293
write(node);
1294
return false;
1295
}
1296
1297
bool visit(class AstExprBinary* node) override
1298
{
1299
write(node);
1300
return false;
1301
}
1302
1303
bool visit(class AstExprTypeAssertion* node) override
1304
{
1305
write(node);
1306
return false;
1307
}
1308
1309
bool visit(class AstExprError* node) override
1310
{
1311
write(node);
1312
return false;
1313
}
1314
1315
bool visit(class AstStatBlock* node) override
1316
{
1317
write(node);
1318
return false;
1319
}
1320
1321
bool visit(class AstStatIf* node) override
1322
{
1323
write(node);
1324
return false;
1325
}
1326
1327
bool visit(class AstStatWhile* node) override
1328
{
1329
write(node);
1330
return false;
1331
}
1332
1333
bool visit(class AstStatRepeat* node) override
1334
{
1335
write(node);
1336
return false;
1337
}
1338
1339
bool visit(class AstStatBreak* node) override
1340
{
1341
write(node);
1342
return false;
1343
}
1344
1345
bool visit(class AstStatContinue* node) override
1346
{
1347
write(node);
1348
return false;
1349
}
1350
1351
bool visit(class AstStatReturn* node) override
1352
{
1353
write(node);
1354
return false;
1355
}
1356
1357
bool visit(class AstStatExpr* node) override
1358
{
1359
write(node);
1360
return false;
1361
}
1362
1363
bool visit(class AstStatLocal* node) override
1364
{
1365
write(node);
1366
return false;
1367
}
1368
1369
bool visit(class AstStatFor* node) override
1370
{
1371
write(node);
1372
return false;
1373
}
1374
1375
bool visit(class AstStatForIn* node) override
1376
{
1377
write(node);
1378
return false;
1379
}
1380
1381
bool visit(class AstStatAssign* node) override
1382
{
1383
write(node);
1384
return false;
1385
}
1386
1387
bool visit(class AstStatCompoundAssign* node) override
1388
{
1389
write(node);
1390
return false;
1391
}
1392
1393
bool visit(class AstStatFunction* node) override
1394
{
1395
write(node);
1396
return false;
1397
}
1398
1399
bool visit(class AstStatLocalFunction* node) override
1400
{
1401
write(node);
1402
return false;
1403
}
1404
1405
bool visit(class AstStatTypeAlias* node) override
1406
{
1407
write(node);
1408
return false;
1409
}
1410
1411
bool visit(class AstStatDeclareFunction* node) override
1412
{
1413
write(node);
1414
return false;
1415
}
1416
1417
bool visit(class AstStatDeclareGlobal* node) override
1418
{
1419
write(node);
1420
return false;
1421
}
1422
1423
bool visit(class AstStatDeclareExternType* node) override
1424
{
1425
write(node);
1426
return false;
1427
}
1428
1429
bool visit(class AstStatError* node) override
1430
{
1431
write(node);
1432
return false;
1433
}
1434
1435
bool visit(class AstTypeReference* node) override
1436
{
1437
write(node);
1438
return false;
1439
}
1440
1441
bool visit(class AstTypeTable* node) override
1442
{
1443
write(node);
1444
return false;
1445
}
1446
1447
bool visit(class AstTypeFunction* node) override
1448
{
1449
write(node);
1450
return false;
1451
}
1452
1453
bool visit(class AstTypeTypeof* node) override
1454
{
1455
write(node);
1456
return false;
1457
}
1458
1459
bool visit(class AstTypeOptional* node) override
1460
{
1461
write(node);
1462
return false;
1463
}
1464
1465
bool visit(class AstTypeUnion* node) override
1466
{
1467
write(node);
1468
return false;
1469
}
1470
1471
bool visit(class AstTypeIntersection* node) override
1472
{
1473
write(node);
1474
return false;
1475
}
1476
1477
bool visit(class AstTypeError* node) override
1478
{
1479
write(node);
1480
return false;
1481
}
1482
1483
bool visit(class AstTypePack* node) override
1484
{
1485
write(node);
1486
return false;
1487
}
1488
1489
bool visit(class AstTypePackExplicit* node) override
1490
{
1491
write(node);
1492
return false;
1493
}
1494
1495
bool visit(class AstTypePackVariadic* node) override
1496
{
1497
write(node);
1498
return false;
1499
}
1500
1501
bool visit(class AstTypePackGeneric* node) override
1502
{
1503
write(node);
1504
return false;
1505
}
1506
1507
void writeComments(std::vector<Comment> commentLocations)
1508
{
1509
bool commentComma = false;
1510
for (Comment comment : commentLocations)
1511
{
1512
if (commentComma)
1513
{
1514
writeRaw(",");
1515
}
1516
else
1517
{
1518
commentComma = true;
1519
}
1520
writeRaw("{");
1521
bool c = pushComma();
1522
switch (comment.type)
1523
{
1524
case Lexeme::Comment:
1525
writeType("Comment");
1526
break;
1527
case Lexeme::BlockComment:
1528
writeType("BlockComment");
1529
break;
1530
case Lexeme::BrokenComment:
1531
writeType("BrokenComment");
1532
break;
1533
default:
1534
break;
1535
}
1536
write("location", comment.location);
1537
popComma(c);
1538
writeRaw("}");
1539
}
1540
}
1541
};
1542
1543
std::string toJson(AstNode* node)
1544
{
1545
AstJsonEncoder encoder;
1546
node->visit(&encoder);
1547
return encoder.str();
1548
}
1549
1550
std::string toJson(AstNode* node, const std::vector<Comment>& commentLocations)
1551
{
1552
AstJsonEncoder encoder;
1553
encoder.writeRaw(R"({"root":)");
1554
node->visit(&encoder);
1555
encoder.writeRaw(R"(,"commentLocations":[)");
1556
encoder.writeComments(commentLocations);
1557
encoder.writeRaw("]}");
1558
return encoder.str();
1559
}
1560
1561
} // namespace Luau
1562
1563