agency-lang 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/backends/agencyGenerator.js +9 -3
- package/dist/lib/backends/baseGenerator.d.ts +1 -1
- package/dist/lib/backends/graphGenerator.js +20 -10
- package/dist/lib/backends/typescriptGenerator.js +4 -1
- package/dist/lib/parsers/function.d.ts +2 -1
- package/dist/lib/parsers/function.js +4 -3
- package/dist/lib/parsers/function.test.js +865 -9
- package/dist/lib/templates/backends/graphGenerator/graphNode.d.ts +1 -1
- package/dist/lib/templates/backends/graphGenerator/graphNode.js +1 -1
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.d.ts +2 -1
- package/dist/lib/templates/backends/graphGenerator/runNodeFunction.js +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.d.ts +2 -1
- package/dist/lib/templates/backends/typescriptGenerator/functionDefinition.js +1 -1
- package/dist/lib/types/function.d.ts +1 -1
- package/dist/lib/types/graphNode.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { functionParser, docStringParser } from "./function.js";
|
|
2
|
+
import { functionParser, docStringParser, graphNodeParser } from "./function.js";
|
|
3
3
|
describe("docStringParser", () => {
|
|
4
4
|
const testCases = [
|
|
5
5
|
// Happy path - basic docstrings
|
|
@@ -124,6 +124,7 @@ describe("functionParser", () => {
|
|
|
124
124
|
type: "function",
|
|
125
125
|
functionName: "test",
|
|
126
126
|
parameters: [],
|
|
127
|
+
returnType: null,
|
|
127
128
|
docString: undefined,
|
|
128
129
|
body: [
|
|
129
130
|
{
|
|
@@ -143,6 +144,7 @@ describe("functionParser", () => {
|
|
|
143
144
|
type: "function",
|
|
144
145
|
functionName: "greet",
|
|
145
146
|
parameters: [],
|
|
147
|
+
returnType: null,
|
|
146
148
|
docString: undefined,
|
|
147
149
|
body: [
|
|
148
150
|
{
|
|
@@ -165,6 +167,7 @@ describe("functionParser", () => {
|
|
|
165
167
|
type: "function",
|
|
166
168
|
functionName: "calculate",
|
|
167
169
|
parameters: [],
|
|
170
|
+
returnType: null,
|
|
168
171
|
docString: undefined,
|
|
169
172
|
body: [
|
|
170
173
|
{
|
|
@@ -189,6 +192,7 @@ describe("functionParser", () => {
|
|
|
189
192
|
type: "function",
|
|
190
193
|
functionName: "empty",
|
|
191
194
|
parameters: [],
|
|
195
|
+
returnType: null,
|
|
192
196
|
docString: undefined,
|
|
193
197
|
body: [],
|
|
194
198
|
},
|
|
@@ -202,6 +206,7 @@ describe("functionParser", () => {
|
|
|
202
206
|
type: "function",
|
|
203
207
|
functionName: "withSpaces",
|
|
204
208
|
parameters: [],
|
|
209
|
+
returnType: null,
|
|
205
210
|
docString: undefined,
|
|
206
211
|
body: [
|
|
207
212
|
{
|
|
@@ -221,6 +226,7 @@ describe("functionParser", () => {
|
|
|
221
226
|
type: "function",
|
|
222
227
|
functionName: "noSpaces",
|
|
223
228
|
parameters: [],
|
|
229
|
+
returnType: null,
|
|
224
230
|
docString: undefined,
|
|
225
231
|
body: [
|
|
226
232
|
{
|
|
@@ -240,6 +246,7 @@ describe("functionParser", () => {
|
|
|
240
246
|
type: "function",
|
|
241
247
|
functionName: "multiline",
|
|
242
248
|
parameters: [],
|
|
249
|
+
returnType: null,
|
|
243
250
|
docString: undefined,
|
|
244
251
|
body: [
|
|
245
252
|
{
|
|
@@ -289,6 +296,7 @@ describe("functionParser", () => {
|
|
|
289
296
|
type: "function",
|
|
290
297
|
functionName: "test",
|
|
291
298
|
parameters: [],
|
|
299
|
+
returnType: null,
|
|
292
300
|
docString: {
|
|
293
301
|
type: "docString",
|
|
294
302
|
value: "This is a test function",
|
|
@@ -311,6 +319,7 @@ describe("functionParser", () => {
|
|
|
311
319
|
type: "function",
|
|
312
320
|
functionName: "greet",
|
|
313
321
|
parameters: [],
|
|
322
|
+
returnType: null,
|
|
314
323
|
docString: {
|
|
315
324
|
type: "docString",
|
|
316
325
|
value: "Greets the user",
|
|
@@ -336,6 +345,7 @@ describe("functionParser", () => {
|
|
|
336
345
|
type: "function",
|
|
337
346
|
functionName: "calculate",
|
|
338
347
|
parameters: [],
|
|
348
|
+
returnType: null,
|
|
339
349
|
docString: {
|
|
340
350
|
type: "docString",
|
|
341
351
|
value: "Calculate something",
|
|
@@ -363,6 +373,7 @@ describe("functionParser", () => {
|
|
|
363
373
|
type: "function",
|
|
364
374
|
functionName: "empty",
|
|
365
375
|
parameters: [],
|
|
376
|
+
returnType: null,
|
|
366
377
|
docString: {
|
|
367
378
|
type: "docString",
|
|
368
379
|
value: "Empty function with docstring",
|
|
@@ -379,6 +390,7 @@ describe("functionParser", () => {
|
|
|
379
390
|
type: "function",
|
|
380
391
|
functionName: "multilineDoc",
|
|
381
392
|
parameters: [],
|
|
393
|
+
returnType: null,
|
|
382
394
|
docString: {
|
|
383
395
|
type: "docString",
|
|
384
396
|
value: "This is a multi-line\n docstring",
|
|
@@ -402,6 +414,7 @@ describe("functionParser", () => {
|
|
|
402
414
|
type: "function",
|
|
403
415
|
functionName: "add",
|
|
404
416
|
parameters: [{ type: "functionParameter", name: "x" }],
|
|
417
|
+
returnType: null,
|
|
405
418
|
docString: undefined,
|
|
406
419
|
body: [
|
|
407
420
|
{
|
|
@@ -420,6 +433,7 @@ describe("functionParser", () => {
|
|
|
420
433
|
type: "function",
|
|
421
434
|
functionName: "greet",
|
|
422
435
|
parameters: [{ type: "functionParameter", name: "name" }],
|
|
436
|
+
returnType: null,
|
|
423
437
|
docString: undefined,
|
|
424
438
|
body: [
|
|
425
439
|
{
|
|
@@ -449,6 +463,7 @@ describe("functionParser", () => {
|
|
|
449
463
|
{ type: "functionParameter", name: "x" },
|
|
450
464
|
{ type: "functionParameter", name: "y" },
|
|
451
465
|
],
|
|
466
|
+
returnType: null,
|
|
452
467
|
docString: undefined,
|
|
453
468
|
body: [
|
|
454
469
|
{
|
|
@@ -471,6 +486,7 @@ describe("functionParser", () => {
|
|
|
471
486
|
{ type: "functionParameter", name: "b" },
|
|
472
487
|
{ type: "functionParameter", name: "c" },
|
|
473
488
|
],
|
|
489
|
+
returnType: null,
|
|
474
490
|
docString: undefined,
|
|
475
491
|
body: [
|
|
476
492
|
{
|
|
@@ -497,6 +513,7 @@ describe("functionParser", () => {
|
|
|
497
513
|
{ type: "functionParameter", name: "x" },
|
|
498
514
|
{ type: "functionParameter", name: "y" },
|
|
499
515
|
],
|
|
516
|
+
returnType: null,
|
|
500
517
|
docString: undefined,
|
|
501
518
|
body: [
|
|
502
519
|
{
|
|
@@ -518,6 +535,7 @@ describe("functionParser", () => {
|
|
|
518
535
|
{ type: "functionParameter", name: "a" },
|
|
519
536
|
{ type: "functionParameter", name: "b" },
|
|
520
537
|
],
|
|
538
|
+
returnType: null,
|
|
521
539
|
docString: undefined,
|
|
522
540
|
body: [
|
|
523
541
|
{
|
|
@@ -540,6 +558,7 @@ describe("functionParser", () => {
|
|
|
540
558
|
{ type: "functionParameter", name: "x" },
|
|
541
559
|
{ type: "functionParameter", name: "y" },
|
|
542
560
|
],
|
|
561
|
+
returnType: null,
|
|
543
562
|
docString: {
|
|
544
563
|
type: "docString",
|
|
545
564
|
value: "Adds two numbers",
|
|
@@ -564,6 +583,7 @@ describe("functionParser", () => {
|
|
|
564
583
|
{ type: "functionParameter", name: "name" },
|
|
565
584
|
{ type: "functionParameter", name: "greeting" },
|
|
566
585
|
],
|
|
586
|
+
returnType: null,
|
|
567
587
|
docString: {
|
|
568
588
|
type: "docString",
|
|
569
589
|
value: "Greets someone with a custom greeting",
|
|
@@ -604,6 +624,7 @@ describe("functionParser", () => {
|
|
|
604
624
|
typeHint: { type: "primitiveType", value: "number" },
|
|
605
625
|
},
|
|
606
626
|
],
|
|
627
|
+
returnType: null,
|
|
607
628
|
docString: undefined,
|
|
608
629
|
body: [{ type: "variableName", value: "x" }],
|
|
609
630
|
},
|
|
@@ -623,6 +644,7 @@ describe("functionParser", () => {
|
|
|
623
644
|
typeHint: { type: "primitiveType", value: "string" },
|
|
624
645
|
},
|
|
625
646
|
],
|
|
647
|
+
returnType: null,
|
|
626
648
|
docString: undefined,
|
|
627
649
|
body: [{ type: "variableName", value: "name" }],
|
|
628
650
|
},
|
|
@@ -642,6 +664,7 @@ describe("functionParser", () => {
|
|
|
642
664
|
typeHint: { type: "primitiveType", value: "boolean" },
|
|
643
665
|
},
|
|
644
666
|
],
|
|
667
|
+
returnType: null,
|
|
645
668
|
docString: undefined,
|
|
646
669
|
body: [{ type: "variableName", value: "active" }],
|
|
647
670
|
},
|
|
@@ -661,6 +684,7 @@ describe("functionParser", () => {
|
|
|
661
684
|
typeHint: { type: "typeAliasVariable", aliasName: "any" },
|
|
662
685
|
},
|
|
663
686
|
],
|
|
687
|
+
returnType: null,
|
|
664
688
|
docString: undefined,
|
|
665
689
|
body: [{ type: "variableName", value: "data" }],
|
|
666
690
|
},
|
|
@@ -680,6 +704,7 @@ describe("functionParser", () => {
|
|
|
680
704
|
typeHint: { type: "primitiveType", value: "number" },
|
|
681
705
|
},
|
|
682
706
|
],
|
|
707
|
+
returnType: null,
|
|
683
708
|
docString: undefined,
|
|
684
709
|
body: [{ type: "variableName", value: "x" }],
|
|
685
710
|
},
|
|
@@ -705,6 +730,7 @@ describe("functionParser", () => {
|
|
|
705
730
|
typeHint: { type: "primitiveType", value: "number" },
|
|
706
731
|
},
|
|
707
732
|
],
|
|
733
|
+
returnType: null,
|
|
708
734
|
docString: undefined,
|
|
709
735
|
body: [{ type: "variableName", value: "x" }],
|
|
710
736
|
},
|
|
@@ -734,6 +760,7 @@ describe("functionParser", () => {
|
|
|
734
760
|
typeHint: { type: "primitiveType", value: "string" },
|
|
735
761
|
},
|
|
736
762
|
],
|
|
763
|
+
returnType: null,
|
|
737
764
|
docString: undefined,
|
|
738
765
|
body: [{ type: "variableName", value: "a" }],
|
|
739
766
|
},
|
|
@@ -758,6 +785,7 @@ describe("functionParser", () => {
|
|
|
758
785
|
typeHint: { type: "primitiveType", value: "string" },
|
|
759
786
|
},
|
|
760
787
|
],
|
|
788
|
+
returnType: null,
|
|
761
789
|
docString: undefined,
|
|
762
790
|
body: [{ type: "variableName", value: "x" }],
|
|
763
791
|
},
|
|
@@ -782,6 +810,7 @@ describe("functionParser", () => {
|
|
|
782
810
|
typeHint: { type: "primitiveType", value: "number" },
|
|
783
811
|
},
|
|
784
812
|
],
|
|
813
|
+
returnType: null,
|
|
785
814
|
docString: undefined,
|
|
786
815
|
body: [{ type: "variableName", value: "x" }],
|
|
787
816
|
},
|
|
@@ -803,6 +832,7 @@ describe("functionParser", () => {
|
|
|
803
832
|
},
|
|
804
833
|
{ type: "functionParameter", name: "y" },
|
|
805
834
|
],
|
|
835
|
+
returnType: null,
|
|
806
836
|
docString: undefined,
|
|
807
837
|
body: [{ type: "variableName", value: "x" }],
|
|
808
838
|
},
|
|
@@ -824,6 +854,7 @@ describe("functionParser", () => {
|
|
|
824
854
|
},
|
|
825
855
|
{ type: "functionParameter", name: "c" },
|
|
826
856
|
],
|
|
857
|
+
returnType: null,
|
|
827
858
|
docString: undefined,
|
|
828
859
|
body: [{ type: "variableName", value: "a" }],
|
|
829
860
|
},
|
|
@@ -844,6 +875,7 @@ describe("functionParser", () => {
|
|
|
844
875
|
},
|
|
845
876
|
{ type: "functionParameter", name: "untyped" },
|
|
846
877
|
],
|
|
878
|
+
returnType: null,
|
|
847
879
|
docString: undefined,
|
|
848
880
|
body: [{ type: "variableName", value: "typed" }],
|
|
849
881
|
},
|
|
@@ -867,6 +899,7 @@ describe("functionParser", () => {
|
|
|
867
899
|
},
|
|
868
900
|
},
|
|
869
901
|
],
|
|
902
|
+
returnType: null,
|
|
870
903
|
docString: undefined,
|
|
871
904
|
body: [{ type: "variableName", value: "items" }],
|
|
872
905
|
},
|
|
@@ -889,6 +922,7 @@ describe("functionParser", () => {
|
|
|
889
922
|
},
|
|
890
923
|
},
|
|
891
924
|
],
|
|
925
|
+
returnType: null,
|
|
892
926
|
docString: undefined,
|
|
893
927
|
body: [{ type: "variableName", value: "names" }],
|
|
894
928
|
},
|
|
@@ -908,6 +942,7 @@ describe("functionParser", () => {
|
|
|
908
942
|
typeHint: { type: "typeAliasVariable", aliasName: "object" },
|
|
909
943
|
},
|
|
910
944
|
],
|
|
945
|
+
returnType: null,
|
|
911
946
|
docString: undefined,
|
|
912
947
|
body: [{ type: "variableName", value: "obj" }],
|
|
913
948
|
},
|
|
@@ -935,6 +970,7 @@ describe("functionParser", () => {
|
|
|
935
970
|
typeHint: { type: "primitiveType", value: "number" },
|
|
936
971
|
},
|
|
937
972
|
],
|
|
973
|
+
returnType: null,
|
|
938
974
|
docString: undefined,
|
|
939
975
|
body: [{ type: "variableName", value: "arr" }],
|
|
940
976
|
},
|
|
@@ -960,6 +996,7 @@ describe("functionParser", () => {
|
|
|
960
996
|
},
|
|
961
997
|
},
|
|
962
998
|
],
|
|
999
|
+
returnType: null,
|
|
963
1000
|
docString: undefined,
|
|
964
1001
|
body: [{ type: "variableName", value: "matrix" }],
|
|
965
1002
|
},
|
|
@@ -986,6 +1023,7 @@ describe("functionParser", () => {
|
|
|
986
1023
|
},
|
|
987
1024
|
},
|
|
988
1025
|
],
|
|
1026
|
+
returnType: null,
|
|
989
1027
|
docString: undefined,
|
|
990
1028
|
body: [{ type: "variableName", value: "value" }],
|
|
991
1029
|
},
|
|
@@ -1012,6 +1050,7 @@ describe("functionParser", () => {
|
|
|
1012
1050
|
},
|
|
1013
1051
|
},
|
|
1014
1052
|
],
|
|
1053
|
+
returnType: null,
|
|
1015
1054
|
docString: undefined,
|
|
1016
1055
|
body: [{ type: "variableName", value: "x" }],
|
|
1017
1056
|
},
|
|
@@ -1042,6 +1081,7 @@ describe("functionParser", () => {
|
|
|
1042
1081
|
typeHint: { type: "primitiveType", value: "boolean" },
|
|
1043
1082
|
},
|
|
1044
1083
|
],
|
|
1084
|
+
returnType: null,
|
|
1045
1085
|
docString: undefined,
|
|
1046
1086
|
body: [{ type: "variableName", value: "a" }],
|
|
1047
1087
|
},
|
|
@@ -1067,6 +1107,7 @@ describe("functionParser", () => {
|
|
|
1067
1107
|
typeHint: { type: "primitiveType", value: "number" },
|
|
1068
1108
|
},
|
|
1069
1109
|
],
|
|
1110
|
+
returnType: null,
|
|
1070
1111
|
docString: {
|
|
1071
1112
|
type: "docString",
|
|
1072
1113
|
value: "Adds two numbers",
|
|
@@ -1089,6 +1130,7 @@ describe("functionParser", () => {
|
|
|
1089
1130
|
typeHint: { type: "primitiveType", value: "string" },
|
|
1090
1131
|
},
|
|
1091
1132
|
],
|
|
1133
|
+
returnType: null,
|
|
1092
1134
|
docString: {
|
|
1093
1135
|
type: "docString",
|
|
1094
1136
|
value: "Greets a person by name",
|
|
@@ -1112,6 +1154,7 @@ describe("functionParser", () => {
|
|
|
1112
1154
|
},
|
|
1113
1155
|
{ type: "functionParameter", name: "untyped" },
|
|
1114
1156
|
],
|
|
1157
|
+
returnType: null,
|
|
1115
1158
|
docString: {
|
|
1116
1159
|
type: "docString",
|
|
1117
1160
|
value: "Mix of typed and untyped params",
|
|
@@ -1135,6 +1178,7 @@ describe("functionParser", () => {
|
|
|
1135
1178
|
typeHint: { type: "primitiveType", value: "number" },
|
|
1136
1179
|
},
|
|
1137
1180
|
],
|
|
1181
|
+
returnType: null,
|
|
1138
1182
|
docString: undefined,
|
|
1139
1183
|
body: [{ type: "variableName", value: "x" }],
|
|
1140
1184
|
},
|
|
@@ -1159,6 +1203,7 @@ describe("functionParser", () => {
|
|
|
1159
1203
|
typeHint: { type: "primitiveType", value: "string" },
|
|
1160
1204
|
},
|
|
1161
1205
|
],
|
|
1206
|
+
returnType: null,
|
|
1162
1207
|
docString: undefined,
|
|
1163
1208
|
body: [{ type: "variableName", value: "x" }],
|
|
1164
1209
|
},
|
|
@@ -1178,6 +1223,7 @@ describe("functionParser", () => {
|
|
|
1178
1223
|
typeHint: { type: "primitiveType", value: "string" },
|
|
1179
1224
|
},
|
|
1180
1225
|
],
|
|
1226
|
+
returnType: null,
|
|
1181
1227
|
docString: undefined,
|
|
1182
1228
|
body: [{ type: "variableName", value: "my_var" }],
|
|
1183
1229
|
},
|
|
@@ -1194,32 +1240,842 @@ describe("functionParser", () => {
|
|
|
1194
1240
|
{
|
|
1195
1241
|
type: "functionParameter",
|
|
1196
1242
|
name: "data",
|
|
1197
|
-
typeHint: {
|
|
1243
|
+
typeHint: {
|
|
1244
|
+
type: "typeAliasVariable",
|
|
1245
|
+
aliasName: "SomeLongTypeName",
|
|
1246
|
+
},
|
|
1247
|
+
},
|
|
1248
|
+
],
|
|
1249
|
+
returnType: null,
|
|
1250
|
+
docString: undefined,
|
|
1251
|
+
body: [{ type: "variableName", value: "data" }],
|
|
1252
|
+
},
|
|
1253
|
+
},
|
|
1254
|
+
},
|
|
1255
|
+
// Failure cases for type hints
|
|
1256
|
+
{
|
|
1257
|
+
input: "def bad(x:) { x }",
|
|
1258
|
+
expected: { success: false },
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
input: "def bad(: number) { x }",
|
|
1262
|
+
expected: { success: false },
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
input: "def bad(x: number y: string) { x }",
|
|
1266
|
+
expected: { success: false },
|
|
1267
|
+
},
|
|
1268
|
+
// Functions with return types - primitive types
|
|
1269
|
+
{
|
|
1270
|
+
input: "def getNumber(): number { 42 }",
|
|
1271
|
+
expected: {
|
|
1272
|
+
success: true,
|
|
1273
|
+
result: {
|
|
1274
|
+
type: "function",
|
|
1275
|
+
functionName: "getNumber",
|
|
1276
|
+
parameters: [],
|
|
1277
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1278
|
+
docString: undefined,
|
|
1279
|
+
body: [{ type: "number", value: "42" }],
|
|
1280
|
+
},
|
|
1281
|
+
},
|
|
1282
|
+
},
|
|
1283
|
+
{
|
|
1284
|
+
input: "def getString(): string { name }",
|
|
1285
|
+
expected: {
|
|
1286
|
+
success: true,
|
|
1287
|
+
result: {
|
|
1288
|
+
type: "function",
|
|
1289
|
+
functionName: "getString",
|
|
1290
|
+
parameters: [],
|
|
1291
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1292
|
+
docString: undefined,
|
|
1293
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
input: "def getBoolean(): boolean { true }",
|
|
1299
|
+
expected: {
|
|
1300
|
+
success: true,
|
|
1301
|
+
result: {
|
|
1302
|
+
type: "function",
|
|
1303
|
+
functionName: "getBoolean",
|
|
1304
|
+
parameters: [],
|
|
1305
|
+
returnType: { type: "primitiveType", value: "boolean" },
|
|
1306
|
+
docString: undefined,
|
|
1307
|
+
body: [{ type: "variableName", value: "true" }],
|
|
1308
|
+
},
|
|
1309
|
+
},
|
|
1310
|
+
},
|
|
1311
|
+
// Functions with return types and parameters
|
|
1312
|
+
{
|
|
1313
|
+
input: "def add(x: number, y: number): number { x }",
|
|
1314
|
+
expected: {
|
|
1315
|
+
success: true,
|
|
1316
|
+
result: {
|
|
1317
|
+
type: "function",
|
|
1318
|
+
functionName: "add",
|
|
1319
|
+
parameters: [
|
|
1320
|
+
{
|
|
1321
|
+
type: "functionParameter",
|
|
1322
|
+
name: "x",
|
|
1323
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
type: "functionParameter",
|
|
1327
|
+
name: "y",
|
|
1328
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1329
|
+
},
|
|
1330
|
+
],
|
|
1331
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1332
|
+
docString: undefined,
|
|
1333
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1334
|
+
},
|
|
1335
|
+
},
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
input: "def greet(name: string): string { name }",
|
|
1339
|
+
expected: {
|
|
1340
|
+
success: true,
|
|
1341
|
+
result: {
|
|
1342
|
+
type: "function",
|
|
1343
|
+
functionName: "greet",
|
|
1344
|
+
parameters: [
|
|
1345
|
+
{
|
|
1346
|
+
type: "functionParameter",
|
|
1347
|
+
name: "name",
|
|
1348
|
+
typeHint: { type: "primitiveType", value: "string" },
|
|
1349
|
+
},
|
|
1350
|
+
],
|
|
1351
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1352
|
+
docString: undefined,
|
|
1353
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1354
|
+
},
|
|
1355
|
+
},
|
|
1356
|
+
},
|
|
1357
|
+
{
|
|
1358
|
+
input: "def check(value): boolean { value }",
|
|
1359
|
+
expected: {
|
|
1360
|
+
success: true,
|
|
1361
|
+
result: {
|
|
1362
|
+
type: "function",
|
|
1363
|
+
functionName: "check",
|
|
1364
|
+
parameters: [{ type: "functionParameter", name: "value" }],
|
|
1365
|
+
returnType: { type: "primitiveType", value: "boolean" },
|
|
1366
|
+
docString: undefined,
|
|
1367
|
+
body: [{ type: "variableName", value: "value" }],
|
|
1368
|
+
},
|
|
1369
|
+
},
|
|
1370
|
+
},
|
|
1371
|
+
// Functions with array return types
|
|
1372
|
+
{
|
|
1373
|
+
input: "def getNumbers(): number[] { items }",
|
|
1374
|
+
expected: {
|
|
1375
|
+
success: true,
|
|
1376
|
+
result: {
|
|
1377
|
+
type: "function",
|
|
1378
|
+
functionName: "getNumbers",
|
|
1379
|
+
parameters: [],
|
|
1380
|
+
returnType: {
|
|
1381
|
+
type: "arrayType",
|
|
1382
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
1383
|
+
},
|
|
1384
|
+
docString: undefined,
|
|
1385
|
+
body: [{ type: "variableName", value: "items" }],
|
|
1386
|
+
},
|
|
1387
|
+
},
|
|
1388
|
+
},
|
|
1389
|
+
{
|
|
1390
|
+
input: "def getStrings(): string[] { names }",
|
|
1391
|
+
expected: {
|
|
1392
|
+
success: true,
|
|
1393
|
+
result: {
|
|
1394
|
+
type: "function",
|
|
1395
|
+
functionName: "getStrings",
|
|
1396
|
+
parameters: [],
|
|
1397
|
+
returnType: {
|
|
1398
|
+
type: "arrayType",
|
|
1399
|
+
elementType: { type: "primitiveType", value: "string" },
|
|
1400
|
+
},
|
|
1401
|
+
docString: undefined,
|
|
1402
|
+
body: [{ type: "variableName", value: "names" }],
|
|
1403
|
+
},
|
|
1404
|
+
},
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
input: "def processArray(items: number[]): number[] { items }",
|
|
1408
|
+
expected: {
|
|
1409
|
+
success: true,
|
|
1410
|
+
result: {
|
|
1411
|
+
type: "function",
|
|
1412
|
+
functionName: "processArray",
|
|
1413
|
+
parameters: [
|
|
1414
|
+
{
|
|
1415
|
+
type: "functionParameter",
|
|
1416
|
+
name: "items",
|
|
1417
|
+
typeHint: {
|
|
1418
|
+
type: "arrayType",
|
|
1419
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
1420
|
+
},
|
|
1421
|
+
},
|
|
1422
|
+
],
|
|
1423
|
+
returnType: {
|
|
1424
|
+
type: "arrayType",
|
|
1425
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
1426
|
+
},
|
|
1427
|
+
docString: undefined,
|
|
1428
|
+
body: [{ type: "variableName", value: "items" }],
|
|
1429
|
+
},
|
|
1430
|
+
},
|
|
1431
|
+
},
|
|
1432
|
+
// Functions with union return types
|
|
1433
|
+
{
|
|
1434
|
+
input: "def getValue(): string | number { value }",
|
|
1435
|
+
expected: {
|
|
1436
|
+
success: true,
|
|
1437
|
+
result: {
|
|
1438
|
+
type: "function",
|
|
1439
|
+
functionName: "getValue",
|
|
1440
|
+
parameters: [],
|
|
1441
|
+
returnType: {
|
|
1442
|
+
type: "unionType",
|
|
1443
|
+
types: [
|
|
1444
|
+
{ type: "primitiveType", value: "string" },
|
|
1445
|
+
{ type: "primitiveType", value: "number" },
|
|
1446
|
+
],
|
|
1447
|
+
},
|
|
1448
|
+
docString: undefined,
|
|
1449
|
+
body: [{ type: "variableName", value: "value" }],
|
|
1450
|
+
},
|
|
1451
|
+
},
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
input: "def flexible(x: number): string | number | boolean { x }",
|
|
1455
|
+
expected: {
|
|
1456
|
+
success: true,
|
|
1457
|
+
result: {
|
|
1458
|
+
type: "function",
|
|
1459
|
+
functionName: "flexible",
|
|
1460
|
+
parameters: [
|
|
1461
|
+
{
|
|
1462
|
+
type: "functionParameter",
|
|
1463
|
+
name: "x",
|
|
1464
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1465
|
+
},
|
|
1466
|
+
],
|
|
1467
|
+
returnType: {
|
|
1468
|
+
type: "unionType",
|
|
1469
|
+
types: [
|
|
1470
|
+
{ type: "primitiveType", value: "string" },
|
|
1471
|
+
{ type: "primitiveType", value: "number" },
|
|
1472
|
+
{ type: "primitiveType", value: "boolean" },
|
|
1473
|
+
],
|
|
1474
|
+
},
|
|
1475
|
+
docString: undefined,
|
|
1476
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1477
|
+
},
|
|
1478
|
+
},
|
|
1479
|
+
},
|
|
1480
|
+
// Functions with return types and docstrings
|
|
1481
|
+
{
|
|
1482
|
+
input: 'def add(x: number, y: number): number {\n """Adds two numbers"""\n x\n}',
|
|
1483
|
+
expected: {
|
|
1484
|
+
success: true,
|
|
1485
|
+
result: {
|
|
1486
|
+
type: "function",
|
|
1487
|
+
functionName: "add",
|
|
1488
|
+
parameters: [
|
|
1489
|
+
{
|
|
1490
|
+
type: "functionParameter",
|
|
1491
|
+
name: "x",
|
|
1492
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
type: "functionParameter",
|
|
1496
|
+
name: "y",
|
|
1497
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1498
|
+
},
|
|
1499
|
+
],
|
|
1500
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1501
|
+
docString: {
|
|
1502
|
+
type: "docString",
|
|
1503
|
+
value: "Adds two numbers",
|
|
1504
|
+
},
|
|
1505
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
input: 'def greet(name: string): string {\n """Greets a person"""\n name\n}',
|
|
1511
|
+
expected: {
|
|
1512
|
+
success: true,
|
|
1513
|
+
result: {
|
|
1514
|
+
type: "function",
|
|
1515
|
+
functionName: "greet",
|
|
1516
|
+
parameters: [
|
|
1517
|
+
{
|
|
1518
|
+
type: "functionParameter",
|
|
1519
|
+
name: "name",
|
|
1520
|
+
typeHint: { type: "primitiveType", value: "string" },
|
|
1521
|
+
},
|
|
1522
|
+
],
|
|
1523
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1524
|
+
docString: {
|
|
1525
|
+
type: "docString",
|
|
1526
|
+
value: "Greets a person",
|
|
1527
|
+
},
|
|
1528
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1529
|
+
},
|
|
1530
|
+
},
|
|
1531
|
+
},
|
|
1532
|
+
// Functions with whitespace variations in return types
|
|
1533
|
+
{
|
|
1534
|
+
input: "def foo():number { 1 }",
|
|
1535
|
+
expected: {
|
|
1536
|
+
success: true,
|
|
1537
|
+
result: {
|
|
1538
|
+
type: "function",
|
|
1539
|
+
functionName: "foo",
|
|
1540
|
+
parameters: [],
|
|
1541
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1542
|
+
docString: undefined,
|
|
1543
|
+
body: [{ type: "number", value: "1" }],
|
|
1544
|
+
},
|
|
1545
|
+
},
|
|
1546
|
+
},
|
|
1547
|
+
{
|
|
1548
|
+
input: "def bar() : string { name }",
|
|
1549
|
+
expected: {
|
|
1550
|
+
success: true,
|
|
1551
|
+
result: {
|
|
1552
|
+
type: "function",
|
|
1553
|
+
functionName: "bar",
|
|
1554
|
+
parameters: [],
|
|
1555
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1556
|
+
docString: undefined,
|
|
1557
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1558
|
+
},
|
|
1559
|
+
},
|
|
1560
|
+
},
|
|
1561
|
+
{
|
|
1562
|
+
input: "def baz(x: number) : number { x }",
|
|
1563
|
+
expected: {
|
|
1564
|
+
success: true,
|
|
1565
|
+
result: {
|
|
1566
|
+
type: "function",
|
|
1567
|
+
functionName: "baz",
|
|
1568
|
+
parameters: [
|
|
1569
|
+
{
|
|
1570
|
+
type: "functionParameter",
|
|
1571
|
+
name: "x",
|
|
1572
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1573
|
+
},
|
|
1574
|
+
],
|
|
1575
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1576
|
+
docString: undefined,
|
|
1577
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1578
|
+
},
|
|
1579
|
+
},
|
|
1580
|
+
},
|
|
1581
|
+
// Functions with type alias return types
|
|
1582
|
+
{
|
|
1583
|
+
input: "def getPoint(): Point { point }",
|
|
1584
|
+
expected: {
|
|
1585
|
+
success: true,
|
|
1586
|
+
result: {
|
|
1587
|
+
type: "function",
|
|
1588
|
+
functionName: "getPoint",
|
|
1589
|
+
parameters: [],
|
|
1590
|
+
returnType: { type: "typeAliasVariable", aliasName: "Point" },
|
|
1591
|
+
docString: undefined,
|
|
1592
|
+
body: [{ type: "variableName", value: "point" }],
|
|
1593
|
+
},
|
|
1594
|
+
},
|
|
1595
|
+
},
|
|
1596
|
+
{
|
|
1597
|
+
input: "def getData(id: number): UserData { data }",
|
|
1598
|
+
expected: {
|
|
1599
|
+
success: true,
|
|
1600
|
+
result: {
|
|
1601
|
+
type: "function",
|
|
1602
|
+
functionName: "getData",
|
|
1603
|
+
parameters: [
|
|
1604
|
+
{
|
|
1605
|
+
type: "functionParameter",
|
|
1606
|
+
name: "id",
|
|
1607
|
+
typeHint: { type: "primitiveType", value: "number" },
|
|
1608
|
+
},
|
|
1609
|
+
],
|
|
1610
|
+
returnType: { type: "typeAliasVariable", aliasName: "UserData" },
|
|
1611
|
+
docString: undefined,
|
|
1612
|
+
body: [{ type: "variableName", value: "data" }],
|
|
1613
|
+
},
|
|
1614
|
+
},
|
|
1615
|
+
},
|
|
1616
|
+
// Functions with object return types
|
|
1617
|
+
{
|
|
1618
|
+
input: "def getCoords(): { x: number; y: number } { coords }",
|
|
1619
|
+
expected: {
|
|
1620
|
+
success: true,
|
|
1621
|
+
result: {
|
|
1622
|
+
type: "function",
|
|
1623
|
+
functionName: "getCoords",
|
|
1624
|
+
parameters: [],
|
|
1625
|
+
returnType: {
|
|
1626
|
+
type: "objectType",
|
|
1627
|
+
properties: [
|
|
1628
|
+
{
|
|
1629
|
+
key: "x",
|
|
1630
|
+
value: { type: "primitiveType", value: "number" },
|
|
1631
|
+
},
|
|
1632
|
+
{
|
|
1633
|
+
key: "y",
|
|
1634
|
+
value: { type: "primitiveType", value: "number" },
|
|
1635
|
+
},
|
|
1636
|
+
],
|
|
1637
|
+
},
|
|
1638
|
+
docString: undefined,
|
|
1639
|
+
body: [{ type: "variableName", value: "coords" }],
|
|
1640
|
+
},
|
|
1641
|
+
},
|
|
1642
|
+
},
|
|
1643
|
+
// Failure cases for return types
|
|
1644
|
+
{
|
|
1645
|
+
input: "def bad(): { x }",
|
|
1646
|
+
expected: { success: false },
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
input: "def bad() : { x }",
|
|
1650
|
+
expected: { success: false },
|
|
1651
|
+
},
|
|
1652
|
+
];
|
|
1653
|
+
testCases.forEach(({ input, expected }) => {
|
|
1654
|
+
if (expected.success) {
|
|
1655
|
+
it(`should parse "${input.replace(/\n/g, "\\n")}" successfully`, () => {
|
|
1656
|
+
const result = functionParser(input);
|
|
1657
|
+
expect(result.success).toBe(true);
|
|
1658
|
+
if (result.success) {
|
|
1659
|
+
expect(result.result).toEqual(expected.result);
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
}
|
|
1663
|
+
else {
|
|
1664
|
+
it(`should fail to parse "${input.replace(/\n/g, "\\n")}"`, () => {
|
|
1665
|
+
const result = functionParser(input);
|
|
1666
|
+
expect(result.success).toBe(false);
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
});
|
|
1670
|
+
});
|
|
1671
|
+
describe("graphNodeParser", () => {
|
|
1672
|
+
const testCases = [
|
|
1673
|
+
// Basic graph nodes without return types
|
|
1674
|
+
{
|
|
1675
|
+
input: "node main() { x = 1 }",
|
|
1676
|
+
expected: {
|
|
1677
|
+
success: true,
|
|
1678
|
+
result: {
|
|
1679
|
+
type: "graphNode",
|
|
1680
|
+
nodeName: "main",
|
|
1681
|
+
parameters: [],
|
|
1682
|
+
returnType: null,
|
|
1683
|
+
body: [
|
|
1684
|
+
{
|
|
1685
|
+
type: "assignment",
|
|
1686
|
+
variableName: "x",
|
|
1687
|
+
value: { type: "number", value: "1" },
|
|
1198
1688
|
},
|
|
1199
1689
|
],
|
|
1200
|
-
|
|
1690
|
+
},
|
|
1691
|
+
},
|
|
1692
|
+
},
|
|
1693
|
+
{
|
|
1694
|
+
input: "node greet() { message = `hello` }",
|
|
1695
|
+
expected: {
|
|
1696
|
+
success: true,
|
|
1697
|
+
result: {
|
|
1698
|
+
type: "graphNode",
|
|
1699
|
+
nodeName: "greet",
|
|
1700
|
+
parameters: [],
|
|
1701
|
+
returnType: null,
|
|
1702
|
+
body: [
|
|
1703
|
+
{
|
|
1704
|
+
type: "assignment",
|
|
1705
|
+
variableName: "message",
|
|
1706
|
+
value: {
|
|
1707
|
+
type: "prompt",
|
|
1708
|
+
segments: [{ type: "text", value: "hello" }],
|
|
1709
|
+
},
|
|
1710
|
+
},
|
|
1711
|
+
],
|
|
1712
|
+
},
|
|
1713
|
+
},
|
|
1714
|
+
},
|
|
1715
|
+
{
|
|
1716
|
+
input: "node empty() {}",
|
|
1717
|
+
expected: {
|
|
1718
|
+
success: true,
|
|
1719
|
+
result: {
|
|
1720
|
+
type: "graphNode",
|
|
1721
|
+
nodeName: "empty",
|
|
1722
|
+
parameters: [],
|
|
1723
|
+
returnType: null,
|
|
1724
|
+
body: [],
|
|
1725
|
+
},
|
|
1726
|
+
},
|
|
1727
|
+
},
|
|
1728
|
+
// Graph nodes with parameters
|
|
1729
|
+
{
|
|
1730
|
+
input: "node process(input) { x = input }",
|
|
1731
|
+
expected: {
|
|
1732
|
+
success: true,
|
|
1733
|
+
result: {
|
|
1734
|
+
type: "graphNode",
|
|
1735
|
+
nodeName: "process",
|
|
1736
|
+
parameters: ["input"],
|
|
1737
|
+
returnType: null,
|
|
1738
|
+
body: [
|
|
1739
|
+
{
|
|
1740
|
+
type: "assignment",
|
|
1741
|
+
variableName: "x",
|
|
1742
|
+
value: { type: "variableName", value: "input" },
|
|
1743
|
+
},
|
|
1744
|
+
],
|
|
1745
|
+
},
|
|
1746
|
+
},
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
input: "node calculate(a, b) { result = 42 }",
|
|
1750
|
+
expected: {
|
|
1751
|
+
success: true,
|
|
1752
|
+
result: {
|
|
1753
|
+
type: "graphNode",
|
|
1754
|
+
nodeName: "calculate",
|
|
1755
|
+
parameters: ["a", "b"],
|
|
1756
|
+
returnType: null,
|
|
1757
|
+
body: [
|
|
1758
|
+
{
|
|
1759
|
+
type: "assignment",
|
|
1760
|
+
variableName: "result",
|
|
1761
|
+
value: { type: "number", value: "42" },
|
|
1762
|
+
},
|
|
1763
|
+
],
|
|
1764
|
+
},
|
|
1765
|
+
},
|
|
1766
|
+
},
|
|
1767
|
+
// Graph nodes with return types - primitive types
|
|
1768
|
+
{
|
|
1769
|
+
input: "node getNumber(): number { 42 }",
|
|
1770
|
+
expected: {
|
|
1771
|
+
success: true,
|
|
1772
|
+
result: {
|
|
1773
|
+
type: "graphNode",
|
|
1774
|
+
nodeName: "getNumber",
|
|
1775
|
+
parameters: [],
|
|
1776
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1777
|
+
body: [{ type: "number", value: "42" }],
|
|
1778
|
+
},
|
|
1779
|
+
},
|
|
1780
|
+
},
|
|
1781
|
+
{
|
|
1782
|
+
input: "node getString(): string { name }",
|
|
1783
|
+
expected: {
|
|
1784
|
+
success: true,
|
|
1785
|
+
result: {
|
|
1786
|
+
type: "graphNode",
|
|
1787
|
+
nodeName: "getString",
|
|
1788
|
+
parameters: [],
|
|
1789
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1790
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1791
|
+
},
|
|
1792
|
+
},
|
|
1793
|
+
},
|
|
1794
|
+
{
|
|
1795
|
+
input: "node getBoolean(): boolean { true }",
|
|
1796
|
+
expected: {
|
|
1797
|
+
success: true,
|
|
1798
|
+
result: {
|
|
1799
|
+
type: "graphNode",
|
|
1800
|
+
nodeName: "getBoolean",
|
|
1801
|
+
parameters: [],
|
|
1802
|
+
returnType: { type: "primitiveType", value: "boolean" },
|
|
1803
|
+
body: [{ type: "variableName", value: "true" }],
|
|
1804
|
+
},
|
|
1805
|
+
},
|
|
1806
|
+
},
|
|
1807
|
+
// Graph nodes with parameters and return types
|
|
1808
|
+
{
|
|
1809
|
+
input: "node add(x, y): number { result = 10 }",
|
|
1810
|
+
expected: {
|
|
1811
|
+
success: true,
|
|
1812
|
+
result: {
|
|
1813
|
+
type: "graphNode",
|
|
1814
|
+
nodeName: "add",
|
|
1815
|
+
parameters: ["x", "y"],
|
|
1816
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1817
|
+
body: [
|
|
1818
|
+
{
|
|
1819
|
+
type: "assignment",
|
|
1820
|
+
variableName: "result",
|
|
1821
|
+
value: { type: "number", value: "10" },
|
|
1822
|
+
},
|
|
1823
|
+
],
|
|
1824
|
+
},
|
|
1825
|
+
},
|
|
1826
|
+
},
|
|
1827
|
+
{
|
|
1828
|
+
input: "node greet(name): string { message = `hello` }",
|
|
1829
|
+
expected: {
|
|
1830
|
+
success: true,
|
|
1831
|
+
result: {
|
|
1832
|
+
type: "graphNode",
|
|
1833
|
+
nodeName: "greet",
|
|
1834
|
+
parameters: ["name"],
|
|
1835
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1836
|
+
body: [
|
|
1837
|
+
{
|
|
1838
|
+
type: "assignment",
|
|
1839
|
+
variableName: "message",
|
|
1840
|
+
value: {
|
|
1841
|
+
type: "prompt",
|
|
1842
|
+
segments: [{ type: "text", value: "hello" }],
|
|
1843
|
+
},
|
|
1844
|
+
},
|
|
1845
|
+
],
|
|
1846
|
+
},
|
|
1847
|
+
},
|
|
1848
|
+
},
|
|
1849
|
+
{
|
|
1850
|
+
input: "node process(input): boolean { result }",
|
|
1851
|
+
expected: {
|
|
1852
|
+
success: true,
|
|
1853
|
+
result: {
|
|
1854
|
+
type: "graphNode",
|
|
1855
|
+
nodeName: "process",
|
|
1856
|
+
parameters: ["input"],
|
|
1857
|
+
returnType: { type: "primitiveType", value: "boolean" },
|
|
1858
|
+
body: [{ type: "variableName", value: "result" }],
|
|
1859
|
+
},
|
|
1860
|
+
},
|
|
1861
|
+
},
|
|
1862
|
+
// Graph nodes with array return types
|
|
1863
|
+
{
|
|
1864
|
+
input: "node getNumbers(): number[] { items }",
|
|
1865
|
+
expected: {
|
|
1866
|
+
success: true,
|
|
1867
|
+
result: {
|
|
1868
|
+
type: "graphNode",
|
|
1869
|
+
nodeName: "getNumbers",
|
|
1870
|
+
parameters: [],
|
|
1871
|
+
returnType: {
|
|
1872
|
+
type: "arrayType",
|
|
1873
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
1874
|
+
},
|
|
1875
|
+
body: [{ type: "variableName", value: "items" }],
|
|
1876
|
+
},
|
|
1877
|
+
},
|
|
1878
|
+
},
|
|
1879
|
+
{
|
|
1880
|
+
input: "node getStrings(): string[] { names }",
|
|
1881
|
+
expected: {
|
|
1882
|
+
success: true,
|
|
1883
|
+
result: {
|
|
1884
|
+
type: "graphNode",
|
|
1885
|
+
nodeName: "getStrings",
|
|
1886
|
+
parameters: [],
|
|
1887
|
+
returnType: {
|
|
1888
|
+
type: "arrayType",
|
|
1889
|
+
elementType: { type: "primitiveType", value: "string" },
|
|
1890
|
+
},
|
|
1891
|
+
body: [{ type: "variableName", value: "names" }],
|
|
1892
|
+
},
|
|
1893
|
+
},
|
|
1894
|
+
},
|
|
1895
|
+
{
|
|
1896
|
+
input: "node processArray(items): number[] { items }",
|
|
1897
|
+
expected: {
|
|
1898
|
+
success: true,
|
|
1899
|
+
result: {
|
|
1900
|
+
type: "graphNode",
|
|
1901
|
+
nodeName: "processArray",
|
|
1902
|
+
parameters: ["items"],
|
|
1903
|
+
returnType: {
|
|
1904
|
+
type: "arrayType",
|
|
1905
|
+
elementType: { type: "primitiveType", value: "number" },
|
|
1906
|
+
},
|
|
1907
|
+
body: [{ type: "variableName", value: "items" }],
|
|
1908
|
+
},
|
|
1909
|
+
},
|
|
1910
|
+
},
|
|
1911
|
+
// Graph nodes with union return types
|
|
1912
|
+
{
|
|
1913
|
+
input: "node getValue(): string | number { value }",
|
|
1914
|
+
expected: {
|
|
1915
|
+
success: true,
|
|
1916
|
+
result: {
|
|
1917
|
+
type: "graphNode",
|
|
1918
|
+
nodeName: "getValue",
|
|
1919
|
+
parameters: [],
|
|
1920
|
+
returnType: {
|
|
1921
|
+
type: "unionType",
|
|
1922
|
+
types: [
|
|
1923
|
+
{ type: "primitiveType", value: "string" },
|
|
1924
|
+
{ type: "primitiveType", value: "number" },
|
|
1925
|
+
],
|
|
1926
|
+
},
|
|
1927
|
+
body: [{ type: "variableName", value: "value" }],
|
|
1928
|
+
},
|
|
1929
|
+
},
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
input: "node flexible(x): string | number | boolean { x }",
|
|
1933
|
+
expected: {
|
|
1934
|
+
success: true,
|
|
1935
|
+
result: {
|
|
1936
|
+
type: "graphNode",
|
|
1937
|
+
nodeName: "flexible",
|
|
1938
|
+
parameters: ["x"],
|
|
1939
|
+
returnType: {
|
|
1940
|
+
type: "unionType",
|
|
1941
|
+
types: [
|
|
1942
|
+
{ type: "primitiveType", value: "string" },
|
|
1943
|
+
{ type: "primitiveType", value: "number" },
|
|
1944
|
+
{ type: "primitiveType", value: "boolean" },
|
|
1945
|
+
],
|
|
1946
|
+
},
|
|
1947
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1948
|
+
},
|
|
1949
|
+
},
|
|
1950
|
+
},
|
|
1951
|
+
// Graph nodes with whitespace variations in return types
|
|
1952
|
+
{
|
|
1953
|
+
input: "node foo():number { 1 }",
|
|
1954
|
+
expected: {
|
|
1955
|
+
success: true,
|
|
1956
|
+
result: {
|
|
1957
|
+
type: "graphNode",
|
|
1958
|
+
nodeName: "foo",
|
|
1959
|
+
parameters: [],
|
|
1960
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1961
|
+
body: [{ type: "number", value: "1" }],
|
|
1962
|
+
},
|
|
1963
|
+
},
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
input: "node bar() : string { name }",
|
|
1967
|
+
expected: {
|
|
1968
|
+
success: true,
|
|
1969
|
+
result: {
|
|
1970
|
+
type: "graphNode",
|
|
1971
|
+
nodeName: "bar",
|
|
1972
|
+
parameters: [],
|
|
1973
|
+
returnType: { type: "primitiveType", value: "string" },
|
|
1974
|
+
body: [{ type: "variableName", value: "name" }],
|
|
1975
|
+
},
|
|
1976
|
+
},
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
input: "node baz(x) : number { x }",
|
|
1980
|
+
expected: {
|
|
1981
|
+
success: true,
|
|
1982
|
+
result: {
|
|
1983
|
+
type: "graphNode",
|
|
1984
|
+
nodeName: "baz",
|
|
1985
|
+
parameters: ["x"],
|
|
1986
|
+
returnType: { type: "primitiveType", value: "number" },
|
|
1987
|
+
body: [{ type: "variableName", value: "x" }],
|
|
1988
|
+
},
|
|
1989
|
+
},
|
|
1990
|
+
},
|
|
1991
|
+
// Graph nodes with type alias return types
|
|
1992
|
+
{
|
|
1993
|
+
input: "node getPoint(): Point { point }",
|
|
1994
|
+
expected: {
|
|
1995
|
+
success: true,
|
|
1996
|
+
result: {
|
|
1997
|
+
type: "graphNode",
|
|
1998
|
+
nodeName: "getPoint",
|
|
1999
|
+
parameters: [],
|
|
2000
|
+
returnType: { type: "typeAliasVariable", aliasName: "Point" },
|
|
2001
|
+
body: [{ type: "variableName", value: "point" }],
|
|
2002
|
+
},
|
|
2003
|
+
},
|
|
2004
|
+
},
|
|
2005
|
+
{
|
|
2006
|
+
input: "node getData(id): UserData { data }",
|
|
2007
|
+
expected: {
|
|
2008
|
+
success: true,
|
|
2009
|
+
result: {
|
|
2010
|
+
type: "graphNode",
|
|
2011
|
+
nodeName: "getData",
|
|
2012
|
+
parameters: ["id"],
|
|
2013
|
+
returnType: { type: "typeAliasVariable", aliasName: "UserData" },
|
|
1201
2014
|
body: [{ type: "variableName", value: "data" }],
|
|
1202
2015
|
},
|
|
1203
2016
|
},
|
|
1204
2017
|
},
|
|
1205
|
-
//
|
|
2018
|
+
// Graph nodes with object return types
|
|
1206
2019
|
{
|
|
1207
|
-
input: "
|
|
2020
|
+
input: "node getCoords(): { x: number; y: number } { coords }",
|
|
2021
|
+
expected: {
|
|
2022
|
+
success: true,
|
|
2023
|
+
result: {
|
|
2024
|
+
type: "graphNode",
|
|
2025
|
+
nodeName: "getCoords",
|
|
2026
|
+
parameters: [],
|
|
2027
|
+
returnType: {
|
|
2028
|
+
type: "objectType",
|
|
2029
|
+
properties: [
|
|
2030
|
+
{
|
|
2031
|
+
key: "x",
|
|
2032
|
+
value: { type: "primitiveType", value: "number" },
|
|
2033
|
+
},
|
|
2034
|
+
{
|
|
2035
|
+
key: "y",
|
|
2036
|
+
value: { type: "primitiveType", value: "number" },
|
|
2037
|
+
},
|
|
2038
|
+
],
|
|
2039
|
+
},
|
|
2040
|
+
body: [{ type: "variableName", value: "coords" }],
|
|
2041
|
+
},
|
|
2042
|
+
},
|
|
2043
|
+
},
|
|
2044
|
+
// Failure cases
|
|
2045
|
+
{
|
|
2046
|
+
input: "main() { x = 1 }",
|
|
1208
2047
|
expected: { success: false },
|
|
1209
2048
|
},
|
|
1210
2049
|
{
|
|
1211
|
-
input: "
|
|
2050
|
+
input: "node { x = 1 }",
|
|
1212
2051
|
expected: { success: false },
|
|
1213
2052
|
},
|
|
1214
2053
|
{
|
|
1215
|
-
input: "
|
|
2054
|
+
input: "node main() x = 1",
|
|
2055
|
+
expected: { success: false },
|
|
2056
|
+
},
|
|
2057
|
+
{
|
|
2058
|
+
input: "node main() {",
|
|
2059
|
+
expected: { success: false },
|
|
2060
|
+
},
|
|
2061
|
+
{
|
|
2062
|
+
input: "",
|
|
2063
|
+
expected: { success: false },
|
|
2064
|
+
},
|
|
2065
|
+
// Failure cases for return types
|
|
2066
|
+
{
|
|
2067
|
+
input: "node bad(): { x }",
|
|
2068
|
+
expected: { success: false },
|
|
2069
|
+
},
|
|
2070
|
+
{
|
|
2071
|
+
input: "node bad() : { x }",
|
|
1216
2072
|
expected: { success: false },
|
|
1217
2073
|
},
|
|
1218
2074
|
];
|
|
1219
2075
|
testCases.forEach(({ input, expected }) => {
|
|
1220
2076
|
if (expected.success) {
|
|
1221
2077
|
it(`should parse "${input.replace(/\n/g, "\\n")}" successfully`, () => {
|
|
1222
|
-
const result =
|
|
2078
|
+
const result = graphNodeParser(input);
|
|
1223
2079
|
expect(result.success).toBe(true);
|
|
1224
2080
|
if (result.success) {
|
|
1225
2081
|
expect(result.result).toEqual(expected.result);
|
|
@@ -1228,7 +2084,7 @@ describe("functionParser", () => {
|
|
|
1228
2084
|
}
|
|
1229
2085
|
else {
|
|
1230
2086
|
it(`should fail to parse "${input.replace(/\n/g, "\\n")}"`, () => {
|
|
1231
|
-
const result =
|
|
2087
|
+
const result = graphNodeParser(input);
|
|
1232
2088
|
expect(result.success).toBe(false);
|
|
1233
2089
|
});
|
|
1234
2090
|
}
|