skir 0.0.1 → 0.0.3
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/casing.d.ts +1 -4
- package/dist/casing.d.ts.map +1 -1
- package/dist/casing.js +0 -29
- package/dist/casing.js.map +1 -1
- package/dist/casing.test.js +2 -13
- package/dist/casing.test.js.map +1 -1
- package/dist/command_line_parser.d.ts +3 -3
- package/dist/command_line_parser.d.ts.map +1 -1
- package/dist/command_line_parser.js +35 -38
- package/dist/command_line_parser.js.map +1 -1
- package/dist/command_line_parser.test.js +73 -78
- package/dist/command_line_parser.test.js.map +1 -1
- package/dist/compatibility_checker.d.ts +9 -3
- package/dist/compatibility_checker.d.ts.map +1 -1
- package/dist/compatibility_checker.js +17 -4
- package/dist/compatibility_checker.js.map +1 -1
- package/dist/compatibility_checker.test.js +55 -1
- package/dist/compatibility_checker.test.js.map +1 -1
- package/dist/compiler.js +34 -17
- package/dist/compiler.js.map +1 -1
- package/dist/config.d.ts +5 -35
- package/dist/config.d.ts.map +1 -1
- package/dist/definition_finder.d.ts +1 -1
- package/dist/definition_finder.d.ts.map +1 -1
- package/dist/doc_comment_parser.d.ts +3 -0
- package/dist/doc_comment_parser.d.ts.map +1 -0
- package/dist/doc_comment_parser.js +223 -0
- package/dist/doc_comment_parser.js.map +1 -0
- package/dist/doc_comment_parser.test.d.ts +2 -0
- package/dist/doc_comment_parser.test.d.ts.map +1 -0
- package/dist/doc_comment_parser.test.js +496 -0
- package/dist/doc_comment_parser.test.js.map +1 -0
- package/dist/error_renderer.d.ts +1 -1
- package/dist/error_renderer.d.ts.map +1 -1
- package/dist/error_renderer.js +84 -65
- package/dist/error_renderer.js.map +1 -1
- package/dist/formatter.d.ts +15 -2
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +191 -234
- package/dist/formatter.js.map +1 -1
- package/dist/formatter.test.js +322 -88
- package/dist/formatter.test.js.map +1 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/language_server.js +1 -1
- package/dist/language_server.js.map +1 -1
- package/dist/literals.d.ts +1 -2
- package/dist/literals.d.ts.map +1 -1
- package/dist/literals.js +1 -12
- package/dist/literals.js.map +1 -1
- package/dist/literals.test.js +1 -4
- package/dist/literals.test.js.map +1 -1
- package/dist/module_set.d.ts +3 -7
- package/dist/module_set.d.ts.map +1 -1
- package/dist/module_set.js +205 -51
- package/dist/module_set.js.map +1 -1
- package/dist/module_set.test.js +595 -28
- package/dist/module_set.test.js.map +1 -1
- package/dist/parser.d.ts +3 -4
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +186 -92
- package/dist/parser.js.map +1 -1
- package/dist/parser.test.js +243 -15
- package/dist/parser.test.js.map +1 -1
- package/dist/project_initializer.d.ts +2 -0
- package/dist/project_initializer.d.ts.map +1 -0
- package/dist/project_initializer.js +30 -0
- package/dist/project_initializer.js.map +1 -0
- package/dist/snapshotter.d.ts +3 -0
- package/dist/snapshotter.d.ts.map +1 -1
- package/dist/snapshotter.js +43 -6
- package/dist/snapshotter.js.map +1 -1
- package/dist/tokenizer.d.ts +8 -2
- package/dist/tokenizer.d.ts.map +1 -1
- package/dist/tokenizer.js +26 -20
- package/dist/tokenizer.js.map +1 -1
- package/dist/tokenizer.test.js +285 -269
- package/dist/tokenizer.test.js.map +1 -1
- package/package.json +7 -5
- package/src/casing.ts +1 -36
- package/src/command_line_parser.ts +42 -48
- package/src/compatibility_checker.ts +29 -7
- package/src/compiler.ts +35 -18
- package/src/definition_finder.ts +1 -1
- package/src/doc_comment_parser.ts +251 -0
- package/src/error_renderer.ts +90 -66
- package/src/formatter.ts +249 -238
- package/src/index.ts +0 -6
- package/src/language_server.ts +8 -8
- package/src/literals.ts +5 -14
- package/src/module_set.ts +259 -79
- package/src/parser.ts +214 -98
- package/src/project_initializer.ts +39 -0
- package/src/snapshotter.ts +46 -5
- package/src/tokenizer.ts +47 -25
- package/dist/encoding.d.ts +0 -2
- package/dist/encoding.d.ts.map +0 -1
- package/dist/encoding.js +0 -38
- package/dist/encoding.js.map +0 -1
- package/dist/encoding.test.d.ts +0 -2
- package/dist/encoding.test.d.ts.map +0 -1
- package/dist/encoding.test.js +0 -23
- package/dist/encoding.test.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -14
- package/dist/index.test.js.map +0 -1
- package/dist/types.d.ts +0 -375
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/src/encoding.ts +0 -32
- package/src/types.ts +0 -518
package/dist/module_set.test.js
CHANGED
|
@@ -26,10 +26,13 @@ describe("module set", () => {
|
|
|
26
26
|
struct Inner(101) {}
|
|
27
27
|
inner: Inner;
|
|
28
28
|
zoo: other_module.Outer.Zoo;
|
|
29
|
+
|
|
30
|
+
loo_loo: struct {};
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
method GetBar(Outer.Foo): Bar;
|
|
32
34
|
method GetBar2(Outer.Foo): Bar = 100;
|
|
35
|
+
method Search(enum {}): struct {};
|
|
33
36
|
`);
|
|
34
37
|
fakeFileReader.pathToCode.set("path/to/root/path/to/other/module", `
|
|
35
38
|
struct Outer {
|
|
@@ -103,9 +106,10 @@ describe("module set", () => {
|
|
|
103
106
|
{ name: { text: "foo2" } },
|
|
104
107
|
{ name: { text: "inner" } },
|
|
105
108
|
{ name: { text: "zoo" } },
|
|
109
|
+
{ name: { text: "loo_loo" } },
|
|
106
110
|
],
|
|
107
|
-
numSlots:
|
|
108
|
-
numSlotsInclRemovedNumbers:
|
|
111
|
+
numSlots: 5,
|
|
112
|
+
numSlotsInclRemovedNumbers: 5,
|
|
109
113
|
},
|
|
110
114
|
GetBar: {
|
|
111
115
|
kind: "method",
|
|
@@ -132,6 +136,14 @@ describe("module set", () => {
|
|
|
132
136
|
GetBar2: {
|
|
133
137
|
number: 100,
|
|
134
138
|
},
|
|
139
|
+
Search: {},
|
|
140
|
+
SearchRequest: {
|
|
141
|
+
name: {
|
|
142
|
+
text: "SearchRequest",
|
|
143
|
+
originalText: "Search",
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
SearchResponse: {},
|
|
135
147
|
},
|
|
136
148
|
declarations: [
|
|
137
149
|
{ name: { text: "other_module" } },
|
|
@@ -139,12 +151,18 @@ describe("module set", () => {
|
|
|
139
151
|
{ name: { text: "Bar" } },
|
|
140
152
|
{ name: { text: "GetBar" } },
|
|
141
153
|
{ name: { text: "GetBar2" } },
|
|
154
|
+
{ name: { text: "Search" } },
|
|
155
|
+
{ name: { text: "SearchRequest" } },
|
|
156
|
+
{ name: { text: "SearchResponse" } },
|
|
142
157
|
],
|
|
143
158
|
records: [
|
|
144
159
|
{ record: { name: { text: "Foo" } } },
|
|
145
160
|
{ record: { name: { text: "Outer" } } },
|
|
146
161
|
{ record: { name: { text: "Inner" }, recordNumber: 101 } },
|
|
162
|
+
{ record: { name: { text: "LooLoo" } } },
|
|
147
163
|
{ record: { name: { text: "Bar" } } },
|
|
164
|
+
{ record: { name: { text: "SearchRequest" } } },
|
|
165
|
+
{ record: { name: { text: "SearchResponse" } } },
|
|
148
166
|
],
|
|
149
167
|
},
|
|
150
168
|
errors: [],
|
|
@@ -362,25 +380,6 @@ describe("module set", () => {
|
|
|
362
380
|
const actual = moduleSet.parseAndResolve("path/to/module");
|
|
363
381
|
expect(actual).toMatch({ errors: [] });
|
|
364
382
|
});
|
|
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
383
|
describe("keyed arrays", () => {
|
|
385
384
|
it("works", () => {
|
|
386
385
|
const fakeFileReader = new FakeFileReader();
|
|
@@ -522,7 +521,7 @@ describe("module set", () => {
|
|
|
522
521
|
token: {
|
|
523
522
|
text: "|",
|
|
524
523
|
},
|
|
525
|
-
expected: '
|
|
524
|
+
expected: "']'",
|
|
526
525
|
},
|
|
527
526
|
],
|
|
528
527
|
});
|
|
@@ -566,7 +565,7 @@ describe("module set", () => {
|
|
|
566
565
|
token: {
|
|
567
566
|
text: "key",
|
|
568
567
|
},
|
|
569
|
-
expected: '
|
|
568
|
+
expected: "'kind'",
|
|
570
569
|
},
|
|
571
570
|
],
|
|
572
571
|
});
|
|
@@ -693,8 +692,9 @@ describe("module set", () => {
|
|
|
693
692
|
{
|
|
694
693
|
token: {
|
|
695
694
|
text: "Foo",
|
|
695
|
+
position: 18,
|
|
696
696
|
},
|
|
697
|
-
message: "Cannot reimport imported
|
|
697
|
+
message: "Cannot reimport imported record",
|
|
698
698
|
},
|
|
699
699
|
],
|
|
700
700
|
});
|
|
@@ -709,7 +709,7 @@ describe("module set", () => {
|
|
|
709
709
|
struct Bar { foo: foo.Foo; }
|
|
710
710
|
`);
|
|
711
711
|
fakeFileReader.pathToCode.set("path/to/root/path/to/module", `
|
|
712
|
-
import foo from "./bar";
|
|
712
|
+
import foo, DoesNotExist from "./bar";
|
|
713
713
|
struct Zoo { foo: foo.Foo; }
|
|
714
714
|
`);
|
|
715
715
|
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
@@ -719,8 +719,15 @@ describe("module set", () => {
|
|
|
719
719
|
{
|
|
720
720
|
token: {
|
|
721
721
|
text: "foo",
|
|
722
|
+
position: 18,
|
|
722
723
|
},
|
|
723
|
-
message: "
|
|
724
|
+
message: "Not a record",
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
token: {
|
|
728
|
+
text: "DoesNotExist",
|
|
729
|
+
},
|
|
730
|
+
message: "Not found",
|
|
724
731
|
},
|
|
725
732
|
],
|
|
726
733
|
});
|
|
@@ -746,7 +753,7 @@ describe("module set", () => {
|
|
|
746
753
|
token: {
|
|
747
754
|
text: "Foo",
|
|
748
755
|
},
|
|
749
|
-
message: "Cannot
|
|
756
|
+
message: "Cannot refer to imports of imported module",
|
|
750
757
|
},
|
|
751
758
|
],
|
|
752
759
|
});
|
|
@@ -772,7 +779,7 @@ describe("module set", () => {
|
|
|
772
779
|
token: {
|
|
773
780
|
text: "foo",
|
|
774
781
|
},
|
|
775
|
-
message: "Cannot
|
|
782
|
+
message: "Cannot refer to imports of imported module",
|
|
776
783
|
},
|
|
777
784
|
],
|
|
778
785
|
});
|
|
@@ -1326,5 +1333,565 @@ describe("module set", () => {
|
|
|
1326
1333
|
});
|
|
1327
1334
|
});
|
|
1328
1335
|
});
|
|
1336
|
+
describe("doc comment references", () => {
|
|
1337
|
+
it("resolves reference to enum field", () => {
|
|
1338
|
+
const fakeFileReader = new FakeFileReader();
|
|
1339
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1340
|
+
/// Hello [Bar.OK]
|
|
1341
|
+
struct Foo {
|
|
1342
|
+
x: int32;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
enum Bar { OK; }
|
|
1346
|
+
`);
|
|
1347
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1348
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1349
|
+
const fooRecord = actual.result?.records.find((r) => r.record?.name.text === "Foo");
|
|
1350
|
+
expect(fooRecord).toMatch({
|
|
1351
|
+
record: {
|
|
1352
|
+
name: { text: "Foo" },
|
|
1353
|
+
doc: {
|
|
1354
|
+
pieces: [
|
|
1355
|
+
{ kind: "text", text: "Hello " },
|
|
1356
|
+
{
|
|
1357
|
+
kind: "reference",
|
|
1358
|
+
nameChain: [{ text: "Bar" }, { text: "OK" }],
|
|
1359
|
+
referee: {
|
|
1360
|
+
kind: "field",
|
|
1361
|
+
field: { name: { text: "OK" } },
|
|
1362
|
+
record: { name: { text: "Bar" } },
|
|
1363
|
+
},
|
|
1364
|
+
},
|
|
1365
|
+
],
|
|
1366
|
+
},
|
|
1367
|
+
},
|
|
1368
|
+
});
|
|
1369
|
+
expect(actual.errors).toMatch([]);
|
|
1370
|
+
});
|
|
1371
|
+
it("resolves reference to sibling field", () => {
|
|
1372
|
+
const fakeFileReader = new FakeFileReader();
|
|
1373
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1374
|
+
struct Foo {
|
|
1375
|
+
x: int32;
|
|
1376
|
+
/// Must be different from [x]
|
|
1377
|
+
y: int32;
|
|
1378
|
+
}
|
|
1379
|
+
`);
|
|
1380
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1381
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1382
|
+
expect(actual).toMatch({
|
|
1383
|
+
result: {
|
|
1384
|
+
records: [
|
|
1385
|
+
{
|
|
1386
|
+
record: {
|
|
1387
|
+
fields: [
|
|
1388
|
+
{ name: { text: "x" } },
|
|
1389
|
+
{
|
|
1390
|
+
name: { text: "y" },
|
|
1391
|
+
doc: {
|
|
1392
|
+
pieces: [
|
|
1393
|
+
{ kind: "text", text: "Must be different from " },
|
|
1394
|
+
{
|
|
1395
|
+
kind: "reference",
|
|
1396
|
+
nameChain: [{ text: "x" }],
|
|
1397
|
+
referee: {
|
|
1398
|
+
kind: "field",
|
|
1399
|
+
field: { name: { text: "x" } },
|
|
1400
|
+
record: { name: { text: "Foo" } },
|
|
1401
|
+
},
|
|
1402
|
+
},
|
|
1403
|
+
],
|
|
1404
|
+
},
|
|
1405
|
+
},
|
|
1406
|
+
],
|
|
1407
|
+
},
|
|
1408
|
+
},
|
|
1409
|
+
],
|
|
1410
|
+
},
|
|
1411
|
+
errors: [],
|
|
1412
|
+
});
|
|
1413
|
+
});
|
|
1414
|
+
it("resolves reference to record", () => {
|
|
1415
|
+
const fakeFileReader = new FakeFileReader();
|
|
1416
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1417
|
+
/// See [Bar] for details
|
|
1418
|
+
struct Foo {
|
|
1419
|
+
x: int32;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
struct Bar {}
|
|
1423
|
+
`);
|
|
1424
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1425
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1426
|
+
const fooRecord = actual.result?.records.find((r) => r.record?.name.text === "Foo");
|
|
1427
|
+
expect(fooRecord).toMatch({
|
|
1428
|
+
record: {
|
|
1429
|
+
name: { text: "Foo" },
|
|
1430
|
+
doc: {
|
|
1431
|
+
pieces: [
|
|
1432
|
+
{ kind: "text", text: "See " },
|
|
1433
|
+
{
|
|
1434
|
+
kind: "reference",
|
|
1435
|
+
nameChain: [{ text: "Bar" }],
|
|
1436
|
+
referee: { kind: "record", name: { text: "Bar" } },
|
|
1437
|
+
},
|
|
1438
|
+
{ kind: "text", text: " for details" },
|
|
1439
|
+
],
|
|
1440
|
+
},
|
|
1441
|
+
},
|
|
1442
|
+
});
|
|
1443
|
+
expect(actual.errors).toMatch([]);
|
|
1444
|
+
});
|
|
1445
|
+
it("resolves reference to nested record", () => {
|
|
1446
|
+
const fakeFileReader = new FakeFileReader();
|
|
1447
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1448
|
+
/// Uses [Outer.Inner]
|
|
1449
|
+
struct Foo {
|
|
1450
|
+
x: int32;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
struct Outer {
|
|
1454
|
+
struct Inner {}
|
|
1455
|
+
}
|
|
1456
|
+
`);
|
|
1457
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1458
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1459
|
+
const fooRecord = actual.result?.records.find((r) => r.record?.name.text === "Foo");
|
|
1460
|
+
expect(fooRecord).toMatch({
|
|
1461
|
+
record: {
|
|
1462
|
+
name: { text: "Foo" },
|
|
1463
|
+
doc: {
|
|
1464
|
+
pieces: [
|
|
1465
|
+
{ kind: "text", text: "Uses " },
|
|
1466
|
+
{
|
|
1467
|
+
kind: "reference",
|
|
1468
|
+
nameChain: [{ text: "Outer" }, { text: "Inner" }],
|
|
1469
|
+
referee: { kind: "record", name: { text: "Inner" } },
|
|
1470
|
+
},
|
|
1471
|
+
],
|
|
1472
|
+
},
|
|
1473
|
+
},
|
|
1474
|
+
});
|
|
1475
|
+
expect(actual.errors).toMatch([]);
|
|
1476
|
+
});
|
|
1477
|
+
it("resolves absolute reference", () => {
|
|
1478
|
+
const fakeFileReader = new FakeFileReader();
|
|
1479
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1480
|
+
struct Outer {
|
|
1481
|
+
/// Reference to [.Bar]
|
|
1482
|
+
struct Inner {}
|
|
1483
|
+
struct Bar {}
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
struct Bar {}
|
|
1487
|
+
`);
|
|
1488
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1489
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1490
|
+
const outerRecord = actual.result?.records.find((r) => r.record?.name.text === "Outer");
|
|
1491
|
+
expect(outerRecord).toMatch({
|
|
1492
|
+
record: {
|
|
1493
|
+
name: { text: "Outer" },
|
|
1494
|
+
nestedRecords: [
|
|
1495
|
+
{
|
|
1496
|
+
name: { text: "Inner" },
|
|
1497
|
+
doc: {
|
|
1498
|
+
pieces: [
|
|
1499
|
+
{ kind: "text", text: "Reference to " },
|
|
1500
|
+
{
|
|
1501
|
+
kind: "reference",
|
|
1502
|
+
absolute: true,
|
|
1503
|
+
nameChain: [{ text: "Bar" }],
|
|
1504
|
+
referee: {
|
|
1505
|
+
kind: "record",
|
|
1506
|
+
name: { text: "Bar", colNumber: 17 },
|
|
1507
|
+
},
|
|
1508
|
+
},
|
|
1509
|
+
],
|
|
1510
|
+
},
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
name: { text: "Bar", colNumber: 19 },
|
|
1514
|
+
},
|
|
1515
|
+
],
|
|
1516
|
+
},
|
|
1517
|
+
});
|
|
1518
|
+
expect(actual.errors).toMatch([]);
|
|
1519
|
+
});
|
|
1520
|
+
it("resolves reference to method", () => {
|
|
1521
|
+
const fakeFileReader = new FakeFileReader();
|
|
1522
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1523
|
+
/// Calls [GetData]
|
|
1524
|
+
struct Foo {}
|
|
1525
|
+
|
|
1526
|
+
method GetData(Foo): Foo;
|
|
1527
|
+
`);
|
|
1528
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1529
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1530
|
+
expect(actual).toMatch({
|
|
1531
|
+
result: {
|
|
1532
|
+
records: [
|
|
1533
|
+
{
|
|
1534
|
+
record: {
|
|
1535
|
+
name: { text: "Foo" },
|
|
1536
|
+
doc: {
|
|
1537
|
+
pieces: [
|
|
1538
|
+
{ kind: "text", text: "Calls " },
|
|
1539
|
+
{
|
|
1540
|
+
kind: "reference",
|
|
1541
|
+
nameChain: [{ text: "GetData" }],
|
|
1542
|
+
referee: { kind: "method", name: { text: "GetData" } },
|
|
1543
|
+
},
|
|
1544
|
+
],
|
|
1545
|
+
},
|
|
1546
|
+
},
|
|
1547
|
+
},
|
|
1548
|
+
],
|
|
1549
|
+
},
|
|
1550
|
+
errors: [],
|
|
1551
|
+
});
|
|
1552
|
+
});
|
|
1553
|
+
it("resolves reference to constant", () => {
|
|
1554
|
+
const fakeFileReader = new FakeFileReader();
|
|
1555
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1556
|
+
/// Default is [DEFAULT_VALUE]
|
|
1557
|
+
struct Foo {
|
|
1558
|
+
x: int32;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
const DEFAULT_VALUE: int32 = 42;
|
|
1562
|
+
`);
|
|
1563
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1564
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1565
|
+
expect(actual).toMatch({
|
|
1566
|
+
result: {
|
|
1567
|
+
records: [
|
|
1568
|
+
{
|
|
1569
|
+
record: {
|
|
1570
|
+
name: { text: "Foo" },
|
|
1571
|
+
doc: {
|
|
1572
|
+
pieces: [
|
|
1573
|
+
{ kind: "text", text: "Default is " },
|
|
1574
|
+
{
|
|
1575
|
+
kind: "reference",
|
|
1576
|
+
nameChain: [{ text: "DEFAULT_VALUE" }],
|
|
1577
|
+
referee: {
|
|
1578
|
+
kind: "constant",
|
|
1579
|
+
name: { text: "DEFAULT_VALUE" },
|
|
1580
|
+
},
|
|
1581
|
+
},
|
|
1582
|
+
],
|
|
1583
|
+
},
|
|
1584
|
+
},
|
|
1585
|
+
},
|
|
1586
|
+
],
|
|
1587
|
+
},
|
|
1588
|
+
errors: [],
|
|
1589
|
+
});
|
|
1590
|
+
});
|
|
1591
|
+
it("resolves reference from field type scope", () => {
|
|
1592
|
+
const fakeFileReader = new FakeFileReader();
|
|
1593
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1594
|
+
struct Foo {
|
|
1595
|
+
/// Uses [OK] from the Bar enum
|
|
1596
|
+
bar: Bar;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
enum Bar { OK; }
|
|
1600
|
+
`);
|
|
1601
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1602
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1603
|
+
const fooRecord = actual.result?.records.find((r) => r.record?.name.text === "Foo");
|
|
1604
|
+
expect(fooRecord).toMatch({
|
|
1605
|
+
record: {
|
|
1606
|
+
name: { text: "Foo" },
|
|
1607
|
+
fields: [
|
|
1608
|
+
{
|
|
1609
|
+
name: { text: "bar" },
|
|
1610
|
+
doc: {
|
|
1611
|
+
pieces: [
|
|
1612
|
+
{ kind: "text", text: "Uses " },
|
|
1613
|
+
{
|
|
1614
|
+
kind: "reference",
|
|
1615
|
+
nameChain: [{ text: "OK" }],
|
|
1616
|
+
referee: {
|
|
1617
|
+
kind: "field",
|
|
1618
|
+
field: { name: { text: "OK" } },
|
|
1619
|
+
record: { name: { text: "Bar" } },
|
|
1620
|
+
},
|
|
1621
|
+
},
|
|
1622
|
+
{ kind: "text", text: " from the Bar enum" },
|
|
1623
|
+
],
|
|
1624
|
+
},
|
|
1625
|
+
},
|
|
1626
|
+
],
|
|
1627
|
+
},
|
|
1628
|
+
});
|
|
1629
|
+
expect(actual.errors).toMatch([]);
|
|
1630
|
+
});
|
|
1631
|
+
it("resolves reference from method request type scope", () => {
|
|
1632
|
+
const fakeFileReader = new FakeFileReader();
|
|
1633
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1634
|
+
struct Request {
|
|
1635
|
+
x: int32;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
struct Response {}
|
|
1639
|
+
|
|
1640
|
+
/// Input [x] must be positive
|
|
1641
|
+
method DoWork(Request): Response;
|
|
1642
|
+
`);
|
|
1643
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1644
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1645
|
+
expect(actual).toMatch({
|
|
1646
|
+
result: {
|
|
1647
|
+
methods: [
|
|
1648
|
+
{
|
|
1649
|
+
name: { text: "DoWork" },
|
|
1650
|
+
doc: {
|
|
1651
|
+
pieces: [
|
|
1652
|
+
{ kind: "text", text: "Input " },
|
|
1653
|
+
{
|
|
1654
|
+
kind: "reference",
|
|
1655
|
+
nameChain: [{ text: "x" }],
|
|
1656
|
+
referee: {
|
|
1657
|
+
kind: "field",
|
|
1658
|
+
field: { name: { text: "x" } },
|
|
1659
|
+
record: { name: { text: "Request" } },
|
|
1660
|
+
},
|
|
1661
|
+
},
|
|
1662
|
+
{ kind: "text", text: " must be positive" },
|
|
1663
|
+
],
|
|
1664
|
+
},
|
|
1665
|
+
},
|
|
1666
|
+
],
|
|
1667
|
+
},
|
|
1668
|
+
errors: [],
|
|
1669
|
+
});
|
|
1670
|
+
});
|
|
1671
|
+
it("resolves reference from constant type scope", () => {
|
|
1672
|
+
const fakeFileReader = new FakeFileReader();
|
|
1673
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1674
|
+
enum Status { OK; }
|
|
1675
|
+
|
|
1676
|
+
/// Default status is [OK]
|
|
1677
|
+
const DEFAULT_STATUS: Status = "OK";
|
|
1678
|
+
`);
|
|
1679
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1680
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1681
|
+
expect(actual).toMatch({
|
|
1682
|
+
result: {
|
|
1683
|
+
constants: [
|
|
1684
|
+
{
|
|
1685
|
+
name: { text: "DEFAULT_STATUS" },
|
|
1686
|
+
doc: {
|
|
1687
|
+
pieces: [
|
|
1688
|
+
{ kind: "text", text: "Default status is " },
|
|
1689
|
+
{
|
|
1690
|
+
kind: "reference",
|
|
1691
|
+
nameChain: [{ text: "OK" }],
|
|
1692
|
+
referee: {
|
|
1693
|
+
kind: "field",
|
|
1694
|
+
field: { name: { text: "OK" } },
|
|
1695
|
+
record: { name: { text: "Status" } },
|
|
1696
|
+
},
|
|
1697
|
+
},
|
|
1698
|
+
],
|
|
1699
|
+
},
|
|
1700
|
+
},
|
|
1701
|
+
],
|
|
1702
|
+
},
|
|
1703
|
+
errors: [],
|
|
1704
|
+
});
|
|
1705
|
+
});
|
|
1706
|
+
it("resolves multiple references in same doc comment", () => {
|
|
1707
|
+
const fakeFileReader = new FakeFileReader();
|
|
1708
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1709
|
+
/// Compare [Foo] and [Bar]
|
|
1710
|
+
struct Baz {}
|
|
1711
|
+
|
|
1712
|
+
struct Foo {}
|
|
1713
|
+
struct Bar {}
|
|
1714
|
+
`);
|
|
1715
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1716
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1717
|
+
const bazRecord = actual.result?.records.find((r) => r.record?.name.text === "Baz");
|
|
1718
|
+
expect(bazRecord).toMatch({
|
|
1719
|
+
record: {
|
|
1720
|
+
name: { text: "Baz" },
|
|
1721
|
+
doc: {
|
|
1722
|
+
pieces: [
|
|
1723
|
+
{ kind: "text", text: "Compare " },
|
|
1724
|
+
{
|
|
1725
|
+
kind: "reference",
|
|
1726
|
+
nameChain: [{ text: "Foo" }],
|
|
1727
|
+
referee: { kind: "record", name: { text: "Foo" } },
|
|
1728
|
+
},
|
|
1729
|
+
{ kind: "text", text: " and " },
|
|
1730
|
+
{
|
|
1731
|
+
kind: "reference",
|
|
1732
|
+
nameChain: [{ text: "Bar" }],
|
|
1733
|
+
referee: { kind: "record", name: { text: "Bar" } },
|
|
1734
|
+
},
|
|
1735
|
+
],
|
|
1736
|
+
},
|
|
1737
|
+
},
|
|
1738
|
+
});
|
|
1739
|
+
expect(actual.errors).toMatch([]);
|
|
1740
|
+
});
|
|
1741
|
+
it("resolves reference through import alias", () => {
|
|
1742
|
+
const fakeFileReader = new FakeFileReader();
|
|
1743
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1744
|
+
import * as other from "./other";
|
|
1745
|
+
|
|
1746
|
+
/// Uses [other.Foo]
|
|
1747
|
+
struct Bar {}
|
|
1748
|
+
`);
|
|
1749
|
+
fakeFileReader.pathToCode.set("path/to/root/other", `
|
|
1750
|
+
struct Foo {}
|
|
1751
|
+
`);
|
|
1752
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1753
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1754
|
+
const barRecord = actual.result?.records.find((r) => r.record?.name.text === "Bar");
|
|
1755
|
+
expect(barRecord).toMatch({
|
|
1756
|
+
record: {
|
|
1757
|
+
name: { text: "Bar" },
|
|
1758
|
+
doc: {
|
|
1759
|
+
pieces: [
|
|
1760
|
+
{ kind: "text", text: "Uses " },
|
|
1761
|
+
{
|
|
1762
|
+
kind: "reference",
|
|
1763
|
+
nameChain: [{ text: "other" }, { text: "Foo" }],
|
|
1764
|
+
referee: { kind: "record", name: { text: "Foo" } },
|
|
1765
|
+
},
|
|
1766
|
+
],
|
|
1767
|
+
},
|
|
1768
|
+
},
|
|
1769
|
+
});
|
|
1770
|
+
expect(actual.errors).toMatch([{ message: "Unused import alias" }]);
|
|
1771
|
+
});
|
|
1772
|
+
it("resolves reference through import", () => {
|
|
1773
|
+
const fakeFileReader = new FakeFileReader();
|
|
1774
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1775
|
+
import * as other from "./other";
|
|
1776
|
+
|
|
1777
|
+
/// Uses [other.Foo]
|
|
1778
|
+
struct Bar {}
|
|
1779
|
+
`);
|
|
1780
|
+
fakeFileReader.pathToCode.set("path/to/root/other", `
|
|
1781
|
+
struct Foo {}
|
|
1782
|
+
`);
|
|
1783
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1784
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1785
|
+
const barRecord = actual.result?.records.find((r) => r.record?.name.text === "Bar");
|
|
1786
|
+
expect(barRecord).toMatch({
|
|
1787
|
+
record: {
|
|
1788
|
+
name: { text: "Bar" },
|
|
1789
|
+
doc: {
|
|
1790
|
+
pieces: [
|
|
1791
|
+
{ kind: "text", text: "Uses " },
|
|
1792
|
+
{
|
|
1793
|
+
kind: "reference",
|
|
1794
|
+
nameChain: [{ text: "other" }, { text: "Foo" }],
|
|
1795
|
+
referee: { kind: "record", name: { text: "Foo" } },
|
|
1796
|
+
},
|
|
1797
|
+
],
|
|
1798
|
+
},
|
|
1799
|
+
},
|
|
1800
|
+
});
|
|
1801
|
+
expect(actual.errors).toMatch([{ message: "Unused import alias" }]);
|
|
1802
|
+
});
|
|
1803
|
+
it("reports error for unresolved reference", () => {
|
|
1804
|
+
const fakeFileReader = new FakeFileReader();
|
|
1805
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1806
|
+
/// See [NonExistent]
|
|
1807
|
+
struct Foo {}
|
|
1808
|
+
`);
|
|
1809
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1810
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1811
|
+
expect(actual).toMatch({
|
|
1812
|
+
result: {},
|
|
1813
|
+
errors: [
|
|
1814
|
+
{
|
|
1815
|
+
token: { text: "[NonExistent]" },
|
|
1816
|
+
message: "Cannot resolve reference",
|
|
1817
|
+
},
|
|
1818
|
+
],
|
|
1819
|
+
});
|
|
1820
|
+
});
|
|
1821
|
+
it("reports error for unresolved nested reference", () => {
|
|
1822
|
+
const fakeFileReader = new FakeFileReader();
|
|
1823
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1824
|
+
/// See [Bar.NonExistent]
|
|
1825
|
+
struct Foo {}
|
|
1826
|
+
|
|
1827
|
+
struct Bar {}
|
|
1828
|
+
`);
|
|
1829
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1830
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1831
|
+
expect(actual).toMatch({
|
|
1832
|
+
result: {},
|
|
1833
|
+
errors: [
|
|
1834
|
+
{
|
|
1835
|
+
token: { text: "[Bar.NonExistent]" },
|
|
1836
|
+
message: "Cannot resolve reference",
|
|
1837
|
+
},
|
|
1838
|
+
],
|
|
1839
|
+
});
|
|
1840
|
+
});
|
|
1841
|
+
it("prioritizes nested scope over module scope", () => {
|
|
1842
|
+
const fakeFileReader = new FakeFileReader();
|
|
1843
|
+
fakeFileReader.pathToCode.set("path/to/root/module", `
|
|
1844
|
+
struct Outer {
|
|
1845
|
+
struct Inner {
|
|
1846
|
+
/// Reference to [Foo] (nested)
|
|
1847
|
+
x: int32;
|
|
1848
|
+
}
|
|
1849
|
+
struct Foo {}
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
struct Foo {}
|
|
1853
|
+
`);
|
|
1854
|
+
const moduleSet = ModuleSet.create(fakeFileReader, "path/to/root");
|
|
1855
|
+
const actual = moduleSet.parseAndResolve("module");
|
|
1856
|
+
// Find the Outer record
|
|
1857
|
+
const outerRecord = actual.result?.records.find((r) => r.record.name.text === "Outer");
|
|
1858
|
+
expect(outerRecord).toMatch({
|
|
1859
|
+
record: {
|
|
1860
|
+
name: { text: "Outer" },
|
|
1861
|
+
nestedRecords: [
|
|
1862
|
+
{
|
|
1863
|
+
name: { text: "Inner" },
|
|
1864
|
+
fields: [
|
|
1865
|
+
{
|
|
1866
|
+
name: { text: "x" },
|
|
1867
|
+
doc: {
|
|
1868
|
+
pieces: [
|
|
1869
|
+
{ kind: "text", text: "Reference to " },
|
|
1870
|
+
{
|
|
1871
|
+
kind: "reference",
|
|
1872
|
+
nameChain: [{ text: "Foo" }],
|
|
1873
|
+
// Should resolve to Outer.Foo, not the top-level Foo
|
|
1874
|
+
referee: {
|
|
1875
|
+
kind: "record",
|
|
1876
|
+
name: { text: "Foo" },
|
|
1877
|
+
},
|
|
1878
|
+
},
|
|
1879
|
+
{ kind: "text", text: " (nested)" },
|
|
1880
|
+
],
|
|
1881
|
+
},
|
|
1882
|
+
},
|
|
1883
|
+
],
|
|
1884
|
+
},
|
|
1885
|
+
{
|
|
1886
|
+
name: { text: "Foo" },
|
|
1887
|
+
},
|
|
1888
|
+
],
|
|
1889
|
+
},
|
|
1890
|
+
});
|
|
1891
|
+
expect(actual).toMatch({
|
|
1892
|
+
errors: [],
|
|
1893
|
+
});
|
|
1894
|
+
});
|
|
1895
|
+
});
|
|
1329
1896
|
});
|
|
1330
1897
|
//# sourceMappingURL=module_set.test.js.map
|