@alloy-js/core 0.20.0-dev.3 → 0.20.0-dev.6

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 (137) hide show
  1. package/dist/src/binder.d.ts +62 -38
  2. package/dist/src/binder.d.ts.map +1 -1
  3. package/dist/src/binder.js +214 -173
  4. package/dist/src/components/Declaration.d.ts +2 -2
  5. package/dist/src/components/Declaration.d.ts.map +1 -1
  6. package/dist/src/components/Declaration.js +8 -2
  7. package/dist/src/components/MemberDeclaration.d.ts +2 -2
  8. package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
  9. package/dist/src/components/MemberDeclaration.js +9 -5
  10. package/dist/src/components/MemberScope.d.ts +30 -13
  11. package/dist/src/components/MemberScope.d.ts.map +1 -1
  12. package/dist/src/components/MemberScope.js +37 -15
  13. package/dist/src/components/Output.d.ts.map +1 -1
  14. package/dist/src/components/Output.js +2 -5
  15. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  16. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  17. package/dist/src/components/Scope.d.ts +5 -5
  18. package/dist/src/components/Scope.d.ts.map +1 -1
  19. package/dist/src/components/Scope.js +9 -5
  20. package/dist/src/context/member-scope.d.ts +7 -8
  21. package/dist/src/context/member-scope.d.ts.map +1 -1
  22. package/dist/src/context/member-scope.js +5 -5
  23. package/dist/src/context/name-policy.d.ts.map +1 -1
  24. package/dist/src/context/name-policy.js +3 -0
  25. package/dist/src/context/scope.d.ts +1 -0
  26. package/dist/src/context/scope.d.ts.map +1 -1
  27. package/dist/src/context/scope.js +7 -0
  28. package/dist/src/inspect.browser.d.ts +5 -0
  29. package/dist/src/inspect.browser.d.ts.map +1 -0
  30. package/dist/src/inspect.browser.js +5 -0
  31. package/dist/src/inspect.d.ts +2 -0
  32. package/dist/src/inspect.d.ts.map +1 -0
  33. package/dist/src/inspect.js +1 -0
  34. package/dist/src/name-policy.d.ts +11 -0
  35. package/dist/src/name-policy.d.ts.map +1 -1
  36. package/dist/src/name-policy.js +3 -0
  37. package/dist/src/reactive-union-set.d.ts.map +1 -1
  38. package/dist/src/reactive-union-set.js +12 -8
  39. package/dist/src/refkey.d.ts +39 -3
  40. package/dist/src/refkey.d.ts.map +1 -1
  41. package/dist/src/refkey.js +52 -8
  42. package/dist/src/symbols/basic-scope.d.ts +14 -0
  43. package/dist/src/symbols/basic-scope.d.ts.map +1 -0
  44. package/dist/src/symbols/basic-scope.js +20 -0
  45. package/dist/src/symbols/basic-symbol.d.ts +19 -0
  46. package/dist/src/symbols/basic-symbol.d.ts.map +1 -0
  47. package/dist/src/symbols/basic-symbol.js +28 -0
  48. package/dist/src/symbols/index.d.ts +3 -1
  49. package/dist/src/symbols/index.d.ts.map +1 -1
  50. package/dist/src/symbols/index.js +3 -1
  51. package/dist/src/symbols/output-scope.d.ts +70 -41
  52. package/dist/src/symbols/output-scope.d.ts.map +1 -1
  53. package/dist/src/symbols/output-scope.js +98 -130
  54. package/dist/src/symbols/output-space.d.ts +25 -0
  55. package/dist/src/symbols/output-space.d.ts.map +1 -0
  56. package/dist/src/symbols/output-space.js +35 -0
  57. package/dist/src/symbols/output-symbol.d.ts +213 -37
  58. package/dist/src/symbols/output-symbol.d.ts.map +1 -1
  59. package/dist/src/symbols/output-symbol.js +323 -203
  60. package/dist/src/symbols/symbol-flow.d.ts +1 -1
  61. package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
  62. package/dist/src/symbols/symbol-flow.js +22 -7
  63. package/dist/src/symbols/symbol-slot.d.ts +27 -9
  64. package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
  65. package/dist/src/symbols/symbol-slot.js +20 -4
  66. package/dist/src/symbols/symbol-table.d.ts +19 -8
  67. package/dist/src/symbols/symbol-table.d.ts.map +1 -1
  68. package/dist/src/symbols/symbol-table.js +65 -16
  69. package/dist/src/tracer.d.ts +15 -3
  70. package/dist/src/tracer.d.ts.map +1 -1
  71. package/dist/src/tracer.js +39 -63
  72. package/dist/src/utils.d.ts +1 -1
  73. package/dist/src/utils.d.ts.map +1 -1
  74. package/dist/src/utils.js +4 -4
  75. package/dist/src/write-output.d.ts +1 -1
  76. package/dist/src/write-output.d.ts.map +1 -1
  77. package/dist/src/write-output.js +31 -37
  78. package/dist/test/components/declaration.test.js +9 -14
  79. package/dist/test/components/reference-or-content.test.js +2 -2
  80. package/dist/test/symbols/output-scope.test.js +33 -198
  81. package/dist/test/symbols/output-symbol.test.js +139 -385
  82. package/dist/test/symbols/resolution.test.js +431 -114
  83. package/dist/test/symbols/symbol-table.test.d.ts +2 -0
  84. package/dist/test/symbols/symbol-table.test.d.ts.map +1 -0
  85. package/dist/test/symbols/symbol-table.test.js +14 -0
  86. package/dist/test/symbols/utils.d.ts +10 -24
  87. package/dist/test/symbols/utils.d.ts.map +1 -1
  88. package/dist/test/symbols/utils.js +23 -45
  89. package/dist/tsconfig.tsbuildinfo +1 -1
  90. package/package.json +4 -2
  91. package/src/binder.ts +348 -273
  92. package/src/components/Declaration.tsx +13 -3
  93. package/src/components/MemberDeclaration.tsx +15 -8
  94. package/src/components/MemberScope.tsx +61 -20
  95. package/src/components/Output.tsx +0 -4
  96. package/src/components/Scope.tsx +16 -9
  97. package/src/context/member-scope.ts +10 -10
  98. package/src/context/name-policy.ts +3 -0
  99. package/src/context/scope.ts +9 -0
  100. package/src/inspect.browser.ts +6 -0
  101. package/src/inspect.ts +1 -0
  102. package/src/name-policy.ts +14 -0
  103. package/src/reactive-union-set.ts +14 -8
  104. package/src/refkey.ts +88 -14
  105. package/src/symbols/basic-scope.ts +23 -0
  106. package/src/symbols/basic-symbol.ts +32 -0
  107. package/src/symbols/index.ts +3 -1
  108. package/src/symbols/output-scope.ts +131 -170
  109. package/src/symbols/output-space.ts +49 -0
  110. package/src/symbols/output-symbol.ts +434 -258
  111. package/src/symbols/symbol-flow.ts +38 -9
  112. package/src/symbols/symbol-slot.tsx +46 -8
  113. package/src/symbols/symbol-table.ts +95 -21
  114. package/src/tracer.ts +53 -83
  115. package/src/utils.tsx +4 -4
  116. package/src/write-output.ts +33 -45
  117. package/temp/api.json +5551 -3066
  118. package/test/components/declaration.test.tsx +6 -19
  119. package/test/components/reference-or-content.test.tsx +2 -2
  120. package/test/symbols/output-scope.test.ts +33 -125
  121. package/test/symbols/output-symbol.test.ts +128 -348
  122. package/test/symbols/resolution.test.ts +530 -117
  123. package/test/symbols/symbol-table.test.ts +15 -0
  124. package/test/symbols/utils.ts +38 -74
  125. package/tsdoc.json +4 -0
  126. package/dist/src/slot.d.ts +0 -15
  127. package/dist/src/slot.d.ts.map +0 -1
  128. package/dist/src/slot.js +0 -50
  129. package/dist/src/symbols/flags.d.ts +0 -70
  130. package/dist/src/symbols/flags.d.ts.map +0 -1
  131. package/dist/src/symbols/flags.js +0 -72
  132. package/dist/test/components/slot.test.d.ts +0 -2
  133. package/dist/test/components/slot.test.d.ts.map +0 -1
  134. package/dist/test/components/slot.test.js +0 -134
  135. package/src/slot.ts +0 -89
  136. package/src/symbols/flags.ts +0 -82
  137. package/test/components/slot.test.tsx +0 -174
@@ -1,141 +1,458 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { createOutputBinder, refkey } from "../../src/index.browser.js";
2
+ import { createOutputBinder } from "../../src/binder.js";
3
+ import { memberRefkey, refkey } from "../../src/refkey.js";
3
4
  import { flushJobs } from "../../src/scheduler.js";
4
- import { OutputSymbolFlags } from "../../src/symbols/flags.js";
5
- import { OutputSymbol } from "../../src/symbols/output-symbol.js";
6
- import { createScopeTree } from "./utils.js";
7
- describe("Symbol name resolution", () => {
8
- it("resolves static symbols", () => {
5
+ import { BasicScope } from "../../src/symbols/basic-scope.js";
6
+ import { BasicSymbol } from "../../src/symbols/basic-symbol.js";
7
+ import { binder, createScope, createSymbol } from "./utils.js";
8
+ describe("dynamic refkey resolution", () => {
9
+ it("resolves symbols by refkey when symbol is added later", () => {
10
+ const key = refkey();
9
11
  const binder = createOutputBinder();
10
- const {
11
- symbols: {
12
- static: staticSym
13
- }
14
- } = createScopeTree(binder, {
15
- root: {
16
- symbols: {
17
- root: {
18
- flags: OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer,
19
- staticMembers: {
20
- static: {
21
- flags: OutputSymbolFlags.StaticMember
22
- }
23
- }
24
- }
25
- }
26
- }
27
- });
28
- const result = binder.resolveFQN("root.root.static");
29
- expect(result.value).toEqual(staticSym);
30
- });
31
- it("resolves static symbols that are added later", () => {
12
+ const scope = new BasicScope("global", undefined);
13
+ const resolvedSym = binder.resolveDeclarationByKey(undefined, key);
14
+ const sym = new BasicSymbol("foo", scope.symbols, {
15
+ binder,
16
+ refkeys: [key]
17
+ });
18
+ expect(resolvedSym.value?.symbol).toBe(sym);
19
+ });
20
+ it("handles deleted symbols by updating resolutions", () => {
21
+ const key = refkey();
32
22
  const binder = createOutputBinder();
33
- const result = binder.resolveFQN("root.root.static");
34
- expect(result.value).toBeUndefined();
35
- const {
36
- symbols: {
37
- static: staticSym
38
- }
39
- } = createScopeTree(binder, {
40
- root: {
41
- symbols: {
42
- root: {
43
- flags: OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer,
44
- staticMembers: {
45
- static: {
46
- flags: OutputSymbolFlags.StaticMember
47
- }
48
- }
49
- }
50
- }
51
- }
52
- });
53
- expect(result.value).toEqual(staticSym);
54
- });
55
- it("resolves instance symbols", () => {
23
+ const resolvedSym = binder.resolveDeclarationByKey(undefined, key);
24
+ const scope = new BasicScope("global", undefined);
25
+ const sym = new BasicSymbol("foo", scope.symbols, {
26
+ binder,
27
+ refkeys: [key]
28
+ });
29
+ flushJobs();
30
+ expect(resolvedSym.value?.symbol).toBe(sym);
31
+ sym.delete();
32
+ flushJobs();
33
+ expect(resolvedSym.value).toBe(undefined);
34
+ });
35
+ });
36
+ describe("resolving lexical declarations by refkey", () => {
37
+ it("from the same scope", () => {
38
+ const key = refkey();
56
39
  const binder = createOutputBinder();
57
- const {
58
- symbols: {
59
- instance
60
- }
61
- } = createScopeTree(binder, {
62
- root: {
63
- symbols: {
64
- root: {
65
- flags: OutputSymbolFlags.InstanceMemberContainer,
66
- instanceMembers: {
67
- instance: {
68
- flags: OutputSymbolFlags.InstanceMember
69
- }
70
- }
71
- }
72
- }
73
- }
74
- });
75
- const result = binder.resolveFQN("root.root#instance");
76
- expect(result.value).toEqual(instance);
77
- });
78
- it("resolves instance symbols that are added later", () => {
40
+ const scope = new BasicScope("global", undefined);
41
+ const sym = new BasicSymbol("foo", scope.symbols, {
42
+ binder,
43
+ refkeys: [key]
44
+ });
45
+ const result = binder.resolveDeclarationByKey(scope, key).value;
46
+ expect(result.symbol).toBe(sym);
47
+ expect(result.commonScope).toBe(scope);
48
+ expect(result.lexicalDeclaration).toBe(sym);
49
+ expect(result.pathDown).toEqual([]);
50
+ expect(result.pathUp).toEqual([]);
51
+ expect(result.memberPath).toEqual([]);
52
+ expect(result.fullReferencePath).toEqual([scope]);
53
+ expect(result.fullSymbolPath).toEqual([scope]);
54
+ });
55
+ it("from a different scope for the same member", () => {
56
+ const key = refkey();
79
57
  const binder = createOutputBinder();
80
- const result = binder.resolveFQN("root.root#instance");
81
- expect(result.value).toBeUndefined();
82
- const {
83
- symbols: {
84
- instance
85
- }
86
- } = createScopeTree(binder, {
87
- root: {
88
- symbols: {
89
- root: {
90
- flags: OutputSymbolFlags.InstanceMemberContainer,
91
- instanceMembers: {
92
- instance: {
93
- flags: OutputSymbolFlags.InstanceMember
94
- }
95
- }
96
- }
97
- }
98
- }
99
- });
100
- expect(result.value).toEqual(instance);
58
+ const globalSym = new BasicSymbol("global", undefined, {
59
+ binder
60
+ });
61
+ const scope = new BasicScope("global", undefined, {
62
+ binder,
63
+ ownerSymbol: globalSym
64
+ });
65
+ const sym = new BasicSymbol("foo", scope.symbols, {
66
+ binder,
67
+ refkeys: [key]
68
+ });
69
+ const resolveScope = new BasicScope("other global", undefined, {
70
+ binder,
71
+ ownerSymbol: globalSym
72
+ });
73
+ const result = binder.resolveDeclarationByKey(resolveScope, key).value;
74
+ expect(result.symbol).toBe(sym);
75
+ expect(result.commonScope).toBe(resolveScope);
76
+ expect(result.lexicalDeclaration).toBe(sym);
77
+ expect(result.pathDown).toEqual([]);
78
+ expect(result.pathUp).toEqual([]);
79
+ expect(result.memberPath).toEqual([]);
80
+ expect(result.fullReferencePath).toEqual([scope]);
81
+ expect(result.fullSymbolPath).toEqual([scope]);
82
+ });
83
+ it("from a parent scope", () => {
84
+ const key = refkey();
85
+ const binder = createOutputBinder();
86
+ const scope = new BasicScope("global", undefined);
87
+ const childScope = new BasicScope("child", scope);
88
+ const sym = new BasicSymbol("foo", childScope.symbols, {
89
+ binder,
90
+ refkeys: [key]
91
+ });
92
+ const result = binder.resolveDeclarationByKey(scope, key).value;
93
+ expect(result.symbol).toBe(sym);
94
+ expect(result.commonScope).toBe(scope);
95
+ expect(result.lexicalDeclaration).toBe(sym);
96
+ expect(result.pathDown).toEqual([childScope]);
97
+ expect(result.pathUp).toEqual([]);
98
+ expect(result.memberPath).toEqual([]);
99
+ expect(result.fullReferencePath).toEqual([scope]);
100
+ expect(result.fullSymbolPath).toEqual([scope, childScope]);
101
101
  });
102
+ it("from a parent scope for the same member", () => {
103
+ const key = refkey();
104
+ const binder = createOutputBinder();
105
+ const globalSym = new BasicSymbol("global", undefined, {
106
+ binder
107
+ });
108
+ const scope = new BasicScope("global", undefined, {
109
+ ownerSymbol: globalSym
110
+ });
111
+ const childScope = new BasicScope("child", scope);
112
+ const sym = new BasicSymbol("foo", childScope.symbols, {
113
+ binder,
114
+ refkeys: [key]
115
+ });
116
+ const referenceScope = new BasicScope("otherGlobal global", undefined, {
117
+ ownerSymbol: globalSym
118
+ });
119
+ const result = binder.resolveDeclarationByKey(referenceScope, key).value;
120
+ expect(result.symbol).toBe(sym);
121
+ expect(result.commonScope).toBe(referenceScope);
122
+ expect(result.lexicalDeclaration).toBe(sym);
123
+ expect(result.pathDown).toEqual([childScope]);
124
+ expect(result.pathUp).toEqual([]);
125
+ expect(result.memberPath).toEqual([]);
126
+ expect(result.fullReferencePath).toEqual([scope]);
127
+ expect(result.fullSymbolPath).toEqual([scope, childScope]);
128
+ });
129
+ it("from a child scope", () => {
130
+ const key = refkey();
131
+ const binder = createOutputBinder();
132
+ const scope = new BasicScope("global", undefined);
133
+ const childScope = new BasicScope("child", scope);
134
+ const sym = new BasicSymbol("foo", scope.symbols, {
135
+ binder,
136
+ refkeys: [key]
137
+ });
138
+ const result = binder.resolveDeclarationByKey(childScope, key).value;
139
+ expect(result.symbol).toBe(sym);
140
+ expect(result.lexicalDeclaration).toBe(sym);
141
+ expect(result.commonScope).toBe(scope);
142
+ expect(result.pathDown).toEqual([]);
143
+ expect(result.pathUp).toEqual([childScope]);
144
+ expect(result.memberPath).toEqual([]);
145
+ expect(result.fullReferencePath).toEqual([scope, childScope]);
146
+ expect(result.fullSymbolPath).toEqual([scope]);
147
+ });
148
+ it("from a different child scope for the same member", () => {
149
+ const key = refkey();
150
+ const binder = createOutputBinder();
151
+ const globalSym = new BasicSymbol("global", undefined, {
152
+ binder
153
+ });
154
+ const scope = new BasicScope("global", undefined, {
155
+ ownerSymbol: globalSym
156
+ });
157
+ const otherGlobalScope = new BasicScope("other global", undefined, {
158
+ ownerSymbol: globalSym
159
+ });
160
+ const childMember = new BasicSymbol("child", scope.symbols);
161
+ const childScope = new BasicScope("child", otherGlobalScope, {
162
+ ownerSymbol: childMember
163
+ });
164
+ const sym = new BasicSymbol("foo", scope.symbols, {
165
+ binder,
166
+ refkeys: [key]
167
+ });
168
+ const result = binder.resolveDeclarationByKey(childScope, key).value;
169
+ expect(result.symbol).toBe(sym);
170
+ expect(result.lexicalDeclaration).toBe(sym);
171
+ expect(result.commonScope).toBe(otherGlobalScope);
172
+ expect(result.pathDown).toEqual([]);
173
+ expect(result.pathUp).toEqual([childScope]);
174
+ expect(result.memberPath).toEqual([]);
175
+ expect(result.fullReferencePath).toEqual([scope, childScope]);
176
+ expect(result.fullSymbolPath).toEqual([scope]);
177
+ });
178
+ it("from a different child scope for the same member with a different root scope", () => {
179
+ const key = refkey();
180
+ const binder = createOutputBinder();
181
+ const rootRefScope = new BasicScope("root", undefined, {
182
+ binder
183
+ });
184
+ const globalSym = new BasicSymbol("global", undefined, {
185
+ binder
186
+ });
187
+ const scope = new BasicScope("global", undefined, {
188
+ ownerSymbol: globalSym
189
+ });
190
+ const otherGlobalScope = new BasicScope("other global", rootRefScope, {
191
+ ownerSymbol: globalSym
192
+ });
193
+ const childMember = new BasicSymbol("child", scope.symbols);
194
+ const childScope = new BasicScope("child", otherGlobalScope, {
195
+ ownerSymbol: childMember
196
+ });
197
+ const sym = new BasicSymbol("foo", scope.symbols, {
198
+ binder,
199
+ refkeys: [key]
200
+ });
201
+ const result = binder.resolveDeclarationByKey(childScope, key).value;
202
+ expect(result.symbol).toBe(sym);
203
+ expect(result.lexicalDeclaration).toBe(sym);
204
+ expect(result.commonScope).toBe(otherGlobalScope);
205
+ expect(result.pathDown).toEqual([]);
206
+ expect(result.pathUp).toEqual([childScope]);
207
+ expect(result.memberPath).toEqual([]);
208
+ expect(result.fullReferencePath).toEqual([rootRefScope, scope, childScope]);
209
+ expect(result.fullSymbolPath).toEqual([rootRefScope, scope]);
210
+ });
211
+ it("from a parallel scope", () => {
212
+ const key = refkey();
213
+ const binder = createOutputBinder();
214
+ const scope = new BasicScope("global", undefined);
215
+ const childScope1 = new BasicScope("child", scope);
216
+ const childScope2 = new BasicScope("child2", scope);
217
+ const sym = new BasicSymbol("foo", childScope1.symbols, {
218
+ binder,
219
+ refkeys: [key]
220
+ });
221
+ const result = binder.resolveDeclarationByKey(childScope2, key).value;
222
+ expect(result.symbol).toBe(sym);
223
+ expect(result.lexicalDeclaration).toBe(sym);
224
+ expect(result.pathDown).toEqual([childScope1]);
225
+ expect(result.pathUp).toEqual([childScope2]);
226
+ expect(result.commonScope).toBe(scope);
227
+ expect(result.memberPath).toEqual([]);
228
+ expect(result.fullReferencePath).toEqual([scope, childScope2]);
229
+ expect(result.fullSymbolPath).toEqual([scope, childScope1]);
230
+ });
231
+ it("from a member scope", () => {
232
+ const key = refkey();
233
+ const binder = createOutputBinder();
234
+ const globalScope = new BasicScope("global", undefined, {
235
+ binder
236
+ });
237
+ const object = new BasicSymbol("object", globalScope.symbols, {
238
+ binder,
239
+ refkeys: key
240
+ });
241
+ const memberScope = new BasicScope("object members", globalScope, {
242
+ binder,
243
+ ownerSymbol: object
244
+ });
245
+ const result = binder.resolveDeclarationByKey(memberScope, key).value;
246
+ expect(result.symbol).toBe(object);
247
+ expect(result.lexicalDeclaration).toBe(object);
248
+ expect(result.commonScope).toBe(globalScope);
249
+ expect(result.pathDown).toEqual([]);
250
+ expect(result.pathUp).toEqual([memberScope]);
251
+ expect(result.memberPath).toEqual([]);
252
+ expect(result.fullReferencePath).toEqual([globalScope, memberScope]);
253
+ expect(result.fullSymbolPath).toEqual([globalScope]);
254
+ });
255
+ it("from another scope for the same member", () => {});
102
256
  });
103
- describe("refkey resolution", () => {
104
- it("resolves existing symbols by refkey", () => {
257
+ describe("resolving members by refkey", () => {
258
+ it("simple member", () => {
105
259
  const key = refkey();
106
260
  const binder = createOutputBinder();
107
- const sym = new OutputSymbol("foo", {
261
+ const globalScope = new BasicScope("global", undefined, {
262
+ binder
263
+ });
264
+ const foo = new BasicSymbol("foo", globalScope.symbols, {
265
+ binder
266
+ });
267
+ const bar = new BasicSymbol("bar", foo.staticMembers, {
108
268
  binder,
109
- scope: binder.globalScope,
110
269
  refkeys: [key]
111
270
  });
112
- const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
113
- expect(resolvedSym.value?.targetDeclaration).toBe(sym);
271
+ const result = binder.resolveDeclarationByKey(globalScope, key).value;
272
+
273
+ // we successfully resolve the symbol, so:
274
+ expect(result.symbol).toBe(bar);
275
+
276
+ // the member is off of a declaration in our current scope, so:
277
+ expect(result.commonScope).toBe(globalScope);
278
+ expect(result.pathUp.length).toBe(0);
279
+ expect(result.pathDown.length).toBe(0);
280
+
281
+ // the declaration symbol carrying the resolved member is:
282
+ expect(result.lexicalDeclaration).toBe(foo);
283
+
284
+ // the path to the resolved symbol is
285
+ expect(result.memberPath).toEqual([bar]);
286
+ expect(result.fullReferencePath).toEqual([globalScope]);
287
+ expect(result.fullSymbolPath).toEqual([globalScope]);
114
288
  });
115
- it("resolves symbols by refkey when symbol is added later", () => {
289
+ it("nested members", () => {
116
290
  const key = refkey();
117
291
  const binder = createOutputBinder();
118
- const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
119
- const sym = new OutputSymbol("foo", {
292
+ const globalScope = new BasicScope("global", undefined, {
293
+ binder
294
+ });
295
+ const foo = new BasicSymbol("foo", globalScope.symbols, {
296
+ binder
297
+ });
298
+ const bar = new BasicSymbol("bar", foo.staticMembers, {
299
+ binder
300
+ });
301
+ const baz = new BasicSymbol("baz", bar.staticMembers, {
120
302
  binder,
121
- scope: binder.globalScope,
122
303
  refkeys: [key]
123
304
  });
124
- expect(resolvedSym.value?.targetDeclaration).toBe(sym);
305
+ const result = binder.resolveDeclarationByKey(globalScope, key).value;
306
+ expect(result.symbol).toBe(baz);
307
+ expect(result.commonScope).toBe(globalScope);
308
+ expect(result.pathUp.length).toBe(0);
309
+ expect(result.pathDown.length).toBe(0);
310
+ expect(result.lexicalDeclaration).toBe(foo);
311
+ expect(result.memberPath).toEqual([bar, baz]);
312
+ expect(result.fullReferencePath).toEqual([globalScope]);
313
+ expect(result.fullSymbolPath).toEqual([globalScope]);
125
314
  });
126
- it("handles deleted symbols by updating resolutions", () => {
315
+ it("nested members, while declaring a neighboring member", () => {
127
316
  const key = refkey();
128
317
  const binder = createOutputBinder();
129
- const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
130
- const sym = new OutputSymbol("foo", {
318
+ const globalScope = new BasicScope("global", undefined, {
319
+ binder
320
+ });
321
+ const foo = new BasicSymbol("foo", globalScope.symbols, {
322
+ binder
323
+ });
324
+ const fooMemberScope = new BasicScope("foo members", globalScope, {
325
+ ownerSymbol: foo
326
+ });
327
+ const bar = new BasicSymbol("bar", foo.staticMembers, {
328
+ binder
329
+ });
330
+ const barMemberScope = new BasicScope("bar members", fooMemberScope, {
331
+ ownerSymbol: bar
332
+ });
333
+ const baz = new BasicSymbol("baz", bar.staticMembers, {
131
334
  binder,
132
- scope: binder.globalScope,
133
335
  refkeys: [key]
134
336
  });
135
- flushJobs();
136
- expect(resolvedSym.value?.targetDeclaration).toBe(sym);
137
- sym.delete();
138
- flushJobs();
139
- expect(resolvedSym.value).toBe(undefined);
337
+ const result = binder.resolveDeclarationByKey(barMemberScope, key).value;
338
+ expect(result.symbol).toBe(baz);
339
+ expect(result.commonScope).toBe(barMemberScope);
340
+ expect(result.pathUp.length).toBe(0);
341
+ expect(result.pathDown.length).toBe(0);
342
+ expect(result.lexicalDeclaration).toBe(baz);
343
+ expect(result.memberPath).toEqual([]);
344
+ expect(result.fullReferencePath).toEqual([globalScope, fooMemberScope, barMemberScope]);
345
+ expect(result.fullSymbolPath).toEqual([globalScope, fooMemberScope, barMemberScope]);
346
+ });
347
+ it("nested members, while declaring a neighboring nested member", () => {
348
+ const globalScope = createScope("global");
349
+ const [foo] = createSymbol("foo", globalScope);
350
+ const fooMemberScope = createScope("foo members", globalScope, {
351
+ ownerSymbol: foo
352
+ });
353
+ const [bar] = createSymbol("bar", foo.staticMembers);
354
+ const barMemberScope = createScope("bar members", fooMemberScope, {
355
+ ownerSymbol: bar
356
+ });
357
+ const [baz, bazKey] = createSymbol("baz", bar.staticMembers);
358
+ const bazMemberScope = createScope("baz members", barMemberScope, {
359
+ ownerSymbol: baz
360
+ });
361
+ createSymbol("otherBaz", bar.staticMembers);
362
+ const result = binder.resolveDeclarationByKey(bazMemberScope, bazKey).value;
363
+ expect(result.symbol).toBe(baz);
364
+ expect(result.commonScope).toBe(barMemberScope);
365
+ expect(result.pathUp).toEqual([bazMemberScope]);
366
+ expect(result.pathDown.length).toBe(0);
367
+ expect(result.lexicalDeclaration).toBe(baz);
368
+ expect(result.memberPath).toEqual([]);
369
+ expect(result.fullReferencePath).toEqual([globalScope, fooMemberScope, barMemberScope, bazMemberScope]);
370
+ expect(result.fullSymbolPath).toEqual([globalScope, fooMemberScope, barMemberScope]);
371
+ });
372
+ });
373
+ describe("resolving type members by refkey", () => {
374
+ it("simple member", () => {
375
+ const globalScope = createScope("global");
376
+ const [typeSymbol, typeKey] = createSymbol("MyType", globalScope);
377
+ const [staticProp, staticKey] = createSymbol("staticProp", typeSymbol.staticMembers);
378
+
379
+ // resolve a member of type
380
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(typeKey, staticKey)).value;
381
+ expect(result.symbol).toBe(staticProp);
382
+ expect(result.lexicalDeclaration).toBe(typeSymbol);
383
+ expect(result.memberPath).toEqual([staticProp]);
384
+ });
385
+ it("nested member", () => {
386
+ const globalScope = createScope("global");
387
+ const [typeSymbol, typeKey] = createSymbol("MyType", globalScope);
388
+ const [staticProp, staticPropKey] = createSymbol("staticProp", typeSymbol.staticMembers);
389
+ const [nestedProp, nestedKey] = createSymbol("nestedProp", staticProp.staticMembers);
390
+
391
+ // resolve a member of type directly
392
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(staticPropKey, nestedKey)).value;
393
+ expect(result.symbol).toBe(nestedProp);
394
+ expect(result.lexicalDeclaration).toBe(typeSymbol);
395
+ expect(result.memberPath).toEqual([staticProp, nestedProp]);
396
+
397
+ // resolve from a member refkey
398
+ const result2 = binder.resolveDeclarationByKey(globalScope, memberRefkey(memberRefkey(typeKey, staticPropKey), nestedKey)).value;
399
+ expect(result2.symbol).toBe(nestedProp);
400
+ expect(result2.lexicalDeclaration).toBe(typeSymbol);
401
+ expect(result2.memberPath).toEqual([staticProp, nestedProp]);
402
+ });
403
+ it("member of type", () => {
404
+ const globalScope = createScope("global");
405
+ const [typeSymbol] = createSymbol("MyType", globalScope);
406
+ const [staticProp, staticKey] = createSymbol("staticProp", typeSymbol.staticMembers);
407
+ const [value, valueKey] = createSymbol("myValue", globalScope, {
408
+ type: typeSymbol
409
+ });
410
+
411
+ // resolve a member of type
412
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(valueKey, staticKey)).value;
413
+ expect(result.symbol).toBe(staticProp);
414
+ expect(result.lexicalDeclaration).toBe(value);
415
+ expect(result.memberPath).toEqual([staticProp]);
416
+ });
417
+ it("nested member of type", () => {
418
+ const globalScope = createScope("global");
419
+ const [typeSymbol] = createSymbol("MyType", globalScope);
420
+ const [staticProp, staticKey] = createSymbol("staticProp", typeSymbol.staticMembers);
421
+ const [nestedProp, nestedKey] = createSymbol("nestedProp", staticProp.staticMembers);
422
+ const [value, valueKey] = createSymbol("myValue", globalScope, {
423
+ type: typeSymbol
424
+ });
425
+
426
+ // resolve a member of type
427
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(memberRefkey(valueKey, staticKey), nestedKey)).value;
428
+ expect(result.symbol).toBe(nestedProp);
429
+ expect(result.lexicalDeclaration).toBe(value);
430
+ expect(result.memberPath).toEqual([staticProp, nestedProp]);
431
+ });
432
+ it("nested member of nested type", () => {
433
+ const globalScope = createScope("global");
434
+ const [typeSymbol] = createSymbol("MyType", globalScope);
435
+ const [staticProp, staticKey] = createSymbol("staticProp", typeSymbol.staticMembers);
436
+ const [nestedProp, nestedKey] = createSymbol("nestedProp", staticProp.staticMembers);
437
+ const [value, valueKey] = createSymbol("myValue", globalScope);
438
+ const [regularProp, regularPropKey] = createSymbol("regularProp", value.staticMembers, {
439
+ type: typeSymbol
440
+ });
441
+
442
+ // resolve a member of type
443
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(memberRefkey(memberRefkey(valueKey, regularPropKey), staticKey), nestedKey)).value;
444
+ expect(result.symbol).toBe(nestedProp);
445
+ expect(result.lexicalDeclaration).toBe(value);
446
+ expect(result.memberPath).toEqual([regularProp, staticProp, nestedProp]);
447
+ });
448
+ it("throws an error when resolving something that isn't a member", () => {
449
+ const globalScope = createScope("global");
450
+ const [typeSymbol] = createSymbol("MyType", globalScope);
451
+ const [, ts2Key] = createSymbol("MyType2", globalScope);
452
+ const [, staticKey] = createSymbol("staticProp", typeSymbol.staticMembers);
453
+ expect(() => {
454
+ const result = binder.resolveDeclarationByKey(globalScope, memberRefkey(ts2Key, staticKey));
455
+ return result.value; // force evaluation
456
+ }).toThrow(/is not a member/);
140
457
  });
141
458
  });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=symbol-table.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-table.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/symbol-table.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createScope, createSymbol } from "./utils.js";
3
+ describe("OutputSymbol#moveTo", () => {
4
+ it("moves the symbol to a new symbol table", () => {
5
+ const scope = createScope("scope");
6
+ const [symbol] = createSymbol("sym", scope);
7
+ expect(symbol.spaces).toEqual([scope.symbols]);
8
+ const newScope = createScope("new-scope");
9
+ scope.symbols.moveTo(newScope.symbols);
10
+ expect(scope.symbols.has(symbol)).toBe(false);
11
+ expect(newScope.symbols.has(symbol)).toBe(true);
12
+ expect(symbol.spaces).toEqual([newScope.symbols]);
13
+ });
14
+ });
@@ -1,25 +1,11 @@
1
- import { Binder } from "../../src/index.browser.js";
2
- import { Refkey } from "../../src/refkey.js";
3
- import { OutputScopeFlags, OutputSymbolFlags } from "../../src/symbols/flags.js";
4
- import { OutputScope } from "../../src/symbols/output-scope.js";
5
- import { OutputSymbol } from "../../src/symbols/output-symbol.js";
6
- type ScopeRecords = Record<string, ScopeDescriptor>;
7
- type SymbolRecords = Record<string, SymbolDescriptor>;
8
- interface ScopeDescriptor {
9
- flags?: OutputScopeFlags;
10
- scopes?: ScopeRecords;
11
- symbols: SymbolRecords;
12
- }
13
- interface SymbolDescriptor {
14
- refkey?: Refkey;
15
- flags?: OutputSymbolFlags;
16
- instanceMembers?: SymbolRecords;
17
- staticMembers?: SymbolRecords;
18
- }
19
- interface ScopeTreeResult {
20
- symbols: Record<string, OutputSymbol>;
21
- scopes: Record<string, OutputScope>;
22
- }
23
- export declare function createScopeTree(binder: Binder, tree: ScopeRecords): ScopeTreeResult;
24
- export {};
1
+ import { Binder } from "../../src/binder.js";
2
+ import { OutputSpace } from "../../src/index.js";
3
+ import { Namekey, Refkey } from "../../src/refkey.js";
4
+ import { BasicScope } from "../../src/symbols/basic-scope.js";
5
+ import { BasicSymbol } from "../../src/symbols/basic-symbol.js";
6
+ import { OutputScopeOptions } from "../../src/symbols/output-scope.js";
7
+ import { OutputSymbolOptions } from "../../src/symbols/output-symbol.js";
8
+ export declare let binder: Binder;
9
+ export declare function createScope(name: string, parent?: BasicScope, options?: OutputScopeOptions): BasicScope;
10
+ export declare function createSymbol(name: string | Namekey, scope: BasicScope | OutputSpace, options?: OutputSymbolOptions): [BasicSymbol, Refkey];
25
11
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/symbols/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAU,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACpD,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAEtD,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,eAAe,CAAC,EAAE,aAAa,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AACD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,GACjB,eAAe,CA4DjB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/symbols/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAU,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAgBzE,eAAO,IAAI,MAAM,EAAE,MAAM,CAAC;AAK1B,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,UAAU,EACnB,OAAO,CAAC,EAAE,kBAAkB,cAM7B;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,KAAK,EAAE,UAAU,GAAG,WAAW,EAC/B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,CAAC,WAAW,EAAE,MAAM,CAAC,CAavB"}