skir 0.0.1

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.
Files changed (141) hide show
  1. package/README.md +447 -0
  2. package/dist/casing.d.ts +8 -0
  3. package/dist/casing.d.ts.map +1 -0
  4. package/dist/casing.js +49 -0
  5. package/dist/casing.js.map +1 -0
  6. package/dist/casing.test.d.ts +2 -0
  7. package/dist/casing.test.d.ts.map +1 -0
  8. package/dist/casing.test.js +134 -0
  9. package/dist/casing.test.js.map +1 -0
  10. package/dist/command_line_parser.d.ts +33 -0
  11. package/dist/command_line_parser.d.ts.map +1 -0
  12. package/dist/command_line_parser.js +171 -0
  13. package/dist/command_line_parser.js.map +1 -0
  14. package/dist/command_line_parser.test.d.ts +2 -0
  15. package/dist/command_line_parser.test.d.ts.map +1 -0
  16. package/dist/command_line_parser.test.js +302 -0
  17. package/dist/command_line_parser.test.js.map +1 -0
  18. package/dist/compatibility_checker.d.ts +68 -0
  19. package/dist/compatibility_checker.d.ts.map +1 -0
  20. package/dist/compatibility_checker.js +328 -0
  21. package/dist/compatibility_checker.js.map +1 -0
  22. package/dist/compatibility_checker.test.d.ts +2 -0
  23. package/dist/compatibility_checker.test.d.ts.map +1 -0
  24. package/dist/compatibility_checker.test.js +528 -0
  25. package/dist/compatibility_checker.test.js.map +1 -0
  26. package/dist/compiler.d.ts +3 -0
  27. package/dist/compiler.d.ts.map +1 -0
  28. package/dist/compiler.js +358 -0
  29. package/dist/compiler.js.map +1 -0
  30. package/dist/config.d.ts +47 -0
  31. package/dist/config.d.ts.map +1 -0
  32. package/dist/config.js +23 -0
  33. package/dist/config.js.map +1 -0
  34. package/dist/definition_finder.d.ts +12 -0
  35. package/dist/definition_finder.d.ts.map +1 -0
  36. package/dist/definition_finder.js +180 -0
  37. package/dist/definition_finder.js.map +1 -0
  38. package/dist/definition_finder.test.d.ts +2 -0
  39. package/dist/definition_finder.test.d.ts.map +1 -0
  40. package/dist/definition_finder.test.js +164 -0
  41. package/dist/definition_finder.test.js.map +1 -0
  42. package/dist/encoding.d.ts +2 -0
  43. package/dist/encoding.d.ts.map +1 -0
  44. package/dist/encoding.js +38 -0
  45. package/dist/encoding.js.map +1 -0
  46. package/dist/encoding.test.d.ts +2 -0
  47. package/dist/encoding.test.d.ts.map +1 -0
  48. package/dist/encoding.test.js +23 -0
  49. package/dist/encoding.test.js.map +1 -0
  50. package/dist/error_renderer.d.ts +10 -0
  51. package/dist/error_renderer.d.ts.map +1 -0
  52. package/dist/error_renderer.js +247 -0
  53. package/dist/error_renderer.js.map +1 -0
  54. package/dist/formatter.d.ts +3 -0
  55. package/dist/formatter.d.ts.map +1 -0
  56. package/dist/formatter.js +263 -0
  57. package/dist/formatter.js.map +1 -0
  58. package/dist/formatter.test.d.ts +2 -0
  59. package/dist/formatter.test.d.ts.map +1 -0
  60. package/dist/formatter.test.js +156 -0
  61. package/dist/formatter.test.js.map +1 -0
  62. package/dist/index.d.ts +6 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +5 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/index.test.d.ts +2 -0
  67. package/dist/index.test.d.ts.map +1 -0
  68. package/dist/index.test.js +14 -0
  69. package/dist/index.test.js.map +1 -0
  70. package/dist/io.d.ts +13 -0
  71. package/dist/io.d.ts.map +1 -0
  72. package/dist/io.js +22 -0
  73. package/dist/io.js.map +1 -0
  74. package/dist/language_server.d.ts +15 -0
  75. package/dist/language_server.d.ts.map +1 -0
  76. package/dist/language_server.js +248 -0
  77. package/dist/language_server.js.map +1 -0
  78. package/dist/literals.d.ts +13 -0
  79. package/dist/literals.d.ts.map +1 -0
  80. package/dist/literals.js +100 -0
  81. package/dist/literals.js.map +1 -0
  82. package/dist/literals.test.d.ts +2 -0
  83. package/dist/literals.test.d.ts.map +1 -0
  84. package/dist/literals.test.js +149 -0
  85. package/dist/literals.test.js.map +1 -0
  86. package/dist/module_collector.d.ts +3 -0
  87. package/dist/module_collector.d.ts.map +1 -0
  88. package/dist/module_collector.js +22 -0
  89. package/dist/module_collector.js.map +1 -0
  90. package/dist/module_set.d.ts +44 -0
  91. package/dist/module_set.d.ts.map +1 -0
  92. package/dist/module_set.js +1025 -0
  93. package/dist/module_set.js.map +1 -0
  94. package/dist/module_set.test.d.ts +2 -0
  95. package/dist/module_set.test.d.ts.map +1 -0
  96. package/dist/module_set.test.js +1330 -0
  97. package/dist/module_set.test.js.map +1 -0
  98. package/dist/parser.d.ts +6 -0
  99. package/dist/parser.d.ts.map +1 -0
  100. package/dist/parser.js +971 -0
  101. package/dist/parser.js.map +1 -0
  102. package/dist/parser.test.d.ts +2 -0
  103. package/dist/parser.test.d.ts.map +1 -0
  104. package/dist/parser.test.js +1366 -0
  105. package/dist/parser.test.js.map +1 -0
  106. package/dist/snapshotter.d.ts +6 -0
  107. package/dist/snapshotter.d.ts.map +1 -0
  108. package/dist/snapshotter.js +107 -0
  109. package/dist/snapshotter.js.map +1 -0
  110. package/dist/tokenizer.d.ts +4 -0
  111. package/dist/tokenizer.d.ts.map +1 -0
  112. package/dist/tokenizer.js +192 -0
  113. package/dist/tokenizer.js.map +1 -0
  114. package/dist/tokenizer.test.d.ts +2 -0
  115. package/dist/tokenizer.test.d.ts.map +1 -0
  116. package/dist/tokenizer.test.js +425 -0
  117. package/dist/tokenizer.test.js.map +1 -0
  118. package/dist/types.d.ts +375 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +2 -0
  121. package/dist/types.js.map +1 -0
  122. package/package.json +63 -0
  123. package/src/casing.ts +64 -0
  124. package/src/command_line_parser.ts +249 -0
  125. package/src/compatibility_checker.ts +470 -0
  126. package/src/compiler.ts +435 -0
  127. package/src/config.ts +28 -0
  128. package/src/definition_finder.ts +221 -0
  129. package/src/encoding.ts +32 -0
  130. package/src/error_renderer.ts +278 -0
  131. package/src/formatter.ts +274 -0
  132. package/src/index.ts +6 -0
  133. package/src/io.ts +33 -0
  134. package/src/language_server.ts +301 -0
  135. package/src/literals.ts +120 -0
  136. package/src/module_collector.ts +22 -0
  137. package/src/module_set.ts +1175 -0
  138. package/src/parser.ts +1122 -0
  139. package/src/snapshotter.ts +136 -0
  140. package/src/tokenizer.ts +216 -0
  141. package/src/types.ts +518 -0
@@ -0,0 +1,1330 @@
1
+ import { expect } from "buckwheat";
2
+ import { describe, it } from "mocha";
3
+ import { ModuleSet } from "./module_set.js";
4
+ class FakeFileReader {
5
+ constructor() {
6
+ this.pathToCode = new Map();
7
+ }
8
+ readTextFile(modulePath) {
9
+ return this.pathToCode.get(modulePath);
10
+ }
11
+ }
12
+ describe("module set", () => {
13
+ it("works", () => {
14
+ const fakeFileReader = new FakeFileReader();
15
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
16
+ import * as other_module from "./other/module";
17
+
18
+ struct Outer {
19
+ struct Foo {}
20
+ }
21
+
22
+ struct Bar(100) {
23
+ foo: Outer.Foo;
24
+ foo2: .Outer.Foo;
25
+
26
+ struct Inner(101) {}
27
+ inner: Inner;
28
+ zoo: other_module.Outer.Zoo;
29
+ }
30
+
31
+ method GetBar(Outer.Foo): Bar;
32
+ method GetBar2(Outer.Foo): Bar = 100;
33
+ `);
34
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
35
+ struct Outer {
36
+ struct Zoo {}
37
+ }
38
+ `);
39
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
40
+ const actual = moduleSet.parseAndResolve("path/to/module");
41
+ expect(actual).toMatch({
42
+ result: {
43
+ nameToDeclaration: {
44
+ other_module: {
45
+ kind: "import-alias",
46
+ name: {
47
+ text: "other_module",
48
+ },
49
+ modulePath: {
50
+ text: '"./other/module"',
51
+ },
52
+ },
53
+ Outer: {
54
+ kind: "record",
55
+ name: {
56
+ text: "Outer",
57
+ },
58
+ recordType: "struct",
59
+ nameToDeclaration: {
60
+ Foo: {
61
+ kind: "record",
62
+ },
63
+ },
64
+ declarations: [
65
+ {
66
+ name: {
67
+ text: "Foo",
68
+ },
69
+ },
70
+ ],
71
+ nestedRecords: [
72
+ {
73
+ recordType: "struct",
74
+ name: {
75
+ text: "Foo",
76
+ },
77
+ nestedRecords: [],
78
+ },
79
+ ],
80
+ },
81
+ Bar: {
82
+ kind: "record",
83
+ recordType: "struct",
84
+ name: {
85
+ text: "Bar",
86
+ },
87
+ fields: [
88
+ {
89
+ kind: "field",
90
+ name: {
91
+ text: "foo",
92
+ },
93
+ number: 0,
94
+ type: {
95
+ kind: "record",
96
+ key: "path/to/module:98",
97
+ recordType: "struct",
98
+ refToken: {
99
+ text: "Foo",
100
+ },
101
+ },
102
+ },
103
+ { name: { text: "foo2" } },
104
+ { name: { text: "inner" } },
105
+ { name: { text: "zoo" } },
106
+ ],
107
+ numSlots: 4,
108
+ numSlotsInclRemovedNumbers: 4,
109
+ },
110
+ GetBar: {
111
+ kind: "method",
112
+ name: { text: "GetBar" },
113
+ requestType: {
114
+ kind: "record",
115
+ key: "path/to/module:98",
116
+ recordType: "struct",
117
+ refToken: {
118
+ text: "Foo",
119
+ },
120
+ },
121
+ responseType: {
122
+ kind: "record",
123
+ key: "path/to/module:131",
124
+ recordType: "struct",
125
+ refToken: {
126
+ text: "Bar",
127
+ },
128
+ },
129
+ number: 2103196129,
130
+ hasExplicitNumber: false,
131
+ },
132
+ GetBar2: {
133
+ number: 100,
134
+ },
135
+ },
136
+ declarations: [
137
+ { name: { text: "other_module" } },
138
+ { name: { text: "Outer" } },
139
+ { name: { text: "Bar" } },
140
+ { name: { text: "GetBar" } },
141
+ { name: { text: "GetBar2" } },
142
+ ],
143
+ records: [
144
+ { record: { name: { text: "Foo" } } },
145
+ { record: { name: { text: "Outer" } } },
146
+ { record: { name: { text: "Inner" }, recordNumber: 101 } },
147
+ { record: { name: { text: "Bar" } } },
148
+ ],
149
+ },
150
+ errors: [],
151
+ });
152
+ });
153
+ it("recursivity works", () => {
154
+ const fakeFileReader = new FakeFileReader();
155
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
156
+ struct A { s: string; }
157
+ struct B { b: B; }
158
+ struct C { c: C?; }
159
+ struct D { d: [D]; }
160
+ struct E { f: F; }
161
+ struct F { e: E; }
162
+ struct G { b: B; }
163
+ struct H { i: I; }
164
+ enum I { h: H; }
165
+ `);
166
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
167
+ const actual = moduleSet.parseAndResolve("path/to/module");
168
+ expect(actual).toMatch({
169
+ result: {
170
+ nameToDeclaration: {
171
+ A: {
172
+ fields: [{ isRecursive: false }],
173
+ },
174
+ B: {
175
+ fields: [{ isRecursive: "hard" }],
176
+ },
177
+ C: {
178
+ fields: [{ isRecursive: "soft" }],
179
+ },
180
+ D: {
181
+ fields: [{ isRecursive: "soft" }],
182
+ },
183
+ E: {
184
+ fields: [{ isRecursive: "hard" }],
185
+ },
186
+ F: {
187
+ fields: [{ isRecursive: "hard" }],
188
+ },
189
+ G: {
190
+ fields: [{ isRecursive: false }],
191
+ },
192
+ H: {
193
+ fields: [{ isRecursive: "soft" }],
194
+ },
195
+ I: {
196
+ fields: [{ isRecursive: "soft" }],
197
+ },
198
+ },
199
+ },
200
+ errors: [],
201
+ });
202
+ });
203
+ it("circular dependency between modules", () => {
204
+ const fakeFileReader = new FakeFileReader();
205
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
206
+ import * as other_module from "./other/module";
207
+ `);
208
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
209
+ import * as module from "path/to/module";
210
+ `);
211
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
212
+ const actual = moduleSet.parseAndResolve("path/to/module");
213
+ expect(actual).toMatch({
214
+ errors: [
215
+ {
216
+ token: {
217
+ text: '"./other/module"',
218
+ },
219
+ message: "Circular dependency between modules",
220
+ },
221
+ ],
222
+ });
223
+ expect(moduleSet.parseAndResolve("path/to/other/module")).toMatch({
224
+ errors: [
225
+ {
226
+ token: {
227
+ text: '"path/to/module"',
228
+ },
229
+ message: "Circular dependency between modules",
230
+ },
231
+ ],
232
+ });
233
+ });
234
+ it("module not found", () => {
235
+ const fakeFileReader = new FakeFileReader();
236
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
237
+ import * as other_module from "./other/module";
238
+ `);
239
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
240
+ const actual = moduleSet.parseAndResolve("path/to/module");
241
+ expect(actual).toMatch({
242
+ errors: [
243
+ {
244
+ token: {
245
+ text: '"./other/module"',
246
+ },
247
+ message: "Module not found",
248
+ },
249
+ ],
250
+ });
251
+ });
252
+ it("module already imported with an alias", () => {
253
+ const fakeFileReader = new FakeFileReader();
254
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
255
+ import * as other_module from "./other/module";
256
+ import Foo from "./other/module";
257
+ `);
258
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
259
+ struct Foo {}
260
+ `);
261
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
262
+ const actual = moduleSet.parseAndResolve("path/to/module");
263
+ expect(actual).toMatch({
264
+ errors: [
265
+ {
266
+ token: {
267
+ text: '"./other/module"',
268
+ },
269
+ message: "Module already imported with an alias",
270
+ },
271
+ ],
272
+ });
273
+ });
274
+ it("module already imported with a different alias", () => {
275
+ const fakeFileReader = new FakeFileReader();
276
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
277
+ import * as foo from "./other/module";
278
+ import * as bar from "./other/module";
279
+ `);
280
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", "");
281
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
282
+ const actual = moduleSet.parseAndResolve("path/to/module");
283
+ expect(actual).toMatch({
284
+ errors: [
285
+ {
286
+ token: {
287
+ text: '"./other/module"',
288
+ },
289
+ message: "Module already imported with a different alias",
290
+ },
291
+ ],
292
+ });
293
+ });
294
+ it("multiple import declarations from same module", () => {
295
+ const fakeFileReader = new FakeFileReader();
296
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
297
+ import Foo from "./other/module";
298
+ import Bar from "./other/module";
299
+
300
+ struct Zoo {
301
+ foo: Foo;
302
+ bar: Bar;
303
+ }
304
+ `);
305
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
306
+ struct Foo {}
307
+ struct Bar {}
308
+ `);
309
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
310
+ const actual = moduleSet.parseAndResolve("path/to/module");
311
+ expect(actual).toMatch({
312
+ errors: [],
313
+ });
314
+ });
315
+ it("multiple imports from same module", () => {
316
+ const fakeFileReader = new FakeFileReader();
317
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
318
+ import Foo, Bar from "./other/module";
319
+
320
+ struct Zoo {
321
+ foo: Foo;
322
+ bar: Bar;
323
+ }
324
+ `);
325
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
326
+ struct Foo {}
327
+ struct Bar {}
328
+ `);
329
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
330
+ const actual = moduleSet.parseAndResolve("path/to/module");
331
+ expect(actual).toMatch({
332
+ errors: [],
333
+ });
334
+ });
335
+ it("module path cannot contain backslash", () => {
336
+ const fakeFileReader = new FakeFileReader();
337
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
338
+ import * as foo from ".\\\\module";
339
+ `);
340
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", "");
341
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
342
+ const actual = moduleSet.parseAndResolve("path/to/module");
343
+ expect(actual).toMatch({
344
+ errors: [
345
+ {
346
+ token: {
347
+ text: '".\\\\module"',
348
+ },
349
+ message: "Replace backslash with slash",
350
+ },
351
+ ],
352
+ });
353
+ });
354
+ it("field numbering constraint satisfied", () => {
355
+ const fakeFileReader = new FakeFileReader();
356
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
357
+ struct Foo {}
358
+ struct Bar { bar: int32 = 0; }
359
+ struct Zoo { foo: Foo = 0; bar: Bar = 1; }
360
+ `);
361
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
362
+ const actual = moduleSet.parseAndResolve("path/to/module");
363
+ expect(actual).toMatch({ errors: [] });
364
+ });
365
+ it("field numbering constraint not satisfied", () => {
366
+ const fakeFileReader = new FakeFileReader();
367
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
368
+ struct Foo { foo: int32; }
369
+ struct Bar { foo: Foo = 0; }
370
+ `);
371
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
372
+ const actual = moduleSet.parseAndResolve("path/to/module");
373
+ expect(actual).toMatch({
374
+ errors: [
375
+ {
376
+ token: {
377
+ text: "Foo",
378
+ },
379
+ message: "Field type references a struct with implicit numbering, but field belongs to a struct with explicit numbering",
380
+ },
381
+ ],
382
+ });
383
+ });
384
+ describe("keyed arrays", () => {
385
+ it("works", () => {
386
+ const fakeFileReader = new FakeFileReader();
387
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
388
+ struct Outer {
389
+ struct User {
390
+ key: string;
391
+ key_enum: Enum;
392
+ }
393
+
394
+ enum Enum {
395
+ MONDAY;
396
+ }
397
+
398
+ struct UserHistory {
399
+ user: User;
400
+ }
401
+ }
402
+
403
+ struct Foo {
404
+ users: [Outer.User|key];
405
+ users_by_enum: [Outer.User|key_enum.kind];
406
+ user_histories: [Outer.UserHistory|user.key]?;
407
+ }
408
+ `);
409
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
410
+ const actual = moduleSet.parseAndResolve("path/to/module");
411
+ expect(actual).toMatch({
412
+ result: {
413
+ nameToDeclaration: {
414
+ Foo: {
415
+ fields: [
416
+ {
417
+ name: { text: "users" },
418
+ type: {
419
+ kind: "array",
420
+ item: {
421
+ kind: "record",
422
+ key: "path/to/module:45",
423
+ },
424
+ key: {
425
+ pipeToken: { text: "|" },
426
+ path: [{ name: { text: "key" } }],
427
+ keyType: {
428
+ kind: "primitive",
429
+ primitive: "string",
430
+ },
431
+ },
432
+ },
433
+ },
434
+ {
435
+ name: { text: "users_by_enum" },
436
+ type: {
437
+ kind: "array",
438
+ item: {
439
+ kind: "record",
440
+ key: "path/to/module:45",
441
+ },
442
+ key: {
443
+ pipeToken: { text: "|" },
444
+ path: [
445
+ {
446
+ name: { text: "key_enum" },
447
+ declaration: { name: { text: "key_enum" } },
448
+ },
449
+ { name: { text: "kind" }, declaration: undefined },
450
+ ],
451
+ keyType: {
452
+ kind: "record",
453
+ key: "path/to/module:141",
454
+ },
455
+ },
456
+ },
457
+ },
458
+ {
459
+ name: { text: "user_histories" },
460
+ type: {
461
+ kind: "optional",
462
+ other: {
463
+ kind: "array",
464
+ item: {
465
+ kind: "record",
466
+ key: "path/to/module:204",
467
+ },
468
+ key: {
469
+ pipeToken: { text: "|" },
470
+ path: [
471
+ { name: { text: "user" } },
472
+ { name: { text: "key" } },
473
+ ],
474
+ keyType: {
475
+ kind: "primitive",
476
+ primitive: "string",
477
+ },
478
+ },
479
+ },
480
+ },
481
+ },
482
+ ],
483
+ },
484
+ },
485
+ },
486
+ });
487
+ });
488
+ it("field not found in struct", () => {
489
+ const fakeFileReader = new FakeFileReader();
490
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
491
+ struct User {}
492
+ struct Foo {
493
+ users: [User|key];
494
+ }
495
+ `);
496
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
497
+ const actual = moduleSet.parseAndResolve("path/to/module");
498
+ expect(actual).toMatch({
499
+ errors: [
500
+ {
501
+ token: {
502
+ text: "key",
503
+ },
504
+ message: "Field not found in struct User",
505
+ },
506
+ ],
507
+ });
508
+ });
509
+ it("item must have struct type", () => {
510
+ // This is actually verified at parsing time.
511
+ const fakeFileReader = new FakeFileReader();
512
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
513
+ struct Foo {
514
+ users: [string|key];
515
+ }
516
+ `);
517
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
518
+ const actual = moduleSet.parseAndResolve("path/to/module");
519
+ expect(actual).toMatch({
520
+ errors: [
521
+ {
522
+ token: {
523
+ text: "|",
524
+ },
525
+ expected: '"]"',
526
+ },
527
+ ],
528
+ });
529
+ });
530
+ it("must have struct type", () => {
531
+ const fakeFileReader = new FakeFileReader();
532
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
533
+ struct User {
534
+ key: string;
535
+ }
536
+ struct Foo {
537
+ users: [User|key.bar];
538
+ }
539
+ `);
540
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
541
+ const actual = moduleSet.parseAndResolve("path/to/module");
542
+ expect(actual).toMatch({
543
+ errors: [
544
+ {
545
+ token: {
546
+ text: "key",
547
+ },
548
+ message: "Must have struct type",
549
+ },
550
+ ],
551
+ });
552
+ });
553
+ it("if enum then expects kind", () => {
554
+ const fakeFileReader = new FakeFileReader();
555
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
556
+ enum Enum { MONDAY; }
557
+ struct Foo {
558
+ users: [Enum|key];
559
+ }
560
+ `);
561
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
562
+ const actual = moduleSet.parseAndResolve("path/to/module");
563
+ expect(actual).toMatch({
564
+ errors: [
565
+ {
566
+ token: {
567
+ text: "key",
568
+ },
569
+ expected: '"kind"',
570
+ },
571
+ ],
572
+ });
573
+ });
574
+ it("all fields but the last must have struct type", () => {
575
+ const fakeFileReader = new FakeFileReader();
576
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
577
+ struct User { key: string; }
578
+ struct Foo {
579
+ users: [User|key.bar];
580
+ }
581
+ `);
582
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
583
+ const actual = moduleSet.parseAndResolve("path/to/module");
584
+ expect(actual).toMatch({
585
+ errors: [
586
+ {
587
+ token: {
588
+ text: "key",
589
+ },
590
+ message: "Must have struct type",
591
+ },
592
+ ],
593
+ });
594
+ });
595
+ it("key must have primitive or enum type", () => {
596
+ const fakeFileReader = new FakeFileReader();
597
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
598
+ struct Bar {}
599
+ struct User { key: Bar; }
600
+ struct Foo {
601
+ users: [User|key];
602
+ }
603
+ `);
604
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
605
+ const actual = moduleSet.parseAndResolve("path/to/module");
606
+ expect(actual).toMatch({
607
+ errors: [
608
+ {
609
+ token: {
610
+ text: "key",
611
+ },
612
+ message: "Does not have primitive type",
613
+ },
614
+ ],
615
+ });
616
+ });
617
+ it("method and constant types are validated", () => {
618
+ const fakeFileReader = new FakeFileReader();
619
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
620
+ struct Foo {
621
+ }
622
+
623
+ method Pa([Foo|a]): string;
624
+ method Pb(string): [Foo|b];
625
+ const FOO: [Foo|c] = [];
626
+ const PI: float32 = -3.14;
627
+ `);
628
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
629
+ const actual = moduleSet.parseAndResolve("path/to/module");
630
+ expect(actual).toMatch({
631
+ errors: [
632
+ {
633
+ token: {
634
+ text: "a",
635
+ },
636
+ message: "Field not found in struct Foo",
637
+ },
638
+ {
639
+ token: {
640
+ text: "b",
641
+ },
642
+ message: "Field not found in struct Foo",
643
+ },
644
+ {
645
+ token: {
646
+ text: "c",
647
+ },
648
+ message: "Field not found in struct Foo",
649
+ },
650
+ ],
651
+ });
652
+ });
653
+ });
654
+ describe("type resolver", () => {
655
+ it("cannot find name", () => {
656
+ const fakeFileReader = new FakeFileReader();
657
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
658
+ struct Foo {
659
+ bar: Bar;
660
+ }
661
+ `);
662
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
663
+ const actual = moduleSet.parseAndResolve("path/to/module");
664
+ expect(actual).toMatch({
665
+ errors: [
666
+ {
667
+ token: {
668
+ text: "Bar",
669
+ },
670
+ message: "Cannot find name 'Bar'",
671
+ },
672
+ ],
673
+ });
674
+ });
675
+ describe("cannot reimport imported name", () => {
676
+ it("no alias / no alias", () => {
677
+ const fakeFileReader = new FakeFileReader();
678
+ fakeFileReader.pathToCode.set("path/to/root/path/to/foo", `
679
+ struct Foo {}
680
+ `);
681
+ fakeFileReader.pathToCode.set("path/to/root/path/to/bar", `
682
+ import Foo from "./foo";
683
+ struct Bar { foo: Foo; }
684
+ `);
685
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
686
+ import Foo from "./bar";
687
+ struct Zoo { foo: Foo; }
688
+ `);
689
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
690
+ const actual = moduleSet.parseAndResolve("path/to/module");
691
+ expect(actual).toMatch({
692
+ errors: [
693
+ {
694
+ token: {
695
+ text: "Foo",
696
+ },
697
+ message: "Cannot reimport imported name 'Foo'",
698
+ },
699
+ ],
700
+ });
701
+ });
702
+ it("no alias / alias", () => {
703
+ const fakeFileReader = new FakeFileReader();
704
+ fakeFileReader.pathToCode.set("path/to/root/path/to/foo", `
705
+ struct Foo {}
706
+ `);
707
+ fakeFileReader.pathToCode.set("path/to/root/path/to/bar", `
708
+ import * as foo from "./foo";
709
+ struct Bar { foo: foo.Foo; }
710
+ `);
711
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
712
+ import foo from "./bar";
713
+ struct Zoo { foo: foo.Foo; }
714
+ `);
715
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
716
+ const actual = moduleSet.parseAndResolve("path/to/module");
717
+ expect(actual).toMatch({
718
+ errors: [
719
+ {
720
+ token: {
721
+ text: "foo",
722
+ },
723
+ message: "Cannot reimport imported name 'foo'",
724
+ },
725
+ ],
726
+ });
727
+ });
728
+ it("alias / no alias", () => {
729
+ const fakeFileReader = new FakeFileReader();
730
+ fakeFileReader.pathToCode.set("path/to/root/path/to/foo", `
731
+ struct Foo {}
732
+ `);
733
+ fakeFileReader.pathToCode.set("path/to/root/path/to/bar", `
734
+ import Foo from "./foo";
735
+ struct Bar { foo: Foo; }
736
+ `);
737
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
738
+ import * as bar from "./bar";
739
+ struct Zoo { foo: bar.Foo; }
740
+ `);
741
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
742
+ const actual = moduleSet.parseAndResolve("path/to/module");
743
+ expect(actual).toMatch({
744
+ errors: [
745
+ {
746
+ token: {
747
+ text: "Foo",
748
+ },
749
+ message: "Cannot reimport imported name 'Foo'",
750
+ },
751
+ ],
752
+ });
753
+ });
754
+ it("alias / alias", () => {
755
+ const fakeFileReader = new FakeFileReader();
756
+ fakeFileReader.pathToCode.set("path/to/root/path/to/foo", `
757
+ struct Foo {}
758
+ `);
759
+ fakeFileReader.pathToCode.set("path/to/root/path/to/bar", `
760
+ import * as foo from "./foo";
761
+ struct Bar { foo: foo.Foo; }
762
+ `);
763
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
764
+ import * as bar from "./bar";
765
+ struct Zoo { foo: bar.foo.Foo; }
766
+ `);
767
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
768
+ const actual = moduleSet.parseAndResolve("path/to/module");
769
+ expect(actual).toMatch({
770
+ errors: [
771
+ {
772
+ token: {
773
+ text: "foo",
774
+ },
775
+ message: "Cannot reimport imported name 'foo'",
776
+ },
777
+ ],
778
+ });
779
+ });
780
+ });
781
+ });
782
+ it("import module with absolute path", () => {
783
+ const fakeFileReader = new FakeFileReader();
784
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
785
+ import Bar from "path/to_other_module";
786
+
787
+ struct Foo {
788
+ bar: Bar;
789
+ }
790
+ `);
791
+ fakeFileReader.pathToCode.set("path/to/root/path/to_other_module", `
792
+ struct Bar {}
793
+ `);
794
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
795
+ const actual = moduleSet.parseAndResolve("path/to/module");
796
+ expect(actual).toMatch({
797
+ errors: [],
798
+ });
799
+ });
800
+ it("normalize module path", () => {
801
+ const fakeFileReader = new FakeFileReader();
802
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
803
+ import Bar from "../foo/../to_other_module";
804
+
805
+ struct Foo {
806
+ bar: Bar;
807
+ }
808
+ `);
809
+ fakeFileReader.pathToCode.set("path/to/root/path/to_other_module", `
810
+ struct Bar {}
811
+ `);
812
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
813
+ const actual = moduleSet.parseAndResolve("path/to/module");
814
+ expect(actual).toMatch({
815
+ errors: [],
816
+ });
817
+ });
818
+ it("module path must point to a file within root", () => {
819
+ const fakeFileReader = new FakeFileReader();
820
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
821
+ import Bar from "../../../other_module";
822
+
823
+ struct Foo {
824
+ bar: Bar;
825
+ }
826
+ `);
827
+ fakeFileReader.pathToCode.set("path/to/other_module", `
828
+ struct Bar {}
829
+ `);
830
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
831
+ const actual = moduleSet.parseAndResolve("path/to/module");
832
+ expect(actual).toMatch({
833
+ errors: [
834
+ {
835
+ token: {
836
+ text: '"../../../other_module"',
837
+ },
838
+ message: "Module path must point to a file within root",
839
+ },
840
+ ],
841
+ });
842
+ });
843
+ it("all imports must be used", () => {
844
+ const fakeFileReader = new FakeFileReader();
845
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
846
+ import Bar, Zoo from "./other_module";
847
+
848
+ struct Foo {
849
+ zoo: Zoo;
850
+ }
851
+ `);
852
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other_module", `
853
+ struct Bar {}
854
+ struct Zoo {}
855
+ `);
856
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
857
+ const actual = moduleSet.parseAndResolve("path/to/module");
858
+ expect(actual).toMatch({
859
+ errors: [
860
+ {
861
+ token: {
862
+ text: "Bar",
863
+ },
864
+ message: "Unused import",
865
+ },
866
+ ],
867
+ });
868
+ });
869
+ it("all stable ids must be distinct", () => {
870
+ const fakeFileReader = new FakeFileReader();
871
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
872
+ struct Foo(100) {}
873
+ `);
874
+ fakeFileReader.pathToCode.set("path/to/root/path/to/other_module", `
875
+ struct Bar(100) {}
876
+ `);
877
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
878
+ {
879
+ const actual = moduleSet.parseAndResolve("path/to/module");
880
+ expect(actual).toMatch({
881
+ errors: [],
882
+ });
883
+ }
884
+ {
885
+ const actual = moduleSet.parseAndResolve("path/to/other_module");
886
+ expect(actual).toMatch({
887
+ errors: [
888
+ {
889
+ token: {
890
+ text: "Bar",
891
+ },
892
+ message: "Same number as Foo in path/to/module",
893
+ },
894
+ ],
895
+ });
896
+ }
897
+ });
898
+ it("all method numbers must be distinct", () => {
899
+ const fakeFileReader = new FakeFileReader();
900
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
901
+ method GetFoo(string): string = 2103196129;
902
+ method GetBar(string): string;
903
+ `);
904
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
905
+ const actual = moduleSet.parseAndResolve("path/to/module");
906
+ expect(actual).toMatch({
907
+ errors: [
908
+ {
909
+ token: {
910
+ text: "GetBar",
911
+ },
912
+ message: "Same number as GetFoo in path/to/module",
913
+ },
914
+ ],
915
+ });
916
+ });
917
+ describe("constants", () => {
918
+ it("works", () => {
919
+ const fakeFileReader = new FakeFileReader();
920
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
921
+ struct Color {
922
+ r: int32;
923
+ g: int32;
924
+ b: int32;
925
+ }
926
+
927
+ struct Point {
928
+ x: float32;
929
+ removed;
930
+ y: float32;
931
+ }
932
+
933
+ struct Shape {
934
+ color: Color;
935
+ points: [Point];
936
+ }
937
+
938
+ const MY_SHAPE: Shape = {
939
+ color: {
940
+ r: 255,
941
+ g: 0,
942
+ b: 0,
943
+ },
944
+ points: [
945
+ {
946
+ x: 10.0,
947
+ y: 10.0,
948
+ },
949
+ {|
950
+ y: 20.0,
951
+ |},
952
+ {
953
+ x: 10.0,
954
+ y: 0.0,
955
+ },
956
+ ],
957
+ };
958
+ const NULL_SHAPE: Shape? = null;
959
+ `);
960
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
961
+ const actual = moduleSet.parseAndResolve("path/to/module");
962
+ expect(actual).toMatch({
963
+ result: {
964
+ nameToDeclaration: {
965
+ MY_SHAPE: {
966
+ kind: "constant",
967
+ name: {
968
+ text: "MY_SHAPE",
969
+ },
970
+ type: {
971
+ kind: "record",
972
+ key: "path/to/module:207",
973
+ recordType: "struct",
974
+ refToken: {
975
+ text: "Shape",
976
+ },
977
+ },
978
+ value: {
979
+ kind: "object",
980
+ token: {
981
+ text: "{",
982
+ },
983
+ entries: {
984
+ color: {
985
+ name: {
986
+ text: "color",
987
+ },
988
+ value: {
989
+ kind: "object",
990
+ token: {
991
+ text: "{",
992
+ },
993
+ entries: {
994
+ r: {
995
+ value: {
996
+ kind: "literal",
997
+ token: {
998
+ text: "255",
999
+ },
1000
+ type: {
1001
+ kind: "primitive",
1002
+ primitive: "int32",
1003
+ },
1004
+ },
1005
+ },
1006
+ g: {},
1007
+ b: {},
1008
+ },
1009
+ type: "path/to/module:16",
1010
+ },
1011
+ },
1012
+ points: {
1013
+ value: {
1014
+ kind: "array",
1015
+ token: {
1016
+ text: "[",
1017
+ },
1018
+ items: [
1019
+ {
1020
+ kind: "object",
1021
+ token: {
1022
+ text: "{",
1023
+ },
1024
+ entries: {
1025
+ x: {
1026
+ value: {
1027
+ kind: "literal",
1028
+ token: {
1029
+ text: "10.0",
1030
+ },
1031
+ type: {
1032
+ kind: "primitive",
1033
+ primitive: "float32",
1034
+ },
1035
+ },
1036
+ },
1037
+ y: {},
1038
+ },
1039
+ type: "path/to/module:110",
1040
+ },
1041
+ {},
1042
+ {},
1043
+ ],
1044
+ },
1045
+ },
1046
+ },
1047
+ type: "path/to/module:207",
1048
+ },
1049
+ valueAsDenseJson: [[255], [[10, 0, 10], [0, 0, 20], [10]]],
1050
+ },
1051
+ NULL_SHAPE: {
1052
+ kind: "constant",
1053
+ type: {
1054
+ kind: "optional",
1055
+ other: {
1056
+ refToken: {
1057
+ text: "Shape",
1058
+ },
1059
+ },
1060
+ },
1061
+ value: {
1062
+ kind: "literal",
1063
+ token: {
1064
+ text: "null",
1065
+ },
1066
+ type: {
1067
+ kind: "null",
1068
+ },
1069
+ },
1070
+ valueAsDenseJson: null,
1071
+ },
1072
+ },
1073
+ constants: [{}, {}],
1074
+ },
1075
+ errors: [],
1076
+ });
1077
+ });
1078
+ it("honors default values", () => {
1079
+ const fakeFileReader = new FakeFileReader();
1080
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1081
+ struct Struct {
1082
+ opt_a: int32?;
1083
+ int: int32;
1084
+ float: float32;
1085
+ bool: bool;
1086
+ ints: [int32];
1087
+ opt_b: int32?;
1088
+ }
1089
+
1090
+ const S: Struct = {
1091
+ opt_a: 0,
1092
+ int: 0,
1093
+ float: 0.0,
1094
+ bool: false,
1095
+ ints: [],
1096
+ opt_b: null,
1097
+ };
1098
+ `);
1099
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1100
+ const actual = moduleSet.parseAndResolve("path/to/module");
1101
+ expect(actual).toMatch({
1102
+ result: {
1103
+ nameToDeclaration: {
1104
+ S: {
1105
+ kind: "constant",
1106
+ name: {
1107
+ text: "S",
1108
+ },
1109
+ valueAsDenseJson: [0],
1110
+ },
1111
+ },
1112
+ },
1113
+ errors: [],
1114
+ });
1115
+ });
1116
+ it("with keyed array", () => {
1117
+ const fakeFileReader = new FakeFileReader();
1118
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1119
+ enum Enum {
1120
+ A;
1121
+ B;
1122
+ c: string;
1123
+ }
1124
+ struct EnumWrapper {
1125
+ e: Enum;
1126
+ }
1127
+ struct Bar {
1128
+ x: int32;
1129
+ }
1130
+ struct Foo {
1131
+ enums: [EnumWrapper|e.kind];
1132
+ bars: [Bar|x]?;
1133
+ }
1134
+
1135
+ const FOO: Foo = {
1136
+ enums: [
1137
+ {
1138
+ e: "A",
1139
+ },
1140
+ {
1141
+ e: "B",
1142
+ },
1143
+ {
1144
+ e: "?",
1145
+ },
1146
+ {
1147
+ e: {
1148
+ kind: "c",
1149
+ value: "v",
1150
+ },
1151
+ },
1152
+ ],
1153
+ bars: [
1154
+ {
1155
+ x: 0,
1156
+ },
1157
+ ],
1158
+ };
1159
+ `);
1160
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1161
+ const actual = moduleSet.parseAndResolve("path/to/module");
1162
+ expect(actual).toMatch({
1163
+ errors: [],
1164
+ });
1165
+ });
1166
+ it("type error", () => {
1167
+ const fakeFileReader = new FakeFileReader();
1168
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1169
+ struct Color {
1170
+ r: int32;
1171
+ g: int32;
1172
+ b: int32;
1173
+ }
1174
+
1175
+ const BLUE: Color = {
1176
+ r: 0,
1177
+ g: 0,
1178
+ b: 255.0,
1179
+ };
1180
+ `);
1181
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1182
+ const actual = moduleSet.parseAndResolve("path/to/module");
1183
+ expect(actual).toMatch({
1184
+ errors: [
1185
+ {
1186
+ token: {
1187
+ text: "255.0",
1188
+ },
1189
+ expected: "int32",
1190
+ },
1191
+ ],
1192
+ });
1193
+ });
1194
+ it("key missing from keyed array", () => {
1195
+ const fakeFileReader = new FakeFileReader();
1196
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1197
+ enum Enum {
1198
+ A;
1199
+ B;
1200
+ }
1201
+ struct EnumWrapper {
1202
+ e: Enum;
1203
+ }
1204
+ struct Foo {
1205
+ enums: [EnumWrapper|e.kind];
1206
+ }
1207
+
1208
+ const FOO: Foo = {
1209
+ enums: [
1210
+ {
1211
+ e: "A",
1212
+ },
1213
+ {
1214
+ },
1215
+ ],
1216
+ };
1217
+ `);
1218
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1219
+ const actual = moduleSet.parseAndResolve("path/to/module");
1220
+ expect(actual).toMatch({
1221
+ errors: [
1222
+ {
1223
+ token: {
1224
+ text: "{",
1225
+ },
1226
+ message: "Missing entry: e",
1227
+ },
1228
+ ],
1229
+ });
1230
+ });
1231
+ it("duplicate key in keyed array", () => {
1232
+ const fakeFileReader = new FakeFileReader();
1233
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1234
+ enum Enum {
1235
+ A;
1236
+ B;
1237
+ }
1238
+ struct EnumWrapper {
1239
+ e: Enum;
1240
+ }
1241
+ struct Foo {
1242
+ enums: [EnumWrapper|e.kind];
1243
+ }
1244
+
1245
+ const FOO: Foo = {
1246
+ enums: [
1247
+ {
1248
+ e: "A",
1249
+ },
1250
+ {
1251
+ e: 'A',
1252
+ },
1253
+ ],
1254
+ };
1255
+ `);
1256
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1257
+ const actual = moduleSet.parseAndResolve("path/to/module");
1258
+ expect(actual).toMatch({
1259
+ errors: [
1260
+ {
1261
+ token: {
1262
+ text: '"A"',
1263
+ },
1264
+ message: "Duplicate key",
1265
+ },
1266
+ {
1267
+ token: {
1268
+ text: "'A'",
1269
+ },
1270
+ message: "Duplicate key",
1271
+ },
1272
+ ],
1273
+ });
1274
+ });
1275
+ it("missing struct field", () => {
1276
+ const fakeFileReader = new FakeFileReader();
1277
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1278
+ struct Point {
1279
+ x: int32;
1280
+ y: int32;
1281
+ }
1282
+
1283
+ const POINT: Point = {
1284
+ x: 10,
1285
+ };
1286
+ `);
1287
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1288
+ const actual = moduleSet.parseAndResolve("path/to/module");
1289
+ expect(actual).toMatch({
1290
+ errors: [
1291
+ {
1292
+ token: {
1293
+ text: "{",
1294
+ },
1295
+ message: "Missing entry: y",
1296
+ },
1297
+ ],
1298
+ });
1299
+ });
1300
+ it("missing struct field okay if partial", () => {
1301
+ const fakeFileReader = new FakeFileReader();
1302
+ fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
1303
+ struct Point {
1304
+ x: int32;
1305
+ y: int32;
1306
+ }
1307
+
1308
+ const POINT: Point = {|
1309
+ x: 10,
1310
+ |};
1311
+ `);
1312
+ const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
1313
+ const actual = moduleSet.parseAndResolve("path/to/module");
1314
+ expect(actual).toMatch({
1315
+ result: {
1316
+ constants: [
1317
+ {
1318
+ name: {
1319
+ text: "POINT",
1320
+ },
1321
+ valueAsDenseJson: [10],
1322
+ },
1323
+ ],
1324
+ },
1325
+ errors: [],
1326
+ });
1327
+ });
1328
+ });
1329
+ });
1330
+ //# sourceMappingURL=module_set.test.js.map